2006-07-27 18:53:57 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
|
2006-09-26 20:59:08 +02:00
|
|
|
#include "list.h"
|
2006-07-27 18:53:57 +02:00
|
|
|
#include "logging.h"
|
|
|
|
#include "multicast.h"
|
|
|
|
#include "unixsock.h"
|
|
|
|
|
|
|
|
#define BUF_SIZE 256
|
|
|
|
|
2006-09-26 20:59:08 +02:00
|
|
|
struct fd_entry {
|
|
|
|
struct list_head list;
|
|
|
|
int fd;
|
|
|
|
};
|
|
|
|
|
|
|
|
static LIST_HEAD(fd_list);
|
|
|
|
|
|
|
|
void selector(int usock, int msock)
|
2006-07-27 18:53:57 +02:00
|
|
|
{
|
|
|
|
fd_set fdsel;
|
|
|
|
|
|
|
|
char *buf = malloc(BUF_SIZE);
|
|
|
|
if (buf == NULL) {
|
|
|
|
log_print(LOG_ERROR, "selector: out of memory");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
struct timeval tv;
|
2006-09-26 20:59:08 +02:00
|
|
|
struct fd_entry *entry, *entry_safe;
|
2006-07-27 18:53:57 +02:00
|
|
|
|
|
|
|
FD_ZERO(&fdsel);
|
|
|
|
FD_SET(usock, &fdsel);
|
|
|
|
FD_SET(msock, &fdsel);
|
|
|
|
|
2006-09-26 20:59:08 +02:00
|
|
|
list_for_each_entry(entry, &fd_list, list) {
|
|
|
|
FD_SET(entry->fd, &fdsel);
|
|
|
|
}
|
2006-07-27 18:53:57 +02:00
|
|
|
|
|
|
|
tv.tv_sec = 60;
|
|
|
|
tv.tv_usec = 0;
|
|
|
|
|
2006-09-26 20:59:08 +02:00
|
|
|
int ret = select(FD_SETSIZE, &fdsel, NULL, NULL, &tv);
|
2006-07-27 18:53:57 +02:00
|
|
|
if (ret < 0) {
|
|
|
|
log_print(LOG_ERROR, "selector: select()");
|
|
|
|
continue;
|
|
|
|
|
|
|
|
} else if (ret == 0) {
|
|
|
|
mcast_send(msock, "KEEPALIVE", 10);
|
2006-09-26 20:59:08 +02:00
|
|
|
}
|
2006-07-27 18:53:57 +02:00
|
|
|
|
2006-09-26 20:59:08 +02:00
|
|
|
if (FD_ISSET(msock, &fdsel)) {
|
2006-07-27 18:53:57 +02:00
|
|
|
int len = read(msock, buf, BUF_SIZE);
|
|
|
|
if (len <= 0) {
|
|
|
|
log_print(LOG_ERROR, "selector: multicast sock closed?");
|
|
|
|
|
|
|
|
} else if (!strncmp(buf, "KEEPALIVE", 10)) {
|
2006-09-26 20:59:08 +02:00
|
|
|
// nothing
|
2006-07-27 18:53:57 +02:00
|
|
|
|
|
|
|
} else if (!strncmp(buf, "DELETE ", 7)) {
|
|
|
|
log_print(LOG_DEBUG, "delete '%s'", buf +7);
|
2006-09-26 20:59:08 +02:00
|
|
|
// delete_file(buf +7);
|
2006-07-27 18:53:57 +02:00
|
|
|
|
|
|
|
} else {
|
|
|
|
log_print(LOG_DEBUG, "recv unknown cmd via multicast: '%s'", buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-26 20:59:08 +02:00
|
|
|
if (FD_ISSET(usock, &fdsel)) {
|
|
|
|
int usock_con;
|
|
|
|
|
|
|
|
usock_con = accept(usock, NULL, NULL);
|
|
|
|
if (usock_con != -1) {
|
|
|
|
entry = malloc(sizeof(struct fd_entry));
|
|
|
|
if (entry) {
|
|
|
|
entry->fd = usock_con;
|
|
|
|
list_add_tail(&entry->list, &fd_list);
|
|
|
|
} else {
|
|
|
|
log_print(LOG_ERROR, "selector: out of memory");
|
|
|
|
close(usock_con);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
log_print(LOG_ERROR, "selector: accept()");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
list_for_each_entry_safe(entry, entry_safe, &fd_list, list) {
|
|
|
|
if (FD_ISSET(entry->fd, &fdsel)) {
|
|
|
|
int len = read(entry->fd, buf, BUF_SIZE);
|
|
|
|
if (len <= 0) {
|
|
|
|
list_del(&entry->list);
|
|
|
|
close(entry->fd);
|
|
|
|
free(entry);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
mcast_send(msock, buf, len);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-07-27 18:53:57 +02:00
|
|
|
msock_close(msock);
|
|
|
|
sock_close(usock);
|
|
|
|
}
|