--- /dev/null
+/* $Id$ */
+
+#include "tw_server.h"
+
+#include "tw_config.h"
+
+#include <unistd.h>
+#include <string.h>
+
+#include <cm_log.h>
+
+#ifdef __MINGW32__
+#include <winsock2.h>
+#define NO_IPV6
+#else
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#endif
+
+extern struct tw_config config;
+
+fd_set fdset;
+int sockcount = 0;
+int sockets[MAX_PORTS];
+
+#ifdef NO_IPV6
+struct sockaddr_in addresses[MAX_PORTS];
+#else
+struct sockaddr_in6 addresses[MAX_PORTS];
+#endif
+
+void close_socket(int sock) {
+#ifdef __MINGW32__
+ closesocket(sock);
+#else
+ close(sock);
+#endif
+}
+
+int tw_server_init(void) {
+ int i;
+#ifdef __MINGW32__
+ WSADATA wsa;
+ WSAStartup(MAKEWORD(2, 0), &wsa);
+#endif
+ FD_ZERO(&fdset);
+ for(i = 0; config.ports[i] != -1; i++)
+ ;
+ sockcount = i;
+ for(i = 0; config.ports[i] != -1; i++) {
+#ifdef NO_IPV6
+ int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+#else
+ int sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
+#endif
+#ifdef __MINGW32__
+ if(sock == INVALID_SOCKET)
+#else
+ if(sock < 0)
+#endif
+ {
+ cm_log("Server", "Socket creation failure");
+ return 1;
+ }
+ int yes = 1;
+ if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&yes, sizeof(yes)) < 0) {
+ close_socket(sock);
+ cm_log("Server", "setsockopt failure (reuseaddr)");
+ return 1;
+ }
+ if(setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&yes, sizeof(yes)) < 0) {
+ close_socket(sock);
+ cm_log("Server", "setsockopt failure (nodelay)");
+ return 1;
+ }
+#ifndef NO_IPV6
+ int no = 0;
+ if(setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void*)&no, sizeof(no)) < 0) {
+ close_socket(sock);
+ cm_log("Server", "setsockopt failure (IPv6)");
+ return 1;
+ }
+#endif
+ memset(&addresses[i], 0, sizeof(addresses[i]));
+#ifdef NO_IPV6
+ addresses[i].sin_family = AF_INET;
+ addresses[i].sin_addr.s_addr = INADDR_ANY;
+ addresses[i].sin_port = htons(config.ports[i]);
+#else
+ addresses[i].sin6_family = AF_INET6;
+ addresses[i].sin6_addr = in6addr_any;
+ addresses[i].sin6_port = htons(config.ports[i]);
+#endif
+ if(bind(sock, (struct sockaddr*)&addresses[i], sizeof(addresses[i])) < 0) {
+ close_socket(sock);
+ cm_log("Server", "Bind failure");
+ return 1;
+ }
+ if(listen(sock, 128) < 0) {
+ close_socket(sock);
+ cm_log("Server", "Listen failure");
+ return 1;
+ }
+ sockets[i] = sock;
+ }
+ return 0;
+}