diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 (patch) | |
tree | 67208f7c145782a7e90b123b982ca78d88cc2c87 /libkdenetwork/libgpgme-copy/assuan | |
download | tdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.tar.gz tdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'libkdenetwork/libgpgme-copy/assuan')
21 files changed, 6507 insertions, 0 deletions
diff --git a/libkdenetwork/libgpgme-copy/assuan/ChangeLog b/libkdenetwork/libgpgme-copy/assuan/ChangeLog new file mode 100644 index 000000000..a3b3f9281 --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/ChangeLog @@ -0,0 +1,829 @@ +2006-11-22 Werner Koch <wk@g10code.com> + + * assuan-handler.c (fun1_cookie_write, fun2_cookie_write): New. + (assuan_get_data_fp) [HAVE_FUNOPEN]: Use it. + +2006-11-21 Werner Koch <wk@g10code.com> + + * Makefile.am (libassuan_pth_a_CFLAGS): New. + + * assuan-pipe-server.c (_assuan_release_context): Free CMDTBL. + +2006-11-14 Werner Koch <wk@g10code.com> + + * libassuan.m4 (AM_CHECK_LIBASSUAN): New. + + * assuan-handler.c (assuan_register_post_cmd_notify) + (assuan_register_post_cmd_notify): New. + * assuan-util.c (assuan_set_io_monitor): New. + * assuan-buffer.c (_assuan_read_line): Use it. + (_assuan_write_line): Ditto. + (_assuan_cookie_write_data): Ditto. + (_assuan_cookie_write_flush): Ditto. + +2006-10-18 Werner Koch <wk@g10code.com> + + * libassuan.m4: Pass "pthread" to the common macro. Reported by + Rex Dieter. + +2006-10-16 Werner Koch <wk@g10code.com> + + * mkerrors: Map ASSUAN_Not_Confirmed. + +2006-10-10 Werner Koch <wk@g10code.com> + + * libassuan.m4 (AM_PATH_LIBASSUAN_PTH) + (AM_PATH_LIBASSUAN_PTHREAD): Fixed. + + * assuan-buffer.c (assuan_sendfd): Implement a runtime detection + of implemented descripotr passing. + + * assuan-uds.c: Take care of USE_DESCRIPTOR_PASSING. + + * assuan-defs.h: Add missing semicolon. + +2006-10-09 Werner Koch <wk@g10code.com> + + * assuan-handler.c (process_request): Use weak pragma for the sake + of old gcc's. Reported by Alain Guibert. + + * assuan-io.c: Removed Pth support. + * assuan-io-pth.c: New. Based on assuan-io.c + +2006-10-06 Werner Koch <wk@g10code.com> + + * libassuan-config.in: New options --api-version and --thread. + +2006-10-04 Werner Koch <wk@g10code.com> + + * assuan-client.c (assuan_transact): Need to map old assuan status + codes so that for example CANCELED is correctly mapped. + +2006-09-28 Marcus Brinkmann <marcus@g10code.de> + + * assuan-client.c (assuan_transact): Do not convert error on + status line, it is already a gpg-error. Do convert + ASSUAN_Server_Fault. + +2006-09-19 Marcus Brinkmann <marcus@g10code.de> + + * assuan.h (assuan_init_socket_server_ext) + [_ASSUAN_EXT_SYM_PREFIX]: Fix typo in macro. + +2006-09-19 Werner Koch <wk@g10code.com> + + * assuan-defs.h (putc_unlocked): Add prototype. + + * assuan-socket-server.c (accept_connection): Made LEN a socklen_t. + + * assuan.h: Replaced assuan error code enum by simple defines and + made assuan_error_t an int. + * mkerrors: Changed parser accordingly. + +2006-09-19 Marcus Brinkmann <marcus@g10code.de> + + * assuan-pipe-connect.c: Add hacks for Slowaris. + * assuan-socket.c: Likewise here. + + * assuan.h (enum): Avoid trailing comma in enumerator list. Ugh. + + * mkerrors (_assuan_error): Change return type to assuan_error_t. + * assuan-buffer.c (_assuan_read_line): Change return type to + assuan_error_t. Map returned value of -1. + (_assuan_write_line): Change type of RC to assuan_error_t. + * assuan-defs.h (_assuan_read_line, _assuan_error): Likewise for + prototypes. + + * assuan-defs.h (unsetenv): Define correctly. + +2006-09-14 Werner Koch <wk@g10code.com> + + * assuan-io.c (_assuan_waitpid): New. Changed all waitpid calls + to this. + + * assuan.h (_ASSUAN_DEPRECATED): New internal macro. + (assuan_pipe_connect2): Declare deprecated. + (assuan_init_connected_socket_server): Declare deprecated. + + * assuan-connect.c (assuan_get_peercred): New. + * assuan-socket-server.c (accept_connection_bottom): Save uid and gid. + +2006-09-13 Werner Koch <wk@g10code.com> + + * assuan-client.c (assuan_transact): Need to map the error code. + * mkerrors: Need to map ASSUAN_No_Secret_Key. + + * assuan-pipe-server.c (is_valid_socket): New. + (assuan_init_pipe_server): Use UDS with the environmet variable is + set and a valid descriptor is given. Ignore FILEDES in this case. + + * assuan-socket-server.c (assuan_init_socket_server_ext): New. + Changed other init fucntions to make use of it. + + * assuan-handler.c (assuan_command_parse_fd): Allow for lowercase + "fd". + (std_handler_reset): Close pending fds. + * assuan-uds.c (uds_receivefd): Fixed. + (_assuan_uds_close_fds): New. + + * assuan-socket-connect.c (assuan_socket_connect_ext): New. Takes + all code of assuan_socket_connect plus an option to use sendmsg. + * assuan-pipe-connect.c (assuan_pipe_connect_ext): New arg FLAGS. + +2006-09-12 Werner Koch <wk@g10code.com> + + * assuan-buffer.c (_assuan_write_line): Also log the prefix. + + * assuan-defs.h (DIM, DIMof): New. + + * assuan-domain-server.c: Removed. + * assuan-domain-connect.c: Renamed to .. + * assuan-uds.c: this. + (domain_reader, domain_writer, domain_sendfd, domain_receivefd) + (assuan_domain_connect, _assuan_domain_init): Removed. + (uds_reader, uds_writer, uds_sendfd, uds_receivefd) + (_assuan_init_uds_io): New. + (_assuan_uds_deinit): New. + + * assuan-io.c (_assuan_simple_sendmsg, _assuan_simple_recvmsg): New. + (my_pth_fdmode, my_pth_select): New. + +2006-09-11 Werner Koch <wk@g10code.com> + + * assuan-pipe-server.c (assuan_init_pipe_server): Allow for + FILEDES to be NULL and try to start as a socketpair server in this + case. + + * assuan-pipe-connect.c (assuan_pipe_connect2): Split up into two + functions (unix and w32) for clarity. + (pipe_connect_unix): This is the new fucntion. Add USE_CMSG flag. + (pipe_connect_w32): Ditto. + (initial_handshake): Factored out code. + (socketpair_connect): New. + (assuan_pipe_connect_ext): New. + (do_finish): Handle case if outbound and inbound fd are the same. + This is to support socketpairs. + +2006-09-10 Werner Koch <wk@g10code.com> + + * assuan-util.c (_assuan_log_print_buffer) + (_assuan_log_sanitized_string,assuan_set_log_stream): Moved to .. + * assuan-logging.c: .. here. + (_assuan_log_print_buffer): Only print the leading bytes in hex + log mode unless the new env variable ASSUAN_FULL_LOGGING has been + set. + (_assuan_set_default_log_stream): Test this env variable. + +2006-09-06 Werner Koch <wk@g10code.com> + + * assuan.h (_ASSUAN_ONLY_GPG_ERRORS): New. + + * assuan-handler.c (dispatch_command): Use Syntax_Error instead of + Invalid_Command. + + * assuan-domain-connect.c: Changed alloc malloc/free/realloc to + xtrymalloc et al. + (read_int, write_int): Make args void pointers. + (domain_receivefd): Take care of realloc shrinking failure. + + * assuan-buffer.c (_assuan_read_line, _assuan_write_line) + (assuan_write_line, _assuan_cookie_write_data) + (_assuan_cookie_write_flush): Print the inbound fd instead of the + address of the context when logging I/0. This makes it more + readable. + +2006-09-05 Werner Koch <wk@g10code.com> + + * assuan-defs.h (err_code, err_is_eof): New. + + * mkerrors (_assuan_error): New. Wrapped all error code + assignments in a call to this. + (assuan_strerror): Map gpg-style error codes back. Also print a + string for the old EOF code. + (assuan_set_assuan_err_source): New. + + * assuan-logging.c (_assuan_log_printf): Do not change ERRNO and + print the pid. + + * assuan-domain-connect.c (domain_reader): Replaced plain printf + by assuan_log function. + +2005-10-24 Werner Koch <wk@g10code.com> + + * putc_unlocked.c, memrchr.c, isascii.c, funopen.c: Changed + distribution terms to LGPL. This are small and trivial files so + there are no obstacles of doing so. + * assuan-socket.c: Likewise, the stated GPL was not intended. + +2005-10-08 Marcus Brinkmann <marcus@g10code.de> + + * assuan-defs.h (setenv, unsetenv, clearenv) [!HAVE_SETENV]: + Define to _assuan_*. + * setenv.c: Include "assuan-defs.h". + (__add_to_environ): Make static. + +2005-10-07 Marcus Brinkmann <marcus@g10code.de> + + * assuan-defs.h (memrchr) [!HAVE_MEMRCHR]: New prototype. + (stpcpy) [!HAVE_STPCPY]: Likewise. + * stpcpy.c: New LGPL'ed file from the GNU C Library. + * setenv.c: New file. + * assuan-domain-connect.c (read_int): New function. + (write_int): New function. + (domain_reader): Use read_int. + (domain_sendfd): Use write_int. + +2005-10-01 Marcus Brinkmann <marcus@g10code.de> + + * assuan.h (assuan_pipe_connect, assuan_pipe_connect2): Make type + of ARGV parameter const in prototype. + * assuan-pipe-connect.c (assuan_pipe_connect, + assuan_pipe_connect2): Likewise in declaration. + (assuan_pipe_connect2): Add braindead cast to make execv happy. + + * assuan-client.c (assuan_transact): Change LINE, S and D from + unsigned char * to char * to silence gcc warning. + * assuan-util.c (_assuan_log_sanitized_string): Add explicit cast + to silence gcc warning. + * assuan-inquire.c (assuan_inquire): Likewise. + +2005-08-19 Werner Koch <wk@g10code.com> + + * funopen.c, assuan-socket.c: Copied from libassuan CVS. + * assuan-pipe-connect.c (assuan_pipe_connect2): Add missing + declaration of PID. + +2005-08-09 Werner Koch <wk@g10code.com> + + * README.1st: Adjusted to cope with changes done in upstream Assuan. + + Merged changes for W32 support from libassuan. + + * 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. + * assuan-logging.c (_assuan_w32_strerror): New. + * assuan-defs.h (w32_strerror): new. + * assuan-pipe-connect.c (assuan_pipe_connect2, fix_signals): + Factored signal code out to new function. + (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) + + * 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. + +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 macro. Changed callers. Noted by Ville Skyttä. + +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. + +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-06-08 Marcus Brinkmann <marcus@g10code.de> + + * assuan-buffer.c (assuan_write_line): If the line is longer than + the maximum line length, bail out early. + +2004-04-19 Werner Koch <wk@gnupg.org> + + * assuan-socket-connect.c: Include sys/types.h + * assuan-socket-server.c: Ditto + * assuan-domain-connect.c: Ditto. + +2004-02-18 Werner Koch <wk@gnupg.org> + + * assuan-handler.c (assuan_get_data_fp): Fail with ENOSYS if we + can't implement this. + +2004-02-13 Werner Koch <wk@gnupg.org> + + * assuan-domain-connect.c: Removed the unneeded alloca.h + +2003-08-13 Werner Koch <wk@gnupg.org> + + * assuan-inquire.c (assuan_inquire): Increase length of cmdbuf to + the Assuan limit. + +2003-06-24 Werner Koch <wk@gnupg.org> + + * mkerrors: Kludge to print libgpg-error values in an easier + readable way. + +2003-04-29 Werner Koch <wk@gnupg.org> + + * libassuan.m4: New. Based on libgrypt.m4. + * Makefile.am (m4data_DATA): New. + + * assuan.h (AssuanCommand): Removed. + + * assuan-handler.c: Remove the cmd_id element, + (assuan_register_command): Likewise. Note that semantics changed. + (_assuan_register_std_commands): Adjusted. + +2003-02-22 Neal H. Walfield <neal@g10code.de> + + * Makefile.am (bin_SCRIPTS): Renamed from bin_PROGRAMS. + +2003-02-18 Neal H. Walfield <neal@g10code.de> + + * Makefile.am (libassuan_a_LIBADD): New variable. + * funopen.c: Move from ../common. + * isascii.c: Likewise. + * memrchr.c: Likewise. + * putc_unlocked.c: Likewise. + +2003-02-18 Neal H. Walfield <neal@g10code.de> + + * assuan-handler.c (_IO_cookie_io_functions_t): Remove. + (cookie_io_functions_t): Remove. + (fopencookie): Remove prototype. + (assuan_get_data_fp): Use funopen, not fopencookie. + +2003-02-18 Neal H. Walfield <neal@g10code.de> + + * libassuan-config.in: New file. + * Makefile.am (bin_PROGRAMS): New variable. + +2003-02-17 Neal H. Walfield <neal@g10code.de> + + * .cvsignore: New file. + +2003-02-17 Neal H. Walfield <neal@g10code.de> + + * Makefile.am (lib_LIBRARIES): Use this instead of . . . + (noinst_LIBRARIES): . . . this. + (include_HEADERS): New variable. + (libassuan_a_SOURCES): Remove assuan.h, add assuan-logging.c. + + * assuan.h (assuan_set_assuan_log_stream): New prototype. + (assuan_get_assuan_log_stream): Likewise. + (assuan_get_assuan_log_prefix): Likewise. + * assuan-logging.c: New file. + + * assuan-buffer.c [HAVE_JNLIB_LOGGIN]: Do not include + "../jnlib/logging.h". + (my_log_prefix): Remove function. + (_assuan_read_line): Use assuan_get_assuan_log_prefix in lieu of + my_log_prefix. + (assuan_write_line): Likewise. + (_assuan_cookie_write_data): Likewise. + (_assuan_cookie_write_flush): Likewise. + * assuan-domain-connect.c (LOGERROR, LOGERROR1, LOGERROR2, + LOGERRORX): Remove. + (LOG): New macro. + (domain_reader): Use it. + (domain_writer): Likewise. + (domain_sendfd): Likewise. + (domain_receivefd): Likewise. + (_assuan_domain_init): Likewise. + (assuan_domain_connect): Likewise. + * assuan-pipe-connect.c [HAVE_JNLIB_LOGGIN]: Do not include + "../jnlib/logging.h". + (LOGERROR, LOGERROR1, LOGERROR2, LOGERRORX): Remove. + (LOG): New macro. + (assuan_pipe_connect): Use it. + * assuan-socket-connect.c [HAVE_JNLIB_LOGGIN]: Do not include + "../jnlib/logging.h". + (LOGERROR, LOGERROR1, LOGERROR2, LOGERRORX): Remove. + (LOG): New macro. + (assuan_socket_connect): Use it. + (socket_reader): Remove dead code. + (socket_writer): Likewise. + * assuan-util.c [HAVE_JNLIB_LOGGIN]: Do not include + "../jnlib/logging.h". + (_assuan_log_sanitized_string): Use assuan_get_assuan_log_stream, + not jnlib. + +2002-11-24 Neal H. Walfield <neal@g10code.de> + + * assuan.h (assuan_command_parse_fd): New prototype. + * assuan-handler.c (assuan_command_parse_fd): Rename from + parse_cmd_input_output. Export. + (std_handler_input): Update to use assuan_command_parse_fd. + (std_handler_output): Likewise. + +2002-11-24 Neal H. Walfield <neal@g10code.de> + + * assuan.h (assuan_sendfd): New prototype. + (assuan_receivefd): New prototype. + * assuan-buffer.c (assuan_sendfd): New function. + (assuan_receivefd): New function. + * assuan-handler.c (parse_cmd_input_output): Recognize incoming + file descriptors and act appropriately. + * assuan-defs.h (struct assuan_io): Add fields sendfd and + receivefd. + (struct assuan_context_s): Add fields pendingfds and + pendingfdscount. + * assuan-pipe-server.c (_assuan_new_context): Update IO to reflect + new features. + * assuan-domain-connect.c (do_deinit): Cleanup any unreceived file + descriptors. + (domain_reader): Receive file descriptors. + (domain_sendfd): New function. + (domain_receivefd): New function. + (_assuan_domain_init): Update initialization code to reflect new + features. + +2002-11-24 Neal H. Walfield <neal@g10code.de> + + * assuan-domain-connect.c (do_finish): Remove. + (_assuan_domain_init): Use default handlers where possible. + Add an assert and update comments. + * assuan-domain-server.c (accept_connection): Remove. + (assuan_init_domain_server): Use default handlers where possible. + Put the server in pipe mode: it can only be used by a single + client. + +2002-11-24 Neal H. Walfield <neal@g10code.de> + + * assuan.h: Add prototype for assuan_domain_connect and + assuan_init_domain_server. + * assuan-defs.h: Include <unistd.h>. + Add prototype for _assuan_domain_init. + * assuan-domain-connect.c: New file. + * assuan-domain-server.c: New file. + * Makefile.am (libassuan_a_SOURCES): Add assuan-domain-connect.c + and assuan-domain-server.c + +2002-11-23 Neal H. Walfield <neal@g10code.de> + + * Makefile.am (libassuan_a_SOURCES): Add assuan-io.c. + * assuan-io.c: Restore. + (_assuan_simple_read): Rename from _assuan_read. + (_assuan_simple_write): Rename from _assuan_write. + * assuan-defs.h (_assuan_simple_read): New prototype. + (_assuan_simple_write): Likewise. + * assuan-pipe-server.c (pipe_reader): Remove. + (pipe_writer): Remove. + (_assuan_new_context): Initialize IO is with _assuan_simple_read + and _assuan_simple_write. + * assuan-socket-connect.c (socket_reader): Remove. + (socket_writer): Remove. + (assuan_socket_connect): Initialize IO is with _assuan_simple_read + and _assuan_simple_write. + * assuan-socket-server.c (io): New local variable. + (assuan_init_socket_server): Initialize CTX->io. + (assuan_init_connected_socket_server): Likewise. + +2002-11-23 Neal H. Walfield <neal@g10code.de> + + * assuan-buffer.c (readline): Use memrchr. + (_assuan_read_line): Rewritten to use the string functions. + +2002-11-20 Neal H. Walfield <neal@g10code.de> + + * assuan-socket-connect.c (assuan_socket_connect): Pass PF_LOCAL + to socket(), not AF_UNIX: it expects a PF_* macro and the former + is more portable. + (assuan_socket_connect): Use AF_LOCAL, not AF_UNIX which is more + POSIXy. + +2002-11-20 Neal H. Walfield <neal@g10code.de> + + * assuan-defs.h (struct assuan_io): New structure. + (struct assuan_context_s): New field, io. + (_assuan_read): Depreciated. + (_assuan_write): Likewise. + * assuan-pipe-server.c: Include <unistd.h>. + (pipe_reader): New function. + (pipe_writer): Likewise. + (_assuan_new_context.IO): New local static. Set to pipe_reader + and pipe_writer. Use it to initialize new context. + * assuan-socket-connect.c (socket_reader): New function. + (socket_writer): New function. + (assuan_socket_connect.IO): New local static. Set to socket_reader + and socket_writer. Use it to initialize new context. + * assuan-buffer.c (writen): Take an ASSUAN_CONTEXT rather than a + file descriptor. Do not use _assuan_write but the write method + in the supplied context. + (readline): Likewise for _assuan_read. + (assuan_write_line): When calling writen, pass CTX; not the file + descriptor directly. + (_assuan_cookie_write_data): Likewise. + (_assuan_cookie_write_flush): Likewise. + (_assuan_read_line): Likewise for readline. + * Makefile.am (libassuan_a_SOURCES): Remove assuan-io.c. + * assuan-io.c: Removed. + +2002-11-10 Werner Koch <wk@gnupg.org> + + * assuan-pipe-connect.c (assuan_pipe_connect): Changed the order + of the dups to handle cases where we have already used fd 2 for + other things. + +2002-10-31 Neal H. Walfield <neal@g10code.de> + + * assuan-util.c: Include <ctype.h>. + (_assuan_log_print_buffer): Elide the magic numbers preferring the + standard isfoo functions. Use putc_unlocked where possible. + (_assuan_log_sanitized_string): Rewrite to use putc_unlocked and + the isfoo functions. + +2002-09-05 Neal H. Walfield <neal@g10code.de> + + * assuan-defs.h (_assuan_read_wrapper): Depreciated. + * assuan-util.c (_assuan_read_wrapper): Removed. + * assuan-defs.h (_assuan_write_wrapper): Depreciated. + * assuan-util.c (_assuan_write_wrapper): Removed. + * assuan.h (assuan_set_io_fun): Depreciated. + * assuan-util.c (assuan_set_io_fun): Removed. + + * assuan-defs.h (_assuan_read): New function. + (_assuan_write): Likewise. + * assuan-io.c: New file. + + * assuan-buffer.c (writen): Use _assuan_write rather than doing + the work here. + (readline): Likewise for _assuan_read. + + * Makefile.am (libassuan_a_SOURCES): Add assuan-io.c. + +2002-08-16 Werner Koch <wk@gnupg.org> + + * assuan.h: Renamed Bad_Certificate_Path to Bad_Certificate_Chain. + +2002-07-30 Werner Koch <wk@gnupg.org> + + Changed the license from GPL to LGPL. + +2002-07-23 Werner Koch <wk@gnupg.org> + + * assuan-handler.c (_IO_cookie_io_functions_t): Define it here if + it does not exists. + +2002-06-27 Werner Koch <wk@gnupg.org> + + * assuan-pipe-connect.c (assuan_pipe_connect): No special handling + for the log_fd and stderr. Connect stderr to /dev/null if it + should not be retained. + +2002-06-26 Werner Koch <wk@gnupg.org> + + * assuan-buffer.c (assuan_write_line): Make sure we never + accidently print an extra LF. + +2002-05-23 Werner Koch <wk@gnupg.org> + + * assuan-util.c (assuan_set_io_func): New. + * assuan-buffer.c (writen, readline): Use the new functions + instead of pth. + * assuan-socket-server.c (accept_connection): Don't use the + pth_accept - using the assuan included accept code would be a bad + idea within Pth so we don't need a replacement function. + +2002-05-22 Werner Koch <wk@gnupg.org> + + * assuan-socket-server.c (assuan_init_connected_socket_server): New. + (accept_connection): Factored most code out to.. + (accept_connection_bottom): .. new function. + +2002-04-04 Werner Koch <wk@gnupg.org> + + * assuan-buffer.c (my_log_prefix): New. Use it for all i/o debug + output. + +2002-03-06 Werner Koch <wk@gnupg.org> + + * assuan-client.c (_assuan_read_from_server): Detect END. + (assuan_transact): Pass it to the data callback. + +2002-02-27 Werner Koch <wk@gnupg.org> + + * assuan-client.c (assuan_transact): Add 2 more arguments to + support status lines. Passing NULL yields the old behaviour. + + * assuan-handler.c (process_request): Flush data lines send + without using the data fp. + +2002-02-14 Werner Koch <wk@gnupg.org> + + * assuan-inquire.c (assuan_inquire): Check for a cancel command + and return ASSUAN_Canceled. Allow for non-data inquiry. + + * assuan.h: Add a few token specific error codes. + +2002-02-13 Werner Koch <wk@gnupg.org> + + * assuan-defs.h (assuan_context_s): New var CLIENT_PID. + * assuan-pipe-server.c (_assuan_new_context): set default value. + * assuan-socket-server.c (accept_connection): get the actual pid. + +2002-02-12 Werner Koch <wk@gnupg.org> + + * assuan-buffer.c (writen,readline) [USE_GNU_PT]: Use pth_read/write. + * assuan-socket-server.c (accept_connection) [USE_GNU_PTH]: Ditto. + +2002-02-01 Marcus Brinkmann <marcus@g10code.de> + + * Makefile.am (MOSTLYCLEANFILES): New variable. + +2002-01-23 Werner Koch <wk@gnupg.org> + + * assuan-socket-connect.c (LOGERRORX): and removed typo. + +2002-01-22 Marcus Brinkmann <marcus@g10code.de> + + * assuan-socket-connect.c (LOGERRORX): Reverse arguments to fputs. + +2002-01-21 Werner Koch <wk@gnupg.org> + + * assuan-connect.c: Move all except assuan_get_pid to... + * assuan-pipe-connect.c: this. + (assuan_pipe_disconnect): Removed. + (do_finish, do_deinit): New + (assuan_pipe_connect): and set them into the context. + * assuan-socket-connect.c: New. + + * assuan-util.c (_assuan_log_sanitized_string): New. + + * assuan-pipe-server.c (assuan_init_pipe_server): Factored most + code out to ... + (_assuan_new_context): new func. + (_assuan_release_context): New + * assuan-connect.c (assuan_pipe_connect): Use the new functions. + +2002-01-20 Werner Koch <wk@gnupg.org> + + * assuan.h: Added Invalid Option error code. + + * assuan-handler.c (std_handler_option): New. + (std_cmd_tbl): Add OPTION as standard command. + (assuan_register_option_handler): New. + (dispatch_command): Use case insensitive matching as a fallback. + (my_strcasecmp): New. + +2002-01-19 Werner Koch <wk@gnupg.org> + + * assuan-buffer.c (_assuan_read_line): Add output logging. + (assuan_write_line): Ditto. + (_assuan_cookie_write_data): Ditto. + (_assuan_cookie_write_flush): Ditto. + * assuan-util.c (_assuan_log_print_buffer): New. + (assuan_set_log_stream): New. + (assuan_begin_confidential): New. + (assuan_end_confidential): New. + + * assuan-defs.h: Add a few handler variables. + * assuan-pipe-server.c (assuan_deinit_pipe_server): Removed. + (deinit_pipe_server): New. + (assuan_deinit_server): New. Changed all callers to use this. + * assuan-listen.c (assuan_accept): Use the accept handler. + * assuan-handler.c (process_request): Use the close Handler. + * assuan-socket-server.c: New. + +2002-01-14 Werner Koch <wk@gnupg.org> + + * assuan-client.c (_assuan_read_from_server): Skip spaces after + the keyword. + +2002-01-03 Werner Koch <wk@gnupg.org> + + * assuan-handler.c (assuan_set_okay_line): New. + (process_request): And use it here. + +2002-01-02 Werner Koch <wk@gnupg.org> + + * assuan-inquire.c (init_membuf,put_membuf,get_membuf): Apply a + hidden 0 behind the buffer so that the buffer can be used as a + string in certain contexts. + +2001-12-14 Marcus Brinkmann <marcus@g10code.de> + + * assuan-connect.c (assuan_pipe_connect): New argument + FD_CHILD_LIST. Don't close those fds. + * assuan.h: Likewise for prototype. + +2001-12-14 Werner Koch <wk@gnupg.org> + + * assuan-listen.c (assuan_close_input_fd): New. + (assuan_close_output_fd): New. + * assuan-handler.c (std_handler_reset): Always close them after a + reset command. + (std_handler_bye): Likewise. + +2001-12-14 Marcus Brinkmann <marcus@g10code.de> + + * assuan-buffer.c (_assuan_read_line): New variable ATTICLEN, use + it to save the length of the attic line. + Rediddle the code a bit to make it more clear what happens. + +2001-12-14 Marcus Brinkmann <marcus@g10code.de> + + * assuan-defs.h (LINELENGTH): Define as ASSUAN_LINELENGTH. + assuan.h: Define ASSUAN_LINELENGTH. + +2001-12-13 Marcus Brinkmann <marcus@g10code.de> + + * assuan-buffer.c (assuan_read_line): Fix order of execution to + get correct return values. + +2001-12-13 Werner Koch <wk@gnupg.org> + + * assuan-handler.c (assuan_get_active_fds): Fixed silly bug, + pretty obvious that nobody ever tested this function. + +2001-12-12 Werner Koch <wk@gnupg.org> + + * assuan-connect.c (assuan_pipe_connect): Implemented the inital + handshake. + * assuan-client.c (read_from_server): Renamed to + (_assuan_read_from_server): this and made external. + + * assuan-listen.c (assuan_set_hello_line): New. + (assuan_accept): Use a custom hello line is available. + + * assuan-buffer.c (assuan_read_line): New. + (assuan_pending_line): New. + (_assuan_write_line): Renamed to .. + (assuan_write_line): this, made public and changed all callers. + +2001-12-04 Werner Koch <wk@gnupg.org> + + * assuan-connect.c (assuan_pipe_connect): Add more error reporting. + * assuan-client.c: New. + + * assuan-inquire.c: New. + * assuan-handler.c (process_request): Check for nested invocations. + +2001-11-27 Werner Koch <wk@gnupg.org> + + * assuan-handler.c (assuan_register_input_notify): New. + (assuan_register_output_notify): New. + +2001-11-26 Werner Koch <wk@gnupg.org> + + * assuan.h: Added more status codes. + +2001-11-25 Werner Koch <wk@gnupg.org> + + * assuan-handler.c (assuan_register_bye_notify) + (assuan_register_reset_notify) + (assuan_register_cancel_notify): New and call them from the + standard handlers. + (assuan_process): Moved bulk of function to .. + (process_request): .. new. + (assuan_process_next): One shot version of above. + (assuan_get_active_fds): New. + +2001-11-24 Werner Koch <wk@gnupg.org> + + * assuan-connect.c (assuan_get_pid): New. + + * assuan-buffer.c (_assuan_read_line): Deal with reads of more + than a line. + * assuan-defs.h: Add space in the context for this. + + + Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/libkdenetwork/libgpgme-copy/assuan/Makefile.am b/libkdenetwork/libgpgme-copy/assuan/Makefile.am new file mode 100644 index 000000000..aea8f558c --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/Makefile.am @@ -0,0 +1,58 @@ +# Assuan Makefile +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +# +# This file is part of Assuan. +# +# Assuan is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of +# the License, or (at your option) any later version. +# +# Assuan is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +## Process this file with automake to produce Makefile.in + +#EXTRA_DIST = mkerrors +INCLUDES = -I.. # -I$(top_srcdir)/include +#BUILT_SOURCES = assuan-errors.c +#MOSTLYCLEANFILES = assuan-errors.c + +noinst_LTLIBRARIES = libassuan.la + +AM_CPPFLAGS = -D_ASSUAN_IN_GPGME_BUILD_ASSUAN + +#libassuan_la_LDFLAGS = +libassuan_la_SOURCES = \ + assuan-util.c \ + assuan-errors.c \ + assuan-buffer.c \ + assuan-handler.c \ + assuan-inquire.c \ + assuan-listen.c \ + assuan-connect.c \ + assuan-client.c \ + assuan-pipe-server.c \ + assuan-socket-server.c \ + assuan-pipe-connect.c \ + assuan-socket-connect.c \ + assuan-socket.c \ + assuan-io.c \ + assuan-uds.c \ + funopen.c \ + assuan-logging.c + +libassuan_la_COMPILE_FIRST=assuan-errors.c + +assuan-errors.c : $(srcdir)/assuan.h + $(srcdir)/mkerrors < $(srcdir)/assuan.h > assuan-errors.c + +CLEANFILES=assuan-errors.c + + diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-buffer.c b/libkdenetwork/libgpgme-copy/assuan/assuan-buffer.c new file mode 100644 index 000000000..b06025b46 --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-buffer.c @@ -0,0 +1,550 @@ +/* assuan-buffer.c - read and send data + * Copyright (C) 2001, 2002, 2003, 2004, 2006 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <assert.h> +#ifdef HAVE_W32_SYSTEM +#include <process.h> +#endif +#include "assuan-defs.h" + + +/* Extended version of write(2) to guarantee that all bytes are + written. Returns 0 on success or -1 and ERRNO on failure. */ +static int +writen (assuan_context_t ctx, const char *buffer, size_t length) +{ + while (length) + { + ssize_t nwritten = ctx->io->writefnc (ctx, buffer, length); + + if (nwritten < 0) + { + if (errno == EINTR) + continue; + return -1; /* write error */ + } + length -= nwritten; + buffer += nwritten; + } + return 0; /* okay */ +} + +/* 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. */ +static int +readline (assuan_context_t ctx, char *buf, size_t buflen, + int *r_nread, int *r_eof) +{ + size_t nleft = buflen; + char *p; + + *r_eof = 0; + *r_nread = 0; + while (nleft > 0) + { + ssize_t n = ctx->io->readfnc (ctx, buf, nleft); + + if (n < 0) + { + if (errno == EINTR) + continue; + return -1; /* read error */ + } + else if (!n) + { + *r_eof = 1; + break; /* allow incomplete lines */ + } + p = buf; + nleft -= n; + buf += n; + *r_nread += n; + + p = memrchr (p, '\n', n); + if (p) + break; /* at least one full line available - that's enough for now */ + } + + return 0; +} + + +/* Function returns an Assuan error. */ +assuan_error_t +_assuan_read_line (assuan_context_t ctx) +{ + char *line = ctx->inbound.line; + int nread, atticlen; + int rc; + char *endp = 0; + + if (ctx->inbound.eof) + return _assuan_error (-1); + + atticlen = ctx->inbound.attic.linelen; + if (atticlen) + { + memcpy (line, ctx->inbound.attic.line, atticlen); + ctx->inbound.attic.linelen = 0; + + endp = memchr (line, '\n', atticlen); + if (endp) + /* Found another line in the attic. */ + { + rc = 0; + nread = atticlen; + atticlen = 0; + } + else + /* There is pending data but not a full line. */ + { + assert (atticlen < LINELENGTH); + rc = readline (ctx, line + atticlen, + LINELENGTH - atticlen, &nread, &ctx->inbound.eof); + } + } + else + /* No pending data. */ + rc = readline (ctx, line, LINELENGTH, + &nread, &ctx->inbound.eof); + if (rc) + { + if (ctx->log_fp) + fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- [Error: %s]\n", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx->inbound.fd, + strerror (errno)); + return _assuan_error (ASSUAN_Read_Error); + } + if (!nread) + { + assert (ctx->inbound.eof); + 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); + return _assuan_error (-1); + } + + ctx->inbound.attic.pending = 0; + nread += atticlen; + + if (! endp) + endp = memchr (line, '\n', nread); + + if (endp) + { + unsigned monitor_result; + int n = endp - line + 1; + + if (n < nread) + /* LINE contains more than one line. We copy it to the attic + now as handlers are allowed to modify the passed + buffer. */ + { + int len = nread - n; + memcpy (ctx->inbound.attic.line, endp + 1, len); + ctx->inbound.attic.pending = memrchr (endp + 1, '\n', len) ? 1 : 0; + ctx->inbound.attic.linelen = len; + } + + if (endp != line && endp[-1] == '\r') + endp --; + *endp = 0; + + ctx->inbound.linelen = endp - line; + + monitor_result = (ctx->io_monitor + ? ctx->io_monitor (ctx, 0, + ctx->inbound.line, + ctx->inbound.linelen) + : 0); + if ( (monitor_result & 2) ) + ctx->inbound.linelen = 0; + + if (ctx->log_fp && !(monitor_result & 1)) + { + fprintf (ctx->log_fp, "%s[%u.%d] DBG: <- ", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx->inbound.fd); + if (ctx->confidential) + fputs ("[Confidential data not shown]", ctx->log_fp); + else + _assuan_log_print_buffer (ctx->log_fp, + ctx->inbound.line, + ctx->inbound.linelen); + putc ('\n', ctx->log_fp); + } + return 0; + } + else + { + 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); + *line = 0; + ctx->inbound.linelen = 0; + return _assuan_error (ctx->inbound.eof + ? ASSUAN_Line_Not_Terminated + : ASSUAN_Line_Too_Long); + } +} + + +/* Read the next line from the client or server and return a pointer + in *LINE to a buffer holding the line. LINELEN is the length of + *LINE. The buffer is valid until the next read operation on it. + The caller may modify the buffer. The buffer is invalid (i.e. must + not be used) if an error is returned. + + Returns 0 on success or an assuan error code. + See also: assuan_pending_line(). +*/ +assuan_error_t +assuan_read_line (assuan_context_t ctx, char **line, size_t *linelen) +{ + assuan_error_t err; + + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + + err = _assuan_read_line (ctx); + *line = ctx->inbound.line; + *linelen = ctx->inbound.linelen; + return err; +} + + +/* Return true if a full line is buffered (i.e. an entire line may be + read without any I/O). */ +int +assuan_pending_line (assuan_context_t ctx) +{ + return ctx && ctx->inbound.attic.pending; +} + + +assuan_error_t +_assuan_write_line (assuan_context_t ctx, const char *prefix, + const char *line, size_t len) +{ + assuan_error_t rc = 0; + size_t prefixlen = prefix? strlen (prefix):0; + unsigned int monitor_result; + + /* Make sure that the line is short enough. */ + if (len + prefixlen + 2 > ASSUAN_LINELENGTH) + { + if (ctx->log_fp) + 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); + if (prefixlen > 5) + prefixlen = 5; + if (len > ASSUAN_LINELENGTH - prefixlen - 2) + len = ASSUAN_LINELENGTH - prefixlen - 2 - 1; + } + + monitor_result = (ctx->io_monitor + ? ctx->io_monitor (ctx, 1, line, len) + : 0); + + /* Fixme: we should do some kind of line buffering. */ + if (ctx->log_fp && !(monitor_result & 1)) + { + fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx->inbound.fd); + if (ctx->confidential) + fputs ("[Confidential data not shown]", ctx->log_fp); + else + { + if (prefixlen) + _assuan_log_print_buffer (ctx->log_fp, prefix, prefixlen); + _assuan_log_print_buffer (ctx->log_fp, line, len); + } + putc ('\n', ctx->log_fp); + } + + if (prefixlen && !(monitor_result & 2)) + { + rc = writen (ctx, prefix, prefixlen); + if (rc) + rc = _assuan_error (ASSUAN_Write_Error); + } + if (!rc && !(monitor_result & 2)) + { + rc = writen (ctx, line, len); + if (rc) + rc = _assuan_error (ASSUAN_Write_Error); + if (!rc) + { + rc = writen (ctx, "\n", 1); + if (rc) + rc = _assuan_error (ASSUAN_Write_Error); + } + } + return rc; +} + + +assuan_error_t +assuan_write_line (assuan_context_t ctx, const char *line) +{ + size_t len; + const char *s; + + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + + /* Make sure that we never take a LF from the user - this might + violate the protocol. */ + s = strchr (line, '\n'); + len = s? (s-line) : strlen (line); + + if (ctx->log_fp && s) + 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); + + return _assuan_write_line (ctx, NULL, line, len); +} + + + +/* Write out the data in buffer as datalines with line wrapping and + percent escaping. This function is used for GNU's custom streams. */ +int +_assuan_cookie_write_data (void *cookie, const char *buffer, size_t orig_size) +{ + assuan_context_t ctx = cookie; + size_t size = orig_size; + char *line; + size_t linelen; + + if (ctx->outbound.data.error) + return 0; + + line = ctx->outbound.data.line; + linelen = ctx->outbound.data.linelen; + line += linelen; + while (size) + { + unsigned int monitor_result; + + /* Insert data line header. */ + if (!linelen) + { + *line++ = 'D'; + *line++ = ' '; + linelen += 2; + } + + /* Copy data, keep space for the CRLF and to escape one character. */ + while (size && linelen < LINELENGTH-2-2) + { + if (*buffer == '%' || *buffer == '\r' || *buffer == '\n') + { + sprintf (line, "%%%02X", *(unsigned char*)buffer); + line += 3; + linelen += 3; + buffer++; + } + else + { + *line++ = *buffer++; + linelen++; + } + size--; + } + + + monitor_result = (ctx->io_monitor + ? ctx->io_monitor (ctx, 1, + ctx->outbound.data.line, linelen) + : 0); + + if (linelen >= LINELENGTH-2-2) + { + if (ctx->log_fp && !(monitor_result & 1)) + { + fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx->inbound.fd); + + if (ctx->confidential) + fputs ("[Confidential data not shown]", ctx->log_fp); + else + _assuan_log_print_buffer (ctx->log_fp, + ctx->outbound.data.line, + linelen); + putc ('\n', ctx->log_fp); + } + *line++ = '\n'; + linelen++; + if ( !(monitor_result & 2) + && writen (ctx, ctx->outbound.data.line, linelen)) + { + ctx->outbound.data.error = _assuan_error (ASSUAN_Write_Error); + return 0; + } + line = ctx->outbound.data.line; + linelen = 0; + } + } + + ctx->outbound.data.linelen = linelen; + return (int)orig_size; +} + + +/* Write out any buffered data + This function is used for GNU's custom streams */ +int +_assuan_cookie_write_flush (void *cookie) +{ + assuan_context_t ctx = cookie; + char *line; + size_t linelen; + unsigned int monitor_result; + + if (ctx->outbound.data.error) + return 0; + + line = ctx->outbound.data.line; + linelen = ctx->outbound.data.linelen; + line += linelen; + + monitor_result = (ctx->io_monitor + ? ctx->io_monitor (ctx, 1, + ctx->outbound.data.line, linelen) + : 0); + + if (linelen) + { + if (ctx->log_fp && !(monitor_result & 1)) + { + fprintf (ctx->log_fp, "%s[%u.%d] DBG: -> ", + assuan_get_assuan_log_prefix (), + (unsigned int)getpid (), ctx->inbound.fd); + if (ctx->confidential) + fputs ("[Confidential data not shown]", ctx->log_fp); + else + _assuan_log_print_buffer (ctx->log_fp, + ctx->outbound.data.line, linelen); + putc ('\n', ctx->log_fp); + } + *line++ = '\n'; + linelen++; + if ( !(monitor_result & 2) + && writen (ctx, ctx->outbound.data.line, linelen)) + { + ctx->outbound.data.error = _assuan_error (ASSUAN_Write_Error); + return 0; + } + ctx->outbound.data.linelen = 0; + } + return 0; +} + + +/** + * assuan_send_data: + * @ctx: An assuan context + * @buffer: Data to send or NULL to flush + * @length: length of the data to send/ + * + * This function may be used by the server or the client to send data + * lines. The data will be escaped as required by the Assuan protocol + * and may get buffered until a line is full. To force sending the + * data out @buffer may be passed as NULL (in which case @length must + * also be 0); however when used by a client this flush operation does + * also send the terminating "END" command to terminate the reponse on + * a INQUIRE response. However, when assuan_transact() is used, this + * function takes care of sending END itself. + * + * Return value: 0 on success or an error code + **/ + +assuan_error_t +assuan_send_data (assuan_context_t ctx, const void *buffer, size_t length) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + if (!buffer && length) + return _assuan_error (ASSUAN_Invalid_Value); + + if (!buffer) + { /* flush what we have */ + _assuan_cookie_write_flush (ctx); + if (ctx->outbound.data.error) + return ctx->outbound.data.error; + if (!ctx->is_server) + return assuan_write_line (ctx, "END"); + } + else + { + _assuan_cookie_write_data (ctx, buffer, length); + if (ctx->outbound.data.error) + return ctx->outbound.data.error; + } + + return 0; +} + +assuan_error_t +assuan_sendfd (assuan_context_t ctx, int fd) +{ + /* It is explicitly allowed to use (NULL, -1) as a runtime test to + check whether descriptor passing is available. */ + if (!ctx && fd == -1) +#ifdef USE_DESCRIPTOR_PASSING + return 0; +#else + return _assuan_error (ASSUAN_Not_Implemented); +#endif + + if (! ctx->io->sendfd) + return set_error (ctx, Not_Implemented, + "server does not support sending and receiving " + "of file descriptors"); + return ctx->io->sendfd (ctx, fd); +} + +assuan_error_t +assuan_receivefd (assuan_context_t ctx, int *fd) +{ + if (! ctx->io->receivefd) + return set_error (ctx, Not_Implemented, + "server does not support sending and receiving " + "of file descriptors"); + return ctx->io->receivefd (ctx, fd); +} diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-client.c b/libkdenetwork/libgpgme-copy/assuan/assuan-client.c new file mode 100644 index 000000000..978c69546 --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-client.c @@ -0,0 +1,234 @@ +/* assuan-client.c - client functions + * Copyright (C) 2001, 2002, 2005 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <assert.h> + +#include "assuan-defs.h" + +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) + + +assuan_error_t +_assuan_read_from_server (assuan_context_t ctx, int *okay, int *off) +{ + char *line; + int linelen; + assuan_error_t rc; + + *okay = 0; + *off = 0; + do + { + rc = _assuan_read_line (ctx); + if (rc) + return rc; + line = ctx->inbound.line; + linelen = ctx->inbound.linelen; + } + while (*line == '#' || !linelen); + + if (linelen >= 1 + && line[0] == 'D' && line[1] == ' ') + { + *okay = 2; /* data line */ + *off = 2; + } + else if (linelen >= 1 + && line[0] == 'S' + && (line[1] == '\0' || line[1] == ' ')) + { + *okay = 4; + *off = 1; + while (line[*off] == ' ') + ++*off; + } + else if (linelen >= 2 + && line[0] == 'O' && line[1] == 'K' + && (line[2] == '\0' || line[2] == ' ')) + { + *okay = 1; + *off = 2; + while (line[*off] == ' ') + ++*off; + } + else if (linelen >= 3 + && line[0] == 'E' && line[1] == 'R' && line[2] == 'R' + && (line[3] == '\0' || line[3] == ' ')) + { + *okay = 0; + *off = 3; + while (line[*off] == ' ') + ++*off; + } + else if (linelen >= 7 + && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q' + && line[3] == 'U' && line[4] == 'I' && line[5] == 'R' + && line[6] == 'E' + && (line[7] == '\0' || line[7] == ' ')) + { + *okay = 3; + *off = 7; + while (line[*off] == ' ') + ++*off; + } + else if (linelen >= 3 + && line[0] == 'E' && line[1] == 'N' && line[2] == 'D' + && (line[3] == '\0' || line[3] == ' ')) + { + *okay = 5; /* end line */ + *off = 3; + } + else + rc = _assuan_error (ASSUAN_Invalid_Response); + return rc; +} + + + +/** + * assuan_transact: + * @ctx: The Assuan context + * @command: Command line to be send to the server + * @data_cb: Callback function for data lines + * @data_cb_arg: first argument passed to @data_cb + * @inquire_cb: Callback function for a inquire response + * @inquire_cb_arg: first argument passed to @inquire_cb + * @status_cb: Callback function for a status response + * @status_cb_arg: first argument passed to @status_cb + * + * FIXME: Write documentation + * + * Return value: 0 on success or error code. The error code may be + * the one one returned by the server in error lines or from the + * callback functions. Take care: When a callback returns an error + * this function returns immediately with an error and thus the caller + * will altter return an Assuan error (write erro in most cases). + **/ +assuan_error_t +assuan_transact (assuan_context_t ctx, + const char *command, + int (*data_cb)(void *, const void *, size_t), + void *data_cb_arg, + int (*inquire_cb)(void*, const char *), + void *inquire_cb_arg, + int (*status_cb)(void*, const char *), + void *status_cb_arg) +{ + assuan_error_t rc; + int okay, off; + char *line; + int linelen; + + rc = assuan_write_line (ctx, command); + if (rc) + return rc; + + if (*command == '#' || !*command) + return 0; /* Don't expect a response for a comment line. */ + + again: + rc = _assuan_read_from_server (ctx, &okay, &off); + if (rc) + return rc; /* error reading from server */ + + line = ctx->inbound.line + off; + linelen = ctx->inbound.linelen - off; + + if (!okay) + { + rc = atoi (line); + if (rc > 0 && rc < 100) + rc = _assuan_error (ASSUAN_Server_Fault); + else if (rc > 0 && rc <= 128) + rc = _assuan_error (rc); + } + else if (okay == 2) + { + if (!data_cb) + rc = _assuan_error (ASSUAN_No_Data_Callback); + else + { + char *s, *d; + + for (s=d=line; linelen; linelen--) + { + if (*s == '%' && linelen > 2) + { /* handle escaping */ + s++; + *d++ = xtoi_2 (s); + s += 2; + linelen -= 2; + } + else + *d++ = *s++; + } + *d = 0; /* add a hidden string terminator */ + rc = data_cb (data_cb_arg, line, d - line); + if (!rc) + goto again; + } + } + else if (okay == 3) + { + if (!inquire_cb) + { + assuan_write_line (ctx, "END"); /* get out of inquire mode */ + _assuan_read_from_server (ctx, &okay, &off); /* dummy read */ + rc = _assuan_error (ASSUAN_No_Inquire_Callback); + } + else + { + rc = inquire_cb (inquire_cb_arg, line); + if (!rc) + rc = assuan_send_data (ctx, NULL, 0); /* flush and send END */ + if (!rc) + goto again; + } + } + else if (okay == 4) + { + if (status_cb) + rc = status_cb (status_cb_arg, line); + if (!rc) + goto again; + } + else if (okay == 5) + { + if (!data_cb) + rc = _assuan_error (ASSUAN_No_Data_Callback); + else + { + rc = data_cb (data_cb_arg, NULL, 0); + if (!rc) + goto again; + } + } + + return rc; +} + diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-connect.c b/libkdenetwork/libgpgme-copy/assuan/assuan-connect.c new file mode 100644 index 000000000..92995d8c1 --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-connect.c @@ -0,0 +1,79 @@ +/* assuan-connect.c - Establish a connection (client) + * Copyright (C) 2001, 2002 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#ifndef HAVE_W32_SYSTEM +#include <sys/wait.h> +#endif + +#include "assuan-defs.h" + +/* Disconnect and release the context CTX. */ +void +assuan_disconnect (assuan_context_t ctx) +{ + if (ctx) + { + assuan_write_line (ctx, "BYE"); + ctx->finish_handler (ctx); + ctx->deinit_handler (ctx); + ctx->deinit_handler = NULL; + _assuan_release_context (ctx); + } +} + +/* Return the PID of the peer or -1 if not known. This function works + in some situations where assuan_get_ucred fails. */ +pid_t +assuan_get_pid (assuan_context_t ctx) +{ + return (ctx && ctx->pid)? ctx->pid : -1; +} + + +/* 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 + 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) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + if (!ctx->peercred.valid) + return _assuan_error (ASSUAN_General_Error); + if (pid) + *pid = ctx->peercred.pid; + if (uid) + *uid = ctx->peercred.uid; + if (gid) + *gid = ctx->peercred.gid; + return 0; +} diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-defs.h b/libkdenetwork/libgpgme-copy/assuan/assuan-defs.h new file mode 100644 index 000000000..fa04f0b29 --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-defs.h @@ -0,0 +1,323 @@ +/* assuan-defs.c - Internal definitions to Assuan + * Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifndef ASSUAN_DEFS_H +#define ASSUAN_DEFS_H + +#include <sys/types.h> +#ifndef HAVE_W32_SYSTEM +#include <sys/socket.h> +#include <sys/un.h> +#else +#include <windows.h> +#endif +#include <unistd.h> + +#include "assuan.h" + +#ifndef HAVE_W32_SYSTEM +#define DIRSEP_C '/' +#else +#define DIRSEP_C '\\' +#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; */ + +/* Missing W32 functions */ +int putc_unlocked (int c, FILE *stream); +void * memrchr (const void *block, int c, size_t size); +char * stpcpy (char *dest, const char *src); +#endif + +#define LINELENGTH ASSUAN_LINELENGTH + + +struct cmdtbl_s +{ + const char *name; + int (*handler)(assuan_context_t, char *line); +}; + + +/* A structure to dispatch I/O functions. All these functions need to + return 0 on success and set ERRNO on failure. */ +struct assuan_io +{ + /* Routine to read from input_fd. */ + ssize_t (*readfnc) (assuan_context_t, void *, size_t); + /* 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); + /* Receive a file descriptor. */ + assuan_error_t (*receivefd) (assuan_context_t, int *); +}; + + +/* The context we use with most functions. */ +struct assuan_context_s +{ + assuan_error_t err_no; + const char *err_str; + int os_errno; /* Last system error number used with certain + error codes. */ + + /* Context specific flags (cf. assuan_flag_t). */ + struct + { + unsigned int no_waitpid:1; /* See ASSUAN_NO_WAITPID. */ + } flags; + + int confidential; + int is_server; /* Set if this is context belongs to a server */ + int in_inquire; + char *hello_line; + char *okay_line; /* See assuan_set_okay_line() */ + + void *user_pointer; /* For assuan_get_pointer and assuan_set_pointer (). */ + + FILE *log_fp; + + struct { + int fd; + int eof; + char line[LINELENGTH]; + int linelen; /* w/o CR, LF - might not be the same as + strlen(line) due to embedded nuls. However a nul + is always written at this pos. */ + struct { + char line[LINELENGTH]; + int linelen ; + int pending; /* i.e. at least one line is available in the attic */ + } attic; + } inbound; + + struct { + int fd; + struct { + FILE *fp; + char line[LINELENGTH]; + int linelen; + int error; + } data; + } outbound; + + int pipe_mode; /* We are in pipe mode, i.e. we can handle just one + connection and must terminate then. */ + pid_t pid; /* The pid of the peer. */ + int listen_fd; /* The fd we are listening on (used by socket servers) */ + int connected_fd; /* helper */ + + struct { + int valid; /* Whether this structure has valid information. */ + pid_t pid; /* The pid of the peer. */ + uid_t uid; /* The uid of the peer. */ + gid_t gid; /* The gid of the peer. */ + } peercred; + + /* Used for Unix domain sockets. */ + struct sockaddr_un myaddr; + struct sockaddr_un serveraddr; + + /* Structure used for unix domain socket buffering. FIXME: We don't + use datagrams anymore thus we could get away with a simpler + buffering approach. */ + struct { + void *buffer; /* Malloced buffer. */ + int bufferallocated; /* Memory allocated. */ + int bufferoffset; /* Offset of start of buffer. */ + int buffersize; /* Bytes buffered. */ + + int pendingfds[5]; /* Array to save received descriptors. */ + int pendingfdscount; /* Number of received descriptors. */ + } uds; + + void (*deinit_handler)(assuan_context_t); + int (*accept_handler)(assuan_context_t); + int (*finish_handler)(assuan_context_t); + + struct cmdtbl_s *cmdtbl; + size_t cmdtbl_used; /* used entries */ + size_t cmdtbl_size; /* allocated size of table */ + + void (*bye_notify_fnc)(assuan_context_t); + void (*reset_notify_fnc)(assuan_context_t); + void (*cancel_notify_fnc)(assuan_context_t); + int (*option_handler_fnc)(assuan_context_t,const char*, const char*); + void (*input_notify_fnc)(assuan_context_t, const char *); + void (*output_notify_fnc)(assuan_context_t, const char *); + + /* This function is called right after a command has been processed. + It may be used to command related cleanup. */ + void (*post_cmd_notify_fnc)(assuan_context_t, int); + + /* 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. */ + 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 */ + + /* io routines. */ + struct assuan_io *io; +}; + +/*-- assuan-pipe-server.c --*/ +int _assuan_new_context (assuan_context_t *r_ctx); +void _assuan_release_context (assuan_context_t ctx); + +/*-- assuan-uds.c --*/ +void _assuan_uds_close_fds (assuan_context_t ctx); +void _assuan_uds_deinit (assuan_context_t ctx); +void _assuan_init_uds_io (assuan_context_t ctx); + + +/*-- assuan-handler.c --*/ +int _assuan_register_std_commands (assuan_context_t ctx); + +/*-- assuan-buffer.c --*/ +assuan_error_t _assuan_read_line (assuan_context_t ctx); +int _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size); +int _assuan_cookie_write_flush (void *cookie); +assuan_error_t _assuan_write_line (assuan_context_t ctx, const char *prefix, + const char *line, size_t len); + +/*-- assuan-client.c --*/ +assuan_error_t _assuan_read_from_server (assuan_context_t ctx, + int *okay, int *off); + +/*-- assuan-error.c --*/ + + +/* Map error codes as used in this implementaion to the libgpg-error + codes. */ +assuan_error_t _assuan_error (int oldcode); + +/* 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. */ +#define err_code(a) ((a) & 0x00ffffff) + +/* Check whether A is the erro code for EOF. We allow forold and new + style EOF error codes here. */ +#define err_is_eof(a) ((a) == (-1) || err_code (a) == 16383) + + + +/*-- assuan-util.c --*/ +void *_assuan_malloc (size_t n); +void *_assuan_calloc (size_t n, size_t m); +void *_assuan_realloc (void *p, size_t n); +void _assuan_free (void *p); + +#define xtrymalloc(a) _assuan_malloc ((a)) +#define xtrycalloc(a,b) _assuan_calloc ((a),(b)) +#define xtryrealloc(a,b) _assuan_realloc((a),(b)) +#define xfree(a) _assuan_free ((a)) + +#define set_error(c,e,t) \ + assuan_set_error ((c), _assuan_error (ASSUAN_ ## e), (t)) + +#ifdef HAVE_W32_SYSTEM +const char *_assuan_w32_strerror (int ec); +#define w32_strerror(e) _assuan_w32_strerror ((e)) +#endif /*HAVE_W32_SYSTEM*/ + + +/*-- assuan-logging.c --*/ +void _assuan_set_default_log_stream (FILE *fp); + +void _assuan_log_printf (const char *format, ...) +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) + __attribute__ ((format (printf,1,2))) +#endif + ; +void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length); +void _assuan_log_sanitized_string (const char *string); + + +/*-- assuan-io.c --*/ +pid_t _assuan_waitpid (pid_t pid, int *status, int options); + +ssize_t _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size); +ssize_t _assuan_simple_write (assuan_context_t ctx, const void *buffer, + size_t size); +ssize_t _assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg); +ssize_t _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg); + +/*-- 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); + +#ifdef HAVE_FOPENCOOKIE +/* We have to implement funopen in terms of glibc's fopencookie. */ +FILE *_assuan_funopen(void *cookie, + cookie_read_function_t *readfn, + cookie_write_function_t *writefn, + cookie_seek_function_t *seekfn, + cookie_close_function_t *closefn); +#define funopen(a,r,w,s,c) _assuan_funopen ((a), (r), (w), (s), (c)) +#endif /*HAVE_FOPENCOOKIE*/ + +/* Prototypes for replacement functions. */ +#ifndef HAVE_MEMRCHR +void *memrchr (const void *block, int c, size_t size); +#endif +#ifndef HAVE_STPCPY +char *stpcpy (char *dest, const char *src); +#endif +#ifndef HAVE_SETENV +#define setenv _assuan_setenv +#define unsetenv _assuan_unsetenv +#define clearenv _assuan_clearenv +int setenv (const char *name, const char *value, int replace); +#endif +#ifndef HAVE_PUTC_UNLOCKED +int putc_unlocked (int c, FILE *stream); +#endif + +#define DIM(v) (sizeof(v)/sizeof((v)[0])) +#define DIMof(type,member) DIM(((type *)0)->member) + + +#endif /*ASSUAN_DEFS_H*/ diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-handler.c b/libkdenetwork/libgpgme-copy/assuan/assuan-handler.c new file mode 100644 index 000000000..866db2259 --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-handler.c @@ -0,0 +1,774 @@ +/* assuan-handler.c - dispatch commands + * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include "assuan-defs.h" + + + +#define spacep(p) (*(p) == ' ' || *(p) == '\t') +#define digitp(a) ((a) >= '0' && (a) <= '9') + +static int my_strcasecmp (const char *a, const char *b); + + + +static int +dummy_handler (assuan_context_t ctx, char *line) +{ + return set_error (ctx, Server_Fault, "no handler registered"); +} + + +static int +std_handler_nop (assuan_context_t ctx, char *line) +{ + return 0; /* okay */ +} + +static int +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); +} + +static int +std_handler_option (assuan_context_t ctx, char *line) +{ + char *key, *value, *p; + + for (key=line; spacep (key); key++) + ; + if (!*key) + return set_error (ctx, Syntax_Error, "argument required"); + if (*key == '=') + return set_error (ctx, Syntax_Error, "no option name given"); + for (value=key; *value && !spacep (value) && *value != '='; value++) + ; + if (*value) + { + if (spacep (value)) + *value++ = 0; /* terminate key */ + for (; spacep (value); value++) + ; + if (*value == '=') + { + *value++ = 0; /* terminate key */ + for (; spacep (value); value++) + ; + if (!*value) + return set_error (ctx, Syntax_Error, "option argument expected"); + } + if (*value) + { + for (p = value + strlen(value) - 1; p > value && spacep (p); p--) + ; + if (p > value) + *++p = 0; /* strip trailing spaces */ + } + } + + if (*key == '-' && key[1] == '-' && key[2]) + key += 2; /* the double dashes are optional */ + if (*key == '-') + return set_error (ctx, Syntax_Error, + "option should not begin with one dash"); + + if (ctx->option_handler_fnc) + return ctx->option_handler_fnc (ctx, key, value); + return 0; +} + +static int +std_handler_bye (assuan_context_t ctx, char *line) +{ + if (ctx->bye_notify_fnc) + ctx->bye_notify_fnc (ctx); + assuan_close_input_fd (ctx); + assuan_close_output_fd (ctx); + return -1; /* pretty simple :-) */ +} + +static int +std_handler_auth (assuan_context_t ctx, char *line) +{ + return set_error (ctx, Not_Implemented, NULL); +} + +static int +std_handler_reset (assuan_context_t ctx, char *line) +{ + if (ctx->reset_notify_fnc) + ctx->reset_notify_fnc (ctx); + assuan_close_input_fd (ctx); + assuan_close_output_fd (ctx); + _assuan_uds_close_fds (ctx); + return 0; +} + +static int +std_handler_end (assuan_context_t ctx, char *line) +{ + return set_error (ctx, Not_Implemented, NULL); +} + +assuan_error_t +assuan_command_parse_fd (assuan_context_t ctx, char *line, int *rfd) +{ + char *endp; + + if ( (strncmp (line, "FD", 2) && strncmp (line, "fd", 2)) + || (line[2] != '=' && line[2] != '\0')) + return set_error (ctx, Syntax_Error, "FD[=<n>] expected"); + line += 2; + if (*line == '=') + { + line ++; + if (!digitp (*line)) + return set_error (ctx, Syntax_Error, "number required"); + *rfd = strtoul (line, &endp, 10); + /* Remove that argument so that a notify handler won't see it. */ + memset (line, ' ', endp? (endp-line):strlen(line)); + + if (*rfd == ctx->inbound.fd) + return set_error (ctx, Parameter_Conflict, "fd same as inbound fd"); + if (*rfd == ctx->outbound.fd) + return set_error (ctx, Parameter_Conflict, "fd same as outbound fd"); + return 0; + } + else + /* Our peer has sent the file descriptor. */ + return assuan_receivefd (ctx, rfd); +} + +/* Format is INPUT FD=<n> */ +static int +std_handler_input (assuan_context_t ctx, char *line) +{ + int rc, fd; + + rc = assuan_command_parse_fd (ctx, line, &fd); + if (rc) + return rc; + ctx->input_fd = fd; + if (ctx->input_notify_fnc) + ctx->input_notify_fnc (ctx, line); + return 0; +} + +/* Format is OUTPUT FD=<n> */ +static int +std_handler_output (assuan_context_t ctx, char *line) +{ + int rc, fd; + + rc = assuan_command_parse_fd (ctx, line, &fd); + if (rc) + return rc; + ctx->output_fd = fd; + if (ctx->output_notify_fnc) + ctx->output_notify_fnc (ctx, line); + return 0; +} + + + + + +/* This is a table with the standard commands and handler for them. + The table is used to initialize a new context and associate strings + with default handlers */ +static struct { + const char *name; + int (*handler)(assuan_context_t, char *line); + int always; /* always initialize this command */ +} std_cmd_table[] = { + { "NOP", std_handler_nop, 1 }, + { "CANCEL", std_handler_cancel, 1 }, + { "OPTION", std_handler_option, 1 }, + { "BYE", std_handler_bye, 1 }, + { "AUTH", std_handler_auth, 1 }, + { "RESET", std_handler_reset, 1 }, + { "END", std_handler_end, 1 }, + + { "INPUT", std_handler_input }, + { "OUTPUT", std_handler_output }, + { "OPTION", std_handler_option, 1 }, + { NULL } +}; + + +/** + * assuan_register_command: + * @ctx: the server context + * @cmd_name: A string with the command name + * @handler: The handler function to be called or NULL to use a default + * handler. + * + * Register a handler to be used for a given command. Note that + * several default handlers are already regsitered with a new context. + * This function however allows to override them. + * + * Return value: 0 on success or an error code + **/ +int +assuan_register_command (assuan_context_t ctx, + const char *cmd_name, + int (*handler)(assuan_context_t, char *)) +{ + int i; + const char *s; + + if (cmd_name && !*cmd_name) + cmd_name = NULL; + + if (!cmd_name) + return _assuan_error (ASSUAN_Invalid_Value); + + if (!handler) + { /* find a default handler. */ + for (i=0; (s=std_cmd_table[i].name) && strcmp (cmd_name, s); i++) + ; + if (!s) + { /* Try again but case insensitive. */ + for (i=0; (s=std_cmd_table[i].name) + && my_strcasecmp (cmd_name, s); i++) + ; + } + if (s) + handler = std_cmd_table[i].handler; + if (!handler) + handler = dummy_handler; /* Last resort is the dummy handler. */ + } + + if (!ctx->cmdtbl) + { + ctx->cmdtbl_size = 50; + ctx->cmdtbl = xtrycalloc ( ctx->cmdtbl_size, sizeof *ctx->cmdtbl); + if (!ctx->cmdtbl) + return _assuan_error (ASSUAN_Out_Of_Core); + ctx->cmdtbl_used = 0; + } + else if (ctx->cmdtbl_used >= ctx->cmdtbl_size) + { + struct cmdtbl_s *x; + + x = xtryrealloc ( ctx->cmdtbl, (ctx->cmdtbl_size+10) * sizeof *x); + if (!x) + return _assuan_error (ASSUAN_Out_Of_Core); + ctx->cmdtbl = x; + ctx->cmdtbl_size += 50; + } + + ctx->cmdtbl[ctx->cmdtbl_used].name = cmd_name; + ctx->cmdtbl[ctx->cmdtbl_used].handler = handler; + ctx->cmdtbl_used++; + return 0; +} + +int +assuan_register_post_cmd_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, int)) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + ctx->post_cmd_notify_fnc = fnc; + return 0; +} + +int +assuan_register_bye_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + ctx->bye_notify_fnc = fnc; + return 0; +} + +int +assuan_register_reset_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + ctx->reset_notify_fnc = fnc; + return 0; +} + +int +assuan_register_cancel_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + ctx->cancel_notify_fnc = fnc; + return 0; +} + +int +assuan_register_option_handler (assuan_context_t ctx, + int (*fnc)(assuan_context_t, + const char*, const char*)) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + ctx->option_handler_fnc = fnc; + return 0; +} + +int +assuan_register_input_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, const char *)) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + ctx->input_notify_fnc = fnc; + return 0; +} + +int +assuan_register_output_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, const char *)) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + ctx->output_notify_fnc = fnc; + return 0; +} + + +/* Helper to register the standards commands */ +int +_assuan_register_std_commands (assuan_context_t ctx) +{ + int i, rc; + + for (i=0; std_cmd_table[i].name; i++) + { + if (std_cmd_table[i].always) + { + rc = assuan_register_command (ctx, std_cmd_table[i].name, NULL); + if (rc) + return rc; + } + } + return 0; +} + + + +/* Process the special data lines. The "D " has already been removed + from the line. As all handlers this function may modify the line. */ +static int +handle_data_line (assuan_context_t ctx, char *line, int linelen) +{ + return set_error (ctx, Not_Implemented, NULL); +} + +/* like ascii_strcasecmp but assume that B is already uppercase */ +static int +my_strcasecmp (const char *a, const char *b) +{ + if (a == b) + return 0; + + for (; *a && *b; a++, b++) + { + if (((*a >= 'a' && *a <= 'z')? (*a&~0x20):*a) != *b) + break; + } + return *a == *b? 0 : (((*a >= 'a' && *a <= 'z')? (*a&~0x20):*a) - *b); +} + +/* Parse the line, break out the command, find it in the command + table, remove leading and white spaces from the arguments, call the + handler with the argument line and return the error */ +static int +dispatch_command (assuan_context_t ctx, char *line, int linelen) +{ + char *p; + const char *s; + int shift, i; + + if (*line == 'D' && line[1] == ' ') /* divert to special handler */ + return handle_data_line (ctx, line+2, linelen-2); + + for (p=line; *p && *p != ' ' && *p != '\t'; p++) + ; + if (p==line) + return set_error (ctx, Syntax_Error, "leading white-space"); + if (*p) + { /* Skip over leading WS after the keyword */ + *p++ = 0; + while ( *p == ' ' || *p == '\t') + p++; + } + shift = p - line; + + for (i=0; (s=ctx->cmdtbl[i].name); i++) + { + if (!strcmp (line, s)) + break; + } + if (!s) + { /* and try case insensitive */ + for (i=0; (s=ctx->cmdtbl[i].name); i++) + { + if (!my_strcasecmp (line, s)) + break; + } + } + if (!s) + return set_error (ctx, Unknown_Command, NULL); + line += shift; + linelen -= shift; + +/* fprintf (stderr, "DBG-assuan: processing %s `%s'\n", s, line); */ + return ctx->cmdtbl[i].handler (ctx, line); +} + + + + +static int +process_request (assuan_context_t ctx) +{ + int rc; + + if (ctx->in_inquire) + return _assuan_error (ASSUAN_Nested_Commands); + + rc = _assuan_read_line (ctx); + if (rc) + return rc; + if (*ctx->inbound.line == '#' || !ctx->inbound.linelen) + return 0; /* comment line - ignore */ + + ctx->outbound.data.error = 0; + ctx->outbound.data.linelen = 0; + /* dispatch command and return reply */ + rc = dispatch_command (ctx, ctx->inbound.line, ctx->inbound.linelen); + /* check from data write errors */ + if (ctx->outbound.data.fp) + { /* Flush the data lines */ + fclose (ctx->outbound.data.fp); + ctx->outbound.data.fp = NULL; + if (!rc && ctx->outbound.data.error) + rc = ctx->outbound.data.error; + } + else /* flush any data send w/o using the data fp */ + { + assuan_send_data (ctx, NULL, 0); + if (!rc && ctx->outbound.data.error) + rc = ctx->outbound.data.error; + } + /* Error handling */ + if (!rc) + { + rc = assuan_write_line (ctx, ctx->okay_line? ctx->okay_line : "OK"); + } + else if (err_is_eof (rc)) + { /* No error checking because the peer may have already disconnect. */ + assuan_write_line (ctx, "OK closing connection"); + ctx->finish_handler (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(__GNUC__) && defined(__ELF__) + /* If we have weak symbol support we try to use the error + strings from libgpg-error without creating a dependency. + They are used for debugging purposes only, so there is no + problem if they are not available. We need to make sure + that we are using ELF because only this guarantees that + weak symbol support is available in case GNU ld is not + used. It seems that old gcc versions don't implement the + weak attribute properly but it works with the weak + pragma. */ + + unsigned int source, code; + + int gpg_strerror_r (unsigned int err, char *buf, size_t buflen) + __attribute__ ((weak)); + const char *gpg_strsource (unsigned int err) + __attribute__ ((weak)); +#if !defined(HAVE_W32_SYSTEM) && __GNUC__ < 3 +#pragma weak gpg_strerror_r +#pragma weak gpg_strsource +#endif + + source = ((rc >> 24) & 0xff); + code = (rc & 0x00ffffff); + if (source && gpg_strsource && gpg_strerror_r) + { + /* 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, + ebuf, + gpg_strsource (rc), + text? " - ":"", text?text:""); + } + else +#endif /* __GNUC__ && __ELF__ */ + sprintf (errline, "ERR %d %.50s%s%.100s", + rc, assuan_strerror (rc), text? " - ":"", text?text:""); + } + 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; +} + +/** + * assuan_process: + * @ctx: assuan context + * + * This function is used to handle the assuan protocol after a + * connection has been established using assuan_accept(). This is the + * main protocol handler. + * + * Return value: 0 on success or an error code if the assuan operation + * failed. Note, that no error is returned for operational errors. + **/ +int +assuan_process (assuan_context_t ctx) +{ + int rc; + + do { + rc = process_request (ctx); + } while (!rc); + + if (err_is_eof (rc)) + rc = 0; + + return rc; +} + + +/** + * assuan_process_next: + * @ctx: Assuan context + * + * Same as assuan_process() but the user has to provide the outer + * loop. He should loop as long as the return code is zero and stop + * otherwise; -1 is regular end. + * + * See also: assuan_get_active_fds() + * Return value: -1 for end of server, 0 on success or an error code + **/ +int +assuan_process_next (assuan_context_t ctx) +{ + return process_request (ctx); +} + + +/** + * assuan_get_active_fds: + * @ctx: Assuan context + * @what: 0 for read fds, 1 for write fds + * @fdarray: Caller supplied array to store the FDs + * @fdarraysize: size of that array + * + * Return all active filedescriptors for the given context. This + * function can be used to select on the fds and call + * assuan_process_next() if there is an active one. The first fd in + * the array is the one used for the command connection. + * + * Note, that write FDs are not yet supported. + * + * Return value: number of FDs active and put into @fdarray or -1 on + * error which is most likely a too small fdarray. + **/ +int +assuan_get_active_fds (assuan_context_t ctx, int what, + int *fdarray, int fdarraysize) +{ + int n = 0; + + if (!ctx || fdarraysize < 2 || what < 0 || what > 1) + return -1; + + if (!what) + { + if (ctx->inbound.fd != -1) + fdarray[n++] = ctx->inbound.fd; + } + else + { + if (ctx->outbound.fd != -1) + fdarray[n++] = ctx->outbound.fd; + if (ctx->outbound.data.fp) + fdarray[n++] = fileno (ctx->outbound.data.fp); + } + + return n; +} + + +/* Two simple wrappers to make the expected function types match. */ +#ifdef HAVE_FUNOPEN +static int +fun1_cookie_write (void *cookie, const char *buffer, int orig_size) +{ + return _assuan_cookie_write_data (cookie, buffer, orig_size); +} +#endif /*HAVE_FUNOPEN*/ +#ifdef HAVE_FOPENCOOKIE +static ssize_t +fun2_cookie_write (void *cookie, const char *buffer, size_t orig_size) +{ + return _assuan_cookie_write_data (cookie, buffer, orig_size); +} +#endif /*HAVE_FOPENCOOKIE*/ + +/* Return a FP to be used for data output. The FILE pointer is valid + until the end of a handler. So a close is not needed. Assuan does + all the buffering needed to insert the status line as well as the + required line wappping and quoting for data lines. + + We use GNU's custom streams here. There should be an alternative + implementaion for systems w/o a glibc, a simple implementation + could use a child process */ +FILE * +assuan_get_data_fp (assuan_context_t ctx) +{ +#if defined (HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN) + if (ctx->outbound.data.fp) + return ctx->outbound.data.fp; + +#ifdef HAVE_FUNOPEN + ctx->outbound.data.fp = funopen (ctx, 0, fun1_cookie_write, + 0, _assuan_cookie_write_flush); +#else + ctx->outbound.data.fp = funopen (ctx, 0, fun2_cookie_write, + 0, _assuan_cookie_write_flush); +#endif + + ctx->outbound.data.error = 0; + return ctx->outbound.data.fp; +#else + errno = ENOSYS; + return NULL; +#endif +} + + +/* Set the text used for the next OK reponse. This string is + automatically reset to NULL after the next command. */ +assuan_error_t +assuan_set_okay_line (assuan_context_t ctx, const char *line) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + if (!line) + { + xfree (ctx->okay_line); + ctx->okay_line = NULL; + } + else + { + /* FIXME: we need to use gcry_is_secure() to test whether + we should allocate the entire line in secure memory */ + char *buf = xtrymalloc (3+strlen(line)+1); + if (!buf) + return _assuan_error (ASSUAN_Out_Of_Core); + strcpy (buf, "OK "); + strcpy (buf+3, line); + xfree (ctx->okay_line); + ctx->okay_line = buf; + } + return 0; +} + + + +assuan_error_t +assuan_write_status (assuan_context_t ctx, + const char *keyword, const char *text) +{ + char buffer[256]; + char *helpbuf; + size_t n; + assuan_error_t ae; + + if ( !ctx || !keyword) + return _assuan_error (ASSUAN_Invalid_Value); + if (!text) + text = ""; + + n = 2 + strlen (keyword) + 1 + strlen (text) + 1; + if (n < sizeof (buffer)) + { + strcpy (buffer, "S "); + strcat (buffer, keyword); + if (*text) + { + strcat (buffer, " "); + strcat (buffer, text); + } + ae = assuan_write_line (ctx, buffer); + } + else if ( (helpbuf = xtrymalloc (n)) ) + { + strcpy (helpbuf, "S "); + strcat (helpbuf, keyword); + if (*text) + { + strcat (helpbuf, " "); + strcat (helpbuf, text); + } + ae = assuan_write_line (ctx, helpbuf); + xfree (helpbuf); + } + else + ae = 0; + return ae; +} diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-inquire.c b/libkdenetwork/libgpgme-copy/assuan/assuan-inquire.c new file mode 100644 index 000000000..d8c52d09a --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-inquire.c @@ -0,0 +1,241 @@ +/* assuan-inquire.c - handle inquire stuff + * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "assuan-defs.h" + +#define digitp(a) ((a) >= '0' && (a) <= '9') +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) + + +struct membuf +{ + size_t len; + size_t size; + char *buf; + int out_of_core; + int too_large; + size_t maxlen; +}; + + + +/* A simple implemnation of a dynamic buffer. Use init_membuf() to + create a buffer, put_membuf to append bytes and get_membuf to + release and return the buffer. Allocation errors are detected but + only returned at the final get_membuf(), this helps not to clutter + the code with out of core checks. */ + +static void +init_membuf (struct membuf *mb, int initiallen, size_t maxlen) +{ + mb->len = 0; + mb->size = initiallen; + mb->out_of_core = 0; + mb->too_large = 0; + mb->maxlen = maxlen; + /* we need to allocate one byte more for get_membuf */ + mb->buf = xtrymalloc (initiallen+1); + if (!mb->buf) + mb->out_of_core = 1; +} + +static void +put_membuf (struct membuf *mb, const void *buf, size_t len) +{ + if (mb->out_of_core || mb->too_large) + return; + + if (mb->maxlen && mb->len + len > mb->maxlen) + { + mb->too_large = 1; + return; + } + + if (mb->len + len >= mb->size) + { + char *p; + + mb->size += len + 1024; + /* we need to allocate one byte more for get_membuf */ + p = xtryrealloc (mb->buf, mb->size+1); + if (!p) + { + mb->out_of_core = 1; + return; + } + mb->buf = p; + } + memcpy (mb->buf + mb->len, buf, len); + mb->len += len; +} + +static void * +get_membuf (struct membuf *mb, size_t *len) +{ + char *p; + + if (mb->out_of_core || mb->too_large) + { + xfree (mb->buf); + mb->buf = NULL; + return NULL; + } + + mb->buf[mb->len] = 0; /* there is enough space for the hidden eos */ + p = mb->buf; + *len = mb->len; + mb->buf = NULL; + mb->out_of_core = 1; /* don't allow a reuse */ + return p; +} + +static void +free_membuf (struct membuf *mb) +{ + xfree (mb->buf); + mb->buf = NULL; +} + + +/** + * assuan_inquire: + * @ctx: An assuan context + * @keyword: The keyword used for the inquire + * @r_buffer: Returns an allocated buffer + * @r_length: Returns the length of this buffer + * @maxlen: If not 0, the size limit of the inquired data. + * + * A Server may use this to Send an inquire. r_buffer, r_length and + * maxlen may all be NULL/0 to indicate that no real data is expected. + * + * Return value: 0 on success or an ASSUAN error code + **/ +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 rc; + struct membuf mb; + char cmdbuf[LINELENGTH-10]; /* (10 = strlen ("INQUIRE ")+CR,LF) */ + unsigned char *line, *p; + int linelen; + int nodataexpected; + + if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf))) + return _assuan_error (ASSUAN_Invalid_Value); + nodataexpected = !r_buffer && !r_length && !maxlen; + if (!nodataexpected && (!r_buffer || !r_length)) + 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); + + ctx->in_inquire = 1; + if (nodataexpected) + memset (&mb, 0, sizeof mb); /* avoid compiler warnings */ + else + init_membuf (&mb, maxlen? maxlen:1024, maxlen); + + strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword); + rc = assuan_write_line (ctx, cmdbuf); + if (rc) + goto leave; + + for (;;) + { + do + { + rc = _assuan_read_line (ctx); + if (rc) + goto leave; + line = (unsigned char *) ctx->inbound.line; + linelen = ctx->inbound.linelen; + } + while (*line == '#' || !linelen); + if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D' + && (!line[3] || line[3] == ' ')) + break; /* END command received*/ + if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N') + { + rc = _assuan_error (ASSUAN_Canceled); + goto leave; + } + if (line[0] != 'D' || line[1] != ' ' || nodataexpected) + { + rc = _assuan_error (ASSUAN_Unexpected_Command); + goto leave; + } + if (linelen < 3) + continue; + line += 2; + linelen -= 2; + + p = line; + while (linelen) + { + for (;linelen && *p != '%'; linelen--, p++) + ; + put_membuf (&mb, line, p-line); + if (linelen > 2) + { /* handle escaping */ + unsigned char tmp[1]; + p++; + *tmp = xtoi_2 (p); + p += 2; + linelen -= 3; + put_membuf (&mb, tmp, 1); + } + line = p; + } + if (mb.too_large) + { + rc = _assuan_error (ASSUAN_Too_Much_Data); + goto leave; + } + } + + if (!nodataexpected) + { + *r_buffer = get_membuf (&mb, r_length); + if (!*r_buffer) + rc = _assuan_error (ASSUAN_Out_Of_Core); + } + + leave: + if (!nodataexpected) + free_membuf (&mb); + ctx->in_inquire = 0; + return rc; +} + + + + + + diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-io.c b/libkdenetwork/libgpgme-copy/assuan/assuan-io.c new file mode 100644 index 000000000..d1f0d5e48 --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-io.c @@ -0,0 +1,87 @@ +/* assuan-io.c - Wraps the read and write functions. + * Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <sys/time.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <unistd.h> +#include <errno.h> +#ifdef HAVE_W32_SYSTEM +# include <windows.h> +#else +# include <sys/wait.h> +#endif + +#include "assuan-defs.h" + + +#ifndef HAVE_W32_SYSTEM +pid_t +_assuan_waitpid (pid_t pid, int *status, int options) +{ + return waitpid (pid, status, options); +} +#endif + + +ssize_t +_assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size) +{ + return read (ctx->inbound.fd, buffer, size); +} + +ssize_t +_assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size) +{ + return write (ctx->outbound.fd, buffer, size); +} + + +ssize_t +_assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg) +{ +#ifdef HAVE_W32_SYSTEM + return _assuan_error (ASSUAN_Not_Implemented); +#else + int ret; + while ( (ret = sendmsg (ctx->outbound.fd, msg, 0)) == -1 && errno == EINTR) + ; + return ret; +#endif +} + + +ssize_t +_assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg) +{ +#ifdef HAVE_W32_SYSTEM + return _assuan_error (ASSUAN_Not_Implemented); +#else + int ret; + while ( (ret = recvmsg (ctx->inbound.fd, msg, 0)) == -1 && errno == EINTR) + ; + return ret; +#endif +} diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-listen.c b/libkdenetwork/libgpgme-copy/assuan/assuan-listen.c new file mode 100644 index 000000000..04db68ce0 --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-listen.c @@ -0,0 +1,157 @@ +/* assuan-listen.c - Wait for a connection (server) + * Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> + +#include "assuan-defs.h" + +assuan_error_t +assuan_set_hello_line (assuan_context_t ctx, const char *line) +{ + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + if (!line) + { + xfree (ctx->hello_line); + ctx->hello_line = NULL; + } + else + { + char *buf = xtrymalloc (3+strlen(line)+1); + if (!buf) + return _assuan_error (ASSUAN_Out_Of_Core); + if (strchr (line, '\n')) + strcpy (buf, line); + else + { + strcpy (buf, "OK "); + strcpy (buf+3, line); + } + xfree (ctx->hello_line); + ctx->hello_line = buf; + } + return 0; +} + + +/** + * assuan_accept: + * @ctx: context + * + * Cancel any existing connection and wait for a connection from a + * client. The initial handshake is performed which may include an + * initial authentication or encryption negotiation. + * + * Return value: 0 on success or an error if the connection could for + * some reason not be established. + **/ +assuan_error_t +assuan_accept (assuan_context_t ctx) +{ + int rc; + const char *p, *pend; + + if (!ctx) + return _assuan_error (ASSUAN_Invalid_Value); + + if (ctx->pipe_mode > 1) + return -1; /* second invocation for pipemode -> terminate */ + ctx->finish_handler (ctx); + + rc = ctx->accept_handler (ctx); + if (rc) + return rc; + + /* Send the hello. */ + p = ctx->hello_line; + if (p && (pend = strchr (p, '\n'))) + { /* This is a multi line hello. Send all but the last line as + comments. */ + do + { + rc = _assuan_write_line (ctx, "# ", p, pend - p); + if (rc) + return rc; + p = pend + 1; + pend = strchr (p, '\n'); + } + while (pend); + rc = _assuan_write_line (ctx, "OK ", p, strlen (p)); + } + else if (p) + rc = assuan_write_line (ctx, p); + else + rc = assuan_write_line (ctx, "OK Pleased to meet you"); + if (rc) + return rc; + + if (ctx->pipe_mode) + ctx->pipe_mode = 2; + + return 0; +} + + + +int +assuan_get_input_fd (assuan_context_t ctx) +{ + return ctx? ctx->input_fd : -1; +} + + +int +assuan_get_output_fd (assuan_context_t ctx) +{ + return ctx? ctx->output_fd : -1; +} + + +/* Close the fd descriptor set by the command INPUT FD=n. We handle + this fd inside assuan so that we can do some initial checks */ +assuan_error_t +assuan_close_input_fd (assuan_context_t ctx) +{ + if (!ctx || ctx->input_fd == -1) + return _assuan_error (ASSUAN_Invalid_Value); + _assuan_close (ctx->input_fd); + ctx->input_fd = -1; + return 0; +} + +/* Close the fd descriptor set by the command OUTPUT FD=n. We handle + this fd inside assuan so that we can do some initial checks */ +assuan_error_t +assuan_close_output_fd (assuan_context_t ctx) +{ + if (!ctx || ctx->output_fd == -1) + return _assuan_error (ASSUAN_Invalid_Value); + + _assuan_close (ctx->output_fd); + ctx->output_fd = -1; + return 0; +} + diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-logging.c b/libkdenetwork/libgpgme-copy/assuan/assuan-logging.c new file mode 100644 index 000000000..cfc3d846f --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-logging.c @@ -0,0 +1,241 @@ +/* assuan-logging.c - Default logging function. + * Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#ifdef HAVE_W32_SYSTEM +#include <windows.h> +#endif /*HAVE_W32_SYSTEM*/ +#include <errno.h> +#include <ctype.h> + +#include "assuan-defs.h" + +static char prefix_buffer[80]; +static FILE *_assuan_log; +static int full_logging; + +void +_assuan_set_default_log_stream (FILE *fp) +{ + if (!_assuan_log) + { + _assuan_log = fp; + full_logging = !!getenv ("ASSUAN_FULL_LOGGING"); + } +} + +void +assuan_set_assuan_log_stream (FILE *fp) +{ + _assuan_log = fp; +} + + +/* Set the per context log stream. Also enable the default log stream + if it has not been set. */ +void +assuan_set_log_stream (assuan_context_t ctx, FILE *fp) +{ + if (ctx) + { + if (ctx->log_fp) + fflush (ctx->log_fp); + ctx->log_fp = fp; + _assuan_set_default_log_stream (fp); + } +} + + +FILE * +assuan_get_assuan_log_stream (void) +{ + return _assuan_log ? _assuan_log : stderr; +} + + +/* Set the prefix to be used for logging to TEXT or + resets it to the default if TEXT is NULL. */ +void +assuan_set_assuan_log_prefix (const char *text) +{ + if (text) + { + strncpy (prefix_buffer, text, sizeof (prefix_buffer)-1); + prefix_buffer[sizeof (prefix_buffer)-1] = 0; + } + else + *prefix_buffer = 0; +} + +const char * +assuan_get_assuan_log_prefix (void) +{ + return prefix_buffer; +} + + +void +_assuan_log_printf (const char *format, ...) +{ + va_list arg_ptr; + FILE *fp; + const char *prf; + int save_errno = errno; + + fp = assuan_get_assuan_log_stream (); + prf = assuan_get_assuan_log_prefix (); + if (*prf) + fprintf (fp, "%s[%u]: ", prf, (unsigned int)getpid ()); + + va_start (arg_ptr, format); + vfprintf (fp, format, arg_ptr ); + va_end (arg_ptr); + 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. */ +void +_assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length) +{ + const unsigned char *s; + int n; + + for (n=length,s=buffer; n; n--, s++) + if ((!isascii (*s) || iscntrl (*s) || !isprint (*s)) && !(*s >= 0x80)) + break; + + s = buffer; + if (!n && *s != '[') + fwrite (buffer, length, 1, fp); + else + { +#ifdef HAVE_FLOCKFILE + flockfile (fp); +#endif + putc_unlocked ('[', fp); + if ( length > 16 && !full_logging) + { + for (n=0; n < 12; n++, s++) + fprintf (fp, " %02x", *s); + fprintf (fp, " ...(%d bytes skipped)", (int)length - 12); + } + else + { + for (n=0; n < length; n++, s++) + fprintf (fp, " %02x", *s); + } + putc_unlocked (' ', fp); + putc_unlocked (']', fp); +#ifdef HAVE_FUNLOCKFILE + funlockfile (fp); +#endif + } +} + +/* Log a user supplied string. Escapes non-printable before + printing. */ +void +_assuan_log_sanitized_string (const char *string) +{ + const unsigned char *s = (const unsigned char *) string; + FILE *fp = assuan_get_assuan_log_stream (); + + if (! *s) + return; + +#ifdef HAVE_FLOCKFILE + flockfile (fp); +#endif + + for (; *s; s++) + { + int c = 0; + + switch (*s) + { + case '\r': + c = 'r'; + break; + + case '\n': + c = 'n'; + break; + + case '\f': + c = 'f'; + break; + + case '\v': + c = 'v'; + break; + + case '\b': + c = 'b'; + break; + + default: + if ((isascii (*s) && isprint (*s)) || (*s >= 0x80)) + putc_unlocked (*s, fp); + else + { + putc_unlocked ('\\', fp); + fprintf (fp, "x%02x", *s); + } + } + + if (c) + { + putc_unlocked ('\\', fp); + putc_unlocked (c, fp); + } + } + +#ifdef HAVE_FUNLOCKFILE + funlockfile (fp); +#endif +} + + + +#ifdef HAVE_W32_SYSTEM +const char * +_assuan_w32_strerror (int ec) +{ + static char strerr[256]; + + if (ec == -1) + ec = (int)GetLastError (); + FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec, + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), + strerr, sizeof (strerr)-1, NULL); + return strerr; +} +#endif /*HAVE_W32_SYSTEM*/ diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-pipe-connect.c b/libkdenetwork/libgpgme-copy/assuan/assuan-pipe-connect.c new file mode 100644 index 000000000..8ee9c748b --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-pipe-connect.c @@ -0,0 +1,889 @@ +/* assuan-pipe-connect.c - Establish a pipe connection (client) + * Copyright (C) 2001, 2002, 2003, 2005, 2006 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <signal.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/types.h> +#ifndef HAVE_W32_SYSTEM +#include <sys/wait.h> +#else +#include <windows.h> +#endif + +#include "assuan-defs.h" + +/* Hacks for Slowaris. */ +#ifndef PF_LOCAL +# ifdef PF_UNIX +# define PF_LOCAL PF_UNIX +# else +# define PF_LOCAL AF_UNIX +# endif +#endif +#ifndef AF_LOCAL +# define AF_LOCAL AF_UNIX +#endif + + +#ifdef _POSIX_OPEN_MAX +#define MAX_OPEN_FDS _POSIX_OPEN_MAX +#else +#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 +fix_signals (void) +{ +#ifndef _ASSUAN_NO_FIXED_SIGNALS +#ifndef HAVE_DOSISH_SYSTEM /* No SIGPIPE for these systems. */ + static int fixed_signals; + + if (!fixed_signals) + { + struct sigaction act; + + sigaction (SIGPIPE, NULL, &act); + if (act.sa_handler == SIG_DFL) + { + act.sa_handler = SIG_IGN; + sigemptyset (&act.sa_mask); + act.sa_flags = 0; + sigaction (SIGPIPE, &act, NULL); + } + fixed_signals = 1; + /* FIXME: This is not MT safe */ + } +#endif /*HAVE_DOSISH_SYSTEM*/ +#endif /*!_ASSUAN_NO_FIXED_SIGNALS*/ +} + + +#ifndef HAVE_W32_SYSTEM +static int +writen (int fd, const char *buffer, size_t length) +{ + while (length) + { + int nwritten = write (fd, buffer, length); + + if (nwritten < 0) + { + if (errno == EINTR) + continue; + return -1; /* write error */ + } + length -= nwritten; + buffer += nwritten; + } + return 0; /* okay */ +} +#endif + +static int +do_finish (assuan_context_t ctx) +{ + if (ctx->inbound.fd != -1) + { + _assuan_close (ctx->inbound.fd); + if (ctx->inbound.fd == ctx->outbound.fd) + ctx->outbound.fd = -1; + ctx->inbound.fd = -1; + } + if (ctx->outbound.fd != -1) + { + _assuan_close (ctx->outbound.fd); + ctx->outbound.fd = -1; + } + if (ctx->pid != -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; +#endif +#endif /*!HAVE_W32_SYSTEM*/ + } + return 0; +} + +static void +do_deinit (assuan_context_t ctx) +{ + do_finish (ctx); +} + + +/* Helper for pipe_connect. */ +static assuan_error_t +initial_handshake (assuan_context_t *ctx) +{ + int okay, off; + assuan_error_t err; + + err = _assuan_read_from_server (*ctx, &okay, &off); + if (err) + _assuan_log_printf ("can't connect server: %s\n", + assuan_strerror (err)); + else if (okay != 1) + { + _assuan_log_printf ("can't connect server: `%s'\n", + (*ctx)->inbound.line); + err = _assuan_error (ASSUAN_Connect_Failed); + } + + if (err) + { + assuan_disconnect (*ctx); + *ctx = NULL; + } + return err; +} + + +#ifndef HAVE_W32_SYSTEM +#define pipe_connect pipe_connect_unix +/* Unix version of the pipe connection code. We use an extra macro to + make ChangeLog entries easier. */ +static assuan_error_t +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) +{ + assuan_error_t err; + int rp[2]; + int wp[2]; + char mypidstr[50]; + + if (!ctx || !name || !argv || !argv[0]) + return _assuan_error (ASSUAN_Invalid_Value); + + fix_signals (); + + sprintf (mypidstr, "%lu", (unsigned long)getpid ()); + + if (pipe (rp) < 0) + return _assuan_error (ASSUAN_General_Error); + + if (pipe (wp) < 0) + { + close (rp[0]); + close (rp[1]); + return _assuan_error (ASSUAN_General_Error); + } + + err = _assuan_new_context (ctx); + if (err) + { + close (rp[0]); + close (rp[1]); + close (wp[0]); + close (wp[1]); + return err; + } + (*ctx)->pipe_mode = 1; + (*ctx)->inbound.fd = rp[0]; /* Our inbound is read end of read pipe. */ + (*ctx)->outbound.fd = wp[1]; /* Our outbound is write end of write pipe. */ + (*ctx)->deinit_handler = do_deinit; + (*ctx)->finish_handler = do_finish; + + /* FIXME: For GPGME we should better use _gpgme_io_spawn. The PID + stored here is actually soon useless. */ + (*ctx)->pid = fork (); + if ((*ctx)->pid < 0) + { + close (rp[0]); + close (rp[1]); + close (wp[0]); + close (wp[1]); + _assuan_release_context (*ctx); + return _assuan_error (ASSUAN_General_Error); + } + + if ((*ctx)->pid == 0) + { +#ifdef _ASSUAN_USE_DOUBLE_FORK + pid_t pid; + + if ((pid = fork ()) == 0) +#endif + { + int i, n; + char errbuf[512]; + int *fdp; + + if (atfork) + atfork (atforkvalue, 0); + + /* Dup handles to stdin/stdout. */ + if (rp[1] != STDOUT_FILENO) + { + if (dup2 (rp[1], STDOUT_FILENO) == -1) + { + _assuan_log_printf ("dup2 failed in child: %s\n", + strerror (errno)); + _exit (4); + } + } + if (wp[0] != STDIN_FILENO) + { + if (dup2 (wp[0], STDIN_FILENO) == -1) + { + _assuan_log_printf ("dup2 failed in child: %s\n", + strerror (errno)); + _exit (4); + } + } + + /* Dup stderr to /dev/null unless it is in the list of FDs to be + passed to the child. */ + fdp = fd_child_list; + if (fdp) + { + for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++) + ; + } + if (!fdp || *fdp == -1) + { + int fd = open ("/dev/null", O_WRONLY); + if (fd == -1) + { + _assuan_log_printf ("can't open `/dev/null': %s\n", + strerror (errno)); + _exit (4); + } + if (dup2 (fd, STDERR_FILENO) == -1) + { + _assuan_log_printf ("dup2(dev/null, 2) failed: %s\n", + strerror (errno)); + _exit (4); + } + } + + + /* Close all files which will not be duped and are not in the + fd_child_list. */ + n = sysconf (_SC_OPEN_MAX); + if (n < 0) + n = MAX_OPEN_FDS; + for (i=0; i < n; i++) + { + if ( i == STDIN_FILENO || i == STDOUT_FILENO + || i == STDERR_FILENO) + continue; + fdp = fd_child_list; + if (fdp) + { + while (*fdp != -1 && *fdp != i) + fdp++; + } + + if (!(fdp && *fdp != -1)) + close(i); + } + errno = 0; + + /* We store our parents pid in the environment so that the + execed assuan server is able to read the actual pid of the + client. The server can't use getppid because it might have + been double forked before the assuan server has been + initialized. */ + setenv ("_assuan_pipe_connect_pid", mypidstr, 1); + + /* Make sure that we never pass a connection fd variable + when using a simple pipe. */ + unsetenv ("_assuan_connection_fd"); + + execv (name, (char *const *) argv); + /* oops - use the pipe to tell the parent about it */ + snprintf (errbuf, sizeof(errbuf)-1, + "ERR %d can't exec `%s': %.50s\n", + _assuan_error (ASSUAN_Problem_Starting_Server), + name, strerror (errno)); + errbuf[sizeof(errbuf)-1] = 0; + writen (1, errbuf, strlen (errbuf)); + _exit (4); + } +#ifdef _ASSUAN_USE_DOUBLE_FORK + if (pid == -1) + _exit (1); + else + _exit (0); +#endif + } + +#ifdef _ASSUAN_USE_DOUBLE_FORK + _assuan_waitpid ((*ctx)->pid, NULL, 0); + (*ctx)->pid = -1; +#endif + + close (rp[1]); + close (wp[0]); + + return initial_handshake (ctx); +} +#endif /*!HAVE_W32_SYSTEM*/ + + +#ifndef HAVE_W32_SYSTEM +/* This function is similar to pipe_connect but uses a socketpair and + sets the I/O up to use sendmsg/recvmsg. */ +static assuan_error_t +socketpair_connect (assuan_context_t *ctx, + const char *name, const char *const argv[], + int *fd_child_list, + void (*atfork) (void *opaque, int reserved), + void *atforkvalue) +{ + assuan_error_t err; + int fds[2]; + char mypidstr[50]; + + if (!ctx + || (name && (!argv || !argv[0])) + || (!name && argv)) + return _assuan_error (ASSUAN_Invalid_Value); + + fix_signals (); + + sprintf (mypidstr, "%lu", (unsigned long)getpid ()); + + if ( socketpair (AF_LOCAL, SOCK_STREAM, 0, fds) ) + { + _assuan_log_printf ("socketpair failed: %s\n", strerror (errno)); + return _assuan_error (ASSUAN_General_Error); + } + + err = _assuan_new_context (ctx); + if (err) + { + close (fds[0]); + close (fds[1]); + return err; + } + (*ctx)->pipe_mode = 1; + (*ctx)->inbound.fd = fds[0]; + (*ctx)->outbound.fd = fds[0]; + _assuan_init_uds_io (*ctx); + (*ctx)->deinit_handler = _assuan_uds_deinit; + (*ctx)->finish_handler = do_finish; + + (*ctx)->pid = fork (); + if ((*ctx)->pid < 0) + { + close (fds[0]); + close (fds[1]); + _assuan_release_context (*ctx); + *ctx = NULL; + return _assuan_error (ASSUAN_General_Error); + } + + if ((*ctx)->pid == 0) + { +#ifdef _ASSUAN_USE_DOUBLE_FORK + pid_t pid; + + if ((pid = fork ()) == 0) +#endif + { + int fd, i, n; + char errbuf[512]; + int *fdp; + + if (atfork) + atfork (atforkvalue, 0); + + /* Connect stdin and stdout to /dev/null. */ + fd = open ("/dev/null", O_RDONLY); + if (fd == -1 || dup2 (fd, STDIN_FILENO) == -1) + { + _assuan_log_printf ("dup2(dev/null) failed: %s\n", + strerror (errno)); + _exit (4); + } + fd = open ("/dev/null", O_WRONLY); + if (fd == -1 || dup2 (fd, STDOUT_FILENO) == -1) + { + _assuan_log_printf ("dup2(dev/null) failed: %s\n", + strerror (errno)); + _exit (4); + } + + /* Dup stderr to /dev/null unless it is in the list of FDs to be + passed to the child. */ + fdp = fd_child_list; + if (fdp) + { + for (; *fdp != -1 && *fdp != STDERR_FILENO; fdp++) + ; + } + if (!fdp || *fdp == -1) + { + fd = open ("/dev/null", O_WRONLY); + if (fd == -1 || dup2 (fd, STDERR_FILENO) == -1) + { + _assuan_log_printf ("dup2(dev/null) failed: %s\n", + strerror (errno)); + _exit (4); + } + } + + + /* Close all files which will not be duped, are not in the + fd_child_list and are not the connection fd. */ + n = sysconf (_SC_OPEN_MAX); + if (n < 0) + n = MAX_OPEN_FDS; + for (i=0; i < n; i++) + { + if ( i == STDIN_FILENO || i == STDOUT_FILENO + || i == STDERR_FILENO || i == fds[1]) + continue; + fdp = fd_child_list; + if (fdp) + { + while (*fdp != -1 && *fdp != i) + fdp++; + } + + if (!(fdp && *fdp != -1)) + close(i); + } + errno = 0; + + /* We store our parents pid in the environment so that the + execed assuan server is able to read the actual pid of the + client. The server can't use getppid becuase it might have + been double forked before the assuan server has been + initialized. */ + setenv ("_assuan_pipe_connect_pid", mypidstr, 1); + + /* Now set the environment variable used to convey the + connection's file descriptor. */ + sprintf (mypidstr, "%d", fds[1]); + if (setenv ("_assuan_connection_fd", mypidstr, 1)) + { + _assuan_log_printf ("setenv failed: %s\n", strerror (errno)); + _exit (4); + } + + if (!name && !argv) + { + /* No name and no args given, thus we don't do an exec + but continue the forked process. */ + _assuan_release_context (*ctx); + *ctx = NULL; + return 0; + } + + execv (name, (char *const *) argv); + /* oops - use the pipe to tell the parent about it */ + snprintf (errbuf, sizeof(errbuf)-1, + "ERR %d can't exec `%s': %.50s\n", + _assuan_error (ASSUAN_Problem_Starting_Server), + name, strerror (errno)); + errbuf[sizeof(errbuf)-1] = 0; + writen (fds[1], errbuf, strlen (errbuf)); + _exit (4); + } +#ifdef _ASSUAN_USE_DOUBLE_FORK + if (pid == -1) + _exit (1); + else + _exit (0); +#endif + } + + +#ifdef _ASSUAN_USE_DOUBLE_FORK + _assuan_waitpid ((*ctx)->pid, NULL, 0); + (*ctx)->pid = -1; +#endif + + close (fds[1]); + + return initial_handshake (ctx); +} +#endif /*!HAVE_W32_SYSTEM*/ + + + +#ifdef HAVE_W32_SYSTEM +/* Build a command line for use with W32's CreateProcess. On success + CMDLINE gets the address of a newly allocated string. */ +static int +build_w32_commandline (char * const *argv, char **cmdline) +{ + int i, n; + const char *s; + char *buf, *p; + + *cmdline = NULL; + n = 0; + for (i=0; (s=argv[i]); i++) + { + n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */ + for (; *s; s++) + if (*s == '\"') + n++; /* Need to double inner quotes. */ + } + n++; + + buf = p = xtrymalloc (n); + if (!buf) + return -1; + + for (i=0; argv[i]; i++) + { + if (i) + p = stpcpy (p, " "); + if (!*argv[i]) /* Empty string. */ + p = stpcpy (p, "\"\""); + else if (strpbrk (argv[i], " \t\n\v\f\"")) + { + p = stpcpy (p, "\""); + for (s=argv[i]; *s; s++) + { + *p++ = *s; + if (*s == '\"') + *p++ = *s; + } + *p++ = '\"'; + *p = 0; + } + else + p = stpcpy (p, argv[i]); + } + + *cmdline= buf; + return 0; +} +#endif /*HAVE_W32_SYSTEM*/ + + +#ifdef HAVE_W32_SYSTEM +/* Create pipe where one end end is inheritable. */ +static int +create_inheritable_pipe (int filedes[2], int for_write) +{ + HANDLE r, w, h; + SECURITY_ATTRIBUTES sec_attr; + + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + if (!CreatePipe (&r, &w, &sec_attr, 0)) + { + _assuan_log_printf ("CreatePipe failed: %s\n", w32_strerror (-1)); + return -1; + } + + if (!DuplicateHandle (GetCurrentProcess(), for_write? r : w, + GetCurrentProcess(), &h, 0, + TRUE, DUPLICATE_SAME_ACCESS )) + { + _assuan_log_printf ("DuplicateHandle failed: %s\n", w32_strerror (-1)); + CloseHandle (r); + CloseHandle (w); + return -1; + } + if (for_write) + { + CloseHandle (r); + r = h; + } + else + { + CloseHandle (w); + w = h; + } + + filedes[0] = handle_to_fd (r); + filedes[1] = handle_to_fd (w); + return 0; +} +#endif /*HAVE_W32_SYSTEM*/ + + +#ifdef HAVE_W32_SYSTEM +#define pipe_connect pipe_connect_w32 +/* W32 version of the pipe connection code. */ +static assuan_error_t +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) +{ + assuan_error_t err; + int rp[2]; + int wp[2]; + char mypidstr[50]; + char *cmdline; + SECURITY_ATTRIBUTES sec_attr; + PROCESS_INFORMATION pi = + { + NULL, /* Returns process handle. */ + 0, /* Returns primary thread handle. */ + 0, /* Returns pid. */ + 0 /* Returns tid. */ + }; + STARTUPINFO si; + int fd, *fdp; + HANDLE nullfd = INVALID_HANDLE_VALUE; + + if (!ctx || !name || !argv || !argv[0]) + return _assuan_error (ASSUAN_Invalid_Value); + + fix_signals (); + + sprintf (mypidstr, "%lu", (unsigned long)getpid ()); + + /* Build the command line. */ + if (build_w32_commandline (argv, &cmdline)) + return _assuan_error (ASSUAN_Out_Of_Core); + + /* Create thew two pipes. */ + if (create_inheritable_pipe (rp, 0)) + { + xfree (cmdline); + return _assuan_error (ASSUAN_General_Error); + } + + if (create_inheritable_pipe (wp, 1)) + { + CloseHandle (fd_to_handle (rp[0])); + CloseHandle (fd_to_handle (rp[1])); + xfree (cmdline); + return _assuan_error (ASSUAN_General_Error); + } + + + 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])); + xfree (cmdline); + return _assuan_error (ASSUAN_General_Error); + } + + (*ctx)->pipe_mode = 1; + (*ctx)->inbound.fd = rp[0]; /* Our inbound is read end of read pipe. */ + (*ctx)->outbound.fd = wp[1]; /* Our outbound is write end of write pipe. */ + (*ctx)->deinit_handler = do_deinit; + (*ctx)->finish_handler = do_finish; + + + /* fixme: Actually we should set the "_assuan_pipe_connect_pid" env + variable. However this requires us to write a full environment + handler, because the strings are expected in sorted order. The + suggestion given in the MS Reference Library, to save the old + value, changeit, create proces and restore it, is not thread + safe. */ + + /* Start the process. */ + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + 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]); + + /* Dup stderr to /dev/null unless it is in the list of FDs to be + passed to the child. */ + fd = fileno (stderr); + fdp = fd_child_list; + if (fdp) + { + for (; *fdp != -1 && *fdp != fd; fdp++) + ; + } + if (!fdp || *fdp == -1) + { + nullfd = CreateFile ("nul", GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, NULL); + 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])); + xfree (cmdline); + _assuan_release_context (*ctx); + return -1; + } + si.hStdError = nullfd; + } + else + si.hStdError = fd_to_handle (_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); */ + 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 + | GetPriorityClass (GetCurrentProcess ()) + | CREATE_SUSPENDED), /* Creation flags. */ + NULL, /* Environment. */ + NULL, /* Use current drive/directory. */ + &si, /* Startup information. */ + &pi /* Returns process information. */ + )) + { + _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])); + if (nullfd != INVALID_HANDLE_VALUE) + CloseHandle (nullfd); + xfree (cmdline); + _assuan_release_context (*ctx); + return _assuan_error (ASSUAN_General_Error); + } + xfree (cmdline); + cmdline = NULL; + if (nullfd != INVALID_HANDLE_VALUE) + { + CloseHandle (nullfd); + nullfd = INVALID_HANDLE_VALUE; + } + + CloseHandle (fd_to_handle (rp[1])); + CloseHandle (fd_to_handle (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); */ + + 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. */ + + return initial_handshake (ctx); +} +#endif /*HAVE_W32_SYSTEM*/ + + +/* Connect to a server over a pipe, creating the assuan context and + returning it in CTX. The server filename is NAME, the argument + vector in ARGV. FD_CHILD_LIST is a -1 terminated list of file + descriptors not to close in the child. */ +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); +} + + + +assuan_error_t +assuan_pipe_connect2 (assuan_context_t *ctx, + const char *name, const char *const argv[], + int *fd_child_list, + void (*atfork) (void *opaque, int reserved), + void *atforkvalue) +{ + return pipe_connect (ctx, name, argv, fd_child_list, atfork, atforkvalue); +} + + +/* Connect to a server over a full-duplex socket (i.e. created by + socketpair), creating the assuan context and returning it in CTX. + The server filename is NAME, the argument vector in ARGV. + FD_CHILD_LIST is a -1 terminated list of file descriptors not to + close in the child. ATFORK is called in the child right after the + fork; ATFORKVALUE is passed as the first argument and 0 is passed + 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. + + 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 + some special environment variables are set. To let the caller + detect whether the child or the parent continues, the child returns + a CTX of NULL. */ +assuan_error_t +assuan_pipe_connect_ext (assuan_context_t *ctx, + const char *name, const char *const argv[], + int *fd_child_list, + void (*atfork) (void *opaque, int reserved), + void *atforkvalue, unsigned int flags) +{ + if ((flags & 1)) + { +#ifdef HAVE_W32_SYSTEM + return _assuan_error (ASSUAN_Not_Implemented); +#else + return socketpair_connect (ctx, name, argv, fd_child_list, + atfork, atforkvalue); +#endif + } + else + return pipe_connect (ctx, name, argv, fd_child_list, atfork, atforkvalue); +} + diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-pipe-server.c b/libkdenetwork/libgpgme-copy/assuan/assuan-pipe-server.c new file mode 100644 index 000000000..f88516143 --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-pipe-server.c @@ -0,0 +1,187 @@ +/* assuan-pipe-server.c - Assuan server working over a pipe + * Copyright (C) 2001, 2002 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#ifdef HAVE_W32_SYSTEM +#include <windows.h> +#include <fcntl.h> +#endif + +#include "assuan-defs.h" + + +static void +deinit_pipe_server (assuan_context_t ctx) +{ + /* nothing to do for this simple server */ +} + +static int +accept_connection (assuan_context_t ctx) +{ + /* This is a NOP for a pipe server */ + return 0; +} + +static int +finish_connection (assuan_context_t ctx) +{ + /* This is a NOP for a pipe server */ + return 0; +} + +/* Create a new context. Note that the handlers are set up for a pipe + server/client - this way we don't need extra dummy functions */ +int +_assuan_new_context (assuan_context_t *r_ctx) +{ + static struct assuan_io io = { _assuan_simple_read, + _assuan_simple_write, + 0, 0 }; + + assuan_context_t ctx; + int rc; + + *r_ctx = NULL; + ctx = xtrycalloc (1, sizeof *ctx); + if (!ctx) + return _assuan_error (ASSUAN_Out_Of_Core); + ctx->input_fd = -1; + ctx->output_fd = -1; + + ctx->inbound.fd = -1; + ctx->outbound.fd = -1; + ctx->io = &io; + + ctx->listen_fd = -1; + /* Use the pipe server handler as a default. */ + ctx->deinit_handler = deinit_pipe_server; + ctx->accept_handler = accept_connection; + ctx->finish_handler = finish_connection; + + rc = _assuan_register_std_commands (ctx); + if (rc) + xfree (ctx); + else + *r_ctx = ctx; + return rc; +} + + +/* Returns true if atoi(S) denotes a valid socket. */ +static int +is_valid_socket (const char *s) +{ + struct stat buf; + + if ( fstat (atoi (s), &buf ) ) + return 0; + return S_ISSOCK (buf.st_mode); +} + + +int +assuan_init_pipe_server (assuan_context_t *r_ctx, int filedes[2]) +{ + int rc; + + rc = _assuan_new_context (r_ctx); + if (!rc) + { + assuan_context_t ctx = *r_ctx; + const char *s; + unsigned long ul; + + ctx->is_server = 1; +#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. */ + setmode (filedes[0], O_BINARY); + setmode (filedes[1], O_BINARY); + ctx->inbound.fd = _get_osfhandle (filedes[0]); + ctx->outbound.fd = _get_osfhandle (filedes[1]); +#else + s = getenv ("_assuan_connection_fd"); + if (s && *s && is_valid_socket (s) ) + { + /* Well, we are called with an bi-directional file + descriptor. Prepare for using sendmsg/recvmsg. In this + case we ignore the passed file descriptors. */ + ctx->inbound.fd = ctx->outbound.fd = atoi (s); + _assuan_init_uds_io (ctx); + ctx->deinit_handler = _assuan_uds_deinit; + } + else if (filedes && filedes[0] != -1 && filedes[1] != -1 ) + { + /* Standard pipe server. */ + ctx->inbound.fd = filedes[0]; + ctx->outbound.fd = filedes[1]; + } + else + { + _assuan_release_context (*r_ctx); + *r_ctx = NULL; + return ASSUAN_Problem_Starting_Server; + } +#endif + ctx->pipe_mode = 1; + + s = getenv ("_assuan_pipe_connect_pid"); + if (s && (ul=strtoul (s, NULL, 10)) && ul) + ctx->pid = (pid_t)ul; + else + ctx->pid = (pid_t)-1; + + } + return rc; +} + + +void +_assuan_release_context (assuan_context_t ctx) +{ + if (ctx) + { + xfree (ctx->hello_line); + xfree (ctx->okay_line); + xfree (ctx->cmdtbl); + xfree (ctx); + } +} + +void +assuan_deinit_server (assuan_context_t ctx) +{ + if (ctx) + { + /* We use this function pointer to avoid linking other server + when not needed but still allow for a generic deinit function. */ + ctx->deinit_handler (ctx); + ctx->deinit_handler = NULL; + _assuan_release_context (ctx); + } +} diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-socket-connect.c b/libkdenetwork/libgpgme-copy/assuan/assuan-socket-connect.c new file mode 100644 index 000000000..5953f1c33 --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-socket-connect.c @@ -0,0 +1,184 @@ +/* assuan-socket-connect.c - Assuan socket based client + * Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#ifndef HAVE_W32_SYSTEM +#include <sys/socket.h> +#include <sys/un.h> +#else +#include <windows.h> +#endif + +#include "assuan-defs.h" + +/* Hacks for Slowaris. */ +#ifndef PF_LOCAL +# ifdef PF_UNIX +# define PF_LOCAL PF_UNIX +# else +# define PF_LOCAL AF_UNIX +# endif +#endif +#ifndef AF_LOCAL +# define AF_LOCAL AF_UNIX +#endif + +#ifndef SUN_LEN +# define SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \ + + strlen ((ptr)->sun_path)) +#endif + + +static int +do_finish (assuan_context_t ctx) +{ + if (ctx->inbound.fd != -1) + { + _assuan_close (ctx->inbound.fd); + } + ctx->inbound.fd = -1; + ctx->outbound.fd = -1; + return 0; +} + +static void +do_deinit (assuan_context_t ctx) +{ + do_finish (ctx); +} + + +/* Make a connection to the Unix domain socket NAME and return a new + Assuan context in CTX. SERVER_PID is currently not used but may + become handy in the future. */ +assuan_error_t +assuan_socket_connect (assuan_context_t *r_ctx, + const char *name, pid_t server_pid) +{ + return assuan_socket_connect_ext (r_ctx, name, server_pid, 0); +} + + +/* Make a connection to the Unix domain socket NAME and return a new + Assuan context in CTX. SERVER_PID is currently not used but may + become handy in the future. With flags set to 1 sendmsg and + recvmesg 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 }; + + assuan_error_t err; + assuan_context_t ctx; + int fd; + struct sockaddr_un srvr_addr; + size_t len; + const char *s; + + if (!r_ctx || !name) + return _assuan_error (ASSUAN_Invalid_Value); + *r_ctx = NULL; + + /* 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. */ + s = name; + if (*s && s[1] == ':') + s += 2; + if (*s != DIRSEP_C && *s != '/') + return _assuan_error (ASSUAN_Invalid_Value); + + if (strlen (name)+1 >= sizeof srvr_addr.sun_path) + return _assuan_error (ASSUAN_Invalid_Value); + + err = _assuan_new_context (&ctx); + if (err) + return err; + ctx->deinit_handler = ((flags&1))? _assuan_uds_deinit : do_deinit; + ctx->finish_handler = do_finish; + + fd = _assuan_sock_new (PF_LOCAL, SOCK_STREAM, 0); + if (fd == -1) + { + _assuan_log_printf ("can't create socket: %s\n", strerror (errno)); + _assuan_release_context (ctx); + return _assuan_error (ASSUAN_General_Error); + } + + memset (&srvr_addr, 0, sizeof srvr_addr); + srvr_addr.sun_family = AF_LOCAL; + strncpy (srvr_addr.sun_path, name, sizeof (srvr_addr.sun_path) - 1); + 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) + { + _assuan_log_printf ("can't connect to `%s': %s\n", + name, strerror (errno)); + _assuan_release_context (ctx); + _assuan_close (fd); + return _assuan_error (ASSUAN_Connect_Failed); + } + + ctx->inbound.fd = fd; + ctx->outbound.fd = fd; + ctx->io = &io; + if ((flags&1)) + _assuan_init_uds_io (ctx); + + /* initial handshake */ + { + int okay, off; + + err = _assuan_read_from_server (ctx, &okay, &off); + if (err) + _assuan_log_printf ("can't connect to server: %s\n", + assuan_strerror (err)); + else if (okay != 1) + { + /*LOG ("can't connect to server: `");*/ + _assuan_log_sanitized_string (ctx->inbound.line); + fprintf (assuan_get_assuan_log_stream (), "'\n"); + err = _assuan_error (ASSUAN_Connect_Failed); + } + } + + if (err) + { + assuan_disconnect (ctx); + } + else + *r_ctx = ctx; + return 0; +} + + diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-socket-server.c b/libkdenetwork/libgpgme-copy/assuan/assuan-socket-server.c new file mode 100644 index 000000000..45c227d6d --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-socket-server.c @@ -0,0 +1,187 @@ +/* assuan-socket-server.c - Assuan socket based server + * Copyright (C) 2002 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#ifndef HAVE_W32_SYSTEM +#include <sys/socket.h> +#include <sys/un.h> +#else +#include <windows.h> +#endif + +#include "assuan-defs.h" + +static struct assuan_io io = { _assuan_simple_read, + _assuan_simple_write }; + + +static int +accept_connection_bottom (assuan_context_t ctx) +{ + int fd = ctx->connected_fd; + + ctx->peercred.valid = 0; +#ifdef HAVE_SO_PEERCRED + { + struct ucred cr; + socklen_t cl = sizeof cr; + + if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl)) + { + ctx->peercred.pid = cr.pid; + ctx->peercred.uid = cr.uid; + ctx->peercred.gid = cr.gid; + ctx->peercred.valid = 1; + + /* This overrides any already set PID if the function returns + a valid one. */ + if (cr.pid != (pid_t)-1 && cr.pid) + ctx->pid = cr.pid; + } + } +#endif + + ctx->inbound.fd = fd; + ctx->inbound.eof = 0; + ctx->inbound.linelen = 0; + ctx->inbound.attic.linelen = 0; + ctx->inbound.attic.pending = 0; + + ctx->outbound.fd = fd; + ctx->outbound.data.linelen = 0; + ctx->outbound.data.error = 0; + + ctx->confidential = 0; + + return 0; +} + + +static int +accept_connection (assuan_context_t ctx) +{ + int 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) + { + ctx->os_errno = errno; + return _assuan_error (ASSUAN_Accept_Failed); + } + + ctx->connected_fd = fd; + return accept_connection_bottom (ctx); +} + +static int +finish_connection (assuan_context_t ctx) +{ + if (ctx->inbound.fd != -1) + { + _assuan_close (ctx->inbound.fd); + } + ctx->inbound.fd = -1; + ctx->outbound.fd = -1; + return 0; +} + + +static void +deinit_socket_server (assuan_context_t ctx) +{ + finish_connection (ctx); +} + +/* Initialize a server for the socket LISTEN_FD which has already be + put into listen mode */ +int +assuan_init_socket_server (assuan_context_t *r_ctx, int 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. */ +int +assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd) +{ + return assuan_init_socket_server_ext (r_ctx, fd, 2); +} + + +/* + Flag bits: 0 - use sendmsg/recvmsg to allow descriptor passing + 1 - FD has already been accepted. +*/ +int +assuan_init_socket_server_ext (assuan_context_t *r_ctx, int fd, + unsigned int flags) +{ + assuan_context_t ctx; + int rc; + + *r_ctx = NULL; + ctx = xtrycalloc (1, sizeof *ctx); + if (!ctx) + return _assuan_error (ASSUAN_Out_Of_Core); + 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->inbound.fd = -1; + ctx->outbound.fd = -1; + + if ((flags & 2)) + { + ctx->listen_fd = -1; + ctx->connected_fd = fd; + } + else + { + ctx->listen_fd = fd; + ctx->connected_fd = -1; + } + ctx->deinit_handler = (flags & 1)? _assuan_uds_deinit:deinit_socket_server; + ctx->accept_handler = ((flags & 2) + ? accept_connection_bottom + : accept_connection); + ctx->finish_handler = finish_connection; + + ctx->io = &io; + if ((flags & 1)) + _assuan_init_uds_io (ctx); + + rc = _assuan_register_std_commands (ctx); + if (rc) + xfree (ctx); + else + *r_ctx = ctx; + return rc; +} diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-socket.c b/libkdenetwork/libgpgme-copy/assuan/assuan-socket.c new file mode 100644 index 000000000..6aa570896 --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-socket.c @@ -0,0 +1,148 @@ +/* assuan-socket.c + * Copyright (C) 2004, 2005 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdio.h> +#ifdef HAVE_W32_SYSTEM +#include <windows.h> +#include <io.h> +#else +#include <sys/types.h> +#include <sys/socket.h> +#endif +#include "assuan-defs.h" + +/* Hacks for Slowaris. */ +#ifndef PF_LOCAL +# ifdef PF_UNIX +# define PF_LOCAL PF_UNIX +# else +# define PF_LOCAL AF_UNIX +# endif +#endif +#ifndef AF_LOCAL +# define AF_LOCAL AF_UNIX +#endif + +int +_assuan_close (int fd) +{ +#ifndef HAVE_W32_SYSTEM + return close (fd); +#else + int rc = closesocket (fd); + if (rc && WSAGetLastError () == WSAENOTSOCK) + rc = close (fd); + return rc; +#endif +} + + +int +_assuan_sock_new (int domain, int type, int proto) +{ +#ifndef HAVE_W32_SYSTEM + return socket (domain, type, proto); +#else + if (domain == AF_UNIX || domain == AF_LOCAL) + domain = AF_INET; + return socket (domain, type, proto); +#endif +} + + +int +_assuan_sock_connect (int 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 + if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX) + { + struct sockaddr_in myaddr; + struct sockaddr_un * unaddr; + FILE * fp; + int len = sizeof myaddr; + int rc; + + myaddr.sin_port = 0; + myaddr.sin_family = AF_INET; + myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + + rc = bind (sockfd, (struct sockaddr *)&myaddr, len); + if (rc) + return rc; + rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len); + if (rc) + return rc; + unaddr = (struct sockaddr_un *)addr; + fp = fopen (unaddr->sun_path, "wb"); + if (!fp) + return -1; + fprintf (fp, "%d", myaddr.sin_port); + fclose (fp); + + /* we need this later. */ + unaddr->sun_family = myaddr.sin_family; + unaddr->sun_port = myaddr.sin_port; + unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr; + + return 0; + } + return bind (sockfd, addr, addrlen); +#endif +} + diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-uds.c b/libkdenetwork/libgpgme-copy/assuan/assuan-uds.c new file mode 100644 index 000000000..77945fb50 --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-uds.c @@ -0,0 +1,311 @@ +/* assuan-uds.c - Assuan unix domain socket utilities + * Copyright (C) 2006 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <stddef.h> +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#ifndef HAVE_W32_SYSTEM +#include <sys/socket.h> +#include <sys/un.h> +#else +#include <windows.h> +#endif +#if HAVE_SYS_UIO_H +#include <sys/uio.h> +#endif +#include <unistd.h> +#include <fcntl.h> +#include <string.h> +#include <assert.h> + +#include "assuan-defs.h" + +#ifdef USE_DESCRIPTOR_PASSING +/* Provide replacement for missing CMSG maccros. We assume that + size_t matches the alignment requirement. */ +#define MY_ALIGN(n) ((((n))+ sizeof(size_t)-1) & (size_t)~(sizeof(size_t)-1)) +#ifndef CMSG_SPACE +#define CMSG_SPACE(n) (MY_ALIGN(sizeof(struct cmsghdr)) + MY_ALIGN((n))) +#endif +#ifndef CMSG_LEN +#define CMSG_LEN(n) (MY_ALIGN(sizeof(struct cmsghdr)) + (n)) +#endif +#ifndef CMSG_FIRSTHDR +#define CMSG_FIRSTHDR(mhdr) \ + ((size_t)(mhdr)->msg_controllen >= sizeof (struct cmsghdr) \ + ? (struct cmsghdr*) (mhdr)->msg_control : (struct cmsghdr*)NULL) +#endif +#ifndef CMSG_DATA +#define CMSG_DATA(cmsg) ((unsigned char*)((struct cmsghdr*)(cmsg)+1)) +#endif +#endif /*USE_DESCRIPTOR_PASSING*/ + + +/* Read from a unix domain socket using sendmsg. + + FIXME: We don't need the buffering. It is a leftover from the time + when we used datagrams. */ +static ssize_t +uds_reader (assuan_context_t ctx, void *buf, size_t buflen) +{ + int len = ctx->uds.buffersize; + +#ifndef HAVE_W32_SYSTEM + if (!ctx->uds.bufferallocated) + { + ctx->uds.buffer = xtrymalloc (2048); + if (!ctx->uds.buffer) + return _assuan_error (ASSUAN_Out_Of_Core); + ctx->uds.bufferallocated = 2048; + } + + while (!len) /* No data is buffered. */ + { + struct msghdr msg; + struct iovec iovec; +#ifdef USE_DESCRIPTOR_PASSING + union { + struct cmsghdr cm; + char control[CMSG_SPACE(sizeof (int))]; + } control_u; + struct cmsghdr *cmptr; +#endif /*USE_DESCRIPTOR_PASSING*/ + + memset (&msg, 0, sizeof (msg)); + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iovec; + msg.msg_iovlen = 1; + iovec.iov_base = ctx->uds.buffer; + iovec.iov_len = ctx->uds.bufferallocated; +#ifdef USE_DESCRIPTOR_PASSING + msg.msg_control = control_u.control; + msg.msg_controllen = sizeof (control_u.control); +#endif + + len = _assuan_simple_recvmsg (ctx, &msg); + if (len < 0) + return -1; + + ctx->uds.buffersize = len; + ctx->uds.bufferoffset = 0; + +#ifdef USE_DESCRIPTOR_PASSING + cmptr = CMSG_FIRSTHDR (&msg); + if (cmptr && cmptr->cmsg_len == CMSG_LEN (sizeof(int))) + { + if (cmptr->cmsg_level != SOL_SOCKET + || cmptr->cmsg_type != SCM_RIGHTS) + _assuan_log_printf ("unexpected ancillary data received\n"); + else + { + int fd = *((int*)CMSG_DATA (cmptr)); + + if (ctx->uds.pendingfdscount >= DIM (ctx->uds.pendingfds)) + { + _assuan_log_printf ("too many descriptors pending - " + "closing received descriptor %d\n", fd); + _assuan_close (fd); + } + else + ctx->uds.pendingfds[ctx->uds.pendingfdscount++] = fd; + } + } +#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. */ + len = buflen; + + memcpy (buf, ctx->uds.buffer + ctx->uds.bufferoffset, len); + ctx->uds.buffersize -= len; + assert (ctx->uds.buffersize >= 0); + ctx->uds.bufferoffset += len; + assert (ctx->uds.bufferoffset <= ctx->uds.bufferallocated); + + return len; +} + + +/* Write to the domain server. */ +static ssize_t +uds_writer (assuan_context_t ctx, const void *buf, size_t buflen) +{ +#ifndef HAVE_W32_SYSTEM + struct msghdr msg; + struct iovec iovec; + ssize_t len; + + memset (&msg, 0, sizeof (msg)); + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iovlen = 1; + msg.msg_iov = &iovec; + iovec.iov_base = (void*)buf; + 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; +} + + +static assuan_error_t +uds_sendfd (assuan_context_t ctx, int fd) +{ +#ifdef USE_DESCRIPTOR_PASSING + struct msghdr msg; + struct iovec iovec; + union { + struct cmsghdr cm; + char control[CMSG_SPACE(sizeof (int))]; + } control_u; + struct cmsghdr *cmptr; + int len; + char buffer[80]; + + /* We need to send some real data so that a read won't return 0 + which will be taken as an EOF. It also helps with debugging. */ + snprintf (buffer, sizeof(buffer)-1, "# descriptor %d is in flight\n", fd); + buffer[sizeof(buffer)-1] = 0; + + memset (&msg, 0, sizeof (msg)); + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iovlen = 1; + msg.msg_iov = &iovec; + iovec.iov_base = buffer; + iovec.iov_len = strlen (buffer); + + msg.msg_control = control_u.control; + msg.msg_controllen = sizeof (control_u.control); + cmptr = CMSG_FIRSTHDR (&msg); + cmptr->cmsg_len = CMSG_LEN(sizeof(int)); + cmptr->cmsg_level = SOL_SOCKET; + cmptr->cmsg_type = SCM_RIGHTS; + *((int*)CMSG_DATA (cmptr)) = fd; + + len = _assuan_simple_sendmsg (ctx, &msg); + if (len < 0) + { + _assuan_log_printf ("uds_sendfd: %s\n", strerror (errno)); + return _assuan_error (ASSUAN_Write_Error); + } + else + return 0; +#else + return _assuan_error (ASSUAN_Not_Implemented); +#endif +} + + +static assuan_error_t +uds_receivefd (assuan_context_t ctx, int *fd) +{ +#ifdef USE_DESCRIPTOR_PASSING + int i; + + if (!ctx->uds.pendingfdscount) + { + _assuan_log_printf ("no pending file descriptors!\n"); + return _assuan_error (ASSUAN_General_Error); + } + assert (ctx->uds.pendingfdscount <= DIM(ctx->uds.pendingfds)); + + *fd = ctx->uds.pendingfds[0]; + for (i=1; i < ctx->uds.pendingfdscount; i++) + ctx->uds.pendingfds[i-1] = ctx->uds.pendingfds[i]; + ctx->uds.pendingfdscount--; + + return 0; +#else + return _assuan_error (ASSUAN_Not_Implemented); +#endif +} + + +/* Close all pending fds. */ +void +_assuan_uds_close_fds (assuan_context_t ctx) +{ + int i; + + for (i = 0; i < ctx->uds.pendingfdscount; i++) + _assuan_close (ctx->uds.pendingfds[i]); + ctx->uds.pendingfdscount = 0; +} + +/* Deinitialize the unix domain socket I/O functions. */ +void +_assuan_uds_deinit (assuan_context_t ctx) +{ + /* First call the finish_handler which should close descriptors etc. */ + ctx->finish_handler (ctx); + + if (ctx->uds.buffer) + { + assert (ctx->uds.bufferallocated); + ctx->uds.bufferallocated = 0; + xfree (ctx->uds.buffer); + } + + _assuan_uds_close_fds (ctx); +} + + +/* Helper function to initialize a context for domain I/O. */ +void +_assuan_init_uds_io (assuan_context_t ctx) +{ + static struct assuan_io io = { uds_reader, uds_writer, + uds_sendfd, uds_receivefd }; + + ctx->io = &io; + ctx->uds.buffer = 0; + ctx->uds.bufferoffset = 0; + ctx->uds.buffersize = 0; + ctx->uds.bufferallocated = 0; + ctx->uds.pendingfdscount = 0; +} + diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan-util.c b/libkdenetwork/libgpgme-copy/assuan/assuan-util.c new file mode 100644 index 000000000..d12277fcc --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan-util.c @@ -0,0 +1,171 @@ +/* assuan-util.c - Utility functions for Assuan + * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include <config.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> + +#include "assuan-defs.h" + +static void *(*alloc_func)(size_t n) = malloc; +static void *(*realloc_func)(void *p, size_t n) = realloc; +static void (*free_func)(void*) = free; + +void +assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), + void *(*new_realloc_func)(void *p, size_t n), + void (*new_free_func)(void*) ) +{ + alloc_func = new_alloc_func; + realloc_func = new_realloc_func; + free_func = new_free_func; +} + +void * +_assuan_malloc (size_t n) +{ + return alloc_func (n); +} + +void * +_assuan_realloc (void *a, size_t n) +{ + return realloc_func (a, n); +} + +void * +_assuan_calloc (size_t n, size_t m) +{ + void *p; + size_t nbytes; + + nbytes = n * m; + if (m && nbytes / m != n) + { + errno = ENOMEM; + return NULL; + } + + p = _assuan_malloc (nbytes); + if (p) + memset (p, 0, nbytes); + return p; +} + +void +_assuan_free (void *p) +{ + if (p) + free_func (p); +} + + +/* Store the error in the context so that the error sending function + can take out a descriptive text. Inside the assuan code, use the + macro set_error instead of this function. */ +int +assuan_set_error (assuan_context_t ctx, int err, const char *text) +{ + ctx->err_no = err; + ctx->err_str = text; + return err; +} + +void +assuan_set_pointer (assuan_context_t ctx, void *pointer) +{ + if (ctx) + ctx->user_pointer = pointer; +} + +void * +assuan_get_pointer (assuan_context_t ctx) +{ + return ctx? ctx->user_pointer : NULL; +} + + +void +assuan_begin_confidential (assuan_context_t ctx) +{ + if (ctx) + { + ctx->confidential = 1; + } +} + +void +assuan_end_confidential (assuan_context_t ctx) +{ + if (ctx) + { + ctx->confidential = 0; + } +} + + +void +assuan_set_io_monitor (assuan_context_t ctx, + unsigned int (*monitor)(assuan_context_t ctx, + int direction, + const char *line, + size_t linelen)) +{ + if (ctx) + { + ctx->io_monitor = monitor; + } +} + + + + +/* For context CTX, set the flag FLAG to VALUE. Values for flags + are usually 1 or 0 but certain flags might allow for other values; + see the description of the type assuan_flag_t for details. */ +void +assuan_set_flag (assuan_context_t ctx, assuan_flag_t flag, int value) +{ + if (!ctx) + return; + switch (flag) + { + case ASSUAN_NO_WAITPID: ctx->flags.no_waitpid = value; break; + } +} + +/* Return the VALUE of FLAG in context CTX. */ +int +assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag) +{ + if (!ctx) + return 0; + switch (flag) + { + case ASSUAN_NO_WAITPID: return ctx->flags.no_waitpid; + } + return 0; +} + + diff --git a/libkdenetwork/libgpgme-copy/assuan/assuan.h b/libkdenetwork/libgpgme-copy/assuan/assuan.h new file mode 100644 index 000000000..cdf0445ab --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/assuan.h @@ -0,0 +1,565 @@ +/* assuan.c - Definitions for the Assuan IPC library + * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifndef ASSUAN_H +#define ASSUAN_H + +#include <stdio.h> +#include <sys/types.h> +#include <unistd.h> + + +/* To use this file with libraries the following macros are useful: + + #define _ASSUAN_EXT_SYM_PREFIX _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. + + The follwing macros are used internally in the implementation of + libassuan: + + #define _ASSUAN_NO_PTH + + This avoids inclusion of special GNU Pth hacks. + + #define _ASSUAN_NO_FIXED_SIGNALS + + This disables changing of certain signal handler; i.e. SIGPIPE. + + #define _ASSUAN_USE_DOUBLE_FORK + + Use a double fork approach when connecting to a server through + a pipe. + */ +/**** Begin GPGME specific modifications. ******/ +#define _ASSUAN_EXT_SYM_PREFIX _gpgme_ +#define _ASSUAN_NO_PTH +#define _ASSUAN_NO_FIXED_SIGNALS +#define _ASSUAN_USE_DOUBLE_FORK + +#ifdef _ASSUAN_IN_GPGME_BUILD_ASSUAN +int _gpgme_io_read (int fd, void *buffer, size_t count); +int _gpgme_io_write (int fd, const void *buffer, size_t count); +ssize_t _gpgme_ath_waitpid (pid_t pid, int *status, int options); +#ifdef HAVE_W32_SYSTEM +int _gpgme_ath_accept (int s, void *addr, int *length_ptr); +#else /*!HAVE_W32_SYSTEM*/ +struct sockaddr; +struct msghdr; +ssize_t _gpgme_ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, + struct timeval *timeout); +int _gpgme_ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr); +int _gpgme_ath_connect (int s, struct sockaddr *addr, socklen_t length); +int _gpgme_ath_sendmsg (int s, const struct msghdr *msg, int flags); +int _gpgme_ath_recvmsg (int s, struct msghdr *msg, int flags); +int _gpgme_io_sendmsg (int sock, const struct msghdr *msg, int flags); +int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags); +#endif /*!HAVE_W32_SYSTEM*/ + +#define read _gpgme_io_read +#define write _gpgme_io_write +#define waitpid _gpgme_ath_waitpid +#define select _gpgme_ath_select +#define accept _gpgme_ath_accept +#define connect _gpgme_ath_connect +#define sendmsg _gpgme_io_sendmsg +#define recvmsg _gpgme_io_recvmsg +#endif /*_ASSUAN_IN_GPGME_BUILD_ASSUAN*/ +/**** End GPGME specific modifications. ******/ + + +#ifdef _ASSUAN_EXT_SYM_PREFIX +#define _ASSUAN_PREFIX1(x,y) x ## y +#define _ASSUAN_PREFIX2(x,y) _ASSUAN_PREFIX1(x,y) +#define _ASSUAN_PREFIX(x) _ASSUAN_PREFIX2(_ASSUAN_EXT_SYM_PREFIX,x) +#define assuan_ _ASSUAN_PREFIX(assuan_) +#define assuan_register_command _ASSUAN_PREFIX(assuan_register_command) +#define assuan_register_post_cmd_notify \ + _ASSUAN_PREFIX(assuan_register_post_cmd_notify) +#define assuan_register_bye_notify _ASSUAN_PREFIX(assuan_register_bye_notify) +#define assuan_register_reset_notify \ + _ASSUAN_PREFIX(assuan_register_reset_notify) +#define assuan_register_cancel_notify \ + _ASSUAN_PREFIX(assuan_register_cancel_notify) +#define assuan_register_input_notify \ + _ASSUAN_PREFIX(assuan_register_input_notify) +#define assuan_register_output_notify \ + _ASSUAN_PREFIX(assuan_register_output_notify) +#define assuan_register_option_handler \ + _ASSUAN_PREFIX(assuan_register_option_handler) +#define assuan_process _ASSUAN_PREFIX(assuan_process) +#define assuan_process_next _ASSUAN_PREFIX(assuan_process_next) +#define assuan_get_active_fds _ASSUAN_PREFIX(assuan_get_active_fds) +#define assuan_get_data_fp _ASSUAN_PREFIX(assuan_get_data_fp) +#define assuan_set_okay_line _ASSUAN_PREFIX(assuan_set_okay_line) +#define assuan_write_status _ASSUAN_PREFIX(assuan_write_status) +#define assuan_command_parse_fd _ASSUAN_PREFIX(assuan_command_parse_fd) +#define assuan_set_hello_line _ASSUAN_PREFIX(assuan_set_hello_line) +#define assuan_accept _ASSUAN_PREFIX(assuan_accept) +#define assuan_get_input_fd _ASSUAN_PREFIX(assuan_get_input_fd) +#define assuan_get_output_fd _ASSUAN_PREFIX(assuan_get_output_fd) +#define assuan_close_input_fd _ASSUAN_PREFIX(assuan_close_input_fd) +#define assuan_close_output_fd _ASSUAN_PREFIX(assuan_close_output_fd) +#define assuan_init_pipe_server _ASSUAN_PREFIX(assuan_init_pipe_server) +#define assuan_deinit_server _ASSUAN_PREFIX(assuan_deinit_server) +#define assuan_init_socket_server _ASSUAN_PREFIX(assuan_init_socket_server) +#define assuan_init_connected_socket_server \ + _ASSUAN_PREFIX(assuan_init_connected_socket_server) +#define assuan_init_socket_server_ext \ + _ASSUAN_PREFIX(assuan_init_socket_server_ext) +#define assuan_pipe_connect _ASSUAN_PREFIX(assuan_pipe_connect) +#define assuan_pipe_connect_ext _ASSUAN_PREFIX(assuan_pipe_connect_ext) +#define assuan_socket_connect _ASSUAN_PREFIX(assuan_socket_connect) +#define assuan_socket_connect_ext _ASSUAN_PREFIX(assuan_socket_connect_ext) +#define assuan_disconnect _ASSUAN_PREFIX(assuan_disconnect) +#define assuan_get_pid _ASSUAN_PREFIX(assuan_get_pid) +#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_read_line _ASSUAN_PREFIX(assuan_read_line) +#define assuan_pending_line _ASSUAN_PREFIX(assuan_pending_line) +#define assuan_write_line _ASSUAN_PREFIX(assuan_write_line) +#define assuan_send_data _ASSUAN_PREFIX(assuan_send_data) +#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_log_stream _ASSUAN_PREFIX(assuan_set_log_stream) +#define assuan_set_error _ASSUAN_PREFIX(assuan_set_error) +#define assuan_set_pointer _ASSUAN_PREFIX(assuan_set_pointer) +#define assuan_get_pointer _ASSUAN_PREFIX(assuan_get_pointer) +#define assuan_set_io_monitor _ASSUAN_PREFIX(assuan_set_io_monitor) +#define assuan_begin_confidential _ASSUAN_PREFIX(assuan_begin_confidential) +#define assuan_end_confidential _ASSUAN_PREFIX(assuan_end_confidential) +#define assuan_strerror _ASSUAN_PREFIX(assuan_strerror) +#define assuan_set_assuan_err_source \ + _ASSUAN_PREFIX(assuan_set_assuan_err_source) +#define assuan_set_assuan_log_stream \ + _ASSUAN_PREFIX(assuan_set_assuan_log_stream) +#define assuan_get_assuan_log_stream \ + _ASSUAN_PREFIX(assuan_get_assuan_log_stream) +#define assuan_get_assuan_log_prefix \ + _ASSUAN_PREFIX(assuan_get_assuan_log_prefix) +#define assuan_set_flag _ASSUAN_PREFIX(assuan_set_flag) +#define assuan_get_flag _ASSUAN_PREFIX(assuan_get_flag) + +/* And now the internal functions, argh... */ +#define _assuan_read_line _ASSUAN_PREFIX(_assuan_read_line) +#define _assuan_cookie_write_data _ASSUAN_PREFIX(_assuan_cookie_write_data) +#define _assuan_cookie_write_flush _ASSUAN_PREFIX(_assuan_cookie_write_flush) +#define _assuan_read_from_server _ASSUAN_PREFIX(_assuan_read_from_server) +#define _assuan_domain_init _ASSUAN_PREFIX(_assuan_domain_init) +#define _assuan_register_std_commands \ + _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_new_context _ASSUAN_PREFIX(_assuan_new_context) +#define _assuan_release_context _ASSUAN_PREFIX(_assuan_release_context) +#define _assuan_malloc _ASSUAN_PREFIX(_assuan_malloc) +#define _assuan_realloc _ASSUAN_PREFIX(_assuan_realloc) +#define _assuan_calloc _ASSUAN_PREFIX(_assuan_calloc) +#define _assuan_free _ASSUAN_PREFIX(_assuan_free) +#define _assuan_log_print_buffer _ASSUAN_PREFIX(_assuan_log_print_buffer) +#define _assuan_log_sanitized_string \ + _ASSUAN_PREFIX(_assuan_log_sanitized_string) +#define _assuan_log_printf _ASSUAN_PREFIX(_assuan_log_printf) +#define _assuan_set_default_log_stream \ + _ASSUAN_PREFIX(_assuan_set_default_log_stream) +#define _assuan_w32_strerror _ASSUAN_PREFIX(_assuan_w32_strerror) +#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) + +#endif /*_ASSUAN_EXT_SYM_PREFIX*/ + + +#ifdef __cplusplus +extern "C" +{ +#if 0 +} +#endif +#endif + + +/* Check for compiler features. */ +#if __GNUC__ +#define _ASSUAN_GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +#if _ASSUAN_GCC_VERSION > 30100 +#define _ASSUAN_DEPRECATED __attribute__ ((__deprecated__)) +#endif +#endif +#ifndef _ASSUAN_DEPRECATED +#define _ASSUAN_DEPRECATED +#endif + + +/* Assuan error codes. These are only used by old applications or + those applications which won't make use of libgpg-error. */ +#ifndef _ASSUAN_ONLY_GPG_ERRORS +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_No_Error 0 +#endif +#define ASSUAN_General_Error 1 +#define ASSUAN_Out_Of_Core 2 +#define ASSUAN_Invalid_Value 3 +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_Timeout 4 +#endif +#define ASSUAN_Read_Error 5 +#define ASSUAN_Write_Error 6 +#define ASSUAN_Problem_Starting_Server 7 +#define ASSUAN_Not_A_Server 8 +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_Not_A_Client 9 +#endif +#define ASSUAN_Nested_Commands 10 +#define ASSUAN_Invalid_Response 11 +#define ASSUAN_No_Data_Callback 12 +#define ASSUAN_No_Inquire_Callback 13 +#define ASSUAN_Connect_Failed 14 +#define ASSUAN_Accept_Failed 15 + + /* Error codes above 99 are meant as status codes */ +#define ASSUAN_Not_Implemented 100 +#define ASSUAN_Server_Fault 101 +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_Invalid_Command 102 +#endif +#define ASSUAN_Unknown_Command 103 +#define ASSUAN_Syntax_Error 104 +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_Parameter_Error 105 +#endif +#define ASSUAN_Parameter_Conflict 106 +#define ASSUAN_Line_Too_Long 107 +#define ASSUAN_Line_Not_Terminated 108 +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_No_Input 109 +#define ASSUAN_No_Output 110 +#endif +#define ASSUAN_Canceled 111 +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_Unsupported_Algorithm 112 +#define ASSUAN_Server_Resource_Problem 113 +#define ASSUAN_Server_IO_Error 114 +#define ASSUAN_Server_Bug 115 +#define ASSUAN_No_Data_Available 116 +#define ASSUAN_Invalid_Data 117 +#endif +#define ASSUAN_Unexpected_Command 118 +#define ASSUAN_Too_Much_Data 119 +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_Inquire_Unknown 120 +#define ASSUAN_Inquire_Error 121 +#define ASSUAN_Invalid_Option 122 +#define ASSUAN_Invalid_Index 123 +#define ASSUAN_Unexpected_Status 124 +#define ASSUAN_Unexpected_Data 125 +#define ASSUAN_Invalid_Status 126 +#define ASSUAN_Locale_Problem 127 +#endif +#define ASSUAN_Not_Confirmed 128 + + /* Warning: Don't use the Error codes, below they are deprecated. */ +#ifndef _ASSUAN_IN_LIBASSUAN +#define ASSUAN_Bad_Certificate 201 +#define ASSUAN_Bad_Certificate_Chain 202 +#define ASSUAN_Missing_Certificate 203 +#define ASSUAN_Bad_Signature 204 +#define ASSUAN_No_Agent 205 +#define ASSUAN_Agent_Error 206 +#define ASSUAN_No_Public_Key 207 +#define ASSUAN_No_Secret_Key 208 +#define ASSUAN_Invalid_Name 209 + +#define ASSUAN_Cert_Revoked 301 +#define ASSUAN_No_CRL_For_Cert 302 +#define ASSUAN_CRL_Too_Old 303 +#define ASSUAN_Not_Trusted 304 + +#define ASSUAN_Card_Error 401 +#define ASSUAN_Invalid_Card 402 +#define ASSUAN_No_PKCS15_App 403 +#define ASSUAN_Card_Not_Present 404 +#define ASSUAN_Invalid_Id 405 + + /* Error codes in the range 1000 to 9999 may be used by applications + at their own discretion. */ +#define ASSUAN_USER_ERROR_FIRST 1000 +#define ASSUAN_USER_ERROR_LAST 9999 +#endif + +typedef int assuan_error_t; + +typedef assuan_error_t AssuanError _ASSUAN_DEPRECATED; + +/* This is a list of pre-registered ASSUAN commands */ +/* Note, these command IDs are now deprectated and solely exists for + compatibility reasons. */ +typedef enum +{ + ASSUAN_CMD_NOP = 0, + ASSUAN_CMD_CANCEL, /* cancel the current request */ + ASSUAN_CMD_BYE, + ASSUAN_CMD_AUTH, + ASSUAN_CMD_RESET, + ASSUAN_CMD_OPTION, + ASSUAN_CMD_DATA, + ASSUAN_CMD_END, + ASSUAN_CMD_INPUT, + ASSUAN_CMD_OUTPUT, + + ASSUAN_CMD_USER = 256 /* Other commands should be used with this offset*/ +} AssuanCommand; + + +#else /*!_ASSUAN_ONLY_GPG_ERRORS*/ + +typedef int assuan_error_t; + +#endif /*!_ASSUAN_ONLY_GPG_ERRORS*/ + + +/* Definitions of flags for assuan_set_flag(). */ +typedef enum + { + /* When using a pipe server, by default Assuan will wait for the + forked process to die in assuan_disconnect. In certain cases + 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_flag_t; + +#define ASSUAN_LINELENGTH 1002 /* 1000 + [CR,]LF */ + +struct assuan_context_s; +typedef struct assuan_context_s *assuan_context_t; +#ifndef _ASSUAN_ONLY_GPG_ERRORS +typedef struct assuan_context_s *ASSUAN_CONTEXT _ASSUAN_DEPRECATED; +#endif /*_ASSUAN_ONLY_GPG_ERRORS*/ + +/*-- assuan-handler.c --*/ +int assuan_register_command (assuan_context_t ctx, + const char *cmd_string, + int (*handler)(assuan_context_t, char *)); +int assuan_register_post_cmd_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, int)); +int assuan_register_bye_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)); +int assuan_register_reset_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)); +int assuan_register_cancel_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)); +int assuan_register_input_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, const char *)); +int assuan_register_output_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, const char *)); + +int assuan_register_option_handler (assuan_context_t ctx, + int (*fnc)(assuan_context_t, + const char*, const char*)); + +int assuan_process (assuan_context_t ctx); +int assuan_process_next (assuan_context_t ctx); +int assuan_get_active_fds (assuan_context_t ctx, int what, + int *fdarray, int fdarraysize); + + +FILE *assuan_get_data_fp (assuan_context_t ctx); +assuan_error_t assuan_set_okay_line (assuan_context_t ctx, const char *line); +assuan_error_t assuan_write_status (assuan_context_t ctx, + const char *keyword, const char *text); + +/* Negotiate a file descriptor. If LINE contains "FD=N", returns N + assuming a local file descriptor. If LINE contains "FD" reads a + file descriptor via CTX and stores it in *RDF (the CTX must be + capable of passing file descriptors). */ +assuan_error_t assuan_command_parse_fd (assuan_context_t ctx, char *line, + int *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_error_t assuan_close_input_fd (assuan_context_t ctx); +assuan_error_t assuan_close_output_fd (assuan_context_t ctx); + + +/*-- assuan-pipe-server.c --*/ +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_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, + unsigned int flags); + +/*-- assuan-pipe-connect.c --*/ +assuan_error_t assuan_pipe_connect (assuan_context_t *ctx, + const char *name, + const char *const argv[], + int *fd_child_list); +assuan_error_t assuan_pipe_connect2 (assuan_context_t *ctx, + const char *name, + const char *const argv[], + int *fd_child_list, + void (*atfork) (void*, int), + void *atforkvalue) _ASSUAN_DEPRECATED; +assuan_error_t assuan_pipe_connect_ext (assuan_context_t *ctx, + const char *name, + const char *const argv[], + int *fd_child_list, + void (*atfork) (void *, int), + void *atforkvalue, + unsigned int flags); + +/*-- assuan-socket-connect.c --*/ +assuan_error_t assuan_socket_connect (assuan_context_t *ctx, + const char *name, + pid_t server_pid); +assuan_error_t assuan_socket_connect_ext (assuan_context_t *ctx, + const char *name, + pid_t server_pid, + unsigned int flags); + +/*-- assuan-connect.c --*/ +void assuan_disconnect (assuan_context_t ctx); +pid_t assuan_get_pid (assuan_context_t ctx); +assuan_error_t assuan_get_peercred (assuan_context_t ctx, + pid_t *pid, uid_t *uid, gid_t *gid); + +/*-- assuan-client.c --*/ +assuan_error_t +assuan_transact (assuan_context_t ctx, + const char *command, + int (*data_cb)(void *, const void *, size_t), + void *data_cb_arg, + int (*inquire_cb)(void*, const char *), + void *inquire_cb_arg, + int (*status_cb)(void*, const char *), + void *status_cb_arg); + + +/*-- assuan-inquire.c --*/ +assuan_error_t assuan_inquire (assuan_context_t ctx, const char *keyword, + unsigned char **r_buffer, size_t *r_length, + size_t maxlen); + +/*-- assuan-buffer.c --*/ +assuan_error_t assuan_read_line (assuan_context_t ctx, + char **line, size_t *linelen); +int assuan_pending_line (assuan_context_t ctx); +assuan_error_t assuan_write_line (assuan_context_t ctx, const char *line ); +assuan_error_t assuan_send_data (assuan_context_t ctx, + const void *buffer, size_t length); + +/* 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-util.c --*/ +void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), + void *(*new_realloc_func)(void *p, size_t n), + void (*new_free_func)(void*) ); +void assuan_set_log_stream (assuan_context_t ctx, FILE *fp); +int assuan_set_error (assuan_context_t ctx, int err, const char *text); +void assuan_set_pointer (assuan_context_t ctx, void *pointer); +void *assuan_get_pointer (assuan_context_t ctx); + +void assuan_begin_confidential (assuan_context_t ctx); +void assuan_end_confidential (assuan_context_t ctx); + +void assuan_set_io_monitor (assuan_context_t ctx, + unsigned int (*monitor)(assuan_context_t ctx, + int direction, + const char *line, + size_t linelen)); + +/* For context CTX, set the flag FLAG to VALUE. Values for flags + are usually 1 or 0 but certain flags might allow for other values; + see the description of the type assuan_flag_t for details. */ +void assuan_set_flag (assuan_context_t ctx, assuan_flag_t flag, int value); + +/* Return the VALUE of FLAG in context CTX. */ +int assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag); + + +/*-- assuan-errors.c --*/ + +#ifndef _ASSUAN_ONLY_GPG_ERRORS +/* Return a string describing the assuan error. The use of this + function is deprecated; it is better to call + assuan_set_assuan_err_source once and then make use libgpg-error. */ +const char *assuan_strerror (assuan_error_t err); +#endif /*_ASSUAN_ONLY_GPG_ERRORS*/ + +/* Enable gpg-error style error codes. ERRSOURCE is one of gpg-error + sources. Note, that this function is not thread-safe and should be + used right at startup. Switching back to the old style mode is not + supported. */ +void assuan_set_assuan_err_source (int errsource); + +/*-- assuan-logging.c --*/ + +/* 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 + context. Note, that this function is not thread-safe and should + in general be used right at startup. */ +extern void assuan_set_assuan_log_stream (FILE *fp); + +/* Return the stream which is currently being using for global logging. */ +extern FILE *assuan_get_assuan_log_stream (void); + +/* Set the prefix to be used at the start of a line emitted by assuan + on the log stream. The default is the empty string. Note, that + this function is not thread-safe and should in general be used + right at startup. */ +void assuan_set_assuan_log_prefix (const char *text); + +/* Return a prefix to be used at the start of a line emitted by assuan + on the log stream. The default implementation returns the empty + string, i.e. "" */ +const char *assuan_get_assuan_log_prefix (void); + +#ifdef __cplusplus +} +#endif +#endif /* ASSUAN_H */ diff --git a/libkdenetwork/libgpgme-copy/assuan/funopen.c b/libkdenetwork/libgpgme-copy/assuan/funopen.c new file mode 100644 index 000000000..ac31007a6 --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/funopen.c @@ -0,0 +1,64 @@ +/* funopen.c - Replacement for funopen. + * Copyright (C) 2003, 2005 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Assuan is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> + + +/* Replacement for the *BSD function: + + FILE *funopen (void *cookie, + int (*readfn)(void *, char *, int), + int (*writefn)(void *, const char *, int), + fpos_t (*seekfn)(void *, fpos_t, int), + int (*closefn)(void *)); + + The functions to provide my either be NULL if not required or + similar to the unistd function with the exception of using the + cookie instead of the fiel descripor. +*/ + + +#ifdef HAVE_FOPENCOOKIE +FILE * +_assuan_funopen(void *cookie, + cookie_read_function_t *readfn, + cookie_write_function_t *writefn, + cookie_seek_function_t *seekfn, + cookie_close_function_t *closefn) +{ + cookie_io_functions_t io = { NULL }; + + io.read = readfn; + io.write = writefn; + io.seek = seekfn; + io.close = closefn; + + return fopencookie (cookie, + readfn ? ( writefn ? "rw" : "r" ) + : ( writefn ? "w" : ""), io); +} +#else +#error No known way to implement funopen. +#endif diff --git a/libkdenetwork/libgpgme-copy/assuan/mkerrors b/libkdenetwork/libgpgme-copy/assuan/mkerrors new file mode 100755 index 000000000..57485411a --- /dev/null +++ b/libkdenetwork/libgpgme-copy/assuan/mkerrors @@ -0,0 +1,228 @@ +#!/bin/sh +# mkerrors - Extract error strings from assuan.h +# and create C source for assuan_strerror +# Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. +# +# This file is part of Assuan. +# +# Assuan is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of +# the License, or (at your option) any later version. +# +# Assuan is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +cat <<EOF +/* Generated automatically by mkerrors */ +/* Do not edit! See mkerrors for copyright notice. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <assert.h> +#include <errno.h> + +#undef _ASSUAN_IN_LIBASSUAN /* undef to get all error codes. */ +#include "assuan.h" + +/* If true the modern gpg-error style error codes are used in the + API. */ +static unsigned int err_source; + +/* Enable gpg-error style error codes. ERRSOURCE is one of gpg-error + sources. Note, that this function is not thread-safe and should be + used right at startup. Switching back to the old style mode is not + supported. */ +void +assuan_set_assuan_err_source (int errsource) +{ + errsource &= 0xff; + err_source = errsource? errsource : 31 /*GPG_ERR_SOURCE_ANY*/; +} + + +/* Helper to map old style Assuan error codes to gpg-error codes. + This is used internally to keep an compatible ABI. */ +assuan_error_t +_assuan_error (int oldcode) +{ + unsigned int n; + + if (!err_source) + return (oldcode & 0x00ffffff); /* Make sure that the gpg-error + source part is cleared. */ + + switch (oldcode) + { + case ASSUAN_General_Error: n = 257; break; + case ASSUAN_Accept_Failed: n = 258; break; + case ASSUAN_Connect_Failed: n = 259; break; + case ASSUAN_Invalid_Response: n = 260; break; + case ASSUAN_Invalid_Value: n = 261; break; + case ASSUAN_Line_Not_Terminated: n = 262; break; + case ASSUAN_Line_Too_Long: n = 263; break; + case ASSUAN_Nested_Commands: n = 264; break; + case ASSUAN_No_Data_Callback: n = 265; break; + case ASSUAN_No_Inquire_Callback: n = 266; break; + case ASSUAN_Not_A_Server: n = 267; break; + case ASSUAN_Not_Implemented: n = 69; break; + case ASSUAN_Parameter_Conflict: n = 280; break; + case ASSUAN_Problem_Starting_Server: n = 269; break; + case ASSUAN_Server_Fault: n = 80; break; + case ASSUAN_Syntax_Error: n = 276; break; + case ASSUAN_Too_Much_Data: n = 273; break; + case ASSUAN_Unexpected_Command: n = 274; break; + case ASSUAN_Unknown_Command: n = 275; break; + case ASSUAN_Canceled: n = 277; break; + case ASSUAN_No_Secret_Key: n = 17; break; + case ASSUAN_Not_Confirmed: n = 114; break; + + case ASSUAN_Read_Error: + switch (errno) + { + case 0: n = 16381; /*GPG_ERR_MISSING_ERRNO*/ break; + default: n = 270; /*GPG_ERR_ASS_READ_ERROR*/ break; + } + break; + + case ASSUAN_Write_Error: + switch (errno) + { + case 0: n = 16381; /*GPG_ERR_MISSING_ERRNO*/ break; + default: n = 271; /*GPG_ERR_ASS_WRITE_ERROR*/ break; + } + break; + + case ASSUAN_Out_Of_Core: + switch (errno) + { + case 0: /* Should not happen but a user might have provided + an incomplete implemented malloc function. Give + him a chance to correct this fault but make sure + an error is indeed returned. */ + n = 16381; /*GPG_ERR_MISSING_ERRNO*/ + break; + case ENOMEM: n = (1 << 15) | 86; break; + default: + n = 16382; /*GPG_ERR_UNKNOWN_ERRNO*/ + break; + } + break; + + case -1: n = 16383 /*GPG_ERR_EOF*/; break; + + default: + n = 257; + break; + } + + return ((err_source << 24) | (n & 0x00ffffff)); + +} + + +/** + * assuan_strerror: + * @err: Error code + * + * This function returns a textual representaion of the given + * errorcode. If this is an unknown value, a string with the value + * is returned (Beware: it is hold in a static buffer). + * + * Return value: String with the error description. + **/ +const char * +assuan_strerror (assuan_error_t err) +{ + const char *s; + static char buf[50]; + + switch (err) + { +EOF + +awk ' +/ASSUAN_No_Error/ { okay=1 } +!okay {next} +/^#define[ ]+ASSUAN_[A-Za-z_]*/ { print_code($2) } +/ASSUAN_USER_ERROR_LAST/ { exit 0 } + + +function print_code( s ) +{ +printf " case %s: s=\"", s ; +gsub(/_/, " ", s ); +printf "%s\"; break;\n", tolower(substr(s,8)); +} +' + +cat <<EOF + case -1: s = "EOF (-1)"; break; + default: + { + unsigned int source, code, n; + + source = ((err >> 24) & 0xff); + code = (err & 0x00ffffff); + if (source) + { + /* Assume this is an libgpg-error and try to map the codes + back. */ + switch (code) + { + case 257: n = ASSUAN_General_Error ; break; + case 258: n = ASSUAN_Accept_Failed ; break; + case 259: n = ASSUAN_Connect_Failed ; break; + case 260: n = ASSUAN_Invalid_Response ; break; + case 261: n = ASSUAN_Invalid_Value ; break; + case 262: n = ASSUAN_Line_Not_Terminated ; break; + case 263: n = ASSUAN_Line_Too_Long ; break; + case 264: n = ASSUAN_Nested_Commands ; break; + case 265: n = ASSUAN_No_Data_Callback ; break; + case 266: n = ASSUAN_No_Inquire_Callback ; break; + case 267: n = ASSUAN_Not_A_Server ; break; + case 69: n = ASSUAN_Not_Implemented ; break; + case 280: n = ASSUAN_Parameter_Conflict ; break; + case 269: n = ASSUAN_Problem_Starting_Server; break; + case 270: n = ASSUAN_Read_Error ; break; + case 271: n = ASSUAN_Write_Error ; break; + case 80: n = ASSUAN_Server_Fault ; break; + case 276: n = ASSUAN_Syntax_Error ; break; + case 273: n = ASSUAN_Too_Much_Data ; break; + case 274: n = ASSUAN_Unexpected_Command ; break; + case 275: n = ASSUAN_Unknown_Command ; break; + case 277: n = ASSUAN_Canceled ; break; + case 114: n = ASSUAN_Not_Confirmed ; break; + case ((1<<15)|86): n = ASSUAN_Out_Of_Core ; break; + default: n = 0; break; + } + if (n) + s = assuan_strerror (n); + else + { + sprintf (buf, "ec=%u.%u", source, code ); + s=buf; + } + } + else + { + sprintf (buf, "ec=%d", err ); + s=buf; + } + } + break; + } + + return s; +} + +EOF |