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};
43 struct client *next, *prev;
46 static struct client *clients;
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));
72 if (c->next) c->next->prev = c;
78 * kill off a dead client
80 static void dead_client(struct client *c)
83 if (c->prev) c->prev->next = c->next;
84 if (c->next) c->next->prev = c->prev;
85 if (c == clients) clients = c->next;
90 void free_polls (void)
96 void check_timeout(struct timeval start_time, char *inbuf,
99 struct timeval diff_time, end_time;
101 if (start_time.tv_sec && gettimeofday(&end_time, NULL) == 0) {
102 timersub(&end_time, &start_time, &diff_time);
105 msecs = diff_time.tv_sec * 1000 +
106 diff_time.tv_usec / 1000;
108 condlog(2, "cli cmd '%s' timeout reached "
109 "after %lu.%06lu secs", inbuf,
110 diff_time.tv_sec, diff_time.tv_usec);
114 void uxsock_cleanup(void *arg)
123 void * uxsock_listen(int (*uxsock_trigger)(char *, char **, int *, void *),
133 ux_sock = ux_socket_listen(DEFAULT_SOCKET);
136 condlog(1, "could not create uxsock: %d", errno);
141 condlog(1, "configuration changed");
145 timeout = conf->uxsock_timeout;
147 pthread_cleanup_push(uxsock_cleanup, NULL);
149 polls = (struct pollfd *)MALLOC(0);
150 pthread_sigmask(SIG_SETMASK, NULL, &mask);
151 sigdelset(&mask, SIGHUP);
152 sigdelset(&mask, SIGUSR1);
158 * Store configuration timeout;
159 * configuration might change during
160 * the call to 'reconfigure'.
163 timeout = conf->uxsock_timeout;
165 /* setup for a poll */
166 polls = REALLOC(polls, (1+num_clients) * sizeof(*polls));
167 polls[0].fd = ux_sock;
168 polls[0].events = POLLIN;
170 /* setup the clients */
171 for (i=1, c = clients; c; i++, c = c->next) {
173 polls[i].events = POLLIN;
176 /* most of our life is spent in this call */
177 poll_count = ppoll(polls, i, &sleep_time, &mask);
179 if (poll_count == -1) {
180 if (errno == EINTR) {
185 /* something went badly wrong! */
193 /* see if a client wants to speak to us */
194 for (i=1, c = clients; c; i++) {
195 struct client *next = c->next;
197 if (polls[i].revents & POLLIN) {
198 struct timeval start_time;
200 if (gettimeofday(&start_time, NULL) != 0)
201 start_time.tv_sec = 0;
203 if (recv_packet(c->fd, &inbuf, &len,
208 condlog(4, "Got request [%s]", inbuf);
209 uxsock_trigger(inbuf, &reply, &rlen,
212 if (send_packet(c->fd, reply,
216 condlog(4, "Reply [%d bytes]",
221 check_timeout(start_time, inbuf,
229 /* see if we got a new client */
230 if (polls[0].revents & POLLIN) {
235 pthread_cleanup_pop(1);