[Pkg-gnupg-commit] [libassuan] 61/437: 2002-11-24 Neal H. Walfield <neal at g10code.de>
Eric Dorland
eric at moszumanska.debian.org
Fri May 22 05:33:24 UTC 2015
This is an automated email from the git hooks/post-receive script.
eric pushed a commit to branch master
in repository libassuan.
commit a7cfdeee902750b4550edfb956417c3aebbaad60
Author: Neal Walfield <neal at walfield.org>
Date: Sun Nov 24 06:34:12 2002 +0000
2002-11-24 Neal H. Walfield <neal at 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
---
src/ChangeLog | 13 +-
src/Makefile.am | 4 +-
src/assuan-defs.h | 10 +-
src/assuan-domain-connect.c | 371 ++++++++++++++++++++++++++++++++++++++++++++
src/assuan-domain-server.c | 52 +++++++
src/assuan.h | 22 ++-
6 files changed, 467 insertions(+), 5 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 0057cd8..2a2355f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,4 +1,15 @@
-2002-11-23 Neal H. Walfield <neal at cs.uml.edu>
+2002-11-24 Neal H. Walfield <neal at 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 at g10code.de>
* Makefile.am (libassuan_a_SOURCES): Add assuan-io.c.
* assuan-io.c: Restore.
diff --git a/src/Makefile.am b/src/Makefile.am
index a095d2f..f741a25 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -43,7 +43,9 @@ libassuan_a_SOURCES = \
assuan-socket-server.c \
assuan-pipe-connect.c \
assuan-socket-connect.c \
- assuan-io.c
+ assuan-io.c \
+ assuan-domain-connect.c \
+ assuan-domain-server.c
assuan-errors.c : assuan.h
$(srcdir)/mkerrors < $(srcdir)/assuan.h > assuan-errors.c
diff --git a/src/assuan-defs.h b/src/assuan-defs.h
index 3a705ec..6e11bbb 100644
--- a/src/assuan-defs.h
+++ b/src/assuan-defs.h
@@ -24,6 +24,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <unistd.h>
#include "assuan.h"
@@ -130,12 +131,17 @@ struct assuan_context_s
struct assuan_io *io;
};
-
-
/*-- assuan-pipe-server.c --*/
int _assuan_new_context (ASSUAN_CONTEXT *r_ctx);
void _assuan_release_context (ASSUAN_CONTEXT ctx);
+/*-- assuan-domain-connect.c --*/
+/* 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. */
+AssuanError _assuan_domain_init (ASSUAN_CONTEXT *r_ctx,
+ int rendezvousfd,
+ pid_t peer);
/*-- assuan-handler.c --*/
int _assuan_register_std_commands (ASSUAN_CONTEXT ctx);
diff --git a/src/assuan-domain-connect.c b/src/assuan-domain-connect.c
new file mode 100644
index 0000000..86f85e2
--- /dev/null
+++ b/src/assuan-domain-connect.c
@@ -0,0 +1,371 @@
+/* assuan-domain-connect.c - Assuan unix domain socket based client
+ * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <alloca.h>
+#include <string.h>
+#include <assert.h>
+
+#include "assuan-defs.h"
+
+#ifdef HAVE_JNLIB_LOGGING
+#include "../jnlib/logging.h"
+#define LOGERROR(a) log_error ((a))
+#define LOGERROR1(a,b) log_error ((a), (b))
+#define LOGERROR2(a,b,c) log_error ((a), (b), (c))
+#define LOGERRORX(a) log_printf ((a))
+#else
+#define LOGERROR(a) fprintf (stderr, (a))
+#define LOGERROR1(a,b) fprintf (stderr, (a), (b))
+#define LOGERROR2(a,b,c) fprintf (stderr, (a), (b), (c))
+#define LOGERRORX(a) fputs ((a), stderr)
+#endif
+
+static int
+do_finish (ASSUAN_CONTEXT ctx)
+{
+ return 0;
+}
+
+static void
+do_deinit (ASSUAN_CONTEXT ctx)
+{
+ if (ctx->inbound.fd != -1)
+ close (ctx->inbound.fd);
+ ctx->inbound.fd = -1;
+ ctx->outbound.fd = -1;
+
+ if (ctx->domainbuffer)
+ {
+ assert (ctx->domainbufferallocated);
+ free (ctx->domainbuffer);
+ }
+
+ /* XXX: Do we want to do this? Most likely. */
+ unlink (ctx->myaddr.sun_path);
+}
+
+
+/* Read from the socket server. */
+static ssize_t
+domain_reader (ASSUAN_CONTEXT ctx, void *buf, size_t buflen)
+{
+ int len = ctx->domainbuffersize;
+
+ start:
+ if (len == 0)
+ /* No data is buffered. */
+ {
+ struct msghdr msg;
+ struct iovec iovec;
+ struct sockaddr_un sender;
+
+ memset (&msg, 0, sizeof (msg));
+
+ for (;;)
+ {
+ msg.msg_name = &sender;
+ msg.msg_namelen = sizeof (struct sockaddr_un);
+ msg.msg_iov = &iovec;
+ msg.msg_iovlen = 1;
+ iovec.iov_base = ctx->domainbuffer;
+ iovec.iov_len = ctx->domainbufferallocated;
+ msg.msg_control = 0;
+ msg.msg_controllen = 0;
+
+ /* Peek first: if the buffer we have is too small then it
+ will be truncated. */
+ len = recvmsg (ctx->inbound.fd, &msg, MSG_PEEK);
+ if (len < 0)
+ {
+ printf ("domain_reader: %m\n");
+ return -1;
+ }
+
+ if (strcmp (ctx->serveraddr.sun_path,
+ ((struct sockaddr_un *) msg.msg_name)->sun_path) != 0)
+ {
+ /* XXX: Arg. Not from whom we expected! What do we
+ want to do? Should we just ignore it? Either way,
+ we still need to consume the message. */
+ break;
+ }
+
+ if (msg.msg_flags & MSG_TRUNC)
+ /* Enlarge the buffer and try again. */
+ {
+ int size = ctx->domainbufferallocated;
+ void *tmp;
+
+ if (size == 0)
+ size = 4 * 1024;
+ else
+ size *= 2;
+
+ tmp = malloc (size);
+ if (! tmp)
+ return -1;
+
+ free (ctx->domainbuffer);
+ ctx->domainbuffer = tmp;
+ ctx->domainbufferallocated = size;
+ }
+ else
+ /* We have enough space! */
+ break;
+ }
+
+ /* Now we have to actually consume it (remember, we only
+ peeked). */
+ msg.msg_name = &sender;
+ msg.msg_namelen = sizeof (struct sockaddr_un);
+ msg.msg_iov = &iovec;
+ msg.msg_iovlen = 1;
+ iovec.iov_base = ctx->domainbuffer;
+ iovec.iov_len = ctx->domainbufferallocated;
+ msg.msg_control = 0;
+ msg.msg_controllen = 0;
+
+ if (strcmp (ctx->serveraddr.sun_path,
+ ((struct sockaddr_un *) msg.msg_name)->sun_path) != 0)
+ {
+ /* XXX: Arg. Not from whom we expected! What do we want to
+ do? Should we just ignore it? We shall do the latter
+ for the moment. */
+ LOGERROR1 ("Not setup to receive messages from: `%s'.",
+ ((struct sockaddr_un *) msg.msg_name)->sun_path);
+ goto start;
+ }
+
+ len = recvmsg (ctx->inbound.fd, &msg, 0);
+ if (len < 0)
+ {
+ LOGERROR1 ("domain_reader: %s\n", strerror (errno));
+ return -1;
+ }
+
+ ctx->domainbuffersize = len;
+ ctx->domainbufferoffset = 0;
+ }
+
+ /* Return some data to the user. */
+
+ if (len > buflen)
+ /* We have more than the user requested. */
+ len = buflen;
+
+ memcpy (buf, ctx->domainbuffer + ctx->domainbufferoffset, len);
+ ctx->domainbuffersize -= len;
+ assert (ctx->domainbuffersize >= 0);
+ ctx->domainbufferoffset += len;
+ assert (ctx->domainbufferoffset <= ctx->domainbufferallocated);
+
+ return len;
+}
+
+/* Write to the pipe server. */
+static ssize_t
+domain_writer (ASSUAN_CONTEXT ctx, const void *buf, size_t buflen)
+{
+ struct msghdr msg;
+ struct iovec iovec;
+ ssize_t len;
+
+ memset (&msg, 0, sizeof (msg));
+
+ msg.msg_name = &ctx->serveraddr;
+ msg.msg_namelen = offsetof (struct sockaddr_un, sun_path)
+ + strlen (ctx->serveraddr.sun_path) + 1;
+
+ msg.msg_iovlen = 1;
+ msg.msg_iov = &iovec;
+ iovec.iov_base = (void *) buf;
+ iovec.iov_len = buflen;
+ msg.msg_control = 0;
+ msg.msg_controllen = 0;
+
+ len = sendmsg (ctx->outbound.fd, &msg, 0);
+ if (len < 0)
+ LOGERROR1 ("domain_writer: %s\n", strerror (errno));
+
+ return len;
+}
+
+/* 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. */
+AssuanError
+_assuan_domain_init (ASSUAN_CONTEXT *r_ctx,
+ int rendezvousfd,
+ pid_t peer)
+{
+ static struct assuan_io io = { domain_reader, domain_writer };
+
+ AssuanError err;
+ ASSUAN_CONTEXT ctx;
+ int fd;
+ size_t len;
+ int tries;
+
+ if (!r_ctx)
+ return ASSUAN_Invalid_Value;
+ *r_ctx = NULL;
+
+ err = _assuan_new_context (&ctx);
+ if (err)
+ return err;
+
+ /* Save it in case we need it later. */
+ ctx->pid = peer;
+ ctx->deinit_handler = do_deinit;
+ ctx->finish_handler = do_finish;
+
+ fd = socket (PF_LOCAL, SOCK_DGRAM, 0);
+ if (fd == -1)
+ {
+ LOGERROR1 ("can't create socket: %s\n", strerror (errno));
+ _assuan_release_context (ctx);
+ return ASSUAN_General_Error;
+ }
+
+ ctx->inbound.fd = fd;
+ ctx->outbound.fd = fd;
+ ctx->io = &io;
+
+ ctx->domainbuffer = 0;
+ ctx->domainbufferoffset = 0;
+ ctx->domainbuffersize = 0;
+ ctx->domainbufferallocated = 0;
+
+ /* Get usable name and bind to it. */
+
+ for (tries = 0; tries < TMP_MAX; tries ++)
+ {
+ char *p;
+ /* XXX: L_tmpnam must be shorter than sizeof (sun_path)! */
+ char buf[L_tmpnam];
+
+ p = tmpnam (buf);
+ if (! p)
+ {
+ LOGERROR ("cannot determine an appropriate temporary file "
+ "name. DOS in progress?\n");
+ _assuan_release_context (ctx);
+ close (fd);
+ return ASSUAN_General_Error;
+ }
+
+ memset (&ctx->myaddr, 0, sizeof ctx->myaddr);
+ ctx->myaddr.sun_family = AF_LOCAL;
+ len = strlen (buf) + 1;
+ memcpy (ctx->myaddr.sun_path, buf, len);
+ len += offsetof (struct sockaddr_un, sun_path);
+
+ err = bind (fd, (struct sockaddr *) &ctx->myaddr, len);
+ if (! err)
+ break;
+ }
+
+ if (err)
+ {
+ LOGERROR2 ("can't bind to `%s': %s\n", ctx->myaddr.sun_path,
+ strerror (errno));
+ _assuan_release_context (ctx);
+ close (fd);
+ return ASSUAN_Connect_Failed;
+ }
+
+ /* Rendezvous with our peer. */
+ {
+ FILE *fp;
+ char *p;
+
+ fp = fdopen (rendezvousfd, "w+");
+ if (! fp)
+ {
+ LOGERROR1 ("can't open rendezvous port: %s\n", strerror (errno));
+ return ASSUAN_Connect_Failed;
+ }
+
+ /* Send our address. */
+ fprintf (fp, "%s\n", ctx->myaddr.sun_path);
+ fflush (fp);
+
+ /* And receive our peer's. */
+ memset (&ctx->serveraddr, 0, sizeof ctx->serveraddr);
+ for (p = ctx->serveraddr.sun_path;
+ p < (ctx->serveraddr.sun_path
+ + sizeof ctx->serveraddr.sun_path - 1);
+ p ++)
+ {
+ *p = fgetc (fp);
+ if (*p == '\n')
+ break;
+ }
+ *p = '\0';
+ fclose (fp);
+
+ ctx->serveraddr.sun_family = AF_LOCAL;
+ }
+
+ *r_ctx = ctx;
+ return 0;
+}
+
+AssuanError
+assuan_domain_connect (ASSUAN_CONTEXT *r_ctx,
+ int rendezvousfd,
+ pid_t peer)
+{
+ AssuanError aerr;
+ int okay, off;
+
+ aerr = _assuan_domain_init (r_ctx, rendezvousfd, peer);
+ if (aerr)
+ return aerr;
+
+ /* Initial handshake. */
+ aerr = _assuan_read_from_server (*r_ctx, &okay, &off);
+ if (aerr)
+ LOGERROR1 ("can't connect to server: %s\n", assuan_strerror (aerr));
+ else if (okay != 1)
+ {
+ LOGERROR ("can't connect to server: `");
+ _assuan_log_sanitized_string ((*r_ctx)->inbound.line);
+ LOGERRORX ("'\n");
+ aerr = ASSUAN_Connect_Failed;
+ }
+
+ if (aerr)
+ assuan_disconnect (*r_ctx);
+
+ return aerr;
+}
diff --git a/src/assuan-domain-server.c b/src/assuan-domain-server.c
new file mode 100644
index 0000000..506ee05
--- /dev/null
+++ b/src/assuan-domain-server.c
@@ -0,0 +1,52 @@
+/* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+
+#include "assuan-defs.h"
+
+static int
+accept_connection (ASSUAN_CONTEXT ctx)
+{
+ /* NOP. */
+ return 0;
+}
+
+/* Initialize a server. */
+AssuanError
+assuan_init_domain_server (ASSUAN_CONTEXT *r_ctx,
+ int rendezvousfd,
+ pid_t peer)
+{
+ AssuanError err;
+
+ err = _assuan_domain_init (r_ctx, rendezvousfd, peer);
+ if (err)
+ return err;
+
+ (*r_ctx)->is_server = 1;
+ (*r_ctx)->accept_handler = accept_connection;
+
+ return 0;
+}
diff --git a/src/assuan.h b/src/assuan.h
index d8b874e..1972702 100644
--- a/src/assuan.h
+++ b/src/assuan.h
@@ -23,7 +23,7 @@
#include <stdio.h>
#include <sys/types.h>
-#include <unistd.h> /* for ssize_t */
+#include <unistd.h>
#ifdef __cplusplus
extern "C" {
@@ -181,6 +181,26 @@ AssuanError assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name,
AssuanError assuan_socket_connect (ASSUAN_CONTEXT *ctx, const char *name,
pid_t server_pid);
+/*-- assuan-domain-connect.c --*/
+
+/* Connect to a Unix domain socket server. RENDEZVOUSFD is
+ bidirectional file descriptor (normally returned via socketpair)
+ which the client can use to rendezvous with the server. SERVER s
+ the server's pid. */
+AssuanError assuan_domain_connect (ASSUAN_CONTEXT *r_ctx,
+ int rendezvousfd,
+ pid_t server);
+
+/*-- assuan-domain-server.c --*/
+
+/* RENDEZVOUSFD is a bidirectional file descriptor (normally returned
+ via socketpair) that the domain server can use to rendezvous with
+ the client. CLIENT is the client's pid. */
+AssuanError assuan_init_domain_server (ASSUAN_CONTEXT *r_ctx,
+ int rendezvousfd,
+ pid_t client);
+
+
/*-- assuan-connect.c --*/
void assuan_disconnect (ASSUAN_CONTEXT ctx);
pid_t assuan_get_pid (ASSUAN_CONTEXT ctx);
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/libassuan.git
More information about the Pkg-gnupg-commit
mailing list