summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pttbbs/daemon/barebone/Makefile14
-rw-r--r--pttbbs/daemon/barebone/server.c194
-rw-r--r--pttbbs/daemon/barebone/server.h19
l---------[-rw-r--r--]pttbbs/daemon/boardd/server.c195
l---------[-rw-r--r--]pttbbs/daemon/boardd/server.h20
5 files changed, 229 insertions, 213 deletions
diff --git a/pttbbs/daemon/barebone/Makefile b/pttbbs/daemon/barebone/Makefile
new file mode 100644
index 00000000..d478d1db
--- /dev/null
+++ b/pttbbs/daemon/barebone/Makefile
@@ -0,0 +1,14 @@
+# $Id$
+
+SRCROOT= ../..
+.include "$(SRCROOT)/pttbbs.mk"
+
+PROG= server
+SRCS= server.c
+
+CFLAGS+= $(LIBEVENT_CFLAGS)
+LDFLAGS+= $(LIBEVENT_LIBS_L)
+
+LDADD+= $(LIBEVENT_LIBS_l)
+
+.include <bsd.prog.mk>
diff --git a/pttbbs/daemon/barebone/server.c b/pttbbs/daemon/barebone/server.c
new file mode 100644
index 00000000..2f9bbac1
--- /dev/null
+++ b/pttbbs/daemon/barebone/server.c
@@ -0,0 +1,194 @@
+// $Id$
+// Barebone TCP socket server daemon based on libevent 2.0
+
+// Copyright (c) 2011, Chen-Yu Tsai <wens@csie.org>
+// All rights reserved.
+
+// This is a simple TCP/IP server daemon based on libevent 2.0.
+// This program does not depend on anything other than libevent 2.0.
+// Without additional code linked in, this program alone will behave as an
+// echo server.
+//
+// You can supply your client_read_cb(), client_event_cb(), setup_client(), or
+// setup_program() functions to modify the behavior of the server.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <event2/event.h>
+#include <event2/buffer.h>
+#include <event2/bufferevent.h>
+#include <event2/util.h>
+#include <event2/listener.h>
+
+#include "server.h"
+
+static const struct timeval timeout = {600, 0};
+
+int
+split_args(char *line, char ***argp)
+{
+ int argc = 0;
+ char *p, **argv;
+
+ if ((argv = calloc(MAX_ARGS + 1, sizeof(char *))) == NULL)
+ return -1;
+
+ while ((p = strsep(&line, " \t\r\n")) != NULL) {
+ argv[argc++] = p;
+
+ if (argc == MAX_ARGS)
+ break;
+ }
+
+ argv = realloc(argv, (argc + 1) * sizeof(char *));
+ *argp = argv;
+
+ return argc;
+}
+
+void __attribute__((weak))
+client_read_cb(struct bufferevent *bev, void *ctx)
+{
+ bufferevent_write_buffer(bev, bufferevent_get_input(bev));
+}
+
+void __attribute__((weak))
+client_event_cb(struct bufferevent *bev, short events, void *ctx)
+{
+ if (events & BEV_EVENT_ERROR)
+ perror("Error from bufferevent");
+ if (events & (BEV_EVENT_EOF | BEV_EVENT_TIMEOUT | BEV_EVENT_ERROR)) {
+ bufferevent_free(bev);
+ }
+}
+
+void __attribute__((weak))
+setup_client(struct event_base *base, evutil_socket_t fd,
+ struct sockaddr *address, int socklen)
+{
+ struct bufferevent *bev = bufferevent_socket_new(base, fd,
+ BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS);
+ bufferevent_setcb(bev, client_read_cb, NULL, client_event_cb, NULL);
+ bufferevent_set_timeouts(bev, &timeout, &timeout);
+ bufferevent_enable(bev, EV_READ|EV_WRITE);
+}
+
+static void
+accept_conn_cb(struct evconnlistener *listener, evutil_socket_t fd,
+ struct sockaddr *address, int socklen, void *ctx)
+{
+ struct event_base *base = evconnlistener_get_base(listener);
+ return setup_client(base, fd, address, socklen);
+}
+
+int __attribute__((weak)) daemon(int nochdir, int noclose);
+void __attribute__((weak)) setup_program();
+
+int main(int argc, char *argv[])
+{
+ int ch, inetd = 0, run_as_daemon = 1;
+ const char *iface_ip = "127.0.0.1:5150";
+ struct event_base *base;
+ struct evconnlistener *listener;
+
+ while ((ch = getopt(argc, argv, "Dil:h")) != -1)
+ switch (ch) {
+ case 'D':
+ run_as_daemon = 0;
+ break;
+ case 'i':
+ inetd = 1;
+ break;
+ case 'l':
+ iface_ip = optarg;
+ break;
+ case 'h':
+ default:
+ fprintf(stderr, "usage: " " [-D] [-i] [-l interface_ip:port]\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (run_as_daemon && !inetd)
+ if (daemon(1, 1) < 0) {
+ perror("daemon");
+ exit(EXIT_FAILURE);
+ }
+
+ base = event_base_new();
+ assert(base);
+
+ if (!inetd) {
+ struct sockaddr sa;
+ int len = sizeof(sa);
+
+ if (evutil_parse_sockaddr_port(iface_ip, &sa, &len) < 0)
+ exit(EXIT_FAILURE);
+
+ listener = evconnlistener_new_bind(base, accept_conn_cb, NULL,
+ LEV_OPT_CLOSE_ON_FREE | LEV_OPT_CLOSE_ON_EXEC | LEV_OPT_REUSEABLE,
+ 100, &sa, len);
+
+ if (!listener)
+ exit(EXIT_FAILURE);
+ } else {
+ struct sockaddr sa;
+ socklen_t len = sizeof(sa);
+ getpeername(0, &sa, &len);
+ setup_client(base, 0, &sa, len);
+ }
+
+ if (setup_program)
+ setup_program();
+
+ signal(SIGPIPE, SIG_IGN);
+
+ event_base_dispatch(base);
+
+ return 0;
+}
+
+#ifdef __linux__
+
+int
+daemon(int nochdir, int noclose)
+{
+ int fd;
+
+ switch (fork()) {
+ case -1:
+ return -1;
+ case 0:
+ break;
+ default:
+ _exit(0);
+ }
+
+ if (setsid() == -1)
+ return -1;
+
+ if (!nochdir)
+ chdir("/");
+
+ if (!noclose && (fd = open("/dev/null", O_RDWR)) >= 0) {
+ dup2(fd, 0);
+ dup2(fd, 1);
+ dup2(fd, 2);
+
+ if (fd > 2)
+ close(fd);
+ }
+
+ return 0;
+}
+
+#endif // __linux__
diff --git a/pttbbs/daemon/barebone/server.h b/pttbbs/daemon/barebone/server.h
new file mode 100644
index 00000000..9cba93b7
--- /dev/null
+++ b/pttbbs/daemon/barebone/server.h
@@ -0,0 +1,19 @@
+// $Id$
+
+// Copyright (c) 2011, Chen-Yu Tsai <wens@csie.org>
+// All rights reserved.
+
+#include <event2/listener.h>
+#include <event2/bufferevent.h>
+
+#ifndef MAX_ARGS
+#define MAX_ARGS 100
+#endif
+
+extern void client_read_cb(struct bufferevent *bev, void *ctx);
+extern void client_event_cb(struct bufferevent *bev, short events, void *ctx);
+extern void setup_client(struct event_base *base, evutil_socket_t fd,
+ struct sockaddr *address, int socklen);
+extern void setup_program();
+
+extern int split_args(char *line, char ***argp);
diff --git a/pttbbs/daemon/boardd/server.c b/pttbbs/daemon/boardd/server.c
index 2f9bbac1..88ec683f 100644..120000
--- a/pttbbs/daemon/boardd/server.c
+++ b/pttbbs/daemon/boardd/server.c
@@ -1,194 +1 @@
-// $Id$
-// Barebone TCP socket server daemon based on libevent 2.0
-
-// Copyright (c) 2011, Chen-Yu Tsai <wens@csie.org>
-// All rights reserved.
-
-// This is a simple TCP/IP server daemon based on libevent 2.0.
-// This program does not depend on anything other than libevent 2.0.
-// Without additional code linked in, this program alone will behave as an
-// echo server.
-//
-// You can supply your client_read_cb(), client_event_cb(), setup_client(), or
-// setup_program() functions to modify the behavior of the server.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <unistd.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include <event2/event.h>
-#include <event2/buffer.h>
-#include <event2/bufferevent.h>
-#include <event2/util.h>
-#include <event2/listener.h>
-
-#include "server.h"
-
-static const struct timeval timeout = {600, 0};
-
-int
-split_args(char *line, char ***argp)
-{
- int argc = 0;
- char *p, **argv;
-
- if ((argv = calloc(MAX_ARGS + 1, sizeof(char *))) == NULL)
- return -1;
-
- while ((p = strsep(&line, " \t\r\n")) != NULL) {
- argv[argc++] = p;
-
- if (argc == MAX_ARGS)
- break;
- }
-
- argv = realloc(argv, (argc + 1) * sizeof(char *));
- *argp = argv;
-
- return argc;
-}
-
-void __attribute__((weak))
-client_read_cb(struct bufferevent *bev, void *ctx)
-{
- bufferevent_write_buffer(bev, bufferevent_get_input(bev));
-}
-
-void __attribute__((weak))
-client_event_cb(struct bufferevent *bev, short events, void *ctx)
-{
- if (events & BEV_EVENT_ERROR)
- perror("Error from bufferevent");
- if (events & (BEV_EVENT_EOF | BEV_EVENT_TIMEOUT | BEV_EVENT_ERROR)) {
- bufferevent_free(bev);
- }
-}
-
-void __attribute__((weak))
-setup_client(struct event_base *base, evutil_socket_t fd,
- struct sockaddr *address, int socklen)
-{
- struct bufferevent *bev = bufferevent_socket_new(base, fd,
- BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS);
- bufferevent_setcb(bev, client_read_cb, NULL, client_event_cb, NULL);
- bufferevent_set_timeouts(bev, &timeout, &timeout);
- bufferevent_enable(bev, EV_READ|EV_WRITE);
-}
-
-static void
-accept_conn_cb(struct evconnlistener *listener, evutil_socket_t fd,
- struct sockaddr *address, int socklen, void *ctx)
-{
- struct event_base *base = evconnlistener_get_base(listener);
- return setup_client(base, fd, address, socklen);
-}
-
-int __attribute__((weak)) daemon(int nochdir, int noclose);
-void __attribute__((weak)) setup_program();
-
-int main(int argc, char *argv[])
-{
- int ch, inetd = 0, run_as_daemon = 1;
- const char *iface_ip = "127.0.0.1:5150";
- struct event_base *base;
- struct evconnlistener *listener;
-
- while ((ch = getopt(argc, argv, "Dil:h")) != -1)
- switch (ch) {
- case 'D':
- run_as_daemon = 0;
- break;
- case 'i':
- inetd = 1;
- break;
- case 'l':
- iface_ip = optarg;
- break;
- case 'h':
- default:
- fprintf(stderr, "usage: " " [-D] [-i] [-l interface_ip:port]\n");
- exit(EXIT_FAILURE);
- }
-
- if (run_as_daemon && !inetd)
- if (daemon(1, 1) < 0) {
- perror("daemon");
- exit(EXIT_FAILURE);
- }
-
- base = event_base_new();
- assert(base);
-
- if (!inetd) {
- struct sockaddr sa;
- int len = sizeof(sa);
-
- if (evutil_parse_sockaddr_port(iface_ip, &sa, &len) < 0)
- exit(EXIT_FAILURE);
-
- listener = evconnlistener_new_bind(base, accept_conn_cb, NULL,
- LEV_OPT_CLOSE_ON_FREE | LEV_OPT_CLOSE_ON_EXEC | LEV_OPT_REUSEABLE,
- 100, &sa, len);
-
- if (!listener)
- exit(EXIT_FAILURE);
- } else {
- struct sockaddr sa;
- socklen_t len = sizeof(sa);
- getpeername(0, &sa, &len);
- setup_client(base, 0, &sa, len);
- }
-
- if (setup_program)
- setup_program();
-
- signal(SIGPIPE, SIG_IGN);
-
- event_base_dispatch(base);
-
- return 0;
-}
-
-#ifdef __linux__
-
-int
-daemon(int nochdir, int noclose)
-{
- int fd;
-
- switch (fork()) {
- case -1:
- return -1;
- case 0:
- break;
- default:
- _exit(0);
- }
-
- if (setsid() == -1)
- return -1;
-
- if (!nochdir)
- chdir("/");
-
- if (!noclose && (fd = open("/dev/null", O_RDWR)) >= 0) {
- dup2(fd, 0);
- dup2(fd, 1);
- dup2(fd, 2);
-
- if (fd > 2)
- close(fd);
- }
-
- return 0;
-}
-
-#endif // __linux__
+../barebone/server.c \ No newline at end of file
diff --git a/pttbbs/daemon/boardd/server.h b/pttbbs/daemon/boardd/server.h
index 9cba93b7..75e7076e 100644..120000
--- a/pttbbs/daemon/boardd/server.h
+++ b/pttbbs/daemon/boardd/server.h
@@ -1,19 +1 @@
-// $Id$
-
-// Copyright (c) 2011, Chen-Yu Tsai <wens@csie.org>
-// All rights reserved.
-
-#include <event2/listener.h>
-#include <event2/bufferevent.h>
-
-#ifndef MAX_ARGS
-#define MAX_ARGS 100
-#endif
-
-extern void client_read_cb(struct bufferevent *bev, void *ctx);
-extern void client_event_cb(struct bufferevent *bev, short events, void *ctx);
-extern void setup_client(struct event_base *base, evutil_socket_t fd,
- struct sockaddr *address, int socklen);
-extern void setup_program();
-
-extern int split_args(char *line, char ***argp);
+../barebone/server.h \ No newline at end of file