From b76330e31e3d2a25da5060aee9ad379db816fb03 Mon Sep 17 00:00:00 2001 From: wens Date: Mon, 7 Apr 2008 16:49:43 +0000 Subject: New daemon: fromd Move source description lookup out of SHM git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@4090 63ad8ddf-47c3-0310-b6dd-a9e9d9715204 --- daemon/fromd/Makefile | 22 +++++++++ daemon/fromd/fromd.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++ daemon/fromd/ip_desc_db.c | 103 ++++++++++++++++++++++++++++++++++++++++++ daemon/fromd/ip_desc_db.h | 6 +++ 4 files changed, 242 insertions(+) create mode 100644 daemon/fromd/Makefile create mode 100644 daemon/fromd/fromd.c create mode 100644 daemon/fromd/ip_desc_db.c create mode 100644 daemon/fromd/ip_desc_db.h diff --git a/daemon/fromd/Makefile b/daemon/fromd/Makefile new file mode 100644 index 00000000..5e3e9aaa --- /dev/null +++ b/daemon/fromd/Makefile @@ -0,0 +1,22 @@ +# $Id$ +SRCROOT= ../.. +.include "$(SRCROOT)/pttbbs.mk" + +PROGRAMS= fromd + +LDLIBS+= $(SRCROOT)/common/sys/libcmsys.a \ + $(SRCROOT)/common/bbs/libcmbbs.a + +all: ${PROGRAMS} + +.SUFFIXES: .c .cpp .o +.c.o: + $(CCACHE) $(CC) $(CFLAGS) -c $*.c +.cpp.o: + $(CCACHE) $(CXX) $(CFLAGS) -c $*.cpp + +fromd: fromd.o ip_desc_db.o + ${CC} ${CFLAGS} ${LDFLAGS} -levent -o $@ $> $(LDLIBS) + +clean: + rm -f *~ ${PROGRAMS} fromd.o ip_desc_db.o diff --git a/daemon/fromd/fromd.c b/daemon/fromd/fromd.c new file mode 100644 index 00000000..c8fb0b06 --- /dev/null +++ b/daemon/fromd/fromd.c @@ -0,0 +1,111 @@ +// $Id$ +#include +#include +#include +#include +#include + +#include "bbs.h" +#include "ip_desc_db.h" + +const char * cfgfile = BBSHOME "/etc/domain_name_query.cidr"; +struct timeval tv = {5, 0}; +static struct event ev_listen, ev_sighup; + +static void sighup_cb(int signal, short event, void *arg) +{ + ip_desc_db_reload(cfgfile); +} + +static void client_cb(int fd, short event, void *arg) +{ + char buf[32]; + const char *result; + int len; + + // ignore clients that timeout + if (event & EV_TIMEOUT) + return; + + if ( (len = read(fd, buf, sizeof(buf) - 1)) <= 0 ) + return; + + buf[len] = '\0'; + + result = ip_desc_db_lookup(buf); + write(fd, result, strlen(result)); + + // cleanup + close(fd); + free(arg); +} + +static void listen_cb(int fd, short event, void *arg) +{ + int cfd; + + if ((cfd = accept(fd, NULL, NULL)) < 0 ) + return; + + struct event *ev = malloc(sizeof(struct event)); + + event_set(ev, cfd, EV_READ, client_cb, ev); + event_add(ev, &tv); +} + +void daemonize() +{ + pid_t pid; + + if ( (pid = fork()) < 0) + exit(1); + + if (pid > 0) + exit(0); + + umask(0); + + if (setsid() < 0) + exit(-1); + + if (chdir("/") < 0) + exit(-1); +} + +int main(int argc, char *argv[]) +{ + int ch, port = 5120, sfd; + char *iface_ip = NULL; + + Signal(SIGPIPE, SIG_IGN); + + while ( (ch = getopt(argc, argv, "p:i:h")) != -1 ) + switch( ch ){ + case 'p': + port = atoi(optarg); + break; + case 'i': + iface_ip = optarg; + break; + case 'h': + default: + fprintf(stderr, "usage: %s [-i interface_ip] [-p port]\n", argv[0]); + return 1; + } + + if ( (sfd = tobind(iface_ip, port)) < 0 ) + return 1; + + daemonize(); + + ip_desc_db_reload(cfgfile); + + event_init(); + event_set(&ev_listen, sfd, EV_READ | EV_PERSIST, listen_cb, &ev_listen); + event_add(&ev_listen, NULL); + signal_set(&ev_sighup, SIGHUP, sighup_cb, &ev_sighup); + signal_add(&ev_sighup, NULL); + event_dispatch(); + + return 0; +} diff --git a/daemon/fromd/ip_desc_db.c b/daemon/fromd/ip_desc_db.c new file mode 100644 index 00000000..137e5fa7 --- /dev/null +++ b/daemon/fromd/ip_desc_db.c @@ -0,0 +1,103 @@ +// $Id$ +#include +#include +#include +#include +#include +#include + +#include "bbs.h" + +typedef struct { + uint32_t network, netmask; + char desc[32]; +} db_entry; + +static db_entry *db = NULL; +static int db_len = 0, db_size = 0; + +#define DB_INCREMENT 200 + +int ip_desc_db_reload(const char * cfgfile) +{ + FILE *fp; + char buf[256]; + char *ip, *mask; + db_entry *new_db = NULL; + int new_db_len = 0, new_db_size = 0; + int result = 0; + + if ( (fp = fopen(cfgfile, "r")) == NULL) + return -1; + + while (fgets(buf, sizeof(buf), fp)) { + //skip empty lines + if (!buf[0] || buf[0] == '\n') + continue; + + ip = strtok(buf, " \t\n"); + + if (ip == NULL || *ip == '#' || *ip == '@') + continue; + + // expand database if nessecary + if (new_db_len == new_db_size) { + void * ptr; + if ( (ptr = realloc(new_db, sizeof(db_entry) * + (new_db_size + DB_INCREMENT))) == NULL ) { + result = 1; + break; + } + + new_db = ptr; + new_db_size += DB_INCREMENT; + } + + // netmask + if ( (mask = strchr(ip, '/')) != NULL ) { + int shift = 32 - atoi(mask + 1); + new_db[new_db_len].netmask = htonl(0xFFFFFFFFu << shift); + *mask = '\0'; + } + else + new_db[new_db_len].netmask = 0xFFFFFFFFu; + + // network + new_db[new_db_len].network = htonl(ipstr2int(ip)) & + new_db[new_db_len].netmask; + + // description + if ( (ip = strtok(NULL, " \t\n")) == NULL ) { + strcpy(new_db[new_db_len].desc, "¶³²`¤£ª¾³B"); + } + else { + strlcpy(new_db[new_db_len].desc, ip, + sizeof(new_db[new_db_len].desc)); + } + + new_db_len++; + } + + fclose(fp); + + if (new_db != NULL) { + free(db); + db = new_db; + db_len = new_db_len; + db_size = new_db_size; + } + + return result; +} + +const char * ip_desc_db_lookup(const char * ip) +{ + int i; + + for (i = 0; i < db_len; i++) { + if (db[i].network == (htonl(ipstr2int(ip)) & db[i].netmask)) { + return db[i].desc; + } + } + return ip; +} diff --git a/daemon/fromd/ip_desc_db.h b/daemon/fromd/ip_desc_db.h new file mode 100644 index 00000000..d67ebae5 --- /dev/null +++ b/daemon/fromd/ip_desc_db.h @@ -0,0 +1,6 @@ +// $Id$ +#ifndef _IP_DESC_DB_H +#define _IP_DESC_DB_H +int ip_desc_db_reload(const char * cfgfile); +const char * ip_desc_db_lookup(const char * ip); +#endif -- cgit v1.2.3