aboutsummaryrefslogtreecommitdiffstats
path: root/src/symsocket.c
diff options
context:
space:
mode:
authorjames <>2008-02-13 18:05:06 +0000
committerjames <>2008-02-13 18:05:06 +0000
commit7b7996c7bb4bd66f6262f4e721b6960d6b58b801 (patch)
tree9f5e12b05faf7fb66de0d20c05c0db4b804bb8b2 /src/symsocket.c
parent9644f7cf7d6949303984a058b9b3694c92ac9be5 (diff)
downloadsympathy-7b7996c7bb4bd66f6262f4e721b6960d6b58b801.tar.gz
sympathy-7b7996c7bb4bd66f6262f4e721b6960d6b58b801.tar.bz2
sympathy-7b7996c7bb4bd66f6262f4e721b6960d6b58b801.zip
*** empty log message ***
Diffstat (limited to 'src/symsocket.c')
-rw-r--r--src/symsocket.c249
1 files changed, 249 insertions, 0 deletions
diff --git a/src/symsocket.c b/src/symsocket.c
new file mode 100644
index 0000000..fde1b2d
--- /dev/null
+++ b/src/symsocket.c
@@ -0,0 +1,249 @@
+/*
+ * symsocket.c:
+ *
+ * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
+ * All rights reserved.
+ *
+ */
+
+static char rcsid[] = "$Id$";
+
+/*
+ * $Log$
+ * Revision 1.1 2008/02/13 18:05:06 james
+ * *** empty log message ***
+ *
+ */
+
+#include "project.h"
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#define BUF_SIZE 16384
+#define MAX_TXN 4096
+
+
+void socket_free(Socket *s)
+{
+if (!s) return;
+if (s->read_buf) slide_free(s->read_buf);
+if (s->write_buf) slide_free(s->write_buf);
+close(s->fd);
+}
+
+
+Socket *
+socket_listen (char *path)
+{
+ int fd;
+ struct sockaddr_un *sun;
+ Socket *ret;
+ int n;
+
+
+ unlink (path);
+
+ fd = socket (PF_UNIX, SOCK_STREAM, 0);
+
+ if (fd < 0)
+ return NULL;
+
+ n = strlen (path) + sizeof (struct sockaddr_un);
+ sun = (struct sockaddr_un *) malloc (n);
+ memset (sun, 0, n);
+
+ sun->sun_family = AF_UNIX;
+ strcpy (sun->sun_path, path);
+
+ if (bind (fd, (struct sockaddr *) sun, SUN_LEN (sun)) < 0)
+ {
+ free (sun);
+ close (fd);
+ return NULL;
+ }
+
+ free (sun);
+
+ if (listen (fd, 5) < 0)
+ {
+ close (fd);
+ return NULL;
+ }
+
+ set_nonblocking (fd);
+
+ ret = (Socket *) malloc (sizeof (Socket));
+ memset (ret, 0, sizeof (Socket));
+ ret->read_buf = NULL;
+ ret->write_buf = NULL;
+
+ ret->fd = fd;
+
+
+ return ret;
+}
+
+Socket *
+socket_accept (Socket * l)
+{
+ Socket *ret;
+ int len;
+ int fd;
+ struct sockaddr_un sun;
+
+ len = sizeof (struct sockaddr_un);
+
+ fd = accept (l->fd, (struct sockaddr *) &sun, &len);
+
+ if (fd < 0)
+ return NULL;
+
+
+ ret = (Socket *) malloc (sizeof (Socket));
+ memset (ret, 0, sizeof (Socket));
+
+ set_nonblocking (fd);
+
+ ret->fd = fd;
+ ret->read_buf = slide_new (BUF_SIZE);
+ ret->write_buf = slide_new (BUF_SIZE);
+ ret->msg = 0;
+
+ return ret;
+}
+
+
+/*Blocking for now*/
+Socket *
+socket_connect (char *path)
+{
+ int n;
+ int fd;
+ struct sockaddr_un *sun;
+ Socket *ret;
+
+ unlink (path);
+
+ fd = socket (PF_UNIX, SOCK_STREAM, 0);
+
+ if (fd < 0)
+ return NULL;
+
+ n = strlen (path) + sizeof (struct sockaddr_un);
+ sun = (struct sockaddr_un *) malloc (n);
+ memset (sun, 0, n);
+
+ sun->sun_family = AF_UNIX;
+ strcpy (sun->sun_path, path);
+
+ if (connect (fd, (struct sockaddr *) sun, SUN_LEN (sun)))
+ {
+ free (sun);
+ close (fd);
+ return NULL;
+ }
+
+ free (sun);
+
+ set_nonblocking (fd);
+
+ ret = (Socket *) malloc (sizeof (Socket));
+ memset (ret, 0, sizeof (Socket));
+
+ ret->fd = fd;
+ ret->read_buf = slide_new (BUF_SIZE);
+ ret->write_buf = slide_new (BUF_SIZE);
+ ret->msg = 0;
+
+ return ret;
+}
+
+Socket *
+socket_post_select (Socket * s, fd_set * rfds, fd_set * wfds)
+{
+ char buf[1024];
+ int n;
+
+ if (SOCKET_IS_LISTENER (s))
+ {
+ if (!FD_ISSET (s->fd, rfds))
+ return NULL;
+
+ return socket_accept (s);
+ }
+
+
+ if ((!SLIDE_EMPTY (s->write_buf)) && FD_ISSET (s->fd, wfds))
+ {
+ n =
+ (SLIDE_BYTES (s->write_buf) >
+ MAX_TXN) ? MAX_TXN : SLIDE_BYTES (s->write_buf);
+ n = write (s->fd, SLIDE_RPTR (s->write_buf), n);
+ if (n > 0)
+ slide_consume (s->write_buf, n);
+ }
+
+ if (!SLIDE_FULL (s->read_buf) && FD_ISSET (s->fd, rfds))
+ {
+ n =
+ (SLIDE_SPACE (s->read_buf) >
+ MAX_TXN) ? MAX_TXN : SLIDE_SPACE (s->read_buf);
+ n = read (s->fd, SLIDE_RPTR (s->read_buf), n);
+
+ if (n > 0)
+ slide_added (s->read_buf, n);
+ }
+
+ if (SLIDE_BYTES (s->read_buf) >= sizeof (IPC_Msg))
+ {
+ s->msg = ipc_check_for_message_in_slide(s->read_buf);
+ } else {
+ s->msg=NULL;
+ }
+
+
+ return NULL;
+
+}
+
+void socket_consume_msg(Socket *s)
+{
+int n;
+
+if (!s->msg) return;
+
+n=s->msg->size;
+
+slide_consume(s->read_buf,n);
+
+ if (SLIDE_BYTES (s->read_buf) >= sizeof (IPC_Msg))
+ {
+ s->msg = ipc_check_for_message_in_slide(s->read_buf);
+ } else {
+ s->msg=NULL;
+ }
+
+}
+
+void
+socket_pre_select (Socket * s, fd_set * rfds, fd_set * wfds)
+{
+ char buf[1024];
+ int n;
+
+ /*Server socket */
+ if (SOCKET_IS_LISTENER (s))
+ {
+ FD_SET (s->fd, rfds);
+ return;
+ }
+
+ if (!SLIDE_EMPTY (s->write_buf))
+ FD_SET (s->fd, wfds);
+
+ if (!SLIDE_FULL (s->read_buf))
+ FD_SET (s->fd, rfds);
+
+}
+
+