2 * Original author : tridge@samba.org, January 2002
4 * Copyright (c) 2005 Christophe Varoqui
5 * Copyright (c) 2005 Benjamin Marzinski, Redhat
9 * A simple domain socket listener
18 #include <sys/ioctl.h>
19 #include <sys/types.h>
20 #include <sys/socket.h>
30 #include <structs_vec.h>
39 struct timespec sleep_time = {5, 0};
42 struct list_head node;
47 static unsigned num_clients;
49 volatile sig_atomic_t reconfig_sig = 0;
50 volatile sig_atomic_t log_reset_sig = 0;
53 * handle a new client joining
55 static void new_client(int ux_sock)
59 socklen_t len = sizeof(addr);
62 fd = accept(ux_sock, &addr, &len);
67 /* put it in our linked list */
68 c = (struct client *)MALLOC(sizeof(*c));
69 memset(c, 0, sizeof(*c));
70 INIT_LIST_HEAD(&c->node);
73 list_add_tail(&c->node, &clients);
78 * kill off a dead client
80 static void dead_client(struct client *c)
84 list_del_init(&c->node);
89 void free_polls (void)
95 void check_timeout(struct timeval start_time, char *inbuf,
98 struct timeval diff_time, end_time;
100 if (start_time.tv_sec && gettimeofday(&end_time, NULL) == 0) {
101 timersub(&end_time, &start_time, &diff_time);
104 msecs = diff_time.tv_sec * 1000 +
105 diff_time.tv_usec / 1000;
107 condlog(2, "cli cmd '%s' timeout reached "
108 "after %lu.%06lu secs", inbuf,
109 diff_time.tv_sec, diff_time.tv_usec);
113 void uxsock_cleanup(void *arg)
122 void * uxsock_listen(int (*uxsock_trigger)(char *, char **, int *, void *),
132 ux_sock = ux_socket_listen(DEFAULT_SOCKET);
135 condlog(1, "could not create uxsock: %d", errno);
140 condlog(1, "configuration changed");
144 timeout = conf->uxsock_timeout;
146 pthread_cleanup_push(uxsock_cleanup, NULL);
148 polls = (struct pollfd *)MALLOC(0);
149 pthread_sigmask(SIG_SETMASK, NULL, &mask);
150 sigdelset(&mask, SIGHUP);
151 sigdelset(&mask, SIGUSR1);
153 struct client *c, *tmp;
157 * Store configuration timeout;
158 * configuration might change during
159 * the call to 'reconfigure'.
162 timeout = conf->uxsock_timeout;
164 /* setup for a poll */
165 polls = REALLOC(polls, (1+num_clients) * sizeof(*polls));
166 polls[0].fd = ux_sock;
167 polls[0].events = POLLIN;
169 /* setup the clients */
171 list_for_each_entry(c, &clients, node) {
173 polls[i].events = POLLIN;
179 /* most of our life is spent in this call */
180 poll_count = ppoll(polls, i, &sleep_time, &mask);
182 if (poll_count == -1) {
183 if (errno == EINTR) {
188 /* something went badly wrong! */
196 /* see if a client wants to speak to us */
197 for (i = 1; i < num_clients + 1; i++) {
198 if (polls[i].revents & POLLIN) {
199 struct timeval start_time;
202 list_for_each_entry(tmp, &clients, node) {
203 if (tmp->fd == polls[i].fd) {
209 condlog(3, "cli%d: invalid fd %d",
213 if (gettimeofday(&start_time, NULL) != 0)
214 start_time.tv_sec = 0;
216 if (recv_packet(c->fd, &inbuf, &len,
221 condlog(4, "Got request [%s]", inbuf);
222 uxsock_trigger(inbuf, &reply, &rlen,
225 if (send_packet(c->fd, reply,
229 condlog(4, "Reply [%d bytes]",
234 check_timeout(start_time, inbuf,
241 /* see if we got a new client */
242 if (polls[0].revents & POLLIN) {
247 pthread_cleanup_pop(1);