2 rxpd_socket.c - regex policy daemon
5 2007, Christian Thaeter <ct@pipapo.org>
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 rxpd_socket_new_tcp4 (struct rxpd_base* base, const char* addr, unsigned short port)
27 struct rxpd_socket* self;
28 self = rxpd_malloc (sizeof (struct rxpd_socket));
32 llist_init (&self->node);
34 // TODO all abort() shall become rxpd_die
35 self->fd = socket (PF_INET, SOCK_STREAM, 0);
39 struct sockaddr_in listen_addr;
40 memset (&listen_addr, 0, sizeof (listen_addr));
42 listen_addr.sin_family = AF_INET;
45 if (inet_aton (addr, &listen_addr.sin_addr) == 0)
49 listen_addr.sin_addr.s_addr = INADDR_ANY;
51 listen_addr.sin_port = htons(port);
53 if (bind (self->fd, (struct sockaddr*)&listen_addr, sizeof (listen_addr)) == -1)
57 if (setsockopt (self->fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
60 if (listen (self->fd, 20) == -1)
63 self->rxpd_socket_addr = rxpd_socket_tcp4addr;
65 self->accepter = NULL;
66 llist_insert_tail (&base->sockets, &self->node);
68 rxpd_log (base, LOG_INFO, "Listening on tcp4:%d\n", port);
73 rxpd_socket_tcp4addr (struct rxpd_connection* conn, char* dst, const char* pfx, size_t size)
75 struct sockaddr_in peer;
76 socklen_t len = sizeof (peer);
77 getpeername (conn->fd, (struct sockaddr*)&peer, &len);
80 addr = inet_ntoa (peer.sin_addr);
81 if (sizeof (":tcp4:") + strlen (pfx) + strlen (addr) > size)
85 strcat (dst, ":tcp4:");
91 rxpd_socket_delete (struct rxpd_socket* self)
95 event_del (&self->ev);
96 llist_unlink (&self->node);
103 rxpd_socket_join (struct rxpd_socket* self)
105 pth_join (self->accepter, NULL);
106 self->accepter = NULL;
111 rxpd_socket_spawn (struct rxpd_socket* self)
116 rxpd_die ("socket thread already spawned\n");
118 self->accepter = pth_spawn (PTH_ATTR_DEFAULT, rxpd_socket_accept, self);
121 rxpd_die ("failed spawning thread\n");
127 rxpd_socket_accept (void* ptr)
129 struct rxpd_socket* self = ptr;
131 pth_event_t ev = pth_event (PTH_EVENT_FD|PTH_UNTIL_FD_READABLE, self->fd);
133 rxpd_log (NULL, LOG_NOTICE, "pre ACCEPT\n");
135 // TODO cancel thread to leave the loop?
136 while (pth_wait (ev))
138 rxpd_log (NULL, LOG_NOTICE, "ACCEPT\n");
140 struct rxpd_connection* conn =
141 rxpd_connection_new (self);
142 rxpd_connection_spawn (conn);
145 rxpd_log (NULL, LOG_NOTICE, "closed\n");