diff options
author | Werner Koch <wk@gnupg.org> | 2006-09-13 15:55:25 +0000 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2006-09-13 15:55:25 +0000 |
commit | 7a22110230b9f1e5b5a73c065571935df21ef9b1 (patch) | |
tree | b312d30d17edc30dc7514dbc80a323f54ca71cf8 /src | |
parent | d1210ab25c96e60fc439cfa9b50ec431642ada36 (diff) | |
download | libassuan-7a22110230b9f1e5b5a73c065571935df21ef9b1.tar.gz |
More tweaks for descriptor passing.
gpg-connect-agent may now be used as a test program.
Diffstat (limited to 'src')
-rw-r--r-- | src/ChangeLog | 24 | ||||
-rw-r--r-- | src/assuan-buffer.c | 6 | ||||
-rw-r--r-- | src/assuan-client.c | 2 | ||||
-rw-r--r-- | src/assuan-defs.h | 1 | ||||
-rw-r--r-- | src/assuan-handler.c | 76 | ||||
-rw-r--r-- | src/assuan-listen.c | 1 | ||||
-rw-r--r-- | src/assuan-pipe-connect.c | 38 | ||||
-rw-r--r-- | src/assuan-pipe-server.c | 18 | ||||
-rw-r--r-- | src/assuan-socket-connect.c | 38 | ||||
-rw-r--r-- | src/assuan-socket-server.c | 70 | ||||
-rw-r--r-- | src/assuan-uds.c | 34 | ||||
-rw-r--r-- | src/assuan.h | 21 | ||||
-rwxr-xr-x | src/mkerrors | 4 |
13 files changed, 213 insertions, 120 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index fd4e3d3..04fb712 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,29 @@ +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. diff --git a/src/assuan-buffer.c b/src/assuan-buffer.c index 57eba95..f7b45a3 100644 --- a/src/assuan-buffer.c +++ b/src/assuan-buffer.c @@ -269,7 +269,11 @@ _assuan_write_line (assuan_context_t ctx, const char *prefix, if (ctx->confidential) fputs ("[Confidential data not shown]", ctx->log_fp); else - _assuan_log_print_buffer (ctx->log_fp, line, len); + { + 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); } diff --git a/src/assuan-client.c b/src/assuan-client.c index cf85ddf..f82abbd 100644 --- a/src/assuan-client.c +++ b/src/assuan-client.c @@ -160,7 +160,7 @@ assuan_transact (ASSUAN_CONTEXT ctx, if (!okay) { - rc = atoi (line); + rc = _assuan_error (atoi (line)); if (rc < 100) rc = ASSUAN_Server_Fault; } diff --git a/src/assuan-defs.h b/src/assuan-defs.h index 1f908fb..93aca85 100644 --- a/src/assuan-defs.h +++ b/src/assuan-defs.h @@ -185,6 +185,7 @@ int _assuan_new_context (ASSUAN_CONTEXT *r_ctx); void _assuan_release_context (ASSUAN_CONTEXT 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); diff --git a/src/assuan-handler.c b/src/assuan-handler.c index 0624305..bf00d1a 100644 --- a/src/assuan-handler.c +++ b/src/assuan-handler.c @@ -37,20 +37,20 @@ static int my_strcasecmp (const char *a, const char *b); static int -dummy_handler (ASSUAN_CONTEXT ctx, char *line) +dummy_handler (assuan_context_t ctx, char *line) { return set_error (ctx, Server_Fault, "no handler registered"); } static int -std_handler_nop (ASSUAN_CONTEXT ctx, char *line) +std_handler_nop (assuan_context_t ctx, char *line) { return 0; /* okay */ } static int -std_handler_cancel (ASSUAN_CONTEXT ctx, char *line) +std_handler_cancel (assuan_context_t ctx, char *line) { if (ctx->cancel_notify_fnc) ctx->cancel_notify_fnc (ctx); @@ -58,7 +58,7 @@ std_handler_cancel (ASSUAN_CONTEXT ctx, char *line) } static int -std_handler_option (ASSUAN_CONTEXT ctx, char *line) +std_handler_option (assuan_context_t ctx, char *line) { char *key, *value, *p; @@ -105,7 +105,7 @@ std_handler_option (ASSUAN_CONTEXT ctx, char *line) } static int -std_handler_bye (ASSUAN_CONTEXT ctx, char *line) +std_handler_bye (assuan_context_t ctx, char *line) { if (ctx->bye_notify_fnc) ctx->bye_notify_fnc (ctx); @@ -115,33 +115,35 @@ std_handler_bye (ASSUAN_CONTEXT ctx, char *line) } static int -std_handler_auth (ASSUAN_CONTEXT ctx, char *line) +std_handler_auth (assuan_context_t ctx, char *line) { return set_error (ctx, Not_Implemented, NULL); } static int -std_handler_reset (ASSUAN_CONTEXT ctx, char *line) +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 ctx, char *line) +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 ctx, char *line, int *rfd) +assuan_command_parse_fd (assuan_context_t ctx, char *line, int *rfd) { char *endp; - if (strncmp (line, "FD", 2) != 0 || (line[2] != '=' && line[2] != '\0')) + 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 == '=') @@ -150,7 +152,7 @@ assuan_command_parse_fd (ASSUAN_CONTEXT ctx, char *line, int *rfd) 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 */ + /* Remove that argument so that a notify handler won't see it. */ memset (line, ' ', endp? (endp-line):strlen(line)); if (*rfd == ctx->inbound.fd) @@ -166,7 +168,7 @@ assuan_command_parse_fd (ASSUAN_CONTEXT ctx, char *line, int *rfd) /* Format is INPUT FD=<n> */ static int -std_handler_input (ASSUAN_CONTEXT ctx, char *line) +std_handler_input (assuan_context_t ctx, char *line) { int rc, fd; @@ -181,7 +183,7 @@ std_handler_input (ASSUAN_CONTEXT ctx, char *line) /* Format is OUTPUT FD=<n> */ static int -std_handler_output (ASSUAN_CONTEXT ctx, char *line) +std_handler_output (assuan_context_t ctx, char *line) { int rc, fd; @@ -203,7 +205,7 @@ std_handler_output (ASSUAN_CONTEXT ctx, char *line) with default handlers */ static struct { const char *name; - int (*handler)(ASSUAN_CONTEXT, char *line); + int (*handler)(assuan_context_t, char *line); int always; /* always initialize this command */ } std_cmd_table[] = { { "NOP", std_handler_nop, 1 }, @@ -235,9 +237,9 @@ static struct { * Return value: 0 on success or an error code **/ int -assuan_register_command (ASSUAN_CONTEXT ctx, +assuan_register_command (assuan_context_t ctx, const char *cmd_name, - int (*handler)(ASSUAN_CONTEXT, char *)) + int (*handler)(assuan_context_t, char *)) { int i; const char *s; @@ -290,7 +292,8 @@ assuan_register_command (ASSUAN_CONTEXT ctx, } int -assuan_register_bye_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT)) +assuan_register_bye_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)) { if (!ctx) return _assuan_error (ASSUAN_Invalid_Value); @@ -299,7 +302,8 @@ assuan_register_bye_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT)) } int -assuan_register_reset_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT)) +assuan_register_reset_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)) { if (!ctx) return _assuan_error (ASSUAN_Invalid_Value); @@ -308,7 +312,8 @@ assuan_register_reset_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT)) } int -assuan_register_cancel_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT)) +assuan_register_cancel_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t)) { if (!ctx) return _assuan_error (ASSUAN_Invalid_Value); @@ -317,8 +322,8 @@ assuan_register_cancel_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT)) } int -assuan_register_option_handler (ASSUAN_CONTEXT ctx, - int (*fnc)(ASSUAN_CONTEXT, +assuan_register_option_handler (assuan_context_t ctx, + int (*fnc)(assuan_context_t, const char*, const char*)) { if (!ctx) @@ -328,8 +333,8 @@ assuan_register_option_handler (ASSUAN_CONTEXT ctx, } int -assuan_register_input_notify (ASSUAN_CONTEXT ctx, - void (*fnc)(ASSUAN_CONTEXT, const char *)) +assuan_register_input_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, const char *)) { if (!ctx) return _assuan_error (ASSUAN_Invalid_Value); @@ -338,8 +343,8 @@ assuan_register_input_notify (ASSUAN_CONTEXT ctx, } int -assuan_register_output_notify (ASSUAN_CONTEXT ctx, - void (*fnc)(ASSUAN_CONTEXT, const char *)) +assuan_register_output_notify (assuan_context_t ctx, + void (*fnc)(assuan_context_t, const char *)) { if (!ctx) return _assuan_error (ASSUAN_Invalid_Value); @@ -350,7 +355,7 @@ assuan_register_output_notify (ASSUAN_CONTEXT ctx, /* Helper to register the standards commands */ int -_assuan_register_std_commands (ASSUAN_CONTEXT ctx) +_assuan_register_std_commands (assuan_context_t ctx) { int i, rc; @@ -371,7 +376,7 @@ _assuan_register_std_commands (ASSUAN_CONTEXT ctx) /* Process the special data lines. The "D " has already been removed from the line. As all handlers this function may modify the line. */ static int -handle_data_line (ASSUAN_CONTEXT ctx, char *line, int linelen) +handle_data_line (assuan_context_t ctx, char *line, int linelen) { return set_error (ctx, Not_Implemented, NULL); } @@ -395,7 +400,7 @@ my_strcasecmp (const char *a, const char *b) 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 ctx, char *line, int linelen) +dispatch_command (assuan_context_t ctx, char *line, int linelen) { char *p; const char *s; @@ -442,7 +447,7 @@ dispatch_command (ASSUAN_CONTEXT ctx, char *line, int linelen) static int -process_request (ASSUAN_CONTEXT ctx) +process_request (assuan_context_t ctx) { int rc; @@ -553,7 +558,7 @@ process_request (ASSUAN_CONTEXT ctx) * failed. Note, that no error is returned for operational errors. **/ int -assuan_process (ASSUAN_CONTEXT ctx) +assuan_process (assuan_context_t ctx) { int rc; @@ -580,7 +585,7 @@ assuan_process (ASSUAN_CONTEXT ctx) * Return value: -1 for end of server, 0 on success or an error code **/ int -assuan_process_next (ASSUAN_CONTEXT ctx) +assuan_process_next (assuan_context_t ctx) { return process_request (ctx); } @@ -604,7 +609,7 @@ assuan_process_next (ASSUAN_CONTEXT ctx) * error which is most likely a too small fdarray. **/ int -assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what, +assuan_get_active_fds (assuan_context_t ctx, int what, int *fdarray, int fdarraysize) { int n = 0; @@ -637,7 +642,7 @@ assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what, implementaion for systems w/o a glibc, a simple implementation could use a child process */ FILE * -assuan_get_data_fp (ASSUAN_CONTEXT ctx) +assuan_get_data_fp (assuan_context_t ctx) { #if defined (HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN) if (ctx->outbound.data.fp) @@ -659,7 +664,7 @@ assuan_get_data_fp (ASSUAN_CONTEXT ctx) /* 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 ctx, const char *line) +assuan_set_okay_line (assuan_context_t ctx, const char *line) { if (!ctx) return _assuan_error (ASSUAN_Invalid_Value); @@ -686,7 +691,8 @@ assuan_set_okay_line (ASSUAN_CONTEXT ctx, const char *line) assuan_error_t -assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text) +assuan_write_status (assuan_context_t ctx, + const char *keyword, const char *text) { char buffer[256]; char *helpbuf; diff --git a/src/assuan-listen.c b/src/assuan-listen.c index b81db84..04db68c 100644 --- a/src/assuan-listen.c +++ b/src/assuan-listen.c @@ -24,6 +24,7 @@ #include <stdio.h> #include <string.h> #include <unistd.h> +#include <errno.h> #include "assuan-defs.h" diff --git a/src/assuan-pipe-connect.c b/src/assuan-pipe-connect.c index c3ceb53..5dd91cc 100644 --- a/src/assuan-pipe-connect.c +++ b/src/assuan-pipe-connect.c @@ -512,7 +512,7 @@ socketpair_connect (assuan_context_t *ctx, _assuan_error (ASSUAN_Problem_Starting_Server), name, strerror (errno)); errbuf[sizeof(errbuf)-1] = 0; - writen (1, errbuf, strlen (errbuf)); + writen (fds[1], errbuf, strlen (errbuf)); _exit (4); } #ifdef _ASSUAN_USE_DOUBLE_FORK @@ -842,31 +842,41 @@ assuan_pipe_connect2 (assuan_context_t *ctx, } -/* Connect to a server over a 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. +/* 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 specila environment variables are set. To let the caller - detect whether the cild or the parent continues, the child returns + 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) + void *atforkvalue, unsigned int flags) { + if ((flags & 1)) + { #ifdef HAVE_W32_SYSTEM - return _assuan_error (ASSUAN_Not_Implemented); + return _assuan_error (ASSUAN_Not_Implemented); #else - return socketpair_connect (ctx, name, argv, fd_child_list, - atfork, atforkvalue); + 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/src/assuan-pipe-server.c b/src/assuan-pipe-server.c index 509fc12..18f8cc5 100644 --- a/src/assuan-pipe-server.c +++ b/src/assuan-pipe-server.c @@ -22,6 +22,8 @@ #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> @@ -89,6 +91,18 @@ _assuan_new_context (ASSUAN_CONTEXT *r_ctx) } +/* 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 *r_ctx, int filedes[2]) { @@ -112,7 +126,7 @@ assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2]) ctx->outbound.fd = _get_osfhandle (filedes[1]); #else s = getenv ("_assuan_connection_fd"); - if (!filedes && s && *s && atoi (s) >= 0 ) + if (s && *s && is_valid_socket (s) ) { /* Well, we are called with an bi-directional file descriptor. Prepare for using sendmsg/recvmsg. In this @@ -121,7 +135,7 @@ assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2]) _assuan_init_uds_io (ctx); ctx->deinit_handler = _assuan_uds_deinit; } - else if (filedes) + else if (filedes && filedes[0] != -1 && filedes[1] != -1 ) { /* Standard pipe server. */ ctx->inbound.fd = filedes[0]; diff --git a/src/assuan-socket-connect.c b/src/assuan-socket-connect.c index 8df7812..5953f1c 100644 --- a/src/assuan-socket-connect.c +++ b/src/assuan-socket-connect.c @@ -55,7 +55,7 @@ static int -do_finish (ASSUAN_CONTEXT ctx) +do_finish (assuan_context_t ctx) { if (ctx->inbound.fd != -1) { @@ -67,22 +67,37 @@ do_finish (ASSUAN_CONTEXT ctx) } static void -do_deinit (ASSUAN_CONTEXT ctx) +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 *r_ctx, +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 ctx; + assuan_context_t ctx; int fd; struct sockaddr_un srvr_addr; size_t len; @@ -92,9 +107,9 @@ assuan_socket_connect (ASSUAN_CONTEXT *r_ctx, return _assuan_error (ASSUAN_Invalid_Value); *r_ctx = NULL; - /* We require that the name starts with a slash, so that we can - alter reuse this function for other socket types. To make things - easier we allow an optional dirver prefix. */ + /* 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; @@ -107,10 +122,9 @@ assuan_socket_connect (ASSUAN_CONTEXT *r_ctx, err = _assuan_new_context (&ctx); if (err) return err; - ctx->deinit_handler = do_deinit; + 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) { @@ -138,7 +152,9 @@ assuan_socket_connect (ASSUAN_CONTEXT *r_ctx, ctx->inbound.fd = fd; ctx->outbound.fd = fd; ctx->io = &io; - + if ((flags&1)) + _assuan_init_uds_io (ctx); + /* initial handshake */ { int okay, off; @@ -164,3 +180,5 @@ assuan_socket_connect (ASSUAN_CONTEXT *r_ctx, *r_ctx = ctx; return 0; } + + diff --git a/src/assuan-socket-server.c b/src/assuan-socket-server.c index 91adb71..468826e 100644 --- a/src/assuan-socket-server.c +++ b/src/assuan-socket-server.c @@ -114,40 +114,25 @@ deinit_socket_server (assuan_context_t ctx) int assuan_init_socket_server (assuan_context_t *r_ctx, int listen_fd) { - 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; - ctx->input_fd = -1; - ctx->output_fd = -1; - - ctx->inbound.fd = -1; - ctx->outbound.fd = -1; - - ctx->listen_fd = listen_fd; - ctx->connected_fd = -1; - ctx->deinit_handler = deinit_socket_server; - ctx->accept_handler = accept_connection; - ctx->finish_handler = finish_connection; - - ctx->io = &io; - - rc = _assuan_register_std_commands (ctx); - if (rc) - xfree (ctx); - else - *r_ctx = ctx; - return rc; + return assuan_init_socket_server_ext (r_ctx, listen_fd, 0); } /* Initialize a server using the already accepted socket FD. */ 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; @@ -156,21 +141,34 @@ assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd) if (!ctx) return _assuan_error (ASSUAN_Out_Of_Core); ctx->is_server = 1; - ctx->pipe_mode = 1; /* we want a second accept to indicate EOF */ + 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; - ctx->io = &io; - - ctx->listen_fd = -1; - ctx->connected_fd = fd; - ctx->deinit_handler = deinit_socket_server; - ctx->accept_handler = accept_connection_bottom; + 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); @@ -178,5 +176,3 @@ assuan_init_connected_socket_server (assuan_context_t *r_ctx, int fd) *r_ctx = ctx; return rc; } - - diff --git a/src/assuan-uds.c b/src/assuan-uds.c index 52988d4..c725392 100644 --- a/src/assuan-uds.c +++ b/src/assuan-uds.c @@ -45,7 +45,10 @@ #include "assuan-defs.h" -/* Read from a unix domain socket using sendmsg. */ +/* 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) { @@ -215,16 +218,19 @@ static assuan_error_t uds_receivefd (assuan_context_t ctx, int *fd) { #ifndef HAVE_W32_SYSTEM - if (!ctx->uds.pendingfds) + 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]; - if (--ctx->uds.pendingfdscount) - memmove (ctx->uds.pendingfds, ctx->uds.pendingfds + 1, - ctx->uds.pendingfdscount * sizeof (int)); + for (i=1; i < ctx->uds.pendingfdscount; i++) + ctx->uds.pendingfds[i-1] = ctx->uds.pendingfds[i]; + ctx->uds.pendingfdscount--; return 0; #else @@ -233,12 +239,21 @@ uds_receivefd (assuan_context_t ctx, int *fd) } -/* Deinitialize the unix domain socket I/O functions. */ +/* Close all pending fds. */ void -_assuan_uds_deinit (assuan_context_t ctx) +_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); @@ -249,13 +264,10 @@ _assuan_uds_deinit (assuan_context_t ctx) xfree (ctx->uds.buffer); } - for (i = 0; i < ctx->uds.pendingfdscount; i++) - _assuan_close (ctx->uds.pendingfds[i]); - ctx->uds.pendingfdscount = 0; + _assuan_uds_close_fds (ctx); } - /* Helper function to initialize a context for domain I/O. */ void _assuan_init_uds_io (assuan_context_t ctx) diff --git a/src/assuan.h b/src/assuan.h index e16d821..8a22f90 100644 --- a/src/assuan.h +++ b/src/assuan.h @@ -91,10 +91,12 @@ #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_domain_connect _ASSUAN_PREFIX(assuan_domain_connect) -#define assuan_init_domain_server _ASSUAN_PREFIX(assuan_init_domain_server) +#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_transact _ASSUAN_PREFIX(assuan_transact) @@ -365,7 +367,8 @@ 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); - +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, @@ -383,13 +386,17 @@ assuan_error_t assuan_pipe_connect_ext (assuan_context_t *ctx, const char *const argv[], int *fd_child_list, void (*atfork) (void *, int), - void *atforkvalue); + void *atforkvalue, + unsigned int flags); /*-- assuan-socket-connect.c --*/ -assuan_error_t assuan_socket_connect (assuan_context_t *ctx, const char *name, +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); diff --git a/src/mkerrors b/src/mkerrors index 552cb17..b5ab114 100755 --- a/src/mkerrors +++ b/src/mkerrors @@ -83,6 +83,7 @@ _assuan_error (int oldcode) 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_Read_Error: switch (errno) @@ -119,8 +120,7 @@ _assuan_error (int oldcode) case -1: n = 16383 /*GPG_ERR_EOF*/; break; default: - assert (!"unmapped error code used in libassuan!!"); - n = 257; /* Just in case someone compiled with NDEBUG. */ + n = 257; break; } |