assuan/
2009-03-06 Marcus Brinkmann <marcus@g10code.de> * assuan/: Update to libassuan SVN 2009-03-06. src/ 2009-03-06 Marcus Brinkmann <marcus@g10code.de> * version.c (do_subsystem_inits): Do not set assuan log level. * debug.c (debug_init): Likewise.
This commit is contained in:
parent
f0dccac380
commit
9ace1d5642
@ -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.
|
||||
|
423
assuan/ChangeLog
423
assuan/ChangeLog
@ -3,68 +3,262 @@
|
||||
* assuan-buffer.c (assuan_send_data): Add hack to optionally send
|
||||
a final "CAN".
|
||||
|
||||
2008-11-03 Marcus Brinkmann <marcus@g10code.com>
|
||||
2008-11-03 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* Makefile.am (INCLUDES): Replace gpgme path with src.
|
||||
* assuan-handler.c (std_handler_help): Make I unsigned to silence
|
||||
gcc -W warning.
|
||||
* assuan-logging.c (_assuan_log_print_buffer): Likewise for N.
|
||||
* funopen.c (_assuan_funopen): Remove initializer to silence gcc
|
||||
-W warning.
|
||||
* assuan-handler.c (std_cmd_table): Add missing initializer to
|
||||
silence gcc -W warning.
|
||||
* assuan-socket-server.c (io): Likewise.
|
||||
* assuan-socket-connect.c (assuan_socket_connect_ext): Likewise.
|
||||
|
||||
2008-10-30 Marcus Brinkmann <marcus@g10code.de>
|
||||
2008-10-29 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-pipe-connect.c: Fix prototype for _gpgme_io_spawn. Cast
|
||||
second argument in its invocation to silence gcc warning.
|
||||
* assuan.h (assuan_error_t) (_ASSUAN_ONLY_GPG_ERRORS): Make
|
||||
unsigned int.
|
||||
(assuan_transact): Change return type of callback handlers to
|
||||
assuan_error_t.
|
||||
|
||||
2008-06-25 Marcus Brinkmann <marcus@g10code.de>
|
||||
2008-10-15 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-pipe-connect.c (struct spawn_fd_item_s): Add new members.
|
||||
(HANDLE_TRANSLATION): New macro.
|
||||
(pipe_connect_gpgme): Adjust caller of _gpgme_io_spawn.
|
||||
[HANDLE_TRANSLATION]: Return translated handles.
|
||||
* assuan-logging.c (_assuan_log_printf): Flush if the format
|
||||
string ends with a LF.
|
||||
|
||||
2008-02-14 Werner Koch <wk@g10code.com>
|
||||
2008-09-01 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-pipe-connect.c (_gpgme_io_spawn): Adjust prototype.
|
||||
(pipe_connect_gpgme, pipe_connect_gpgme): Adjust call.
|
||||
* assuan-io.c: Include time.h. Fixes bug#951.
|
||||
(_assuan_usleep): Use nanosleep only is available.
|
||||
|
||||
2008-01-04 Marcus Brinkmann <marcus@g10code.de>
|
||||
2008-03-25 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-pipe-connect.c (_gpgme_io_pipe)
|
||||
(_gpgme_io_spawn) [_ASSUAN_IN_GPGME_BUILD_ASSUAN]: Add prototypes
|
||||
to silence compiler warning. Reported by Alon Bar-Lev.
|
||||
* assuan-inquire.c (assuan_inquire): Loop over _assuan_read_line
|
||||
for EAGAIN.
|
||||
|
||||
2008-03-21 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-defs.h (_assuan_usleep): New prototype.
|
||||
* assuan-io.c (_assuan_usleep): New function.
|
||||
* assuan-io-pth.c (_assuan_usleep): New function.
|
||||
* mkerrors: Do not incude <windows.h>, but assuan-defs.h.
|
||||
(_assuan_error_is_eagain): Call _assuan_usleep.
|
||||
|
||||
* mkerrors [HAVE_W32_SYSTEM]: Include <windows.h>
|
||||
(_assuan_error_is_eagain) [HAVE_W32_SYSTEM]: Wait the tenth of a
|
||||
second.
|
||||
|
||||
2007-11-23 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-inquire.c (_assuan_inquire_ext_cb): Pass through return
|
||||
value from callback function.
|
||||
Suggested by Ben Kibbey <bjk@luxsci.net>.
|
||||
|
||||
2007-11-14 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-pipe-connect.c (pipe_connect_unix): Add dummy arg FLAGS.
|
||||
(pipe_connect_w32): Add arg FLAGS and start process detached if
|
||||
requested. Changed callers to pass 0.
|
||||
(assuan_pipe_connect_ext): Pass FLAG.
|
||||
|
||||
2007-11-12 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-inquire.c (_assuan_inquire_ext_cb): Clear
|
||||
CTX->inquire_membuf after deallocating it.
|
||||
|
||||
2007-10-18 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-handler.c (std_handler_help): New function.
|
||||
(std_cmd_table): Add new command HELP.
|
||||
|
||||
2007-10-08 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-util.c (assuan_set_io_hooks): New.
|
||||
* assuan.h (struct assuan_io_hooks): New.
|
||||
(assuan_set_io_hooks, _assuan_io_hooks): Add prefix macros.
|
||||
* assuan-defs.h (_assuan_io_hooks): New.
|
||||
* assuan-io.c (do_io_read): Take all code from _assuan_io_read.
|
||||
(_assuan_io_read, _assuan_simple_read): Add hook feature.
|
||||
(do_io_write): Take all code from _assuan_io_write.
|
||||
(_assuan_io_write, _assuan_simple_write): Add hook feature.
|
||||
* assuan-io-pth.c (_assuan_simple_read, _assuan_simple_write)
|
||||
(_assuan_io_read, _assuan_io_write): Add hook feature.
|
||||
|
||||
2007-10-05 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan.h (_assuan_error_is_eagain): Add prefix macro.
|
||||
|
||||
* assuan-defs.h (_assuan_error_is_eagain): New prototype.
|
||||
* mkerrors (_assuan_error_is_eagain): New function.
|
||||
* assuan-handler.c (process_next): Leave on EAGAIN.
|
||||
* assuan-handler.c (process_request),
|
||||
assuan-client.c (_assuan_read_from_server),
|
||||
assuan-buffer.c (assuan_read_line): Busy loop over EAGAIN.
|
||||
|
||||
2007-10-05 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-socket.c (_assuan_sock_wsa2errno): Map WSANOTINITIALISED.
|
||||
(_assuan_sock_new): Use assuan_fd_t.
|
||||
* assuan.h (_assuan_sock_wsa2errno): Add prefix macro.
|
||||
|
||||
2007-10-05 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-defs.h (_assuan_sock_wsa2errno) [HAVE_W32_SYSTEM]: Add prototype.
|
||||
* assuan-uds.c (wsa2errno) [HAVE_W32_SYSTEM]: Move and rename to ...
|
||||
* assuan-socket.c (_assuan_sock_wsa2errno) [HAVE_W32_SYSTEM]: ... this.
|
||||
(_assuan_close, _assuan_sock_new, _assuan_sock_connect, _assuan_sock_bind):
|
||||
Always set errno on error.
|
||||
|
||||
* assuan-uds.c (wsa2errno) [HAVE_W32_SYSTEM]: New function.
|
||||
(uds_reader, uds_writer) [HAVE_W32_SYSTEM]: Set errno.
|
||||
|
||||
2007-10-04 Werner Koch <wk@g10code.com>
|
||||
|
||||
* mkerrors: Map EAGAIN to GPG_ERR_EAGAIN for read and write
|
||||
errors.
|
||||
|
||||
2007-10-02 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-io.c (_assuan_io_read) [W32]: Map WSAEWOULDBLOCK to EAGAIN.
|
||||
* assuan-socket.c (_assuan_sock_check_nonce): N needs to be signed.
|
||||
|
||||
* assuan-defs.h (struct assuan_context_s): Add LISTEN_NONCE.
|
||||
* assuan-socket-server.c (assuan_set_sock_nonce): New.
|
||||
(accept_connection): Check the nonce.
|
||||
|
||||
2007-10-01 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan.h (ASSUAN_INT2FD, ASSUAN_FD2INT): New.
|
||||
|
||||
* assuan-socket.c: Rewritten.
|
||||
(assuan_sock_new, assuan_sock_connect, assuan_sock_bind)
|
||||
(assuan_sock_get_nonce, assuan_sock_check_nonce): New APIs.
|
||||
|
||||
* assuan-io.c (_assuan_simple_read, _assuan_simple_write):
|
||||
Factored code out to ...
|
||||
(_assuan_io_read, _assuan_io_write): .. new.
|
||||
* assuan-io-pth.c (_assuan_io_read, _assuan_io_write): New.
|
||||
|
||||
2007-09-25 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan.h (_assuan_gpg_strerror_r, _assuan_gpg_strsource): Add
|
||||
new wrappers.
|
||||
wrappers for these new internal functions.
|
||||
|
||||
2007-09-24 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-uds.c (uds_reader) [HAVE_W32_SYSTEM]: Do not touch the
|
||||
UDS structure in the context. Reported by Frank Osterfeld.
|
||||
(uds_writer): Clarify code.
|
||||
|
||||
2007-09-14 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-pipe-connect.c (do_finish) [HAVE_W32_SYSTEM]: Close
|
||||
ctx->pid as handle.
|
||||
(pipe_connect_w32): Save the spawned processes handle.
|
||||
|
||||
2007-09-13 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-socket.c (_assuan_close): Add inactive debug outputs.
|
||||
|
||||
2007-09-11 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan.h: Use _WIN32 instead of HAVE_W32_SYSTEM.
|
||||
|
||||
2007-09-07 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-inquire.c (assuan_inquire_ext): If MAXLEN is 0, still
|
||||
initialize MEMBUF.
|
||||
|
||||
* assuan-inquire.c (_assuan_inquire_ext_cb): Clear CTX->in_inquire
|
||||
before invoking callback and returning.
|
||||
|
||||
2007-09-05 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-handler.c (dispatch_command): Return non-critical errors
|
||||
with PROCESS_DONE ().
|
||||
|
||||
2007-09-03 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan.h [_ASSUAN_EXT_SYM_PREFIX]: Add missing symbol renames
|
||||
with _ASSUAN_PREFIX.
|
||||
|
||||
2007-08-02 Werner Koch <wk@g10code.com>
|
||||
2007-09-03 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-pipe-connect.c (pipe_connect_w32): A bit more debug output.
|
||||
(pipe_connect_w32): Use DETACHED_PROCESS flag.
|
||||
* assuan-logging.c (log_level): New. Use this to disable logging.
|
||||
(assuan_set_assuan_log_level): New.
|
||||
* assuan.h: Add prototype.
|
||||
* assuan.h [_ASSUAN_EXT_SYM_PREFIX]: Add missing symbol renames
|
||||
with _ASSUAN_PREFIX.
|
||||
|
||||
* assuan.h (assuan_inquire_ext): Move buffer and buffer_length
|
||||
arguments callback in prototype.
|
||||
* assuan-defs.h (struct assuan_context_s): Remove members
|
||||
inquire_r_buffer and inquire_r_buffer_len. Add buffer and buffer
|
||||
length arguments to inquire_cb.
|
||||
* assuan-inquire.c (_assuan_inquire_ext_cb): Return buffer and
|
||||
buffer length via callback.
|
||||
(assuan_inquire_ext): Move buffer and buffer length arguments to
|
||||
callback.
|
||||
|
||||
2007-08-24 Werner Koch <wk@g10code.com>
|
||||
|
||||
Switched license to back to LGPLv2.1.
|
||||
|
||||
2007-08-09 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan.h (assuan_process_done, assuan_inquire_ext): New
|
||||
prototypes.
|
||||
* assuan-defs.h (struct assuan_context_s): New members
|
||||
in_process_next, in_command, inquire_cb, inquire_cb_data,
|
||||
inquire_r_buffer, inquire_r_buffer_len, inquire_membuf.
|
||||
(_assuan_inquire_ext_cb, _assuan_inquire_release): New prototypes.
|
||||
* assuan-handler.c (PROCESS_DONE): New macro.
|
||||
(dummy_handler, std_handler_nop, std_handler_cancel)
|
||||
(std_handler_option, std_handler_bye, std_handler_auth)
|
||||
(std_handler_reset, std_handler_end): Use PROCESS_DONE to
|
||||
optionally call assuan_process_done if CTX->in_process_next is
|
||||
true.
|
||||
(assuan_process_done, process_next): New functions.
|
||||
(assuan_process_next): Rewritten to support external event
|
||||
handling.
|
||||
* mkerrors: Do not clear high bits of -1 for old style EOF.
|
||||
* assuan-inquire.c (_assuan_inquire_release)
|
||||
(_assuan_inquire_ext_cb, assuan_inquire_ext): New functions.
|
||||
* assuan-pipe-server.c (_assuan_release_context): Call
|
||||
_assuan_inquire_release.
|
||||
|
||||
2007-07-12 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-handler.c (assuan_get_active_fds): Use get_osfhandle for
|
||||
the data fp.
|
||||
* assuan-socket.c (_assuan_close) [W32]: Use CloseHandle and not close.
|
||||
|
||||
* assuan-io.c (_assuan_simple_write, _assuan_simple_read): Map
|
||||
ERROR_BROKEN_PIPE to EPIPE.
|
||||
* 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>
|
||||
|
||||
* assuan-defs.h (struct assuan_context_s): Have partial peercred
|
||||
structure even if HAVE_W32_SYSTEM, and have full peercred
|
||||
structure only if HAVE_SO_PEERCRED.
|
||||
* assuan-defs.h (struct assuan_context_s): Have full peercred
|
||||
structure for HAVE_SO_PEERCRED.
|
||||
* assuan-connect.c (assuan_get_peercred) [!HAVE_SO_PEERCRED]: Do
|
||||
not try to set PID, UID and GID.
|
||||
|
||||
2007-07-05 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-defs.h (struct assuan_context_s): Have peercred.valid
|
||||
even for Windows. This makes some other code cleaner.
|
||||
|
||||
* assuan.h (ASSUAN_CONFIDENTIAL): New flag.
|
||||
* assuan-util.c (assuan_set_flag, assuan_get_flag): Support flag.
|
||||
|
||||
2007-07-04 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
Change _WIN32 to HAVE_W32_SYSTEM for consistency.
|
||||
@ -382,28 +576,63 @@
|
||||
to silence gcc warning.
|
||||
* assuan-inquire.c (assuan_inquire): Likewise.
|
||||
|
||||
2005-08-19 Werner Koch <wk@g10code.com>
|
||||
2005-09-08 Marcus Brinkmann <marcus@g10code.com>
|
||||
|
||||
* funopen.c, assuan-socket.c: Copied from libassuan CVS.
|
||||
* assuan-pipe-connect.c (assuan_pipe_connect2): Add missing
|
||||
declaration of PID.
|
||||
|
||||
2005-08-09 Werner Koch <wk@g10code.com>
|
||||
|
||||
* README.1st: Adjusted to cope with changes done in upstream Assuan.
|
||||
* 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-logging.c, assuan-io.c: Include config.h
|
||||
Replaced all usages of _WIN32 by the new HAVE_W32_SYSTEM because
|
||||
there is nothing winning in this API.
|
||||
* assuan-pipe-connect.c (assuan_pipe_connect2) [_WIN32]: Return
|
||||
error Not Imlemented.
|
||||
|
||||
2005-05-21 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-util.c (assuan_set_flag, assuan_get_flag): New.
|
||||
* assuan-defs.h (struct assuan_context_s): New field flags.
|
||||
* assuan.h (assuan_flag_t): New with one flag value
|
||||
ASSUAN_NO_WAITPID for now.
|
||||
* assuan-pipe-connect.c (do_finish): Take care of the no_waitpid
|
||||
flag.
|
||||
|
||||
2005-04-04 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-util.c (_assuan_calloc): Avoid integer overflow.
|
||||
|
||||
2005-03-22 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-defs.h (struct assuan_io): Renamed elements READ and
|
||||
WRITE to READFNC and WRITEFNC to avoid problems with read defined
|
||||
as macros. Changed callers. Noted by Ville Skyttä.
|
||||
|
||||
2005-02-24 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-client.c (assuan_transact): Handle empty and comment
|
||||
commands correctly.
|
||||
|
||||
2004-12-20 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-socket-connect.c (assuan_socket_connect) [W32]: Allow for
|
||||
a drive letter in the path.
|
||||
|
||||
2004-12-19 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-pipe-server.c (assuan_init_pipe_server) [W32]: Map file
|
||||
descriptors using _get_osfhandle.
|
||||
|
||||
2004-12-19 Moritz Schulte <moritz@g10code.com>
|
||||
|
||||
* assuan-pipe-connect.c (assuan_pipe_connect2): Removed "`"
|
||||
character at beginning of line 532.
|
||||
|
||||
2004-12-18 Werner Koch <wk@g10code.com>
|
||||
|
||||
* assuan-logging.c (_assuan_w32_strerror): New.
|
||||
* assuan-defs.h (w32_strerror): new.
|
||||
* assuan-pipe-connect.c (assuan_pipe_connect2, fix_signals):
|
||||
@ -411,57 +640,95 @@
|
||||
(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.
|
||||
|
||||
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>
|
||||
|
||||
2004-12-16 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.
|
||||
|
||||
2004-12-07 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* README.1st: Add copyright notice.
|
||||
* assuan-socket-connect.c: Define SUN_LEN, AF_LOCAL and PF_LOCAL
|
||||
if they are not available.
|
||||
* assuan-domain-connect.c: Define PF_LOCAL and AF_LOCAL if needed.
|
||||
|
||||
2004-06-23 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* assuan-domain-connect.c [HAVE_SYS_UIO_H]: Include <sys/uio.h>.
|
||||
|
||||
* assuan-handler.c: Include <errno.h>.
|
||||
2004-05-11 Werner Koch <wk@gnupg.org>
|
||||
|
||||
2004-06-08 Marcus Brinkmann <marcus@g10code.de>
|
||||
* assuan-listen.c (assuan_set_hello_line, assuan_accept): Allow
|
||||
for multi line hello strings.
|
||||
|
||||
* assuan-buffer.c (assuan_write_line): If the line is longer than
|
||||
the maximum line length, bail out early.
|
||||
* assuan-buffer.c (_assuan_write_line): New with parts of ..
|
||||
(assuan_write_line): .. factored out.
|
||||
|
||||
2004-04-29 Werner Koch <wk@gnupg.org>
|
||||
|
||||
* assuan-socket-connect.c: Include string.h.
|
||||
* assuan-logging.c: Ditto.
|
||||
|
||||
2004-04-22 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* libassuan.m4: Quote first argument to AC_DEFUN.
|
||||
|
||||
2004-04-21 Werner Koch <wk@gnupg.org>
|
||||
|
||||
@ -1039,7 +1306,7 @@
|
||||
* assuan-defs.h: Add space in the context for this.
|
||||
|
||||
|
||||
Copyright 2001, 2002, 2006 Free Software Foundation, Inc.
|
||||
Copyright 2001, 2002, 2006, 2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is free software; as a special exception the author gives
|
||||
unlimited permission to copy and/or distribute it, with or without
|
||||
|
@ -14,9 +14,7 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -53,9 +51,10 @@ writen (assuan_context_t ctx, const char *buffer, size_t length)
|
||||
return 0; /* okay */
|
||||
}
|
||||
|
||||
/* Read an entire line. Returns 0 on success or -1 and ERRNo on
|
||||
/* Read an entire line. Returns 0 on success or -1 and ERRNO on
|
||||
failure. EOF is indictated by setting the integer at address
|
||||
R_EOF. */
|
||||
R_EOF. Note: BUF, R_NREAD and R_EOF contain a valid result even if
|
||||
an error is returned. */
|
||||
static int
|
||||
readline (assuan_context_t ctx, char *buf, size_t buflen,
|
||||
int *r_nread, int *r_eof)
|
||||
@ -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)
|
||||
{
|
||||
@ -134,11 +133,23 @@ _assuan_read_line (assuan_context_t ctx)
|
||||
&nread, &ctx->inbound.eof);
|
||||
if (rc)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
|
||||
if (ctx->log_fp)
|
||||
fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Error: %s (%d)]\n",
|
||||
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)
|
||||
@ -147,7 +158,7 @@ _assuan_read_line (assuan_context_t ctx)
|
||||
if (ctx->log_fp)
|
||||
fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [EOF]\n",
|
||||
assuan_get_assuan_log_prefix (),
|
||||
(unsigned int)getpid (), ctx->inbound.fd);
|
||||
(unsigned int)getpid (), (int)ctx->inbound.fd);
|
||||
return _assuan_error (-1);
|
||||
}
|
||||
|
||||
@ -191,7 +202,7 @@ _assuan_read_line (assuan_context_t ctx)
|
||||
{
|
||||
fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- ",
|
||||
assuan_get_assuan_log_prefix (),
|
||||
(unsigned int)getpid (), ctx->inbound.fd);
|
||||
(unsigned int)getpid (), (int)ctx->inbound.fd);
|
||||
if (ctx->confidential)
|
||||
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||
else
|
||||
@ -207,7 +218,7 @@ _assuan_read_line (assuan_context_t ctx)
|
||||
if (ctx->log_fp)
|
||||
fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Invalid line]\n",
|
||||
assuan_get_assuan_log_prefix (),
|
||||
(unsigned int)getpid (), ctx->inbound.fd);
|
||||
(unsigned int)getpid (), (int)ctx->inbound.fd);
|
||||
*line = 0;
|
||||
ctx->inbound.linelen = 0;
|
||||
return _assuan_error (ctx->inbound.eof
|
||||
@ -234,7 +245,12 @@ assuan_read_line (assuan_context_t ctx, char **line, size_t *linelen)
|
||||
if (!ctx)
|
||||
return _assuan_error (ASSUAN_Invalid_Value);
|
||||
|
||||
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;
|
||||
@ -265,7 +281,7 @@ _assuan_write_line (assuan_context_t ctx, const char *prefix,
|
||||
fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> "
|
||||
"[supplied line too long -truncated]\n",
|
||||
assuan_get_assuan_log_prefix (),
|
||||
(unsigned int)getpid (), ctx->inbound.fd);
|
||||
(unsigned int)getpid (), (int)ctx->inbound.fd);
|
||||
if (prefixlen > 5)
|
||||
prefixlen = 5;
|
||||
if (len > ASSUAN_LINELENGTH - prefixlen - 2)
|
||||
@ -281,7 +297,7 @@ _assuan_write_line (assuan_context_t ctx, const char *prefix,
|
||||
{
|
||||
fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
|
||||
assuan_get_assuan_log_prefix (),
|
||||
(unsigned int)getpid (), ctx->inbound.fd);
|
||||
(unsigned int)getpid (), (int)ctx->inbound.fd);
|
||||
if (ctx->confidential)
|
||||
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||
else
|
||||
@ -333,7 +349,7 @@ assuan_write_line (assuan_context_t ctx, const char *line)
|
||||
fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> "
|
||||
"[supplied line contained a LF - truncated]\n",
|
||||
assuan_get_assuan_log_prefix (),
|
||||
(unsigned int)getpid (), ctx->inbound.fd);
|
||||
(unsigned int)getpid (), (int)ctx->inbound.fd);
|
||||
|
||||
return _assuan_write_line (ctx, NULL, line, len);
|
||||
}
|
||||
@ -398,7 +414,7 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size)
|
||||
{
|
||||
fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
|
||||
assuan_get_assuan_log_prefix (),
|
||||
(unsigned int)getpid (), ctx->inbound.fd);
|
||||
(unsigned int)getpid (), (int)ctx->inbound.fd);
|
||||
|
||||
if (ctx->confidential)
|
||||
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||
@ -454,7 +470,7 @@ _assuan_cookie_write_flush (void *cookie)
|
||||
{
|
||||
fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ",
|
||||
assuan_get_assuan_log_prefix (),
|
||||
(unsigned int)getpid (), ctx->inbound.fd);
|
||||
(unsigned int)getpid (), (int)ctx->inbound.fd);
|
||||
if (ctx->confidential)
|
||||
fputs ("[Confidential data not shown]", ctx->log_fp);
|
||||
else
|
||||
@ -524,11 +540,11 @@ assuan_send_data (assuan_context_t ctx, const void *buffer, size_t length)
|
||||
}
|
||||
|
||||
assuan_error_t
|
||||
assuan_sendfd (assuan_context_t ctx, int fd)
|
||||
assuan_sendfd (assuan_context_t ctx, assuan_fd_t fd)
|
||||
{
|
||||
/* It is explicitly allowed to use (NULL, -1) as a runtime test to
|
||||
check whether descriptor passing is available. */
|
||||
if (!ctx && fd == -1)
|
||||
if (!ctx && fd == ASSUAN_INVALID_FD)
|
||||
#ifdef USE_DESCRIPTOR_PASSING
|
||||
return 0;
|
||||
#else
|
||||
@ -543,7 +559,7 @@ assuan_sendfd (assuan_context_t ctx, int fd)
|
||||
}
|
||||
|
||||
assuan_error_t
|
||||
assuan_receivefd (assuan_context_t ctx, int *fd)
|
||||
assuan_receivefd (assuan_context_t ctx, assuan_fd_t *fd)
|
||||
{
|
||||
if (! ctx->io->receivefd)
|
||||
return set_error (ctx, Not_Implemented,
|
||||
|
@ -14,9 +14,7 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -44,7 +42,11 @@ _assuan_read_from_server (assuan_context_t ctx, int *okay, int *off)
|
||||
*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;
|
||||
|
@ -14,9 +14,7 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -60,8 +58,8 @@ assuan_get_pid (assuan_context_t ctx)
|
||||
|
||||
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
/* Return user credentials. PID, UID and GID amy be gived as NULL if
|
||||
you are not interested in this value. For getting the pid of the
|
||||
/* Return user credentials. PID, UID and GID may be given as NULL if
|
||||
you are not interested in a value. For getting the pid of the
|
||||
peer the assuan_get_pid is usually better suited. */
|
||||
assuan_error_t
|
||||
assuan_get_peercred (assuan_context_t ctx, pid_t *pid, uid_t *uid, gid_t *gid)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* assuan-defs.c - Internal definitions to Assuan
|
||||
* Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Assuan.
|
||||
*
|
||||
@ -40,17 +40,6 @@
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
#define AF_LOCAL AF_UNIX
|
||||
/* We need to prefix the structure with a sockaddr_in header so we can
|
||||
use it later for sendto and recvfrom. */
|
||||
struct sockaddr_un
|
||||
{
|
||||
short sun_family;
|
||||
unsigned short sun_port;
|
||||
struct in_addr sun_addr;
|
||||
char sun_path[108-2-4]; /* Path name. */
|
||||
};
|
||||
|
||||
/* Not needed anymore because the current mingw32 defines this in
|
||||
sys/types.h */
|
||||
/* typedef int ssize_t; */
|
||||
@ -80,12 +69,16 @@ struct assuan_io
|
||||
/* Routine to write to output_fd. */
|
||||
ssize_t (*writefnc) (assuan_context_t, const void *, size_t);
|
||||
/* Send a file descriptor. */
|
||||
assuan_error_t (*sendfd) (assuan_context_t, int);
|
||||
assuan_error_t (*sendfd) (assuan_context_t, assuan_fd_t);
|
||||
/* Receive a file descriptor. */
|
||||
assuan_error_t (*receivefd) (assuan_context_t, int *);
|
||||
assuan_error_t (*receivefd) (assuan_context_t, assuan_fd_t *);
|
||||
};
|
||||
|
||||
|
||||
/* The global variable with the optional hook fucntions. */
|
||||
extern struct assuan_io_hooks _assuan_io_hooks;
|
||||
|
||||
|
||||
/* The context we use with most functions. */
|
||||
struct assuan_context_s
|
||||
{
|
||||
@ -103,6 +96,14 @@ struct assuan_context_s
|
||||
int confidential;
|
||||
int is_server; /* Set if this is context belongs to a server */
|
||||
int in_inquire;
|
||||
int in_process_next;
|
||||
int in_command;
|
||||
|
||||
/* The following members are used by assuan_inquire_ext. */
|
||||
int (*inquire_cb) (void *cb_data, int rc, unsigned char *buf, size_t len);
|
||||
void *inquire_cb_data;
|
||||
void *inquire_membuf;
|
||||
|
||||
char *hello_line;
|
||||
char *okay_line; /* See assuan_set_okay_line() */
|
||||
|
||||
@ -111,7 +112,7 @@ struct assuan_context_s
|
||||
FILE *log_fp;
|
||||
|
||||
struct {
|
||||
int fd;
|
||||
assuan_fd_t fd;
|
||||
int eof;
|
||||
char line[LINELENGTH];
|
||||
int linelen; /* w/o CR, LF - might not be the same as
|
||||
@ -125,7 +126,7 @@ struct assuan_context_s
|
||||
} inbound;
|
||||
|
||||
struct {
|
||||
int fd;
|
||||
assuan_fd_t fd;
|
||||
struct {
|
||||
FILE *fp;
|
||||
char line[LINELENGTH];
|
||||
@ -137,8 +138,10 @@ struct assuan_context_s
|
||||
int pipe_mode; /* We are in pipe mode, i.e. we can handle just one
|
||||
connection and must terminate then. */
|
||||
pid_t pid; /* The pid of the peer. */
|
||||
int listen_fd; /* The fd we are listening on (used by socket servers) */
|
||||
int connected_fd; /* helper */
|
||||
assuan_fd_t listen_fd; /* The fd we are listening on (used by
|
||||
socket servers) */
|
||||
assuan_sock_nonce_t listen_nonce; /* Used with LISTEN_FD. */
|
||||
assuan_fd_t connected_fd; /* helper */
|
||||
|
||||
struct {
|
||||
int valid; /* Whether this structure has valid information. */
|
||||
@ -162,7 +165,7 @@ struct assuan_context_s
|
||||
int bufferoffset; /* Offset of start of buffer. */
|
||||
int buffersize; /* Bytes buffered. */
|
||||
|
||||
int pendingfds[5]; /* Array to save received descriptors. */
|
||||
assuan_fd_t pendingfds[5]; /* Array to save received descriptors. */
|
||||
int pendingfdscount; /* Number of received descriptors. */
|
||||
} uds;
|
||||
|
||||
@ -188,15 +191,15 @@ struct assuan_context_s
|
||||
/* If set, this is called right before logging an I/O line. With
|
||||
DIRECTION set to 1 it is called for an output oeration; 0 means
|
||||
an input operation. If bit 0 is set in the return value, the
|
||||
logging of the will be suppressed. With bit 1 set, the entire
|
||||
line will be ignored. */
|
||||
logging of the line will be suppressed. With bit 1 set, the
|
||||
entire line will be ignored. */
|
||||
unsigned int (*io_monitor)(assuan_context_t ctx,
|
||||
int direction,
|
||||
const char *line,
|
||||
size_t linelen);
|
||||
|
||||
int input_fd; /* set by INPUT command */
|
||||
int output_fd; /* set by OUTPUT command */
|
||||
assuan_fd_t input_fd; /* Set by the INPUT command. */
|
||||
assuan_fd_t output_fd; /* Set by the OUTPUT command. */
|
||||
|
||||
/* io routines. */
|
||||
struct assuan_io *io;
|
||||
@ -228,17 +231,22 @@ assuan_error_t _assuan_read_from_server (assuan_context_t ctx,
|
||||
|
||||
/*-- assuan-error.c --*/
|
||||
|
||||
/*-- assuan-inquire.c --*/
|
||||
int _assuan_inquire_ext_cb (assuan_context_t ctx);
|
||||
void _assuan_inquire_release (assuan_context_t ctx);
|
||||
|
||||
/* Map error codes as used in this implementaion to the libgpg-error
|
||||
/* Map error codes as used in this implementation to the libgpg-error
|
||||
codes. */
|
||||
assuan_error_t _assuan_error (int oldcode);
|
||||
/* Check if ERR means EAGAIN. */
|
||||
int _assuan_error_is_eagain (assuan_error_t err);
|
||||
|
||||
/* Extrac the erro code from A. This works for both the old and the
|
||||
new style error codes. This needs to be whenever an error code is
|
||||
compared. */
|
||||
/* Extract the error code from A. This works for both the old and the
|
||||
new style error codes. This needs to be used whenever an error
|
||||
code is compared. */
|
||||
#define err_code(a) ((a) & 0x00ffffff)
|
||||
|
||||
/* Check whether A is the erro code for EOF. We allow forold and new
|
||||
/* Check whether A is the erro code for EOF. We allow for old and new
|
||||
style EOF error codes here. */
|
||||
#define err_is_eof(a) ((a) == (-1) || err_code (a) == 16383)
|
||||
|
||||
@ -284,6 +292,8 @@ pid_t _assuan_waitpid (pid_t pid, int *status, int options);
|
||||
ssize_t _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size);
|
||||
ssize_t _assuan_simple_write (assuan_context_t ctx, const void *buffer,
|
||||
size_t size);
|
||||
ssize_t _assuan_io_read (assuan_fd_t fd, void *buffer, size_t size);
|
||||
ssize_t _assuan_io_write (assuan_fd_t fd, const void *buffer, size_t size);
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
int _assuan_simple_sendmsg (assuan_context_t ctx, void *msg);
|
||||
int _assuan_simple_recvmsg (assuan_context_t ctx, void *msg);
|
||||
@ -292,11 +302,21 @@ ssize_t _assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg);
|
||||
ssize_t _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg);
|
||||
#endif
|
||||
|
||||
void _assuan_usleep (unsigned int usec);
|
||||
|
||||
|
||||
/*-- assuan-socket.c --*/
|
||||
int _assuan_close (int fd);
|
||||
int _assuan_sock_new (int domain, int type, int proto);
|
||||
int _assuan_sock_bind (int sockfd, struct sockaddr *addr, int addrlen);
|
||||
int _assuan_sock_connect (int sockfd, struct sockaddr *addr, int addrlen);
|
||||
int _assuan_close (assuan_fd_t fd);
|
||||
assuan_fd_t _assuan_sock_new (int domain, int type, int proto);
|
||||
int _assuan_sock_connect (assuan_fd_t sockfd,
|
||||
struct sockaddr *addr, int addrlen);
|
||||
int _assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen);
|
||||
int _assuan_sock_get_nonce (struct sockaddr *addr, int addrlen,
|
||||
assuan_sock_nonce_t *nonce);
|
||||
int _assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce);
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
int _assuan_sock_wsa2errno (int err);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FOPENCOOKIE
|
||||
/* We have to implement funopen in terms of glibc's fopencookie. */
|
||||
@ -329,4 +349,13 @@ int putc_unlocked (int c, FILE *stream);
|
||||
#define DIMof(type,member) DIM(((type *)0)->member)
|
||||
|
||||
|
||||
#if HAVE_W32_SYSTEM
|
||||
#define SOCKET2HANDLE(s) ((void *)(s))
|
||||
#define HANDLE2SOCKET(h) ((unsigned int)(h))
|
||||
#else
|
||||
#define SOCKET2HANDLE(s) (s)
|
||||
#define HANDLE2SOCKET(h) (h)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /*ASSUAN_DEFS_H*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* assuan-handler.c - dispatch commands
|
||||
* Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002, 2003, 2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Assuan.
|
||||
*
|
||||
@ -14,9 +14,7 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -35,18 +33,21 @@
|
||||
static int my_strcasecmp (const char *a, const char *b);
|
||||
|
||||
|
||||
#define PROCESS_DONE(ctx, rc) \
|
||||
((ctx)->in_process_next ? assuan_process_done ((ctx), (rc)) : (rc))
|
||||
|
||||
static int
|
||||
dummy_handler (assuan_context_t ctx, char *line)
|
||||
{
|
||||
return set_error (ctx, Server_Fault, "no handler registered");
|
||||
return
|
||||
PROCESS_DONE (ctx, set_error (ctx, Server_Fault, "no handler registered"));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
std_handler_nop (assuan_context_t ctx, char *line)
|
||||
{
|
||||
return 0; /* okay */
|
||||
return PROCESS_DONE (ctx, 0); /* okay */
|
||||
}
|
||||
|
||||
static int
|
||||
@ -54,7 +55,7 @@ std_handler_cancel (assuan_context_t ctx, char *line)
|
||||
{
|
||||
if (ctx->cancel_notify_fnc)
|
||||
ctx->cancel_notify_fnc (ctx);
|
||||
return set_error (ctx, Not_Implemented, NULL);
|
||||
return PROCESS_DONE (ctx, set_error (ctx, Not_Implemented, NULL));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -65,9 +66,12 @@ std_handler_option (assuan_context_t ctx, char *line)
|
||||
for (key=line; spacep (key); key++)
|
||||
;
|
||||
if (!*key)
|
||||
return set_error (ctx, Syntax_Error, "argument required");
|
||||
return
|
||||
PROCESS_DONE (ctx, set_error (ctx, Syntax_Error, "argument required"));
|
||||
if (*key == '=')
|
||||
return set_error (ctx, Syntax_Error, "no option name given");
|
||||
return
|
||||
PROCESS_DONE (ctx, set_error (ctx, Syntax_Error,
|
||||
"no option name given"));
|
||||
for (value=key; *value && !spacep (value) && *value != '='; value++)
|
||||
;
|
||||
if (*value)
|
||||
@ -82,7 +86,9 @@ std_handler_option (assuan_context_t ctx, char *line)
|
||||
for (; spacep (value); value++)
|
||||
;
|
||||
if (!*value)
|
||||
return set_error (ctx, Syntax_Error, "option argument expected");
|
||||
return
|
||||
PROCESS_DONE (ctx, set_error (ctx, Syntax_Error,
|
||||
"option argument expected"));
|
||||
}
|
||||
if (*value)
|
||||
{
|
||||
@ -96,12 +102,13 @@ std_handler_option (assuan_context_t ctx, char *line)
|
||||
if (*key == '-' && key[1] == '-' && key[2])
|
||||
key += 2; /* the double dashes are optional */
|
||||
if (*key == '-')
|
||||
return set_error (ctx, Syntax_Error,
|
||||
"option should not begin with one dash");
|
||||
return PROCESS_DONE (ctx,
|
||||
set_error (ctx, Syntax_Error,
|
||||
"option should not begin with one dash"));
|
||||
|
||||
if (ctx->option_handler_fnc)
|
||||
return ctx->option_handler_fnc (ctx, key, value);
|
||||
return 0;
|
||||
return PROCESS_DONE (ctx, ctx->option_handler_fnc (ctx, key, value));
|
||||
return PROCESS_DONE (ctx, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -111,13 +118,13 @@ std_handler_bye (assuan_context_t ctx, char *line)
|
||||
ctx->bye_notify_fnc (ctx);
|
||||
assuan_close_input_fd (ctx);
|
||||
assuan_close_output_fd (ctx);
|
||||
return -1; /* pretty simple :-) */
|
||||
return PROCESS_DONE (ctx, _assuan_error (-1)); /* pretty simple :-) */
|
||||
}
|
||||
|
||||
static int
|
||||
std_handler_auth (assuan_context_t ctx, char *line)
|
||||
{
|
||||
return set_error (ctx, Not_Implemented, NULL);
|
||||
return PROCESS_DONE (ctx, set_error (ctx, Not_Implemented, NULL));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -128,17 +135,35 @@ std_handler_reset (assuan_context_t ctx, char *line)
|
||||
assuan_close_input_fd (ctx);
|
||||
assuan_close_output_fd (ctx);
|
||||
_assuan_uds_close_fds (ctx);
|
||||
return 0;
|
||||
return PROCESS_DONE (ctx, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
std_handler_end (assuan_context_t ctx, char *line)
|
||||
std_handler_help (assuan_context_t ctx, char *line)
|
||||
{
|
||||
return set_error (ctx, Not_Implemented, NULL);
|
||||
unsigned int i;
|
||||
char buf[ASSUAN_LINELENGTH];
|
||||
|
||||
for (i = 0; i < ctx->cmdtbl_used; i++)
|
||||
{
|
||||
snprintf (buf, sizeof (buf), "# %s", ctx->cmdtbl[i].name);
|
||||
buf[ASSUAN_LINELENGTH - 1] = '\0';
|
||||
assuan_write_line (ctx, buf);
|
||||
}
|
||||
|
||||
return PROCESS_DONE (ctx, 0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
std_handler_end (assuan_context_t ctx, char *line)
|
||||
{
|
||||
return PROCESS_DONE (ctx, set_error (ctx, Not_Implemented, NULL));
|
||||
}
|
||||
|
||||
|
||||
assuan_error_t
|
||||
assuan_command_parse_fd (assuan_context_t ctx, char *line, int *rfd)
|
||||
assuan_command_parse_fd (assuan_context_t ctx, char *line, assuan_fd_t *rfd)
|
||||
{
|
||||
char *endp;
|
||||
|
||||
@ -151,7 +176,13 @@ assuan_command_parse_fd (assuan_context_t ctx, char *line, int *rfd)
|
||||
line ++;
|
||||
if (!digitp (*line))
|
||||
return set_error (ctx, Syntax_Error, "number required");
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
/* Fixme: For a W32/64bit system we will need to change the cast
|
||||
and the conversion fucntion. */
|
||||
*rfd = (void*)strtoul (line, &endp, 10);
|
||||
#else
|
||||
*rfd = strtoul (line, &endp, 10);
|
||||
#endif
|
||||
/* Remove that argument so that a notify handler won't see it. */
|
||||
memset (line, ' ', endp? (endp-line):strlen(line));
|
||||
|
||||
@ -166,34 +197,37 @@ assuan_command_parse_fd (assuan_context_t ctx, char *line, int *rfd)
|
||||
return assuan_receivefd (ctx, rfd);
|
||||
}
|
||||
|
||||
|
||||
/* Format is INPUT FD=<n> */
|
||||
static int
|
||||
std_handler_input (assuan_context_t ctx, char *line)
|
||||
{
|
||||
int rc, fd;
|
||||
int rc;
|
||||
assuan_fd_t fd;
|
||||
|
||||
rc = assuan_command_parse_fd (ctx, line, &fd);
|
||||
if (rc)
|
||||
return rc;
|
||||
return PROCESS_DONE (ctx, rc);
|
||||
ctx->input_fd = fd;
|
||||
if (ctx->input_notify_fnc)
|
||||
ctx->input_notify_fnc (ctx, line);
|
||||
return 0;
|
||||
return PROCESS_DONE (ctx, 0);
|
||||
}
|
||||
|
||||
/* Format is OUTPUT FD=<n> */
|
||||
static int
|
||||
std_handler_output (assuan_context_t ctx, char *line)
|
||||
{
|
||||
int rc, fd;
|
||||
int rc;
|
||||
assuan_fd_t fd;
|
||||
|
||||
rc = assuan_command_parse_fd (ctx, line, &fd);
|
||||
if (rc)
|
||||
return rc;
|
||||
return PROCESS_DONE (ctx, rc);
|
||||
ctx->output_fd = fd;
|
||||
if (ctx->output_notify_fnc)
|
||||
ctx->output_notify_fnc (ctx, line);
|
||||
return 0;
|
||||
return PROCESS_DONE (ctx, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -215,11 +249,12 @@ static struct {
|
||||
{ "AUTH", std_handler_auth, 1 },
|
||||
{ "RESET", std_handler_reset, 1 },
|
||||
{ "END", std_handler_end, 1 },
|
||||
{ "HELP", std_handler_help, 1 },
|
||||
|
||||
{ "INPUT", std_handler_input },
|
||||
{ "OUTPUT", std_handler_output },
|
||||
{ "INPUT", std_handler_input, 0 },
|
||||
{ "OUTPUT", std_handler_output, 0 },
|
||||
{ "OPTION", std_handler_option, 1 },
|
||||
{ NULL }
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
|
||||
@ -406,9 +441,10 @@ my_strcasecmp (const char *a, const char *b)
|
||||
return *a == *b? 0 : (((*a >= 'a' && *a <= 'z')? (*a&~0x20):*a) - *b);
|
||||
}
|
||||
|
||||
|
||||
/* Parse the line, break out the command, find it in the command
|
||||
table, remove leading and white spaces from the arguments, call the
|
||||
handler with the argument line and return the error */
|
||||
handler with the argument line and return the error. */
|
||||
static int
|
||||
dispatch_command (assuan_context_t ctx, char *line, int linelen)
|
||||
{
|
||||
@ -416,13 +452,21 @@ dispatch_command (assuan_context_t ctx, char *line, int linelen)
|
||||
const char *s;
|
||||
int shift, i;
|
||||
|
||||
/* Note that as this function is invoked by assuan_process_next as
|
||||
well, we need to hide non-critical errors with PROCESS_DONE. */
|
||||
|
||||
if (*line == 'D' && line[1] == ' ') /* divert to special handler */
|
||||
return handle_data_line (ctx, line+2, linelen-2);
|
||||
/* FIXME: Depending on the final implementation of
|
||||
handle_data_line, this may be wrong here. For example, if a
|
||||
user callback is invoked, and that callback is responsible for
|
||||
calling assuan_process_done, then this is wrong. */
|
||||
return PROCESS_DONE (ctx, handle_data_line (ctx, line+2, linelen-2));
|
||||
|
||||
for (p=line; *p && *p != ' ' && *p != '\t'; p++)
|
||||
;
|
||||
if (p==line)
|
||||
return set_error (ctx, Syntax_Error, "leading white-space");
|
||||
return PROCESS_DONE
|
||||
(ctx, set_error (ctx, Syntax_Error, "leading white-space"));
|
||||
if (*p)
|
||||
{ /* Skip over leading WS after the keyword */
|
||||
*p++ = 0;
|
||||
@ -445,7 +489,7 @@ dispatch_command (assuan_context_t ctx, char *line, int linelen)
|
||||
}
|
||||
}
|
||||
if (!s)
|
||||
return set_error (ctx, Unknown_Command, NULL);
|
||||
return PROCESS_DONE (ctx, set_error (ctx, Unknown_Command, NULL));
|
||||
line += shift;
|
||||
linelen -= shift;
|
||||
|
||||
@ -453,42 +497,34 @@ dispatch_command (assuan_context_t ctx, char *line, int linelen)
|
||||
return ctx->cmdtbl[i].handler (ctx, line);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static int
|
||||
process_request (assuan_context_t ctx)
|
||||
/* Call this to acknowledge the current command. */
|
||||
int
|
||||
assuan_process_done (assuan_context_t ctx, int rc)
|
||||
{
|
||||
int rc;
|
||||
if (!ctx->in_command)
|
||||
return _assuan_error (ASSUAN_General_Error);
|
||||
|
||||
if (ctx->in_inquire)
|
||||
return _assuan_error (ASSUAN_Nested_Commands);
|
||||
ctx->in_command = 0;
|
||||
|
||||
rc = _assuan_read_line (ctx);
|
||||
if (rc)
|
||||
return rc;
|
||||
if (*ctx->inbound.line == '#' || !ctx->inbound.linelen)
|
||||
return 0; /* comment line - ignore */
|
||||
|
||||
ctx->outbound.data.error = 0;
|
||||
ctx->outbound.data.linelen = 0;
|
||||
/* dispatch command and return reply */
|
||||
rc = dispatch_command (ctx, ctx->inbound.line, ctx->inbound.linelen);
|
||||
/* check from data write errors */
|
||||
/* Check for data write errors. */
|
||||
if (ctx->outbound.data.fp)
|
||||
{ /* Flush the data lines */
|
||||
{
|
||||
/* Flush the data lines. */
|
||||
fclose (ctx->outbound.data.fp);
|
||||
ctx->outbound.data.fp = NULL;
|
||||
if (!rc && ctx->outbound.data.error)
|
||||
rc = ctx->outbound.data.error;
|
||||
rc = ctx->outbound.data.error;
|
||||
}
|
||||
else /* flush any data send w/o using the data fp */
|
||||
else
|
||||
{
|
||||
/* Flush any data send without using the data FP. */
|
||||
assuan_send_data (ctx, NULL, 0);
|
||||
if (!rc && ctx->outbound.data.error)
|
||||
rc = ctx->outbound.data.error;
|
||||
rc = ctx->outbound.data.error;
|
||||
}
|
||||
/* Error handling */
|
||||
|
||||
/* Error handling. */
|
||||
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];
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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:"");
|
||||
@ -554,7 +590,7 @@ process_request (assuan_context_t ctx)
|
||||
{
|
||||
/* 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,
|
||||
@ -569,19 +605,123 @@ process_request (assuan_context_t ctx)
|
||||
}
|
||||
rc = assuan_write_line (ctx, errline);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
process_next (assuan_context_t ctx)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* What the next thing to do is depends on the current state.
|
||||
However, we will always first read the next line. The client is
|
||||
required to write full lines without blocking long after starting
|
||||
a partial line. */
|
||||
rc = _assuan_read_line (ctx);
|
||||
if (_assuan_error_is_eagain (rc))
|
||||
return 0;
|
||||
if (rc)
|
||||
return rc;
|
||||
if (*ctx->inbound.line == '#' || !ctx->inbound.linelen)
|
||||
/* Comment lines are ignored. */
|
||||
return 0;
|
||||
|
||||
/* Now we have a line that really means something. It could be one
|
||||
of the following things: First, if we are not in a command
|
||||
already, it is the next command to dispatch. Second, if we are
|
||||
in a command, it can only be the response to an INQUIRE
|
||||
reply. */
|
||||
|
||||
if (!ctx->in_command)
|
||||
{
|
||||
ctx->in_command = 1;
|
||||
|
||||
ctx->outbound.data.error = 0;
|
||||
ctx->outbound.data.linelen = 0;
|
||||
/* Dispatch command and return reply. */
|
||||
ctx->in_process_next = 1;
|
||||
rc = dispatch_command (ctx, ctx->inbound.line, ctx->inbound.linelen);
|
||||
ctx->in_process_next = 0;
|
||||
}
|
||||
else if (ctx->in_inquire)
|
||||
{
|
||||
/* FIXME: Pick up the continuation. */
|
||||
rc = _assuan_inquire_ext_cb (ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Should not happen. The client is sending data while we are
|
||||
in a command and not waiting for an inquire. We log an error
|
||||
and discard it. */
|
||||
_assuan_log_printf ("unexpected client data\n");
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* This function should be invoked when the assuan connected FD is
|
||||
ready for reading. If the equivalent to EWOULDBLOCK is returned
|
||||
(this should be done by the command handler), assuan_process_next
|
||||
should be invoked the next time the connected FD is readable.
|
||||
Eventually, the caller will finish by invoking
|
||||
assuan_process_done. */
|
||||
int
|
||||
assuan_process_next (assuan_context_t ctx)
|
||||
{
|
||||
int rc;
|
||||
|
||||
do
|
||||
{
|
||||
rc = process_next (ctx);
|
||||
}
|
||||
while (!rc && assuan_pending_line (ctx));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
process_request (assuan_context_t ctx)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (ctx->in_inquire)
|
||||
return _assuan_error (ASSUAN_Nested_Commands);
|
||||
|
||||
do
|
||||
{
|
||||
rc = _assuan_read_line (ctx);
|
||||
}
|
||||
while (_assuan_error_is_eagain (rc));
|
||||
if (rc)
|
||||
return rc;
|
||||
if (*ctx->inbound.line == '#' || !ctx->inbound.linelen)
|
||||
return 0; /* comment line - ignore */
|
||||
|
||||
ctx->in_command = 1;
|
||||
ctx->outbound.data.error = 0;
|
||||
ctx->outbound.data.linelen = 0;
|
||||
/* dispatch command and return reply */
|
||||
rc = dispatch_command (ctx, ctx->inbound.line, ctx->inbound.linelen);
|
||||
|
||||
return assuan_process_done (ctx, rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* assuan_process:
|
||||
* @ctx: assuan context
|
||||
@ -609,24 +749,6 @@ assuan_process (assuan_context_t ctx)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* assuan_process_next:
|
||||
* @ctx: Assuan context
|
||||
*
|
||||
* Same as assuan_process() but the user has to provide the outer
|
||||
* loop. He should loop as long as the return code is zero and stop
|
||||
* otherwise; -1 is regular end.
|
||||
*
|
||||
* See also: assuan_get_active_fds()
|
||||
* Return value: -1 for end of server, 0 on success or an error code
|
||||
**/
|
||||
int
|
||||
assuan_process_next (assuan_context_t ctx)
|
||||
{
|
||||
return process_request (ctx);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* assuan_get_active_fds:
|
||||
* @ctx: Assuan context
|
||||
@ -646,7 +768,7 @@ assuan_process_next (assuan_context_t ctx)
|
||||
**/
|
||||
int
|
||||
assuan_get_active_fds (assuan_context_t ctx, int what,
|
||||
int *fdarray, int fdarraysize)
|
||||
assuan_fd_t *fdarray, int fdarraysize)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
@ -655,16 +777,16 @@ assuan_get_active_fds (assuan_context_t ctx, int what,
|
||||
|
||||
if (!what)
|
||||
{
|
||||
if (ctx->inbound.fd != -1)
|
||||
if (ctx->inbound.fd != ASSUAN_INVALID_FD)
|
||||
fdarray[n++] = ctx->inbound.fd;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ctx->outbound.fd != -1)
|
||||
if (ctx->outbound.fd != ASSUAN_INVALID_FD)
|
||||
fdarray[n++] = ctx->outbound.fd;
|
||||
if (ctx->outbound.data.fp)
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
fdarray[n++] = _get_osfhandle (fileno (ctx->outbound.data.fp));
|
||||
fdarray[n++] = (void*)_get_osfhandle (fileno (ctx->outbound.data.fp));
|
||||
#else
|
||||
fdarray[n++] = fileno (ctx->outbound.data.fp);
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* assuan-inquire.c - handle inquire stuff
|
||||
* Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Assuan.
|
||||
*
|
||||
@ -14,9 +14,7 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -44,7 +42,7 @@ struct membuf
|
||||
|
||||
|
||||
|
||||
/* A simple implemnation of a dynamic buffer. Use init_membuf() to
|
||||
/* A simple implementation of a dynamic buffer. Use init_membuf() to
|
||||
create a buffer, put_membuf to append bytes and get_membuf to
|
||||
release and return the buffer. Allocation errors are detected but
|
||||
only returned at the final get_membuf(), this helps not to clutter
|
||||
@ -171,7 +169,9 @@ assuan_inquire (assuan_context_t ctx, const char *keyword,
|
||||
{
|
||||
do
|
||||
{
|
||||
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;
|
||||
@ -234,8 +234,154 @@ assuan_inquire (assuan_context_t ctx, const char *keyword,
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_assuan_inquire_release (assuan_context_t ctx)
|
||||
{
|
||||
if (ctx->in_inquire)
|
||||
{
|
||||
if (ctx->inquire_membuf)
|
||||
{
|
||||
free_membuf (ctx->inquire_membuf);
|
||||
free (ctx->inquire_membuf);
|
||||
}
|
||||
ctx->in_inquire = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_assuan_inquire_ext_cb (assuan_context_t ctx)
|
||||
{
|
||||
int rc;
|
||||
unsigned char *line;
|
||||
int linelen;
|
||||
struct membuf *mb;
|
||||
unsigned char *p;
|
||||
|
||||
line = (unsigned char *) ctx->inbound.line;
|
||||
linelen = ctx->inbound.linelen;
|
||||
mb = ctx->inquire_membuf;
|
||||
|
||||
if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N')
|
||||
{
|
||||
rc = _assuan_error (ASSUAN_Canceled);
|
||||
goto leave;
|
||||
}
|
||||
if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
|
||||
&& (!line[3] || line[3] == ' '))
|
||||
{
|
||||
rc = 0;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (line[0] != 'D' || line[1] != ' ' || mb == NULL)
|
||||
{
|
||||
rc = _assuan_error (ASSUAN_Unexpected_Command);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (linelen < 3)
|
||||
return 0;
|
||||
line += 2;
|
||||
linelen -= 2;
|
||||
|
||||
p = line;
|
||||
while (linelen)
|
||||
{
|
||||
for (;linelen && *p != '%'; linelen--, p++)
|
||||
;
|
||||
put_membuf (mb, line, p-line);
|
||||
if (linelen > 2)
|
||||
{ /* handle escaping */
|
||||
unsigned char tmp[1];
|
||||
p++;
|
||||
*tmp = xtoi_2 (p);
|
||||
p += 2;
|
||||
linelen -= 3;
|
||||
put_membuf (mb, tmp, 1);
|
||||
}
|
||||
line = p;
|
||||
}
|
||||
if (mb->too_large)
|
||||
{
|
||||
rc = _assuan_error (ASSUAN_Too_Much_Data);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
leave:
|
||||
{
|
||||
size_t buf_len = 0;
|
||||
unsigned char *buf = NULL;
|
||||
|
||||
if (mb)
|
||||
{
|
||||
buf = get_membuf (mb, &buf_len);
|
||||
if (!buf)
|
||||
rc = _assuan_error (ASSUAN_Out_Of_Core);
|
||||
free_membuf (mb);
|
||||
free (mb);
|
||||
ctx->inquire_membuf = NULL;
|
||||
}
|
||||
ctx->in_inquire = 0;
|
||||
rc = (ctx->inquire_cb) (ctx->inquire_cb_data, rc, buf, buf_len);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* assuan_inquire_ext:
|
||||
* @ctx: An assuan context
|
||||
* @keyword: The keyword used for the inquire
|
||||
* @maxlen: If not 0, the size limit of the inquired data.
|
||||
* @cb: A callback handler which is invoked after the operation completed.
|
||||
* @cb_data: A user-provided value passed to the callback handler.
|
||||
*
|
||||
* A Server may use this to Send an inquire. r_buffer, r_length and
|
||||
* maxlen may all be NULL/0 to indicate that no real data is expected.
|
||||
* When this function returns,
|
||||
*
|
||||
* Return value: 0 on success or an ASSUAN error code
|
||||
**/
|
||||
assuan_error_t
|
||||
assuan_inquire_ext (assuan_context_t ctx, const char *keyword, size_t maxlen,
|
||||
int (*cb) (void *cb_data, int rc, unsigned char *buf,
|
||||
size_t len),
|
||||
void *cb_data)
|
||||
{
|
||||
assuan_error_t rc;
|
||||
struct membuf *mb = NULL;
|
||||
char cmdbuf[LINELENGTH-10]; /* (10 = strlen ("INQUIRE ")+CR,LF) */
|
||||
|
||||
if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf)))
|
||||
return _assuan_error (ASSUAN_Invalid_Value);
|
||||
if (!ctx->is_server)
|
||||
return _assuan_error (ASSUAN_Not_A_Server);
|
||||
if (ctx->in_inquire)
|
||||
return _assuan_error (ASSUAN_Nested_Commands);
|
||||
|
||||
mb = malloc (sizeof (struct membuf));
|
||||
if (!mb)
|
||||
return _assuan_error (ASSUAN_Out_Of_Core);
|
||||
init_membuf (mb, maxlen ? maxlen : 1024, maxlen);
|
||||
|
||||
strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword);
|
||||
rc = assuan_write_line (ctx, cmdbuf);
|
||||
if (rc)
|
||||
{
|
||||
free_membuf (mb);
|
||||
free (mb);
|
||||
return rc;
|
||||
}
|
||||
|
||||
ctx->in_inquire = 1;
|
||||
|
||||
/* Set up the continuation. */
|
||||
ctx->inquire_cb = cb;
|
||||
ctx->inquire_cb_data = cb_data;
|
||||
ctx->inquire_membuf = mb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* assuan-io.c - Wraps the read and write functions.
|
||||
* Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2002, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Assuan.
|
||||
*
|
||||
@ -14,15 +14,14 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
@ -48,8 +47,8 @@ _assuan_waitpid (pid_t pid, int *status, int options)
|
||||
#endif
|
||||
|
||||
|
||||
ssize_t
|
||||
_assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size)
|
||||
static ssize_t
|
||||
do_io_read (assuan_fd_t fd, void *buffer, size_t size)
|
||||
{
|
||||
#if defined(HAVE_W32_SYSTEM) && !defined(_ASSUAN_IN_GPGME_BUILD_ASSUAN)
|
||||
/* Due to the peculiarities of the W32 API we can't use read for a
|
||||
@ -57,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;
|
||||
|
||||
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 read (ctx->inbound.fd, buffer, size);
|
||||
return read (fd, buffer, size);
|
||||
#endif /*!HAVE_W32_SYSTEM*/
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
_assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size)
|
||||
_assuan_io_read (assuan_fd_t fd, void *buffer, size_t size)
|
||||
{
|
||||
ssize_t retval;
|
||||
|
||||
if (_assuan_io_hooks.read_hook
|
||||
&& _assuan_io_hooks.read_hook (NULL, fd, buffer, size, &retval) == 1)
|
||||
return retval;
|
||||
|
||||
return do_io_read (fd, buffer, size);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
_assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size)
|
||||
{
|
||||
ssize_t retval;
|
||||
|
||||
if (_assuan_io_hooks.read_hook
|
||||
&& _assuan_io_hooks.read_hook (ctx, ctx->inbound.fd,
|
||||
buffer, size, &retval) == 1)
|
||||
return retval;
|
||||
|
||||
return do_io_read (ctx->inbound.fd, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ssize_t
|
||||
do_io_write (assuan_fd_t fd, const void *buffer, size_t size)
|
||||
{
|
||||
#if defined(HAVE_W32_SYSTEM) && !defined(_ASSUAN_IN_GPGME_BUILD_ASSUAN)
|
||||
/* Due to the peculiarities of the W32 API we can't use write for a
|
||||
@ -90,12 +128,12 @@ _assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size)
|
||||
write if send detects that it is not a network socket. */
|
||||
int n;
|
||||
|
||||
n = send (ctx->outbound.fd, buffer, size, 0);
|
||||
n = send (HANDLE2SOCKET(fd), buffer, size, 0);
|
||||
if (n == -1 && WSAGetLastError () == WSAENOTSOCK)
|
||||
{
|
||||
DWORD nwrite;
|
||||
|
||||
n = WriteFile ((HANDLE)ctx->outbound.fd, buffer, size, &nwrite, NULL);
|
||||
n = WriteFile (fd, buffer, size, &nwrite, NULL);
|
||||
if (!n)
|
||||
{
|
||||
switch (GetLastError ())
|
||||
@ -111,10 +149,34 @@ _assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size)
|
||||
}
|
||||
return n;
|
||||
#else /*!HAVE_W32_SYSTEM*/
|
||||
return write (ctx->outbound.fd, buffer, size);
|
||||
return write (fd, buffer, size);
|
||||
#endif /*!HAVE_W32_SYSTEM*/
|
||||
}
|
||||
|
||||
ssize_t
|
||||
_assuan_io_write (assuan_fd_t fd, const void *buffer, size_t size)
|
||||
{
|
||||
ssize_t retval;
|
||||
|
||||
if (_assuan_io_hooks.write_hook
|
||||
&& _assuan_io_hooks.write_hook (NULL, fd, buffer, size, &retval) == 1)
|
||||
return retval;
|
||||
return do_io_write (fd, buffer, size);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
_assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size)
|
||||
{
|
||||
ssize_t retval;
|
||||
|
||||
if (_assuan_io_hooks.write_hook
|
||||
&& _assuan_io_hooks.write_hook (ctx, ctx->outbound.fd,
|
||||
buffer, size, &retval) == 1)
|
||||
return retval;
|
||||
|
||||
return do_io_write (ctx->outbound.fd, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
int
|
||||
@ -152,3 +214,32 @@ _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg)
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_assuan_usleep (unsigned int usec)
|
||||
{
|
||||
if (usec)
|
||||
{
|
||||
#ifdef HAVE_NANOSLEEP
|
||||
struct timespec req;
|
||||
struct timespec rem;
|
||||
|
||||
req.tv_sec = 0;
|
||||
req.tv_nsec = usec * 1000;
|
||||
|
||||
while (nanosleep (&req, &rem) < 0 && errno == EINTR)
|
||||
req = rem;
|
||||
|
||||
#elif defined(HAVE_W32_SYSTEM)
|
||||
Sleep (usec / 1000);
|
||||
#else
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = usec / 1000000;
|
||||
tv.tv_usec = usec % 1000000;
|
||||
select (0, NULL, NULL, NULL, &tv);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,7 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -116,17 +114,17 @@ assuan_accept (assuan_context_t ctx)
|
||||
|
||||
|
||||
|
||||
int
|
||||
assuan_fd_t
|
||||
assuan_get_input_fd (assuan_context_t ctx)
|
||||
{
|
||||
return ctx? ctx->input_fd : -1;
|
||||
return ctx? ctx->input_fd : ASSUAN_INVALID_FD;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
assuan_fd_t
|
||||
assuan_get_output_fd (assuan_context_t ctx)
|
||||
{
|
||||
return ctx? ctx->output_fd : -1;
|
||||
return ctx? ctx->output_fd : ASSUAN_INVALID_FD;
|
||||
}
|
||||
|
||||
|
||||
@ -135,10 +133,10 @@ assuan_get_output_fd (assuan_context_t ctx)
|
||||
assuan_error_t
|
||||
assuan_close_input_fd (assuan_context_t ctx)
|
||||
{
|
||||
if (!ctx || ctx->input_fd == -1)
|
||||
if (!ctx || ctx->input_fd == ASSUAN_INVALID_FD)
|
||||
return _assuan_error (ASSUAN_Invalid_Value);
|
||||
_assuan_close (ctx->input_fd);
|
||||
ctx->input_fd = -1;
|
||||
ctx->input_fd = ASSUAN_INVALID_FD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -147,11 +145,11 @@ assuan_close_input_fd (assuan_context_t ctx)
|
||||
assuan_error_t
|
||||
assuan_close_output_fd (assuan_context_t ctx)
|
||||
{
|
||||
if (!ctx || ctx->output_fd == -1)
|
||||
if (!ctx || ctx->output_fd == ASSUAN_INVALID_FD)
|
||||
return _assuan_error (ASSUAN_Invalid_Value);
|
||||
|
||||
_assuan_close (ctx->output_fd);
|
||||
ctx->output_fd = -1;
|
||||
ctx->output_fd = ASSUAN_INVALID_FD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,7 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -37,23 +35,6 @@
|
||||
static char prefix_buffer[80];
|
||||
static FILE *_assuan_log;
|
||||
static int full_logging;
|
||||
static int log_level = 1; /* Defaults to logging enabled. */
|
||||
|
||||
|
||||
/* Set the log level for general assuan commands. 0 is no logging at
|
||||
all, 1 is the standard logging and the default. Higher leveles may
|
||||
be defined in the future. Passing a level of -1 will not change
|
||||
the current log level. Returns previosu log level. */
|
||||
int
|
||||
assuan_set_assuan_log_level (int level)
|
||||
{
|
||||
int old = log_level;
|
||||
|
||||
if (level != -1)
|
||||
log_level = level;
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_assuan_set_default_log_stream (FILE *fp)
|
||||
@ -122,9 +103,6 @@ _assuan_log_printf (const char *format, ...)
|
||||
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 ();
|
||||
@ -134,29 +112,31 @@ _assuan_log_printf (const char *format, ...)
|
||||
va_start (arg_ptr, format);
|
||||
vfprintf (fp, format, arg_ptr );
|
||||
va_end (arg_ptr);
|
||||
/* If the log stream is a file, the output would be buffered. This
|
||||
is bad for debugging, thus we flush the stream if FORMAT ends
|
||||
with a LF. */
|
||||
if (format && *format && format[strlen(format)-1] == '\n')
|
||||
fflush (fp);
|
||||
errno = save_errno;
|
||||
}
|
||||
|
||||
|
||||
/* Dump a possibly binary string (used for debugging). Distinguish
|
||||
ascii text from binary and print it accordingly. This function
|
||||
takes FILE pointer arg becuase logging may be enabled on a per
|
||||
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;
|
||||
int n;
|
||||
unsigned int n;
|
||||
|
||||
if (!log_level)
|
||||
return;
|
||||
|
||||
for (n=length,s=buffer; n; n--, s++)
|
||||
if ((!isascii (*s) || iscntrl (*s) || !isprint (*s)) && !(*s >= 0x80))
|
||||
for (n = length, s = buffer; n; n--, s++)
|
||||
if ((! isascii (*s) || iscntrl (*s) || ! isprint (*s)) && !(*s >= 0x80))
|
||||
break;
|
||||
|
||||
s = buffer;
|
||||
if (!n && *s != '[')
|
||||
if (! n && *s != '[')
|
||||
fwrite (buffer, length, 1, fp);
|
||||
else
|
||||
{
|
||||
@ -164,15 +144,15 @@ _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length)
|
||||
flockfile (fp);
|
||||
#endif
|
||||
putc_unlocked ('[', fp);
|
||||
if ( length > 16 && !full_logging)
|
||||
if (length > 16 && ! full_logging)
|
||||
{
|
||||
for (n=0; n < 12; n++, s++)
|
||||
for (n = 0; n < 12; n++, s++)
|
||||
fprintf (fp, " %02x", *s);
|
||||
fprintf (fp, " ...(%d bytes skipped)", (int)length - 12);
|
||||
fprintf (fp, " ...(%d bytes skipped)", (int) length - 12);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (n=0; n < length; n++, s++)
|
||||
for (n = 0; n < length; n++, s++)
|
||||
fprintf (fp, " %02x", *s);
|
||||
}
|
||||
putc_unlocked (' ', fp);
|
||||
@ -189,16 +169,11 @@ void
|
||||
_assuan_log_sanitized_string (const char *string)
|
||||
{
|
||||
const unsigned char *s = (const unsigned char *) string;
|
||||
FILE *fp;
|
||||
FILE *fp = assuan_get_assuan_log_stream ();
|
||||
|
||||
if (!log_level)
|
||||
if (! *s)
|
||||
return;
|
||||
|
||||
if (!*s)
|
||||
return;
|
||||
|
||||
fp = assuan_get_assuan_log_stream ();
|
||||
|
||||
#ifdef HAVE_FLOCKFILE
|
||||
flockfile (fp);
|
||||
#endif
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* assuan-pipe-connect.c - Establish a pipe connection (client)
|
||||
* Copyright (C) 2001, 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002, 2003, 2005, 2006,
|
||||
* 2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Assuan.
|
||||
*
|
||||
@ -14,9 +15,7 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -75,17 +74,6 @@ int _gpgme_io_spawn (const char *path, char *const argv[],
|
||||
#define MAX_OPEN_FDS 20
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
/* We assume that a HANDLE can be represented by an int which should
|
||||
be true for all i386 systems (HANDLE is defined as void *) and
|
||||
these are the only systems for which Windows is available. Further
|
||||
we assume that -1 denotes an invalid handle. */
|
||||
#define fd_to_handle(a) ((HANDLE)(a))
|
||||
#define handle_to_fd(a) ((int)(a))
|
||||
#define pid_to_handle(a) ((HANDLE)(a))
|
||||
#define handle_to_pid(a) ((int)(a))
|
||||
#endif /*HAVE_W32_SYSTEM*/
|
||||
|
||||
|
||||
/* This should be called to make sure that SIGPIPE gets ignored. */
|
||||
static void
|
||||
@ -139,31 +127,35 @@ writen (int fd, const char *buffer, size_t length)
|
||||
static int
|
||||
do_finish (assuan_context_t ctx)
|
||||
{
|
||||
if (ctx->inbound.fd != -1)
|
||||
if (ctx->inbound.fd != ASSUAN_INVALID_FD)
|
||||
{
|
||||
_assuan_close (ctx->inbound.fd);
|
||||
if (ctx->inbound.fd == ctx->outbound.fd)
|
||||
ctx->outbound.fd = -1;
|
||||
ctx->inbound.fd = -1;
|
||||
ctx->outbound.fd = ASSUAN_INVALID_FD;
|
||||
ctx->inbound.fd = ASSUAN_INVALID_FD;
|
||||
}
|
||||
if (ctx->outbound.fd != -1)
|
||||
if (ctx->outbound.fd != ASSUAN_INVALID_FD)
|
||||
{
|
||||
_assuan_close (ctx->outbound.fd);
|
||||
ctx->outbound.fd = -1;
|
||||
ctx->outbound.fd = ASSUAN_INVALID_FD;
|
||||
}
|
||||
if (ctx->pid != -1 && ctx->pid)
|
||||
if (ctx->pid != (pid_t)(-1) && ctx->pid)
|
||||
{
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
#ifndef _ASSUAN_USE_DOUBLE_FORK
|
||||
if (!ctx->flags.no_waitpid)
|
||||
_assuan_waitpid (ctx->pid, NULL, 0);
|
||||
ctx->pid = -1;
|
||||
ctx->pid =(pid_t)(-1);
|
||||
#endif
|
||||
#endif /*!HAVE_W32_SYSTEM*/
|
||||
#else /*!HAVE_W32_SYSTEM*/
|
||||
CloseHandle ((HANDLE) ctx->pid);
|
||||
ctx->pid = (pid_t) INVALID_HANDLE_VALUE;
|
||||
#endif /*HAVE_W32_SYSTEM*/
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_deinit (assuan_context_t ctx)
|
||||
{
|
||||
@ -209,13 +201,15 @@ pipe_connect_unix (assuan_context_t *ctx,
|
||||
const char *name, const char *const argv[],
|
||||
int *fd_child_list,
|
||||
void (*atfork) (void *opaque, int reserved),
|
||||
void *atforkvalue)
|
||||
void *atforkvalue, unsigned int flags)
|
||||
{
|
||||
assuan_error_t err;
|
||||
int rp[2];
|
||||
int wp[2];
|
||||
char mypidstr[50];
|
||||
|
||||
(void)flags;
|
||||
|
||||
if (!ctx || !name || !argv || !argv[0])
|
||||
return _assuan_error (ASSUAN_Invalid_Value);
|
||||
|
||||
@ -581,7 +575,7 @@ pipe_connect_gpgme (assuan_context_t *ctx,
|
||||
const char *name, const char *const argv[],
|
||||
int *fd_child_list,
|
||||
void (*atfork) (void *opaque, int reserved),
|
||||
void *atforkvalue)
|
||||
void *atforkvalue, unsigned int flags)
|
||||
{
|
||||
assuan_error_t err;
|
||||
int res;
|
||||
@ -744,9 +738,9 @@ build_w32_commandline (const char * const *argv, char **cmdline)
|
||||
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
/* Create pipe where one end is inheritable. */
|
||||
/* Create pipe where one end end is inheritable. */
|
||||
static int
|
||||
create_inheritable_pipe (int filedes[2], int for_write)
|
||||
create_inheritable_pipe (assuan_fd_t filedes[2], int for_write)
|
||||
{
|
||||
HANDLE r, w, h;
|
||||
SECURITY_ATTRIBUTES sec_attr;
|
||||
@ -781,14 +775,12 @@ create_inheritable_pipe (int filedes[2], int for_write)
|
||||
w = h;
|
||||
}
|
||||
|
||||
_assuan_log_printf ("created pipe: read=%p%s, write=%p%s\n",
|
||||
r, for_write? " (inherit)":"",
|
||||
w, for_write? "":" (inherit)");
|
||||
filedes[0] = handle_to_fd (r);
|
||||
filedes[1] = handle_to_fd (w);
|
||||
filedes[0] = r;
|
||||
filedes[1] = w;
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_W32_SYSTEM */
|
||||
#endif /*HAVE_W32_SYSTEM*/
|
||||
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
#define pipe_connect pipe_connect_w32
|
||||
@ -798,11 +790,11 @@ pipe_connect_w32 (assuan_context_t *ctx,
|
||||
const char *name, const char *const argv[],
|
||||
int *fd_child_list,
|
||||
void (*atfork) (void *opaque, int reserved),
|
||||
void *atforkvalue)
|
||||
void *atforkvalue, unsigned int flags)
|
||||
{
|
||||
assuan_error_t err;
|
||||
int rp[2];
|
||||
int wp[2];
|
||||
assuan_fd_t rp[2];
|
||||
assuan_fd_t wp[2];
|
||||
char mypidstr[50];
|
||||
char *cmdline;
|
||||
SECURITY_ATTRIBUTES sec_attr;
|
||||
@ -837,8 +829,8 @@ pipe_connect_w32 (assuan_context_t *ctx,
|
||||
|
||||
if (create_inheritable_pipe (wp, 1))
|
||||
{
|
||||
CloseHandle (fd_to_handle (rp[0]));
|
||||
CloseHandle (fd_to_handle (rp[1]));
|
||||
CloseHandle (rp[0]);
|
||||
CloseHandle (rp[1]);
|
||||
xfree (cmdline);
|
||||
return _assuan_error (ASSUAN_General_Error);
|
||||
}
|
||||
@ -847,10 +839,10 @@ pipe_connect_w32 (assuan_context_t *ctx,
|
||||
err = _assuan_new_context (ctx);
|
||||
if (err)
|
||||
{
|
||||
CloseHandle (fd_to_handle (rp[0]));
|
||||
CloseHandle (fd_to_handle (rp[1]));
|
||||
CloseHandle (fd_to_handle (wp[0]));
|
||||
CloseHandle (fd_to_handle (wp[1]));
|
||||
CloseHandle (rp[0]);
|
||||
CloseHandle (rp[1]);
|
||||
CloseHandle (wp[0]);
|
||||
CloseHandle (wp[1]);
|
||||
xfree (cmdline);
|
||||
return _assuan_error (ASSUAN_General_Error);
|
||||
}
|
||||
@ -877,8 +869,8 @@ pipe_connect_w32 (assuan_context_t *ctx,
|
||||
memset (&si, 0, sizeof si);
|
||||
si.cb = sizeof (si);
|
||||
si.dwFlags = STARTF_USESTDHANDLES;
|
||||
si.hStdInput = fd_to_handle (wp[0]);
|
||||
si.hStdOutput = fd_to_handle (rp[1]);
|
||||
si.hStdInput = wp[0];
|
||||
si.hStdOutput = rp[1];
|
||||
|
||||
/* Dup stderr to /dev/null unless it is in the list of FDs to be
|
||||
passed to the child. */
|
||||
@ -894,14 +886,13 @@ pipe_connect_w32 (assuan_context_t *ctx,
|
||||
nullfd = CreateFile ("nul", GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
_assuan_log_printf ("created nul device, hd=%p\n", nullfd);
|
||||
if (nullfd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
_assuan_log_printf ("can't open `nul': %s\n", w32_strerror (-1));
|
||||
CloseHandle (fd_to_handle (rp[0]));
|
||||
CloseHandle (fd_to_handle (rp[1]));
|
||||
CloseHandle (fd_to_handle (wp[0]));
|
||||
CloseHandle (fd_to_handle (wp[1]));
|
||||
CloseHandle (rp[0]);
|
||||
CloseHandle (rp[1]);
|
||||
CloseHandle (wp[0]);
|
||||
CloseHandle (wp[1]);
|
||||
xfree (cmdline);
|
||||
_assuan_release_context (*ctx);
|
||||
return -1;
|
||||
@ -909,23 +900,21 @@ pipe_connect_w32 (assuan_context_t *ctx,
|
||||
si.hStdError = nullfd;
|
||||
}
|
||||
else
|
||||
si.hStdError = fd_to_handle (_get_osfhandle (fd));
|
||||
si.hStdError = (void*)_get_osfhandle (fd);
|
||||
|
||||
|
||||
/* Note: We inherit all handles flagged as inheritable. This seems
|
||||
to be a security flaw but there seems to be no way of selecting
|
||||
handles to inherit. */
|
||||
_assuan_log_printf ("CreateProcess, path=`%s' cmdline=`%s'\n",
|
||||
name, cmdline);
|
||||
_assuan_log_printf (" stdin=%p stdout=%p stderr=%p\n",
|
||||
si.hStdInput, si.hStdOutput, si.hStdError);
|
||||
/* _assuan_log_printf ("CreateProcess, path=`%s' cmdline=`%s'\n", */
|
||||
/* name, cmdline); */
|
||||
if (!CreateProcess (name, /* Program to start. */
|
||||
cmdline, /* Command line arguments. */
|
||||
&sec_attr, /* Process security attributes. */
|
||||
&sec_attr, /* Thread security attributes. */
|
||||
TRUE, /* Inherit handles. */
|
||||
(CREATE_DEFAULT_ERROR_MODE
|
||||
| DETACHED_PROCESS
|
||||
| ((flags & 128)? DETACHED_PROCESS : 0)
|
||||
| GetPriorityClass (GetCurrentProcess ())
|
||||
| CREATE_SUSPENDED), /* Creation flags. */
|
||||
NULL, /* Environment. */
|
||||
@ -935,10 +924,10 @@ pipe_connect_w32 (assuan_context_t *ctx,
|
||||
))
|
||||
{
|
||||
_assuan_log_printf ("CreateProcess failed: %s\n", w32_strerror (-1));
|
||||
CloseHandle (fd_to_handle (rp[0]));
|
||||
CloseHandle (fd_to_handle (rp[1]));
|
||||
CloseHandle (fd_to_handle (wp[0]));
|
||||
CloseHandle (fd_to_handle (wp[1]));
|
||||
CloseHandle (rp[0]);
|
||||
CloseHandle (rp[1]);
|
||||
CloseHandle (wp[0]);
|
||||
CloseHandle (wp[1]);
|
||||
if (nullfd != INVALID_HANDLE_VALUE)
|
||||
CloseHandle (nullfd);
|
||||
xfree (cmdline);
|
||||
@ -953,20 +942,17 @@ pipe_connect_w32 (assuan_context_t *ctx,
|
||||
nullfd = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
_assuan_log_printf ("closing handles %p and %p\n",
|
||||
fd_to_handle (rp[1]), fd_to_handle (wp[0]) );
|
||||
CloseHandle (fd_to_handle (rp[1]));
|
||||
CloseHandle (fd_to_handle (wp[0]));
|
||||
CloseHandle (rp[1]);
|
||||
CloseHandle (wp[0]);
|
||||
|
||||
_assuan_log_printf ("CreateProcess ready: hProcess=%p hThread=%p"
|
||||
" dwProcessID=%d dwThreadId=%d\n",
|
||||
pi.hProcess, pi.hThread,
|
||||
(int) pi.dwProcessId, (int) pi.dwThreadId);
|
||||
/* _assuan_log_printf ("CreateProcess ready: hProcess=%p hThread=%p" */
|
||||
/* " dwProcessID=%d dwThreadId=%d\n", */
|
||||
/* pi.hProcess, pi.hThread, */
|
||||
/* (int) pi.dwProcessId, (int) pi.dwThreadId); */
|
||||
|
||||
ResumeThread (pi.hThread);
|
||||
CloseHandle (pi.hThread);
|
||||
(*ctx)->pid = 0; /* We don't use the PID. */
|
||||
CloseHandle (pi.hProcess); /* We don't need to wait for the process. */
|
||||
(*ctx)->pid = (pid_t) pi.hProcess;
|
||||
|
||||
return initial_handshake (ctx);
|
||||
}
|
||||
@ -982,7 +968,7 @@ assuan_error_t
|
||||
assuan_pipe_connect (assuan_context_t *ctx, const char *name,
|
||||
const char *const argv[], int *fd_child_list)
|
||||
{
|
||||
return pipe_connect (ctx, name, argv, fd_child_list, NULL, NULL);
|
||||
return pipe_connect (ctx, name, argv, fd_child_list, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -994,7 +980,7 @@ assuan_pipe_connect2 (assuan_context_t *ctx,
|
||||
void (*atfork) (void *opaque, int reserved),
|
||||
void *atforkvalue)
|
||||
{
|
||||
return pipe_connect (ctx, name, argv, fd_child_list, atfork, atforkvalue);
|
||||
return pipe_connect (ctx, name, argv, fd_child_list, atfork, atforkvalue, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -1007,9 +993,19 @@ assuan_pipe_connect2 (assuan_context_t *ctx,
|
||||
as the second argument. The ATFORK function should only act if the
|
||||
second value is 0.
|
||||
|
||||
For now FLAGS may either take the value 0 to behave like
|
||||
assuan_pipe_connect2 or 1 to enable the described full-duplex
|
||||
socket behaviour.
|
||||
FLAGS is a bit vector and controls how the function acts:
|
||||
Bit 0: If cleared a simple pipe based server is expected and the
|
||||
function behaves similar to `assuan_pipe_connect'.
|
||||
|
||||
If set a server based on full-duplex pipes is expected. Such
|
||||
pipes are usually created using the `socketpair' function.
|
||||
It also enables features only available with such servers.
|
||||
|
||||
Bit 7: If set and there is a need to start ther server it will be
|
||||
started as a background process. This flag is useful under
|
||||
W32 systems, so that no new console is created and pops up a
|
||||
console window when starting the server
|
||||
|
||||
|
||||
If NAME as well as ARGV are NULL, no exec is done but the same
|
||||
process is continued. However all file descriptors are closed and
|
||||
@ -1033,6 +1029,7 @@ assuan_pipe_connect_ext (assuan_context_t *ctx,
|
||||
#endif
|
||||
}
|
||||
else
|
||||
return pipe_connect (ctx, name, argv, fd_child_list, atfork, atforkvalue);
|
||||
return pipe_connect (ctx, name, argv, fd_child_list, atfork, atforkvalue,
|
||||
flags);
|
||||
}
|
||||
|
||||
|
@ -14,9 +14,7 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -69,14 +67,14 @@ _assuan_new_context (assuan_context_t *r_ctx)
|
||||
ctx = xtrycalloc (1, sizeof *ctx);
|
||||
if (!ctx)
|
||||
return _assuan_error (ASSUAN_Out_Of_Core);
|
||||
ctx->input_fd = -1;
|
||||
ctx->output_fd = -1;
|
||||
ctx->input_fd = ASSUAN_INVALID_FD;
|
||||
ctx->output_fd = ASSUAN_INVALID_FD;
|
||||
|
||||
ctx->inbound.fd = -1;
|
||||
ctx->outbound.fd = -1;
|
||||
ctx->inbound.fd = ASSUAN_INVALID_FD;
|
||||
ctx->outbound.fd = ASSUAN_INVALID_FD;
|
||||
ctx->io = &io;
|
||||
|
||||
ctx->listen_fd = -1;
|
||||
ctx->listen_fd = ASSUAN_INVALID_FD;
|
||||
/* Use the pipe server handler as a default. */
|
||||
ctx->deinit_handler = deinit_pipe_server;
|
||||
ctx->accept_handler = accept_connection;
|
||||
@ -121,11 +119,11 @@ assuan_init_pipe_server (assuan_context_t *r_ctx, int filedes[2])
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
/* MS Windows has so many different types of handle that one
|
||||
needs to tranlsate them at many place forth and back. Also
|
||||
make sure that the fiel descriptos are in binary mode. */
|
||||
make sure that the file descriptors are in binary mode. */
|
||||
setmode (filedes[0], O_BINARY);
|
||||
setmode (filedes[1], O_BINARY);
|
||||
ctx->inbound.fd = _get_osfhandle (filedes[0]);
|
||||
ctx->outbound.fd = _get_osfhandle (filedes[1]);
|
||||
ctx->inbound.fd = (void*)_get_osfhandle (filedes[0]);
|
||||
ctx->outbound.fd = (void*)_get_osfhandle (filedes[1]);
|
||||
#else
|
||||
s = getenv ("_assuan_connection_fd");
|
||||
if (s && *s && is_valid_socket (s) )
|
||||
@ -137,7 +135,8 @@ assuan_init_pipe_server (assuan_context_t *r_ctx, int filedes[2])
|
||||
_assuan_init_uds_io (ctx);
|
||||
ctx->deinit_handler = _assuan_uds_deinit;
|
||||
}
|
||||
else if (filedes && filedes[0] != -1 && filedes[1] != -1 )
|
||||
else if (filedes && filedes[0] != ASSUAN_INVALID_FD
|
||||
&& filedes[1] != ASSUAN_INVALID_FD )
|
||||
{
|
||||
/* Standard pipe server. */
|
||||
ctx->inbound.fd = filedes[0];
|
||||
@ -168,6 +167,7 @@ _assuan_release_context (assuan_context_t ctx)
|
||||
{
|
||||
if (ctx)
|
||||
{
|
||||
_assuan_inquire_release (ctx);
|
||||
xfree (ctx->hello_line);
|
||||
xfree (ctx->okay_line);
|
||||
xfree (ctx->cmdtbl);
|
||||
|
@ -14,9 +14,7 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -57,12 +55,12 @@
|
||||
static int
|
||||
do_finish (assuan_context_t ctx)
|
||||
{
|
||||
if (ctx->inbound.fd != -1)
|
||||
if (ctx->inbound.fd != ASSUAN_INVALID_FD)
|
||||
{
|
||||
_assuan_close (ctx->inbound.fd);
|
||||
}
|
||||
ctx->inbound.fd = -1;
|
||||
ctx->outbound.fd = -1;
|
||||
ctx->inbound.fd = ASSUAN_INVALID_FD;
|
||||
ctx->outbound.fd = ASSUAN_INVALID_FD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -87,18 +85,17 @@ assuan_socket_connect (assuan_context_t *r_ctx,
|
||||
/* Make a connection to the Unix domain socket NAME and return a new
|
||||
Assuan context in CTX. SERVER_PID is currently not used but may
|
||||
become handy in the future. With flags set to 1 sendmsg and
|
||||
recvmesg are used. */
|
||||
recvmsg are used. */
|
||||
assuan_error_t
|
||||
assuan_socket_connect_ext (assuan_context_t *r_ctx,
|
||||
const char *name, pid_t server_pid,
|
||||
unsigned int flags)
|
||||
{
|
||||
static struct assuan_io io = { _assuan_simple_read,
|
||||
_assuan_simple_write };
|
||||
|
||||
static struct assuan_io io = { _assuan_simple_read, _assuan_simple_write,
|
||||
NULL, NULL };
|
||||
assuan_error_t err;
|
||||
assuan_context_t ctx;
|
||||
int fd;
|
||||
assuan_fd_t fd;
|
||||
struct sockaddr_un srvr_addr;
|
||||
size_t len;
|
||||
const char *s;
|
||||
@ -109,7 +106,7 @@ assuan_socket_connect_ext (assuan_context_t *r_ctx,
|
||||
|
||||
/* We require that the name starts with a slash, so that we
|
||||
eventually can reuse this function for other socket types. To
|
||||
make things easier we allow an optional dirver prefix. */
|
||||
make things easier we allow an optional driver prefix. */
|
||||
s = name;
|
||||
if (*s && s[1] == ':')
|
||||
s += 2;
|
||||
@ -126,7 +123,7 @@ assuan_socket_connect_ext (assuan_context_t *r_ctx,
|
||||
ctx->finish_handler = do_finish;
|
||||
|
||||
fd = _assuan_sock_new (PF_LOCAL, SOCK_STREAM, 0);
|
||||
if (fd == -1)
|
||||
if (fd == ASSUAN_INVALID_FD)
|
||||
{
|
||||
_assuan_log_printf ("can't create socket: %s\n", strerror (errno));
|
||||
_assuan_release_context (ctx);
|
||||
@ -139,8 +136,7 @@ assuan_socket_connect_ext (assuan_context_t *r_ctx,
|
||||
srvr_addr.sun_path[sizeof (srvr_addr.sun_path) - 1] = 0;
|
||||
len = SUN_LEN (&srvr_addr);
|
||||
|
||||
|
||||
if (_assuan_sock_connect (fd, (struct sockaddr *) &srvr_addr, len) == -1)
|
||||
if ( _assuan_sock_connect (fd, (struct sockaddr *) &srvr_addr, len) == -1 )
|
||||
{
|
||||
_assuan_log_printf ("can't connect to `%s': %s\n",
|
||||
name, strerror (errno));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* assuan-socket-server.c - Assuan socket based server
|
||||
* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2002, 2007 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Assuan.
|
||||
*
|
||||
@ -14,9 +14,7 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -40,14 +38,13 @@
|
||||
|
||||
#include "assuan-defs.h"
|
||||
|
||||
static struct assuan_io io = { _assuan_simple_read,
|
||||
_assuan_simple_write };
|
||||
|
||||
static struct assuan_io io = { _assuan_simple_read, _assuan_simple_write,
|
||||
NULL, NULL };
|
||||
|
||||
static int
|
||||
accept_connection_bottom (assuan_context_t ctx)
|
||||
{
|
||||
int fd = ctx->connected_fd;
|
||||
assuan_fd_t fd = ctx->connected_fd;
|
||||
|
||||
ctx->peercred.valid = 0;
|
||||
#ifdef HAVE_SO_PEERCRED
|
||||
@ -89,16 +86,23 @@ accept_connection_bottom (assuan_context_t ctx)
|
||||
static int
|
||||
accept_connection (assuan_context_t ctx)
|
||||
{
|
||||
int fd;
|
||||
assuan_fd_t fd;
|
||||
struct sockaddr_un clnt_addr;
|
||||
socklen_t len = sizeof clnt_addr;
|
||||
|
||||
fd = accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len );
|
||||
if (fd == -1)
|
||||
fd = SOCKET2HANDLE(accept (HANDLE2SOCKET(ctx->listen_fd),
|
||||
(struct sockaddr*)&clnt_addr, &len ));
|
||||
if (fd == ASSUAN_INVALID_FD)
|
||||
{
|
||||
ctx->os_errno = errno;
|
||||
return _assuan_error (ASSUAN_Accept_Failed);
|
||||
}
|
||||
if (_assuan_sock_check_nonce (fd, &ctx->listen_nonce))
|
||||
{
|
||||
_assuan_close (fd);
|
||||
ctx->os_errno = EACCES;
|
||||
return _assuan_error (ASSUAN_Accept_Failed);
|
||||
}
|
||||
|
||||
ctx->connected_fd = fd;
|
||||
return accept_connection_bottom (ctx);
|
||||
@ -107,12 +111,12 @@ accept_connection (assuan_context_t ctx)
|
||||
static int
|
||||
finish_connection (assuan_context_t ctx)
|
||||
{
|
||||
if (ctx->inbound.fd != -1)
|
||||
if (ctx->inbound.fd != ASSUAN_INVALID_FD)
|
||||
{
|
||||
_assuan_close (ctx->inbound.fd);
|
||||
}
|
||||
ctx->inbound.fd = -1;
|
||||
ctx->outbound.fd = -1;
|
||||
ctx->inbound.fd = ASSUAN_INVALID_FD;
|
||||
ctx->outbound.fd = ASSUAN_INVALID_FD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -126,15 +130,15 @@ deinit_socket_server (assuan_context_t ctx)
|
||||
/* Initialize a server for the socket LISTEN_FD which has already be
|
||||
put into listen mode */
|
||||
int
|
||||
assuan_init_socket_server (assuan_context_t *r_ctx, int listen_fd)
|
||||
assuan_init_socket_server (assuan_context_t *r_ctx, assuan_fd_t listen_fd)
|
||||
{
|
||||
return assuan_init_socket_server_ext (r_ctx, listen_fd, 0);
|
||||
}
|
||||
|
||||
/* Initialize a server using the already accepted socket FD. This
|
||||
fucntion is deprecated. */
|
||||
function is deprecated. */
|
||||
int
|
||||
assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd)
|
||||
assuan_init_connected_socket_server (assuan_context_t *r_ctx, assuan_fd_t fd)
|
||||
{
|
||||
return assuan_init_socket_server_ext (r_ctx, fd, 2);
|
||||
}
|
||||
@ -145,7 +149,7 @@ assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd)
|
||||
1 - FD has already been accepted.
|
||||
*/
|
||||
int
|
||||
assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd,
|
||||
assuan_init_socket_server_ext (assuan_context_t *r_ctx, assuan_fd_t fd,
|
||||
unsigned int flags)
|
||||
{
|
||||
assuan_context_t ctx;
|
||||
@ -158,21 +162,21 @@ assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd,
|
||||
ctx->is_server = 1;
|
||||
if ((flags & 2))
|
||||
ctx->pipe_mode = 1; /* We want a second accept to indicate EOF. */
|
||||
ctx->input_fd = -1;
|
||||
ctx->output_fd = -1;
|
||||
ctx->input_fd = ASSUAN_INVALID_FD;
|
||||
ctx->output_fd = ASSUAN_INVALID_FD;
|
||||
|
||||
ctx->inbound.fd = -1;
|
||||
ctx->outbound.fd = -1;
|
||||
ctx->inbound.fd = ASSUAN_INVALID_FD;
|
||||
ctx->outbound.fd = ASSUAN_INVALID_FD;
|
||||
|
||||
if ((flags & 2))
|
||||
{
|
||||
ctx->listen_fd = -1;
|
||||
ctx->listen_fd = ASSUAN_INVALID_FD;
|
||||
ctx->connected_fd = fd;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->listen_fd = fd;
|
||||
ctx->connected_fd = -1;
|
||||
ctx->connected_fd = ASSUAN_INVALID_FD;
|
||||
}
|
||||
ctx->deinit_handler = (flags & 1)? _assuan_uds_deinit:deinit_socket_server;
|
||||
ctx->accept_handler = ((flags & 2)
|
||||
@ -191,3 +195,14 @@ assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd,
|
||||
*r_ctx = ctx;
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/* Save a copy of NONCE in context CTX. This should be used to
|
||||
register the server's nonce with an context established by
|
||||
assuan_init_socket_server. */
|
||||
void
|
||||
assuan_set_sock_nonce (assuan_context_t ctx, assuan_sock_nonce_t *nonce)
|
||||
{
|
||||
if (ctx && nonce)
|
||||
ctx->listen_nonce = *nonce;
|
||||
}
|
||||
|
@ -14,20 +14,26 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "assuan-defs.h"
|
||||
|
||||
/* Hacks for Slowaris. */
|
||||
@ -42,13 +48,114 @@
|
||||
# define AF_LOCAL AF_UNIX
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
#ifndef S_IRGRP
|
||||
# define S_IRGRP 0
|
||||
# define S_IWGRP 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
int
|
||||
_assuan_close (int fd)
|
||||
_assuan_sock_wsa2errno (int err)
|
||||
{
|
||||
switch (err)
|
||||
{
|
||||
case WSAENOTSOCK:
|
||||
return EINVAL;
|
||||
case WSAEWOULDBLOCK:
|
||||
return EAGAIN;
|
||||
case ERROR_BROKEN_PIPE:
|
||||
return EPIPE;
|
||||
case WSANOTINITIALISED:
|
||||
return ENOSYS;
|
||||
default:
|
||||
return EIO;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* W32: Fill BUFFER with LENGTH bytes of random. Returns -1 on
|
||||
failure, 0 on success. Sets errno on failure. */
|
||||
static int
|
||||
get_nonce (char *buffer, size_t nbytes)
|
||||
{
|
||||
HCRYPTPROV prov;
|
||||
int ret = -1;
|
||||
|
||||
if (!CryptAcquireContext (&prov, NULL, NULL, PROV_RSA_FULL,
|
||||
(CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) )
|
||||
errno = ENODEV;
|
||||
else
|
||||
{
|
||||
if (!CryptGenRandom (prov, nbytes, buffer))
|
||||
errno = ENODEV;
|
||||
else
|
||||
ret = 0;
|
||||
CryptReleaseContext (prov, 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* W32: The buffer for NONCE needs to be at least 16 bytes. Returns 0 on
|
||||
success and sets errno on failure. */
|
||||
static int
|
||||
read_port_and_nonce (const char *fname, unsigned short *port, char *nonce)
|
||||
{
|
||||
FILE *fp;
|
||||
char buffer[50], *p;
|
||||
size_t nread;
|
||||
int aval;
|
||||
|
||||
fp = fopen (fname, "rb");
|
||||
if (!fp)
|
||||
return -1;
|
||||
nread = fread (buffer, 1, sizeof buffer - 1, fp);
|
||||
fclose (fp);
|
||||
if (!nread)
|
||||
{
|
||||
errno = ENOFILE;
|
||||
return -1;
|
||||
}
|
||||
buffer[nread] = 0;
|
||||
aval = atoi (buffer);
|
||||
if (aval < 1 || aval > 65535)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
*port = (unsigned int)aval;
|
||||
for (p=buffer; nread && *p != '\n'; p++, nread--)
|
||||
;
|
||||
if (*p != '\n' || nread != 17)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
p++; nread--;
|
||||
memcpy (nonce, p, 16);
|
||||
return 0;
|
||||
}
|
||||
#endif /*HAVE_W32_SYSTEM*/
|
||||
|
||||
|
||||
|
||||
int
|
||||
_assuan_close (assuan_fd_t fd)
|
||||
{
|
||||
#if defined (HAVE_W32_SYSTEM) && !defined(_ASSUAN_IN_GPGME_BUILD_ASSUAN)
|
||||
int rc = closesocket (fd);
|
||||
int rc = closesocket (HANDLE2SOCKET(fd));
|
||||
if (rc)
|
||||
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
|
||||
if (rc && WSAGetLastError () == WSAENOTSOCK)
|
||||
rc = CloseHandle (fd);
|
||||
{
|
||||
rc = CloseHandle (fd);
|
||||
if (rc)
|
||||
/* FIXME. */
|
||||
errno = EIO;
|
||||
}
|
||||
return rc;
|
||||
#else
|
||||
return close (fd);
|
||||
@ -56,93 +163,277 @@ _assuan_close (int fd)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
/* Return a new socket. Note that under W32 we consider a socket the
|
||||
same as an System Handle; all functions using such a handle know
|
||||
about this dual use and act accordingly. */
|
||||
assuan_fd_t
|
||||
_assuan_sock_new (int domain, int type, int proto)
|
||||
{
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
return socket (domain, type, proto);
|
||||
#else
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
assuan_fd_t res;
|
||||
if (domain == AF_UNIX || domain == AF_LOCAL)
|
||||
domain = AF_INET;
|
||||
res = SOCKET2HANDLE(socket (domain, type, proto));
|
||||
if (res == ASSUAN_INVALID_FD)
|
||||
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
|
||||
return res;
|
||||
#else
|
||||
return socket (domain, type, proto);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_assuan_sock_connect (int sockfd, struct sockaddr * addr, int addrlen)
|
||||
_assuan_sock_connect (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen)
|
||||
{
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
return connect (sockfd, addr, addrlen);
|
||||
#else
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
return connect (sockfd, (struct sockaddr *)&myaddr, sizeof myaddr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_assuan_sock_bind (int sockfd, struct sockaddr * addr, int addrlen)
|
||||
{
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
return bind (sockfd, addr, addrlen);
|
||||
#else
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
|
||||
{
|
||||
struct sockaddr_in myaddr;
|
||||
struct sockaddr_un * unaddr;
|
||||
FILE * fp;
|
||||
struct sockaddr_un *unaddr;
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
|
||||
ret = connect (HANDLE2SOCKET(sockfd),
|
||||
(struct sockaddr *)&myaddr, sizeof myaddr);
|
||||
if (!ret)
|
||||
{
|
||||
/* Send the nonce. */
|
||||
ret = _assuan_io_write (sockfd, nonce, 16);
|
||||
if (ret >= 0 && ret != 16)
|
||||
{
|
||||
errno = EIO;
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
int res;
|
||||
res = connect (HANDLE2SOCKET (sockfd), addr, addrlen);
|
||||
if (res < 0)
|
||||
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
|
||||
return res;
|
||||
}
|
||||
#else
|
||||
return connect (sockfd, addr, addrlen);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen)
|
||||
{
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
|
||||
{
|
||||
struct sockaddr_in myaddr;
|
||||
struct sockaddr_un *unaddr;
|
||||
int filefd;
|
||||
FILE *fp;
|
||||
int len = sizeof myaddr;
|
||||
int rc;
|
||||
char nonce[16];
|
||||
|
||||
if (get_nonce (nonce, 16))
|
||||
return -1;
|
||||
|
||||
unaddr = (struct sockaddr_un *)addr;
|
||||
|
||||
myaddr.sin_port = 0;
|
||||
myaddr.sin_family = AF_INET;
|
||||
myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
|
||||
|
||||
rc = bind (sockfd, (struct sockaddr *)&myaddr, len);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len);
|
||||
if (rc)
|
||||
return rc;
|
||||
unaddr = (struct sockaddr_un *)addr;
|
||||
fp = fopen (unaddr->sun_path, "wb");
|
||||
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)
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
else
|
||||
{
|
||||
int res = bind (HANDLE2SOCKET(sockfd), addr, addrlen);
|
||||
if (res < 0)
|
||||
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
|
||||
return res;
|
||||
}
|
||||
#else
|
||||
return bind (sockfd, addr, addrlen);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_assuan_sock_get_nonce (struct sockaddr *addr, int addrlen,
|
||||
assuan_sock_nonce_t *nonce)
|
||||
{
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX)
|
||||
{
|
||||
struct sockaddr_un *unaddr;
|
||||
unsigned short port;
|
||||
|
||||
if (sizeof nonce->nonce != 16)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
nonce->length = 16;
|
||||
unaddr = (struct sockaddr_un *)addr;
|
||||
if (read_port_and_nonce (unaddr->sun_path, &port, nonce->nonce))
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nonce->length = 42; /* Arbitrary valuie to detect unitialized nonce. */
|
||||
nonce->nonce[0] = 42;
|
||||
}
|
||||
#else
|
||||
(void)addr;
|
||||
(void)addrlen;
|
||||
nonce->length = 0;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
|
||||
{
|
||||
#ifdef HAVE_W32_SYSTEM
|
||||
char buffer[16], *p;
|
||||
size_t nleft;
|
||||
int n;
|
||||
|
||||
if (sizeof nonce->nonce != 16)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nonce->length == 42 && nonce->nonce[0] == 42)
|
||||
return 0; /* Not a Unix domain socket. */
|
||||
|
||||
if (nonce->length != 16)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = buffer;
|
||||
nleft = 16;
|
||||
while (nleft)
|
||||
{
|
||||
n = _assuan_io_read (SOCKET2HANDLE(fd), p, nleft);
|
||||
if (n < 0 && errno == EINTR)
|
||||
;
|
||||
else if (n < 0 && errno == EAGAIN)
|
||||
Sleep (100);
|
||||
else if (n < 0)
|
||||
return -1;
|
||||
else if (!n)
|
||||
{
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
p += n;
|
||||
nleft -= n;
|
||||
}
|
||||
}
|
||||
if (memcmp (buffer, nonce->nonce, 16))
|
||||
{
|
||||
errno = EACCES;
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
(void)fd;
|
||||
(void)nonce;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Public API. */
|
||||
int
|
||||
assuan_sock_close (assuan_fd_t fd)
|
||||
{
|
||||
return _assuan_close (fd);
|
||||
}
|
||||
|
||||
assuan_fd_t
|
||||
assuan_sock_new (int domain, int type, int proto)
|
||||
{
|
||||
return _assuan_sock_new (domain, type, proto);
|
||||
}
|
||||
|
||||
int
|
||||
assuan_sock_connect (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen)
|
||||
{
|
||||
return _assuan_sock_connect (sockfd, addr, addrlen);
|
||||
}
|
||||
|
||||
int
|
||||
assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen)
|
||||
{
|
||||
return _assuan_sock_bind (sockfd, addr, addrlen);
|
||||
}
|
||||
|
||||
int
|
||||
assuan_sock_get_nonce (struct sockaddr *addr, int addrlen,
|
||||
assuan_sock_nonce_t *nonce)
|
||||
{
|
||||
return _assuan_sock_get_nonce (addr, addrlen, nonce);
|
||||
}
|
||||
|
||||
int
|
||||
assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce)
|
||||
{
|
||||
return _assuan_sock_check_nonce (fd, nonce);
|
||||
}
|
||||
|
@ -14,9 +14,7 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
@ -72,9 +70,9 @@
|
||||
static ssize_t
|
||||
uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
|
||||
{
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
int len = ctx->uds.buffersize;
|
||||
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
if (!ctx->uds.bufferallocated)
|
||||
{
|
||||
ctx->uds.buffer = xtrymalloc (2048);
|
||||
@ -141,12 +139,6 @@ uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
|
||||
#endif /*USE_DESCRIPTOR_PASSING*/
|
||||
}
|
||||
|
||||
#else /*HAVE_W32_SYSTEM*/
|
||||
|
||||
len = recvfrom (ctx->inbound.fd, buf, buflen, 0, NULL, NULL);
|
||||
|
||||
#endif /*HAVE_W32_SYSTEM*/
|
||||
|
||||
/* Return some data to the user. */
|
||||
|
||||
if (len > buflen) /* We have more than the user requested. */
|
||||
@ -159,6 +151,12 @@ uds_reader (assuan_context_t ctx, void *buf, size_t buflen)
|
||||
assert (ctx->uds.bufferoffset <= ctx->uds.bufferallocated);
|
||||
|
||||
return len;
|
||||
#else /*HAVE_W32_SYSTEM*/
|
||||
int res = recvfrom (HANDLE2SOCKET(ctx->inbound.fd), buf, buflen, 0, NULL, NULL);
|
||||
if (res < 0)
|
||||
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
|
||||
return res;
|
||||
#endif /*HAVE_W32_SYSTEM*/
|
||||
}
|
||||
|
||||
|
||||
@ -181,19 +179,21 @@ uds_writer (assuan_context_t ctx, const void *buf, size_t buflen)
|
||||
iovec.iov_len = buflen;
|
||||
|
||||
len = _assuan_simple_sendmsg (ctx, &msg);
|
||||
#else /*HAVE_W32_SYSTEM*/
|
||||
int len;
|
||||
|
||||
len = sendto (ctx->outbound.fd, buf, buflen, 0,
|
||||
(struct sockaddr *)&ctx->serveraddr,
|
||||
sizeof (struct sockaddr_in));
|
||||
#endif /*HAVE_W32_SYSTEM*/
|
||||
|
||||
return len;
|
||||
#else /*HAVE_W32_SYSTEM*/
|
||||
int res = sendto (HANDLE2SOCKET(ctx->outbound.fd), buf, buflen, 0,
|
||||
(struct sockaddr *)&ctx->serveraddr,
|
||||
sizeof (struct sockaddr_in));
|
||||
if (res < 0)
|
||||
errno = _assuan_sock_wsa2errno (WSAGetLastError ());
|
||||
return res;
|
||||
#endif /*HAVE_W32_SYSTEM*/
|
||||
}
|
||||
|
||||
|
||||
static assuan_error_t
|
||||
uds_sendfd (assuan_context_t ctx, int fd)
|
||||
uds_sendfd (assuan_context_t ctx, assuan_fd_t fd)
|
||||
{
|
||||
#ifdef USE_DESCRIPTOR_PASSING
|
||||
struct msghdr msg;
|
||||
@ -243,7 +243,7 @@ uds_sendfd (assuan_context_t ctx, int fd)
|
||||
|
||||
|
||||
static assuan_error_t
|
||||
uds_receivefd (assuan_context_t ctx, int *fd)
|
||||
uds_receivefd (assuan_context_t ctx, assuan_fd_t *fd)
|
||||
{
|
||||
#ifdef USE_DESCRIPTOR_PASSING
|
||||
int i;
|
||||
|
@ -14,9 +14,7 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
@ -32,6 +30,10 @@ static void *(*alloc_func)(size_t n) = malloc;
|
||||
static void *(*realloc_func)(void *p, size_t n) = realloc;
|
||||
static void (*free_func)(void*) = free;
|
||||
|
||||
struct assuan_io_hooks _assuan_io_hooks;
|
||||
|
||||
|
||||
|
||||
void
|
||||
assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
|
||||
void *(*new_realloc_func)(void *p, size_t n),
|
||||
@ -42,6 +44,20 @@ assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
|
||||
free_func = new_free_func;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
assuan_set_io_hooks (assuan_io_hooks_t io_hooks)
|
||||
{
|
||||
_assuan_io_hooks.read_hook = NULL;
|
||||
_assuan_io_hooks.write_hook = NULL;
|
||||
if (io_hooks)
|
||||
{
|
||||
_assuan_io_hooks.read_hook = io_hooks->read_hook;
|
||||
_assuan_io_hooks.write_hook = io_hooks->write_hook;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
_assuan_malloc (size_t n)
|
||||
{
|
||||
@ -152,6 +168,7 @@ assuan_set_flag (assuan_context_t ctx, assuan_flag_t flag, int value)
|
||||
switch (flag)
|
||||
{
|
||||
case ASSUAN_NO_WAITPID: ctx->flags.no_waitpid = value; break;
|
||||
case ASSUAN_CONFIDENTIAL: ctx->confidential = value; break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -164,8 +181,8 @@ assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag)
|
||||
switch (flag)
|
||||
{
|
||||
case ASSUAN_NO_WAITPID: return ctx->flags.no_waitpid;
|
||||
case ASSUAN_CONFIDENTIAL: return ctx->confidential;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
189
assuan/assuan.h
189
assuan/assuan.h
@ -1,5 +1,6 @@
|
||||
/* assuan.h - Definitions for the Assuan IPC library
|
||||
* Copyright (C) 2001, 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2002, 2003, 2005, 2007,
|
||||
* 2008 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of Assuan.
|
||||
*
|
||||
@ -14,9 +15,7 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ASSUAN_H
|
||||
@ -25,18 +24,28 @@
|
||||
#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_
|
||||
|
||||
This prefixes all external symbols with "_foo_".
|
||||
This prefixes all external symbols with "_foo_".
|
||||
|
||||
#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:
|
||||
@ -69,6 +78,8 @@ int _gpgme_io_write (int fd, const void *buffer, size_t count);
|
||||
int _gpgme_io_sendmsg (int sock, const struct msghdr *msg, int flags);
|
||||
int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
|
||||
|
||||
#define _assuan_funopen _gpgme_funopen
|
||||
|
||||
#define close _gpgme_io_close
|
||||
#define read _gpgme_io_read
|
||||
#define write _gpgme_io_write
|
||||
@ -103,6 +114,7 @@ int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
|
||||
_ASSUAN_PREFIX(assuan_register_option_handler)
|
||||
#define assuan_process _ASSUAN_PREFIX(assuan_process)
|
||||
#define assuan_process_next _ASSUAN_PREFIX(assuan_process_next)
|
||||
#define assuan_process_done _ASSUAN_PREFIX(assuan_process_done)
|
||||
#define assuan_get_active_fds _ASSUAN_PREFIX(assuan_get_active_fds)
|
||||
#define assuan_get_data_fp _ASSUAN_PREFIX(assuan_get_data_fp)
|
||||
#define assuan_set_okay_line _ASSUAN_PREFIX(assuan_set_okay_line)
|
||||
@ -130,6 +142,7 @@ int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
|
||||
#define assuan_get_peercred _ASSUAN_PREFIX(assuan_get_peercred)
|
||||
#define assuan_transact _ASSUAN_PREFIX(assuan_transact)
|
||||
#define assuan_inquire _ASSUAN_PREFIX(assuan_inquire)
|
||||
#define assuan_inquire_ext _ASSUAN_PREFIX(assuan_inquire_ext)
|
||||
#define assuan_read_line _ASSUAN_PREFIX(assuan_read_line)
|
||||
#define assuan_pending_line _ASSUAN_PREFIX(assuan_pending_line)
|
||||
#define assuan_write_line _ASSUAN_PREFIX(assuan_write_line)
|
||||
@ -137,7 +150,7 @@ int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
|
||||
#define assuan_sendfd _ASSUAN_PREFIX(assuan_sendfd)
|
||||
#define assuan_receivefd _ASSUAN_PREFIX(assuan_receivefd)
|
||||
#define assuan_set_malloc_hooks _ASSUAN_PREFIX(assuan_set_malloc_hooks)
|
||||
#define assuan_set_assuan_log_level _ASSUAN_PREFIX(assuan_set_assuan_log_level)
|
||||
#define assuan_set_io_hooks _ASSUAN_PREFIX(assuan_set_io_hooks)
|
||||
#define assuan_set_log_stream _ASSUAN_PREFIX(assuan_set_log_stream)
|
||||
#define assuan_set_error _ASSUAN_PREFIX(assuan_set_error)
|
||||
#define assuan_set_pointer _ASSUAN_PREFIX(assuan_set_pointer)
|
||||
@ -159,6 +172,13 @@ int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
|
||||
#define assuan_pipe_connect2 _ASSUAN_PREFIX(assuan_pipe_connect2)
|
||||
#define assuan_set_assuan_log_prefix \
|
||||
_ASSUAN_PREFIX(assuan_set_assuan_log_prefix)
|
||||
#define assuan_sock_close _ASSUAN_PREFIX(assuan_sock_close)
|
||||
#define assuan_sock_new _ASSUAN_PREFIX(assuan_sock_new)
|
||||
#define assuan_sock_connect _ASSUAN_PREFIX(assuan_sock_connect)
|
||||
#define assuan_sock_bind _ASSUAN_PREFIX(assuan_sock_bind)
|
||||
#define assuan_sock_get_nonce _ASSUAN_PREFIX(assuan_sock_get_nonce)
|
||||
#define assuan_sock_check_nonce _ASSUAN_PREFIX(assuan_sock_check_nonce)
|
||||
|
||||
|
||||
/* And now the internal functions, argh... */
|
||||
#define _assuan_read_line _ASSUAN_PREFIX(_assuan_read_line)
|
||||
@ -170,8 +190,9 @@ int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
|
||||
_ASSUAN_PREFIX(_assuan_register_std_commands)
|
||||
#define _assuan_simple_read _ASSUAN_PREFIX(_assuan_simple_read)
|
||||
#define _assuan_simple_write _ASSUAN_PREFIX(_assuan_simple_write)
|
||||
#define _assuan_simple_read _ASSUAN_PREFIX(_assuan_simple_read)
|
||||
#define _assuan_simple_write _ASSUAN_PREFIX(_assuan_simple_write)
|
||||
#define _assuan_io_read _ASSUAN_PREFIX(_assuan_io_read)
|
||||
#define _assuan_io_write _ASSUAN_PREFIX(_assuan_io_write)
|
||||
#define _assuan_io_hooks _ASSUAN_PREFIX(_assuan_io_hooks)
|
||||
#define _assuan_new_context _ASSUAN_PREFIX(_assuan_new_context)
|
||||
#define _assuan_release_context _ASSUAN_PREFIX(_assuan_release_context)
|
||||
#define _assuan_malloc _ASSUAN_PREFIX(_assuan_malloc)
|
||||
@ -188,19 +209,22 @@ int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags);
|
||||
#define _assuan_gpg_strerror_r _ASSUAN_PREFIX(_assuan_gpg_strerror_r)
|
||||
#define _assuan_gpg_strsource _ASSUAN_PREFIX(_assuan_gpg_strsource)
|
||||
#define _assuan_write_line _ASSUAN_PREFIX(_assuan_write_line)
|
||||
#define _assuan_close _ASSUAN_PREFIX(_assuan_close)
|
||||
#define _assuan_sock_new _ASSUAN_PREFIX(_assuan_sock_new)
|
||||
#define _assuan_sock_bind _ASSUAN_PREFIX(_assuan_sock_bind)
|
||||
#define _assuan_sock_connect _ASSUAN_PREFIX(_assuan_sock_connect)
|
||||
#define _assuan_error _ASSUAN_PREFIX(_assuan_error)
|
||||
#define _assuan_error_is_eagain _ASSUAN_PREFIX(_assuan_error_is_eagain)
|
||||
#define _assuan_init_uds_io _ASSUAN_PREFIX(_assuan_init_uds_io)
|
||||
#define _assuan_uds_close_fds _ASSUAN_PREFIX(_assuan_uds_close_fds)
|
||||
#define _assuan_uds_deinit _ASSUAN_PREFIX(_assuan_uds_deinit)
|
||||
#define _assuan_simple_recvmsg _ASSUAN_PREFIX(_assuan_simple_recvmsg)
|
||||
#define _assuan_simple_sendmsg _ASSUAN_PREFIX(_assuan_simple_sendmsg)
|
||||
#define _assuan_waitpid _ASSUAN_PREFIX(_assuan_waitpid)
|
||||
#define _assuan_sock_wsa2errno _ASSUAN_PREFIX(_assuan_sock_wsa2errno)
|
||||
#define _assuan_sock_close _ASSUAN_PREFIX(_assuan_sock_close)
|
||||
#define _assuan_sock_new _ASSUAN_PREFIX(_assuan_sock_new)
|
||||
#define _assuan_sock_connect _ASSUAN_PREFIX(_assuan_sock_connect)
|
||||
#define _assuan_sock_bind _ASSUAN_PREFIX(_assuan_sock_bind)
|
||||
#define _assuan_sock_get_nonce _ASSUAN_PREFIX(_assuan_sock_get_nonce)
|
||||
#define _assuan_sock_check_nonce _ASSUAN_PREFIX(_assuan_sock_check_nonce)
|
||||
|
||||
#define _assuan_funopen _gpgme_funopen
|
||||
#endif /*_ASSUAN_EXT_SYM_PREFIX*/
|
||||
|
||||
|
||||
@ -350,7 +374,8 @@ typedef enum
|
||||
|
||||
#else /*!_ASSUAN_ONLY_GPG_ERRORS*/
|
||||
|
||||
typedef int assuan_error_t;
|
||||
/* Choose a type compatible with gpg_error_t. */
|
||||
typedef unsigned int assuan_error_t;
|
||||
|
||||
#endif /*!_ASSUAN_ONLY_GPG_ERRORS*/
|
||||
|
||||
@ -363,7 +388,11 @@ typedef enum
|
||||
this is not desirable. By setting this flag, the waitpid will
|
||||
be skipped and the caller is responsible to cleanup a forked
|
||||
process. */
|
||||
ASSUAN_NO_WAITPID = 1
|
||||
ASSUAN_NO_WAITPID = 1,
|
||||
/* This flag indicates whether Assuan logging is in confidential
|
||||
mode. Use assuan_{begin,end}_condidential to change the
|
||||
mode. */
|
||||
ASSUAN_CONFIDENTIAL = 2
|
||||
}
|
||||
assuan_flag_t;
|
||||
|
||||
@ -375,6 +404,66 @@ typedef struct assuan_context_s *assuan_context_t;
|
||||
typedef struct assuan_context_s *ASSUAN_CONTEXT _ASSUAN_DEPRECATED;
|
||||
#endif /*_ASSUAN_ONLY_GPG_ERRORS*/
|
||||
|
||||
/* Because we use system handles and not libc low level file
|
||||
descriptors on W32, we need to declare them as HANDLE (which
|
||||
actually is a plain pointer). This is required to eventually
|
||||
support 64 bit Windows systems. */
|
||||
#ifdef _WIN32
|
||||
typedef void *assuan_fd_t;
|
||||
#define ASSUAN_INVALID_FD ((void*)(-1))
|
||||
#define ASSUAN_INT2FD(s) ((void *)(s))
|
||||
#define ASSUAN_FD2INT(h) ((unsigned int)(h))
|
||||
#else
|
||||
typedef int assuan_fd_t;
|
||||
#define ASSUAN_INVALID_FD (-1)
|
||||
#define ASSUAN_INT2FD(s) ((s))
|
||||
#define ASSUAN_FD2INT(h) ((h))
|
||||
#endif
|
||||
|
||||
|
||||
/* Assuan features an emulation of Unix domain sockets based on a
|
||||
local TCP connections. To implement access permissions based on
|
||||
file permissions a nonce is used which is expected by th server as
|
||||
the first bytes received. This structure is used by the server to
|
||||
save the nonce created initially by bind. On POSIX systems this is
|
||||
a dummy operation. */
|
||||
struct assuan_sock_nonce_s
|
||||
{
|
||||
size_t length;
|
||||
#ifdef _WIN32
|
||||
char nonce[16];
|
||||
#endif
|
||||
};
|
||||
typedef struct assuan_sock_nonce_s assuan_sock_nonce_t;
|
||||
|
||||
/* Define the Unix domain socket structure for Windows. */
|
||||
#if defined(_WIN32) && !defined(_ASSUAN_NO_SOCKET_WRAPPER)
|
||||
#ifndef AF_LOCAL
|
||||
#define AF_LOCAL AF_UNIX
|
||||
#endif
|
||||
#define EADDRINUSE WSAEADDRINUSE
|
||||
struct sockaddr_un
|
||||
{
|
||||
short sun_family;
|
||||
unsigned short sun_port;
|
||||
struct in_addr sun_addr;
|
||||
char sun_path[108-2-4];
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/* Definition of hook functions used to conditionally replace the
|
||||
default I/O functions. */
|
||||
struct assuan_io_hooks
|
||||
{
|
||||
int (*read_hook)(assuan_context_t, assuan_fd_t, void *, size_t, ssize_t *);
|
||||
int (*write_hook)(assuan_context_t, assuan_fd_t fd,
|
||||
const void *, size_t, ssize_t *);
|
||||
};
|
||||
typedef struct assuan_io_hooks *assuan_io_hooks_t;
|
||||
|
||||
|
||||
|
||||
/*-- assuan-handler.c --*/
|
||||
int assuan_register_command (assuan_context_t ctx,
|
||||
const char *cmd_string,
|
||||
@ -398,8 +487,9 @@ int assuan_register_option_handler (assuan_context_t ctx,
|
||||
|
||||
int assuan_process (assuan_context_t ctx);
|
||||
int assuan_process_next (assuan_context_t ctx);
|
||||
int assuan_process_done (assuan_context_t ctx, int rc);
|
||||
int assuan_get_active_fds (assuan_context_t ctx, int what,
|
||||
int *fdarray, int fdarraysize);
|
||||
assuan_fd_t *fdarray, int fdarraysize);
|
||||
|
||||
|
||||
FILE *assuan_get_data_fp (assuan_context_t ctx);
|
||||
@ -410,15 +500,17 @@ assuan_error_t assuan_write_status (assuan_context_t ctx,
|
||||
/* Negotiate a file descriptor. If LINE contains "FD=N", returns N
|
||||
assuming a local file descriptor. If LINE contains "FD" reads a
|
||||
file descriptor via CTX and stores it in *RDF (the CTX must be
|
||||
capable of passing file descriptors). */
|
||||
capable of passing file descriptors). Under W32 the returned FD is
|
||||
a libc-type one. */
|
||||
assuan_error_t assuan_command_parse_fd (assuan_context_t ctx, char *line,
|
||||
int *rfd);
|
||||
assuan_fd_t *rfd);
|
||||
|
||||
|
||||
/*-- assuan-listen.c --*/
|
||||
assuan_error_t assuan_set_hello_line (assuan_context_t ctx, const char *line);
|
||||
assuan_error_t assuan_accept (assuan_context_t ctx);
|
||||
int assuan_get_input_fd (assuan_context_t ctx);
|
||||
int assuan_get_output_fd (assuan_context_t ctx);
|
||||
assuan_fd_t assuan_get_input_fd (assuan_context_t ctx);
|
||||
assuan_fd_t assuan_get_output_fd (assuan_context_t ctx);
|
||||
assuan_error_t assuan_close_input_fd (assuan_context_t ctx);
|
||||
assuan_error_t assuan_close_output_fd (assuan_context_t ctx);
|
||||
|
||||
@ -428,11 +520,12 @@ int assuan_init_pipe_server (assuan_context_t *r_ctx, int filedes[2]);
|
||||
void assuan_deinit_server (assuan_context_t ctx);
|
||||
|
||||
/*-- assuan-socket-server.c --*/
|
||||
int assuan_init_socket_server (assuan_context_t *r_ctx, int listen_fd);
|
||||
int assuan_init_socket_server (assuan_context_t *r_ctx, assuan_fd_t listen_fd);
|
||||
int assuan_init_connected_socket_server (assuan_context_t *r_ctx,
|
||||
int fd) _ASSUAN_DEPRECATED;
|
||||
int assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd,
|
||||
assuan_fd_t fd) _ASSUAN_DEPRECATED;
|
||||
int assuan_init_socket_server_ext (assuan_context_t *r_ctx, assuan_fd_t fd,
|
||||
unsigned int flags);
|
||||
void assuan_set_sock_nonce (assuan_context_t ctx, assuan_sock_nonce_t *nonce);
|
||||
|
||||
/*-- assuan-pipe-connect.c --*/
|
||||
assuan_error_t assuan_pipe_connect (assuan_context_t *ctx,
|
||||
@ -465,7 +558,7 @@ assuan_error_t assuan_socket_connect_ext (assuan_context_t *ctx,
|
||||
/*-- assuan-connect.c --*/
|
||||
void assuan_disconnect (assuan_context_t ctx);
|
||||
pid_t assuan_get_pid (assuan_context_t ctx);
|
||||
#ifndef HAVE_W32_SYSTEM
|
||||
#ifndef _WIN32
|
||||
assuan_error_t assuan_get_peercred (assuan_context_t ctx,
|
||||
pid_t *pid, uid_t *uid, gid_t *gid);
|
||||
#endif
|
||||
@ -474,11 +567,11 @@ assuan_error_t assuan_get_peercred (assuan_context_t ctx,
|
||||
assuan_error_t
|
||||
assuan_transact (assuan_context_t ctx,
|
||||
const char *command,
|
||||
int (*data_cb)(void *, const void *, size_t),
|
||||
assuan_error_t (*data_cb)(void *, const void *, size_t),
|
||||
void *data_cb_arg,
|
||||
int (*inquire_cb)(void*, const char *),
|
||||
assuan_error_t (*inquire_cb)(void*, const char *),
|
||||
void *inquire_cb_arg,
|
||||
int (*status_cb)(void*, const char *),
|
||||
assuan_error_t (*status_cb)(void*, const char *),
|
||||
void *status_cb_arg);
|
||||
|
||||
|
||||
@ -486,7 +579,12 @@ assuan_transact (assuan_context_t ctx,
|
||||
assuan_error_t assuan_inquire (assuan_context_t ctx, const char *keyword,
|
||||
unsigned char **r_buffer, size_t *r_length,
|
||||
size_t maxlen);
|
||||
|
||||
assuan_error_t assuan_inquire_ext (assuan_context_t ctx, const char *keyword,
|
||||
size_t maxlen,
|
||||
int (*cb) (void *cb_data, int rc,
|
||||
unsigned char *buf,
|
||||
size_t buf_len),
|
||||
void *cb_data);
|
||||
/*-- assuan-buffer.c --*/
|
||||
assuan_error_t assuan_read_line (assuan_context_t ctx,
|
||||
char **line, size_t *linelen);
|
||||
@ -498,13 +596,15 @@ assuan_error_t assuan_send_data (assuan_context_t ctx,
|
||||
/* The file descriptor must be pending before assuan_receivefd is
|
||||
called. This means that assuan_sendfd should be called *before* the
|
||||
trigger is sent (normally via assuan_write_line ("INPUT FD")). */
|
||||
assuan_error_t assuan_sendfd (assuan_context_t ctx, int fd);
|
||||
assuan_error_t assuan_receivefd (assuan_context_t ctx, int *fd);
|
||||
assuan_error_t assuan_sendfd (assuan_context_t ctx, assuan_fd_t fd);
|
||||
assuan_error_t assuan_receivefd (assuan_context_t ctx, assuan_fd_t *fd);
|
||||
|
||||
|
||||
/*-- assuan-util.c --*/
|
||||
void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
|
||||
void *(*new_realloc_func)(void *p, size_t n),
|
||||
void (*new_free_func)(void*) );
|
||||
void assuan_set_io_hooks (assuan_io_hooks_t io_hooks);
|
||||
void assuan_set_log_stream (assuan_context_t ctx, FILE *fp);
|
||||
int assuan_set_error (assuan_context_t ctx, int err, const char *text);
|
||||
void assuan_set_pointer (assuan_context_t ctx, void *pointer);
|
||||
@ -545,14 +645,6 @@ void assuan_set_assuan_err_source (int errsource);
|
||||
|
||||
/*-- assuan-logging.c --*/
|
||||
|
||||
/* Set the log level for general assuan commands. 0 is no logging at
|
||||
all, 1 is the standard logging and the default. Higher leveles may
|
||||
be defined in the future. Passing a level of -1 will not change
|
||||
the current log level. Returns previous log level. Note, that
|
||||
this function is not thread-safe and should in general be used
|
||||
right at startup. */
|
||||
int assuan_set_assuan_log_level (int level);
|
||||
|
||||
/* Set the stream to which assuan should log message not associated
|
||||
with a context. By default, this is stderr. The default value
|
||||
will be changed when the first log stream is associated with a
|
||||
@ -574,6 +666,21 @@ void assuan_set_assuan_log_prefix (const char *text);
|
||||
string, i.e. "" */
|
||||
const char *assuan_get_assuan_log_prefix (void);
|
||||
|
||||
|
||||
/*-- assuan-socket.c --*/
|
||||
|
||||
/* These are socket wrapper functions to support an emulation of Unix
|
||||
domain sockets on Windows W32. */
|
||||
int assuan_sock_close (assuan_fd_t fd);
|
||||
assuan_fd_t assuan_sock_new (int domain, int type, int proto);
|
||||
int assuan_sock_connect (assuan_fd_t sockfd,
|
||||
struct sockaddr *addr, int addrlen);
|
||||
int assuan_sock_bind (assuan_fd_t sockfd, struct sockaddr *addr, int addrlen);
|
||||
int assuan_sock_get_nonce (struct sockaddr *addr, int addrlen,
|
||||
assuan_sock_nonce_t *nonce);
|
||||
int assuan_sock_check_nonce (assuan_fd_t fd, assuan_sock_nonce_t *nonce);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -31,6 +31,7 @@ cat <<EOF
|
||||
|
||||
#undef _ASSUAN_IN_LIBASSUAN /* undef to get all error codes. */
|
||||
#include "assuan.h"
|
||||
#include "assuan-defs.h"
|
||||
|
||||
/* If true the modern gpg-error style error codes are used in the
|
||||
API. */
|
||||
@ -94,11 +95,8 @@ _assuan_error (int oldcode)
|
||||
{
|
||||
case 0: n = 16381; /*GPG_ERR_MISSING_ERRNO*/ break;
|
||||
case EAGAIN:
|
||||
if (errno > 0 && errno < 4096)
|
||||
{
|
||||
n = (EAGAIN | (1 << 15));
|
||||
break;
|
||||
}
|
||||
n = (6 | (1 << 15));
|
||||
break;
|
||||
default: n = 270; /*GPG_ERR_ASS_READ_ERROR*/ break;
|
||||
}
|
||||
break;
|
||||
@ -108,11 +106,8 @@ _assuan_error (int oldcode)
|
||||
{
|
||||
case 0: n = 16381; /*GPG_ERR_MISSING_ERRNO*/ break;
|
||||
case EAGAIN:
|
||||
if (errno > 0 && errno < 4096)
|
||||
{
|
||||
n = (EAGAIN | (1 << 15));
|
||||
break;
|
||||
}
|
||||
n = (6 | (1 << 15));
|
||||
break;
|
||||
default: n = 271; /*GPG_ERR_ASS_WRITE_ERROR*/ break;
|
||||
}
|
||||
break;
|
||||
@ -127,11 +122,8 @@ _assuan_error (int oldcode)
|
||||
n = 16381; /*GPG_ERR_MISSING_ERRNO*/
|
||||
break;
|
||||
case ENOMEM:
|
||||
if (errno > 0 && errno < 4096)
|
||||
{
|
||||
n = (ENOMEM | (1 << 15));
|
||||
break;
|
||||
}
|
||||
n = (86 | (1 << 15));
|
||||
break;
|
||||
default:
|
||||
n = 16382; /*GPG_ERR_UNKNOWN_ERRNO*/
|
||||
break;
|
||||
@ -150,6 +142,23 @@ _assuan_error (int oldcode)
|
||||
}
|
||||
|
||||
|
||||
/* A small helper function to treat EAGAIN transparently to the
|
||||
caller. */
|
||||
int
|
||||
_assuan_error_is_eagain (assuan_error_t err)
|
||||
{
|
||||
if ((!err_source && err == ASSUAN_Read_Error && errno == EAGAIN)
|
||||
|| (err_source && (err & ((1 << 24) - 1)) == (6 | (1 << 15))))
|
||||
{
|
||||
/* Avoid spinning by sleeping for one tenth of a second. */
|
||||
_assuan_usleep (100000);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* assuan_strerror:
|
||||
* @err: Error code
|
||||
|
@ -145,8 +145,7 @@ debug_init (void)
|
||||
fprintf (errfp, "gpgme_debug: level=%d\n", debug_level);
|
||||
#ifdef HAVE_ASSUAN_H
|
||||
assuan_set_assuan_log_prefix ("gpgme-assuan");
|
||||
assuan_set_assuan_log_stream (errfp);
|
||||
assuan_set_assuan_log_level (debug_level >= 0? debug_level:0);
|
||||
assuan_set_assuan_log_stream (debug_level > 0 ? errfp : NULL);
|
||||
#endif /* HAVE_ASSUAN_H*/
|
||||
}
|
||||
UNLOCK (debug_lock);
|
||||
|
@ -56,7 +56,6 @@ do_subsystem_inits (void)
|
||||
|
||||
_gpgme_sema_subsystem_init ();
|
||||
#ifdef HAVE_ASSUAN_H
|
||||
assuan_set_assuan_log_level (0);
|
||||
assuan_set_assuan_err_source (GPG_ERR_SOURCE_GPGME);
|
||||
#endif /*HAVE_ASSUAN_H*/
|
||||
_gpgme_debug_subsystem_init ();
|
||||
|
Loading…
Reference in New Issue
Block a user