# the system one.
#CFLAGS= -DNDEBUG -g -O2 -D"FD_SETSIZE=1024"
SHELL=/bin/sh
-SUBDIRS=libratbox modules extensions src tools servlink doc help
+SUBDIRS=libratbox modules extensions src tools ssld doc help
CLEANDIRS = ${SUBDIRS}
RSA_FILES=rsa_respond/README rsa_respond/respond.c rsa_respond/Makefile
extern FILE *conf_fbfile_in;
extern char conf_line_in[256];
-struct ConfItem
-{
- struct ConfItem *next; /* list node pointer */
- unsigned int status; /* If CONF_ILLEGAL, delete when no clients */
- unsigned int flags;
- int clients; /* Number of *LOCAL* clients using this */
- char *name; /* IRC name, nick, server name, or original u@h */
- char *host; /* host part of user@host */
- char *passwd; /* doubles as kline reason *ugh* */
- char *spasswd; /* Password to send. */
- char *user; /* user part of user@host */
- int port;
- time_t hold; /* Hold action until this time (calendar time) */
- char *className; /* Name of class */
- struct Class *c_class; /* Class of connection */
- rb_patricia_node_t *pnode; /* Our patricia node */
+struct ConfItem\r
+{\r
+ unsigned int status; /* If CONF_ILLEGAL, delete when no clients */\r
+ unsigned int flags;\r
+ int clients; /* Number of *LOCAL* clients using this */\r
+\r
+ union\r
+ {\r
+ char *name; /* IRC name, nick, server name, or original u@h */\r
+ const char *oper;\r
+ } info;\r
+\r
+ char *host; /* host part of user@host */\r
+ char *passwd; /* doubles as kline reason *ugh* */\r
+ char *spasswd; /* Password to send. */\r
+ char *user; /* user part of user@host */\r
+ int port;\r
+ time_t hold; /* Hold action until this time (calendar time) */\r
+ struct Class *c_class; /* Class of connection */\r
+ rb_patricia_node_t *pnode;\r
};
#define CONF_ILLEGAL 0x80000000
+++ /dev/null
-Makefile
-setup.h
-servlink
+++ /dev/null
--i8 -bli0 -ut -nsai -l100 -npcs
\ No newline at end of file
+++ /dev/null
-#
-# Makefile.in for servlink/src
-#
-# $Id: Makefile.in 1285 2006-05-05 15:03:53Z nenolod $
-#
-
-CC = @CC@
-INSTALL = @INSTALL@
-INSTALL_BIN = @INSTALL_PROGRAM@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_SUID = @INSTALL_PROGRAM@ -o root -m 4755
-RM = @RM@
-LEX = @LEX@
-LEXLIB = @LEXLIB@
-CFLAGS = @IRC_CFLAGS@ -DIRCD_PREFIX=\"@prefix@\"
-LDFLAGS = @LDFLAGS@
-MKDEP = @MKDEP@ -DIRCD_PREFIX=\"@prefix@\"
-MV = @MV@
-RM = @RM@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-bindir = @bindir@
-libexecdir = @libexecdir@
-confdir = @confdir@
-localstatedir = @localstatedir@
-
-ZIP_LIB = @ZLIB_LD@
-
-IRCDLIBS = @LIBS@ $(ZIP_LIB)
-
-INCLUDES = -I. -I../include $(SSL_INCLUDES)
-CPPFLAGS = ${INCLUDES} @CPPFLAGS@
-
-PROGS = servlink
-
-SOURCES = \
- servlink.c \
- io.c \
- control.c
-
-
-OBJECTS = ${SOURCES:.c=.o}
-
-all: servlink
-
-build: all
-
-servlink: ${OBJECTS}
- ${CC} ${CFLAGS} ${LDFLAGS} -o $@ ${OBJECTS} ${IRCDLIBS}
-
-install: build
- @echo "ircd: installing servlink ($(PROGS))"
- @for i in $(PROGS); do \
- if test -f $(DESTDIR)$(bindir)/$$i; then \
- $(MV) $(DESTDIR)$(bindir)/$$i $(DESTDIR)$(bindir)/$$i.old; \
- fi; \
- $(INSTALL_BIN) $$i $(DESTDIR)$(bindir); \
- done
-
-.c.o:
- ${CC} ${CPPFLAGS} ${CFLAGS} -c $<
-
-.PHONY: depend clean distclean
-depend:
- @${MKDEP} ${CPPFLAGS} ${SOURCES} > .depend.tmp
- @sed -e '/^# DO NOT DELETE THIS LINE/,$$d' <Makefile >Makefile.depend
- @echo '# DO NOT DELETE THIS LINE!!!' >>Makefile.depend
- @echo '# make depend needs it.' >>Makefile.depend
- @cat .depend.tmp >>Makefile.depend
- @mv Makefile.depend Makefile
- @rm -f .depend.tmp
-
-clean:
- ${RM} -f *.o *~ *.core core servlink
-
-lint:
- lint -aacgprxhH $(CPPFLAGS) -DIRCD_PREFIX=\"@prefix@\" $(SOURCES) >>../lint.out
-
-distclean: clean
- ${RM} -f Makefile
-
-# End of Makefile
+++ /dev/null
-Servlink protocol documentation.
-$Id: README 1285 2006-05-05 15:03:53Z nenolod $
---------------
-
-After negotiating an incoming/outgoing server connection, the ircd will
-fork, then execve servlink, with fd 0 as one end of a control pipe and
-fd 1 as one end of a data pipe. fd 2 will be the socket connected to
-the remote server.
-
-The data pipe is used by the ircd to send/receive normal, decrypted,
-uncompressed IRC commands to/from the remote server. The socket is used to
-send the (processed) data to the remote server, and receive the data from
-the remote server.
-
-The control pipe is used to activate encryption/compression and to set the
-encryption key/algorithm to be used.
-
-Format of control messages:
-
-<u8 command><optional data>
-
-data format:
-<u16 len><data>
-
-Commands:
-
-001 - SET_ZIP_OUT_LEVEL
- data: yes
- description:
- set compression level (0 [use default, 6], or 1-9)
-
-002 - START_ZIP_OUT
- data: no
- description:
- all data written to the data pipe will be compressed
- prior to being sent to the remote server.
-
-003 - START_ZIP_IN
- data: no
- description:
- all data not yet read from the slink program will be
- decompressed before reading
-
-004 - INJECT_RECVQ
- data: recvq
-
- Used before INIT to inject any data read from the server fd which
- should be pre-processed by servlink before being sent back
- to the LOCAL_FD through the data fd.
-
-005 - INJECT_SENDQ
- data: sendq
-
- As above, but sent to remote server without processing.
-
-006 - INIT
-
-007 - ZIPSTATS
- request to send ziplinks statistics reply.
-
-replies
-
-001 - ERROR
- data: u32 len/char error[len]
-
- fatal error message.
-
-002 - ZIPSTATS
- data: u32 in/u32 in_wire/u32 out/u32 out_wire
-
- ziplinks commpression statistics
+++ /dev/null
-Servlink todo list
-$Id: TODO 6 2005-09-10 01:02:21Z nenolod $
-------------------
-
-Fix any bugs that come up
-
-Think of improvements :)
+++ /dev/null
-/************************************************************************
- * IRC - Internet Relay Chat, servlink/servlink.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: control.c 1285 2006-05-05 15:03:53Z nenolod $
- */
-
-#include "setup.h"
-
-#include <sys/types.h>
-
-#include <assert.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#ifdef HAVE_LIBZ
-#include <zlib.h>
-#endif
-
-#include "servlink.h"
-#include "io.h"
-#include "control.h"
-
-static cmd_handler cmd_set_zip_out_level;
-static cmd_handler cmd_start_zip_out;
-static cmd_handler cmd_start_zip_in;
-static cmd_handler cmd_init;
-
-struct command_def command_table[] = {
- {CMD_SET_ZIP_OUT_LEVEL, cmd_set_zip_out_level, COMMAND_FLAG_DATA},
- {CMD_START_ZIP_OUT, cmd_start_zip_out, 0},
- {CMD_START_ZIP_IN, cmd_start_zip_in, 0},
- {CMD_INJECT_RECVQ, process_recvq, COMMAND_FLAG_DATA},
- {CMD_INJECT_SENDQ, process_sendq, COMMAND_FLAG_DATA},
- {CMD_INIT, cmd_init, 0},
- {CMD_ZIPSTATS, send_zipstats, 0},
- {0, 0, 0}
-};
-
-void
-cmd_set_zip_out_level(struct ctrl_command *cmd)
-{
-#ifdef HAVE_LIBZ
- out_state.zip_state.level = *cmd->data;
- if((out_state.zip_state.level < -1) || (out_state.zip_state.level > 9))
- send_error("invalid compression level %d", out_state.zip_state.level);
-#else
- send_error("can't set compression level - no libz support!");
-#endif
-}
-
-void
-cmd_start_zip_out(struct ctrl_command *cmd)
-{
-#ifdef HAVE_LIBZ
- int ret;
-
- if(out_state.zip)
- send_error("can't start compression - already started!");
-
- out_state.zip_state.z_stream.total_in = 0;
- out_state.zip_state.z_stream.total_out = 0;
- out_state.zip_state.z_stream.zalloc = (alloc_func) 0;
- out_state.zip_state.z_stream.zfree = (free_func) 0;
- out_state.zip_state.z_stream.data_type = Z_ASCII;
-
- if(out_state.zip_state.level <= 0)
- out_state.zip_state.level = Z_DEFAULT_COMPRESSION;
-
- if((ret = deflateInit(&out_state.zip_state.z_stream, out_state.zip_state.level)) != Z_OK)
- send_error("deflateInit failed: %s", zError(ret));
-
- out_state.zip = 1;
-#else
- send_error("can't start compression - no libz support!");
-#endif
-}
-
-void
-cmd_start_zip_in(struct ctrl_command *cmd)
-{
-#ifdef HAVE_LIBZ
- int ret;
-
- if(in_state.zip)
- send_error("can't start decompression - already started!");
-
- in_state.zip_state.z_stream.total_in = 0;
- in_state.zip_state.z_stream.total_out = 0;
- in_state.zip_state.z_stream.zalloc = (alloc_func) 0;
- in_state.zip_state.z_stream.zfree = (free_func) 0;
- in_state.zip_state.z_stream.data_type = Z_ASCII;
- if((ret = inflateInit(&in_state.zip_state.z_stream)) != Z_OK)
- send_error("inflateInit failed: %s", zError(ret));
- in_state.zip = 1;
-#else
- send_error("can't start decompression - no libz support!");
-#endif
-}
-
-
-void
-cmd_init(struct ctrl_command *cmd)
-{
- if(in_state.active || out_state.active)
- send_error("CMD_INIT sent twice!");
-
- in_state.active = 1;
- out_state.active = 1;
- CONTROL.read_cb = read_ctrl;
- CONTROL.write_cb = NULL;
- LOCAL.read_cb = read_data;
- LOCAL.write_cb = NULL;
- REMOTE.read_cb = read_net;
- REMOTE.write_cb = NULL;
-}
+++ /dev/null
-/************************************************************************
- * IRC - Internet Relay Chat, servlink/control.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: control.h 1285 2006-05-05 15:03:53Z nenolod $
- */
-
-#ifndef INCLUDED_servlink_control_h
-#define INCLUDED_servlink_control_h
-
-#define CMD_SET_ZIP_OUT_LEVEL 1 /* data */
-#define CMD_START_ZIP_OUT 2
-#define CMD_START_ZIP_IN 3
-#define CMD_INJECT_RECVQ 4 /* data */
-#define CMD_INJECT_SENDQ 5 /* data */
-#define CMD_INIT 6
-#define CMD_ZIPSTATS 7
-
-#define RPL_ERROR 1 /* data */
-#define RPL_ZIPSTATS 2 /* data */
-
-/* flags */
-#define COMMAND_FLAG_DATA 0x0001 /* command has data
- following */
-struct ctrl_command
-{
- int command;
- int datalen;
- int gotdatalen;
- int readdata;
- unsigned char *data;
-};
-
-typedef void cmd_handler(struct ctrl_command *);
-
-struct command_def
-{
- unsigned int commandid;
- cmd_handler *handler;
- unsigned int flags;
-};
-
-extern struct command_def command_table[];
-#endif /* INCLUDED_servlink_control_h */
+++ /dev/null
-/************************************************************************
- * IRC - Internet Relay Chat, servlink/io.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: io.c 3319 2007-03-29 20:03:06Z jilles $
- */
-
-#include "setup.h"
-
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#ifdef HAVE_LIBZ
-#include <zlib.h>
-#endif
-
-#include "servlink.h"
-#include "io.h"
-#include "control.h"
-
-static int check_error(int, int, int);
-
-static const char *
-fd_name(int fd)
-{
- if(fd == CONTROL.fd)
- return "control";
- if(fd == LOCAL.fd)
- return "data";
- if(fd == REMOTE.fd)
- return "network";
-
- /* uh oh... */
- return "unknown";
-}
-
-#if defined( HAVE_LIBZ )
-static unsigned char tmp_buf[BUFLEN];
-static unsigned char tmp2_buf[BUFLEN];
-#endif
-
-static unsigned char ctrl_buf[256] = "";
-static unsigned int ctrl_len = 0;
-static unsigned int ctrl_ofs = 0;
-
-void
-io_loop(int nfds)
-{
- fd_set rfds;
- fd_set wfds;
- int i, ret;
-
- /* loop forever */
- for (;;)
- {
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
-
- for (i = 0; i < 3; i++)
- {
- if(fds[i].read_cb)
- FD_SET(fds[i].fd, &rfds);
- if(fds[i].write_cb)
- FD_SET(fds[i].fd, &wfds);
- }
-
- /* we have <3 fds ever, so I don't think select is too painful */
- ret = select(nfds, &rfds, &wfds, NULL, NULL);
-
- if(ret < 0)
- {
- check_error(ret, IO_SELECT, -1); /* exit on fatal errors */
- }
- else if(ret > 0)
- {
- /* call any callbacks */
- for (i = 2; i >= 0; i--)
- {
- if(FD_ISSET(fds[i].fd, &rfds) && fds[i].read_cb)
- (*fds[i].read_cb) ();
- if(FD_ISSET(fds[i].fd, &wfds) && fds[i].write_cb)
- (*fds[i].write_cb) ();
- }
- }
- }
-}
-
-void
-send_data_blocking(int fd, unsigned char *data, int datalen)
-{
- int ret;
- fd_set wfds;
-
- while (1)
- {
- ret = write(fd, data, datalen);
-
- if(ret == datalen)
- return;
- else if(ret > 0)
- {
- data += ret;
- datalen -= ret;
- }
-
- ret = check_error(ret, IO_WRITE, fd);
-
- FD_ZERO(&wfds);
- FD_SET(fd, &wfds);
-
- /* sleep until we can write to the fd */
- while (1)
- {
- ret = select(fd + 1, NULL, &wfds, NULL, NULL);
-
- if(ret > 0) /* break out so we can write */
- break;
-
- if(ret < 0) /* error ? */
- check_error(ret, IO_SELECT, fd); /* exit on fatal errors */
-
- /* loop on non-fatal errors */
- }
- }
-}
-
-/*
- * process_sendq:
- *
- * used before CMD_INIT to pass contents of SendQ from ircd
- * to servlink. This data must _not_ be encrypted/compressed.
- */
-void
-process_sendq(struct ctrl_command *cmd)
-{
- send_data_blocking(REMOTE.fd, cmd->data, cmd->datalen);
-}
-
-/*
- * process_recvq:
- *
- * used before CMD_INIT to pass contents of RecvQ from ircd
- * to servlink. This data must be decrypted/decopmressed before
- * sending back to the ircd.
- */
-void
-process_recvq(struct ctrl_command *cmd)
-{
- int ret;
- unsigned char *buf;
- int blen;
- unsigned char *data = cmd->data;
- unsigned int datalen = cmd->datalen;
-
- buf = data;
- blen = datalen;
- ret = -1;
- if(datalen > READLEN)
- send_error("Error processing INJECT_RECVQ - buffer too long (%d > %d)",
- datalen, READLEN);
-
-#ifdef HAVE_LIBZ
- if(in_state.zip)
- {
- /* decompress data */
- in_state.zip_state.z_stream.next_in = buf;
- in_state.zip_state.z_stream.avail_in = blen;
- in_state.zip_state.z_stream.next_out = tmp2_buf;
- in_state.zip_state.z_stream.avail_out = BUFLEN;
-
- buf = tmp2_buf;
- while (in_state.zip_state.z_stream.avail_in)
- {
- if((ret = inflate(&in_state.zip_state.z_stream, Z_NO_FLUSH)) != Z_OK)
- {
- if(!strncmp("ERROR ", (char *)in_state.zip_state.z_stream.next_in, 6))
- send_error("Received uncompressed ERROR");
- else
- send_error("Inflate failed: %s", zError(ret));
- }
- blen = BUFLEN - in_state.zip_state.z_stream.avail_out;
-
- if(in_state.zip_state.z_stream.avail_in)
- {
- send_data_blocking(LOCAL.fd, buf, blen);
- blen = 0;
- in_state.zip_state.z_stream.next_out = buf;
- in_state.zip_state.z_stream.avail_out = BUFLEN;
- }
- }
-
- if(!blen)
- return;
- }
-#endif
-
- send_data_blocking(LOCAL.fd, buf, blen);
-}
-
-void
-send_zipstats(struct ctrl_command *unused)
-{
-#ifdef HAVE_LIBZ
- int i = 0;
- int ret;
- u_int32_t len;
- if(!in_state.active || !out_state.active)
- send_error("Error processing CMD_ZIPSTATS - link is not active!");
- if(!in_state.zip || !out_state.zip)
- send_error("Error processing CMD_ZIPSTATS - link is not compressed!");
-
- ctrl_buf[i++] = RPL_ZIPSTATS;
- ctrl_buf[i++] = 0;
- ctrl_buf[i++] = 16;
-
- len = (u_int32_t) in_state.zip_state.z_stream.total_out;
- ctrl_buf[i++] = ((len >> 24) & 0xFF);
- ctrl_buf[i++] = ((len >> 16) & 0xFF);
- ctrl_buf[i++] = ((len >> 8) & 0xFF);
- ctrl_buf[i++] = ((len) & 0xFF);
-
- len = (u_int32_t) in_state.zip_state.z_stream.total_in;
- ctrl_buf[i++] = ((len >> 24) & 0xFF);
- ctrl_buf[i++] = ((len >> 16) & 0xFF);
- ctrl_buf[i++] = ((len >> 8) & 0xFF);
- ctrl_buf[i++] = ((len) & 0xFF);
-
- len = (u_int32_t) out_state.zip_state.z_stream.total_in;
- ctrl_buf[i++] = ((len >> 24) & 0xFF);
- ctrl_buf[i++] = ((len >> 16) & 0xFF);
- ctrl_buf[i++] = ((len >> 8) & 0xFF);
- ctrl_buf[i++] = ((len) & 0xFF);
-
- len = (u_int32_t) out_state.zip_state.z_stream.total_out;
- ctrl_buf[i++] = ((len >> 24) & 0xFF);
- ctrl_buf[i++] = ((len >> 16) & 0xFF);
- ctrl_buf[i++] = ((len >> 8) & 0xFF);
- ctrl_buf[i++] = ((len) & 0xFF);
-
- in_state.zip_state.z_stream.total_in = 0;
- in_state.zip_state.z_stream.total_out = 0;
- out_state.zip_state.z_stream.total_in = 0;
- out_state.zip_state.z_stream.total_out = 0;
-
- ret = check_error(write(CONTROL.fd, ctrl_buf, i), IO_WRITE, CONTROL.fd);
- if(ret < i)
- {
- /* write incomplete, register write cb */
- CONTROL.write_cb = write_ctrl;
- /* deregister read_cb */
- CONTROL.read_cb = NULL;
- ctrl_ofs = ret;
- ctrl_len = i - ret;
- return;
- }
-#else
- send_error("can't send_zipstats -- no zlib support!");
-#endif
-}
-
-/* send_error
- * - we ran into some problem, make a last ditch effort to
- * flush the control fd sendq, then (blocking) send an
- * error message over the control fd.
- */
-void
-send_error(const char *message, ...)
-{
- va_list args;
- static int sending_error = 0;
- struct linger linger_opt = { 1, 30 }; /* wait 30 seconds */
- int len;
-
- if(sending_error)
- exit(1); /* we did _try_ */
-
- sending_error = 1;
-
- if(ctrl_len) /* attempt to flush any data we have... */
- {
- send_data_blocking(CONTROL.fd, (ctrl_buf + ctrl_ofs), ctrl_len);
- }
-
- /* prepare the message, in in_buf, since we won't be using it again.. */
- in_state.buf[0] = RPL_ERROR;
- in_state.buf[1] = 0;
- in_state.buf[2] = 0;
-
- va_start(args, message);
- len = vsprintf((char *) in_state.buf + 3, message, args);
- va_end(args);
-
- in_state.buf[3 + len++] = '\0';
- in_state.buf[1] = len >> 8;
- in_state.buf[2] = len & 0xFF;
- len += 3;
-
- send_data_blocking(CONTROL.fd, in_state.buf, len);
-
- /* XXX - is this portable?
- * this obviously will fail on a non socket.. */
- setsockopt(CONTROL.fd, SOL_SOCKET, SO_LINGER, &linger_opt, sizeof(struct linger));
-
- /* well, we've tried... */
- exit(1); /* now abort */
-}
-
-/* read_ctrl
- * called when a command is waiting on the control pipe
- */
-void
-read_ctrl(void)
-{
- int ret;
- unsigned char tmp[2];
- unsigned char *len;
- struct command_def *cdef;
- static struct ctrl_command cmd = { 0, 0, 0, 0, NULL };
-
- if(cmd.command == 0) /* we don't have a command yet */
- {
- cmd.gotdatalen = 0;
- cmd.datalen = 0;
- cmd.readdata = 0;
- cmd.data = NULL;
-
- /* read the command */
- if(!(ret = check_error(read(CONTROL.fd, tmp, 1), IO_READ, CONTROL.fd)))
- return;
-
- cmd.command = tmp[0];
- }
-
- for (cdef = command_table; cdef->commandid; cdef++)
- {
- if((int)cdef->commandid == cmd.command)
- break;
- }
-
- if(!cdef->commandid)
- {
- send_error("Unsupported command (servlink/ircd out of sync?): %d", cmd.command);
- /* NOTREACHED */
- }
-
- /* read datalen for commands including data */
- if(cdef->flags & COMMAND_FLAG_DATA)
- {
- if(cmd.gotdatalen < 2)
- {
- len = tmp;
- if(!(ret = check_error(read(CONTROL.fd, len,
- (2 - cmd.gotdatalen)), IO_READ, CONTROL.fd)))
- return;
-
- if(cmd.gotdatalen == 0)
- {
- cmd.datalen = len[0] << 8;
- cmd.gotdatalen++;
- ret--;
- len++;
- }
- if(ret && (cmd.gotdatalen == 1))
- {
- cmd.datalen |= len[0];
- cmd.gotdatalen++;
- if(cmd.datalen > 0)
- cmd.data = calloc(cmd.datalen, 1);
- }
- }
- }
-
- if(cmd.readdata < cmd.datalen) /* try to get any remaining data */
- {
- if(!(ret = check_error(read(CONTROL.fd,
- (cmd.data + cmd.readdata),
- cmd.datalen - cmd.readdata), IO_READ, CONTROL.fd)))
- return;
-
- cmd.readdata += ret;
- if(cmd.readdata < cmd.datalen)
- return;
- }
-
- /* we now have the command and any data */
- (*cdef->handler) (&cmd);
-
- if(cmd.datalen > 0)
- free(cmd.data);
- cmd.command = 0;
-}
-
-void
-write_ctrl(void)
-{
- int ret;
-
- assert(ctrl_len);
-
- if(!(ret = check_error(write(CONTROL.fd, (ctrl_buf + ctrl_ofs),
- ctrl_len), IO_WRITE, CONTROL.fd)))
- return; /* no data waiting */
-
- ctrl_len -= ret;
-
- if(!ctrl_len)
- {
- /* write completed, de-register write cb */
- CONTROL.write_cb = NULL;
- /* reregister read_cb */
- CONTROL.read_cb = read_ctrl;
- ctrl_ofs = 0;
- }
- else
- ctrl_ofs += ret;
-}
-
-void
-read_data(void)
-{
- int ret, ret2;
- unsigned char *buf = out_state.buf;
- int blen;
- ret2 = -1;
- assert(!out_state.len);
-
-#if defined(HAVE_LIBZ)
- if(out_state.zip || out_state.crypt)
- buf = tmp_buf;
-#endif
-
- while ((ret = check_error(read(LOCAL.fd, buf, READLEN), IO_READ, LOCAL.fd)))
- {
- blen = ret;
-#ifdef HAVE_LIBZ
- if(out_state.zip)
- {
- out_state.zip_state.z_stream.next_in = buf;
- out_state.zip_state.z_stream.avail_in = ret;
-
- buf = out_state.buf;
- out_state.zip_state.z_stream.next_out = buf;
- out_state.zip_state.z_stream.avail_out = BUFLEN;
- if(!(ret2 = deflate(&out_state.zip_state.z_stream,
- Z_PARTIAL_FLUSH)) == Z_OK)
- send_error("error compressing outgoing data - deflate returned: %s",
- zError(ret2));
-
- if(!out_state.zip_state.z_stream.avail_out)
- send_error("error compressing outgoing data - avail_out == 0");
- if(out_state.zip_state.z_stream.avail_in)
- send_error("error compressing outgoing data - avail_in != 0");
-
- blen = BUFLEN - out_state.zip_state.z_stream.avail_out;
- }
-#endif
-
-
- ret = check_error(write(REMOTE.fd, out_state.buf, blen), IO_WRITE, REMOTE.fd);
- if(ret < blen)
- {
- /* write incomplete, register write cb */
- REMOTE.write_cb = write_net;
- /* deregister read_cb */
- LOCAL.read_cb = NULL;
- out_state.ofs = ret;
- out_state.len = blen - ret;
- return;
- }
-#if defined(HAVE_LIBZ)
- if(out_state.zip)
- buf = tmp_buf;
-#endif
- }
-
-}
-
-void
-write_net(void)
-{
- int ret;
-
- assert(out_state.len);
-
- if(!(ret = check_error(write(REMOTE.fd,
- (out_state.buf + out_state.ofs),
- out_state.len), IO_WRITE, REMOTE.fd)))
- return; /* no data waiting */
-
- out_state.len -= ret;
-
- if(!out_state.len)
- {
- /* write completed, de-register write cb */
- REMOTE.write_cb = NULL;
- /* reregister read_cb */
- LOCAL.read_cb = read_data;
- out_state.ofs = 0;
- }
- else
- out_state.ofs += ret;
-}
-
-void
-read_net(void)
-{
- int ret;
- int ret2;
- unsigned char *buf = in_state.buf;
- int blen;
- ret2 = -1;
- assert(!in_state.len);
-
-#if defined(HAVE_LIBZ)
- if(in_state.zip)
- buf = tmp_buf;
-#endif
-
- while ((ret = check_error(read(REMOTE.fd, buf, READLEN), IO_READ, REMOTE.fd)))
- {
- blen = ret;
-#ifdef HAVE_LIBZ
- if(in_state.zip)
- {
- /* decompress data */
- in_state.zip_state.z_stream.next_in = buf;
- in_state.zip_state.z_stream.avail_in = ret;
- in_state.zip_state.z_stream.next_out = in_state.buf;
- in_state.zip_state.z_stream.avail_out = BUFLEN;
-
- while (in_state.zip_state.z_stream.avail_in)
- {
- if((ret2 = inflate(&in_state.zip_state.z_stream,
- Z_NO_FLUSH)) != Z_OK)
- {
- if(!strncmp("ERROR ", (char *)buf, 6))
- send_error("Received uncompressed ERROR");
- send_error("Inflate failed: %s", zError(ret2));
- }
- blen = BUFLEN - in_state.zip_state.z_stream.avail_out;
-
- if(in_state.zip_state.z_stream.avail_in)
- {
- if(blen)
- {
- send_data_blocking(LOCAL.fd, in_state.buf, blen);
- blen = 0;
- }
-
- in_state.zip_state.z_stream.next_out = in_state.buf;
- in_state.zip_state.z_stream.avail_out = BUFLEN;
- }
- }
-
- if(!blen)
- return; /* that didn't generate any decompressed input.. */
- }
-#endif
-
- ret = check_error(write(LOCAL.fd, in_state.buf, blen), IO_WRITE, LOCAL.fd);
-
- if(ret < blen)
- {
- in_state.ofs = ret;
- in_state.len = blen - ret;
- /* write incomplete, register write cb */
- LOCAL.write_cb = write_data;
- /* deregister read_cb */
- REMOTE.read_cb = NULL;
- return;
- }
-#if defined(HAVE_LIBZ)
- if(in_state.zip)
- buf = tmp_buf;
-#endif
- }
-}
-
-void
-write_data(void)
-{
- int ret;
-
- assert(in_state.len);
-
- if(!(ret = check_error(write(LOCAL.fd,
- (in_state.buf + in_state.ofs),
- in_state.len), IO_WRITE, LOCAL.fd)))
- return;
-
- in_state.len -= ret;
-
- if(!in_state.len)
- {
- /* write completed, de-register write cb */
- LOCAL.write_cb = NULL;
- /* reregister read_cb */
- REMOTE.read_cb = read_net;
- in_state.ofs = 0;
- }
- else
- in_state.ofs += ret;
-}
-
-int
-check_error(int ret, int io, int fd)
-{
- if(ret > 0) /* no error */
- return ret;
- if(ret == 0) /* EOF */
- {
- send_error("%s failed on %s: EOF", IO_TYPE(io), FD_NAME(fd));
- exit(1); /* NOTREACHED */
- }
-
- /* ret == -1.. */
- switch (errno)
- {
- case EINPROGRESS:
- case EWOULDBLOCK:
-#if EAGAIN != EWOULDBLOCK
- case EAGAIN:
-#endif
- case EALREADY:
- case EINTR:
-#ifdef ERESTART
- case ERESTART:
-#endif
- /* non-fatal error, 0 bytes read */
- return 0;
- }
-
- /* fatal error */
- send_error("%s failed on %s: %s", IO_TYPE(io), FD_NAME(fd), strerror(errno));
- exit(1); /* NOTREACHED */
-}
+++ /dev/null
-/************************************************************************
- * IRC - Internet Relay Chat, servlink/io.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: io.h 6 2005-09-10 01:02:21Z nenolod $
- */
-
-#ifndef INCLUDED_servlink_io_h
-#define INCLUDED_servlink_io_h
-
-#include "control.h"
-
-#define IO_READ 0
-#define IO_WRITE 1
-#define IO_SELECT 2
-
-#define IO_TYPE(io) ((io==IO_SELECT)?"select": \
- ((io==IO_WRITE)?"write":"read"))
-
-#define FD_NAME(fd) (fd_name(fd))
-
-extern void io_loop(int nfds);
-extern void write_data(void);
-extern void read_data(void);
-extern void write_ctrl(void);
-extern void read_ctrl(void);
-extern void write_net(void);
-extern void read_net(void);
-extern void send_error(const char *, ...);
-extern void send_data_blocking(int fd, unsigned char *data, int datalen);
-extern cmd_handler process_recvq;
-extern cmd_handler process_sendq;
-extern cmd_handler send_zipstats;
-
-#endif /* INCLUDED_servlink_io_h */
+++ /dev/null
-/************************************************************************
- * IRC - Internet Relay Chat, servlink/servlink.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: servlink.c 6 2005-09-10 01:02:21Z nenolod $
- */
-
-#include "setup.h"
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#ifdef HAVE_LIBZ
-#include <zlib.h>
-#endif
-
-#include "servlink.h"
-#include "io.h"
-#include "control.h"
-
-static void usage(void);
-
-struct slink_state in_state;
-struct slink_state out_state;
-
-struct fd_table fds[3] = {
- {0, read_ctrl, NULL}, /* ctrl */
- {0, NULL, NULL}, /* data */
- {0, NULL, NULL}, /* net */
-};
-
-/* usage();
- *
- * Display usage message
- */
-static void
-usage(void)
-{
- fprintf(stderr, "ircd-ratbox server link v1.2\n");
- fprintf(stderr, "2004-03-02\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "This program is called by the ircd-ratbox ircd.\n");
- fprintf(stderr, "It cannot be used on its own.\n");
- exit(1);
-}
-
-int
-main(int argc, char *argv[])
-{
- int max_fd = 0;
- int i, x;
-#ifdef SERVLINK_DEBUG
- int GDBAttached = 0;
-
- while (!GDBAttached)
- sleep(1);
-#endif
-
- /* Make sure we are running under ircd.. */
-
- if(argc != 4 || strcmp(argv[0], "-slink"))
- usage(); /* exits */
-
-
- for (i = 0; i < 3; i++)
- {
- fds[i].fd = atoi(argv[i + 1]);
- if(fds[i].fd < 0)
- exit(1);
- }
-
- for (i = 0; i < 3; i++)
- {
- /* XXX: Hack alert...we need to do dup2() here for some dumb
- * platforms (Solaris) that don't like select using fds > 255
- */
-
- if(fds[i].fd >= 255)
- {
- for(x = 0; x < 255; x++)
- {
- if(x != fds[0].fd && x != fds[1].fd && x != fds[2].fd)
- {
- if(dup2(fds[i].fd, x) < 0)
- exit(1);
- close(fds[i].fd);
- fds[i].fd = x;
- break;
- }
- }
- }
- fcntl(fds[i].fd, F_SETFL, O_NONBLOCK);
- if(fds[i].fd > max_fd)
- max_fd = fds[i].fd;
- }
-
- /* enter io loop */
- io_loop(max_fd + 1);
-
- /* NOTREACHED */
- return (0);
-} /* main() */
+++ /dev/null
-/************************************************************************
- * IRC - Internet Relay Chat, servlink/servlink.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: servlink.h 1285 2006-05-05 15:03:53Z nenolod $
- */
-
-#ifndef INCLUDED_servlink_servlink_h
-#define INCLUDED_servlink_servlink_h
-
-#include "setup.h"
-
-#ifdef HAVE_LIBZ
-#include <zlib.h>
-#endif
-
-/* do not use stdin/out/err, as it seems to break on solaris */
-#define CONTROL fds[0]
-#define LOCAL fds[1]
-#define REMOTE fds[2]
-
-#undef SERVLINK_DEBUG
-
-#define READLEN 16384
-
-#ifdef HAVE_LIBZ
-#define BUFLEN READLEN * 6 /* allow for decompression */
-#else
-#define BUFLEN READLEN
-#endif
-
-
-#ifdef HAVE_LIBZ
-struct zip_state
-{
- z_stream z_stream;
- int level; /* compression level */
-};
-#endif
-
-struct slink_state
-{
- unsigned int crypt:1;
- unsigned int zip:1;
- unsigned int active:1;
-
- unsigned char buf[BUFLEN * 2];
- unsigned int ofs;
- unsigned int len;
-
-#ifdef HAVE_LIBZ
- struct zip_state zip_state;
-#endif
-};
-
-
-typedef void (io_callback) (void);
-
-struct fd_table
-{
- int fd;
- io_callback *read_cb;
- io_callback *write_cb;
-};
-
-extern struct slink_state in_state;
-extern struct slink_state out_state;
-extern struct fd_table fds[3];
-
-#endif /* INCLUDED_servlink_servlink_h */
--- /dev/null
+#
+# $Id: Makefile.am 24818 2008-01-02 18:38:26Z androsyn $
+#
+bin_PROGRAMS = ssld
+AM_CFLAGS=$(WARNFLAGS)
+
+INCLUDES = -I../include -I../libratbox/include
+
+
+ssld_SOURCES = ssld.c
+
+ssld_LDADD = ../libratbox/src/libratbox.la @ZLIB_LD@
+
+
--- /dev/null
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = ssld$(EXEEXT)
+subdir = ssld
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/include/setup.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_ssld_OBJECTS = ssld.$(OBJEXT)
+ssld_OBJECTS = $(am_ssld_OBJECTS)
+ssld_DEPENDENCIES = ../libratbox/src/libratbox.la
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(ssld_SOURCES)
+DIST_SOURCES = $(ssld_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CP = @CP@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+ETC_DIR = @ETC_DIR@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GREP = @GREP@
+HELP_DIR = @HELP_DIR@
+INCLTDL = @INCLTDL@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IRCD_PREFIX = @IRCD_PREFIX@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBLTDL = @LIBLTDL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN = @LN@
+LN_S = @LN_S@
+LOG_DIR = @LOG_DIR@
+LTLIBOBJS = @LTLIBOBJS@
+LT_OBJDIR = @LT_OBJDIR@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MODULE_DIR = @MODULE_DIR@
+MV = @MV@
+NMEDIT = @NMEDIT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PICFLAGS = @PICFLAGS@
+RANLIB = @RANLIB@
+RM = @RM@
+SED = @SED@
+SEDOBJ = @SEDOBJ@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SHLIBEXT = @SHLIBEXT@
+SQLITE_INCLUDES = @SQLITE_INCLUDES@
+SQLITE_LD = @SQLITE_LD@
+SQLITE_SUBDIR = @SQLITE_SUBDIR@
+SSL_INCLUDES = @SSL_INCLUDES@
+SSL_LIBS = @SSL_LIBS@
+SSL_SRCS_ENABLE = @SSL_SRCS_ENABLE@
+STRIP = @STRIP@
+TOUCH = @TOUCH@
+VERSION = @VERSION@
+WARNFLAGS = @WARNFLAGS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+ZLIB_LD = @ZLIB_LD@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+confdir = @confdir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+helpdir = @helpdir@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+logdir = @logdir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+moduledir = @moduledir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CFLAGS = $(WARNFLAGS)
+INCLUDES = -I../include -I../libratbox/include
+ssld_SOURCES = ssld.c
+ssld_LDADD = ../libratbox/src/libratbox.la @ZLIB_LD@
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu ssld/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu ssld/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+ssld$(EXEEXT): $(ssld_OBJECTS) $(ssld_DEPENDENCIES)
+ @rm -f ssld$(EXEEXT)
+ $(LINK) $(ssld_OBJECTS) $(ssld_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssld.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libtool ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-binPROGRAMS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+/*
+ * ssld.c: The ircd-ratbox ssl/zlib helper daemon thingy
+ * Copyright (C) 2007 Aaron Sethman <androsyn@ratbox.org>
+ * Copyright (C) 2007 ircd-ratbox development team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ *
+ * $Id: ssld.c 25179 2008-03-30 16:34:57Z androsyn $
+ */
+
+
+#include "stdinc.h"
+
+#ifdef HAVE_ZLIB
+#include <zlib.h>
+#endif
+
+#define MAXPASSFD 4
+#ifndef READBUF_SIZE
+#define READBUF_SIZE 16384
+#endif
+
+static void setup_signals(void);
+
+static inline rb_int32_t buf_to_int32(char *buf)
+{
+ rb_int32_t x;
+ x = *buf << 24;
+ x |= *(++buf) << 16;
+ x |= *(++buf) << 8;
+ x |= *(++buf);
+ return x;
+}
+
+static inline void int32_to_buf(char *buf, rb_int32_t x)
+{
+ *(buf) = x >> 24 & 0xFF;
+ *(++buf) = x >> 16 & 0xFF;
+ *(++buf) = x >> 8 & 0xFF;
+ *(++buf) = x & 0xFF;
+ return;
+}
+
+static inline rb_uint16_t buf_to_uint16(char *buf)
+{
+ rb_uint16_t x;
+ x = *(buf) << 8;
+ x |= *(++buf);
+ return x;
+}
+
+static inline void uint16_to_buf(char *buf, rb_uint16_t x)
+{
+ *(buf) = x >> 8 & 0xFF;
+ *(++buf) = x & 0xFF;
+ return;
+}
+
+
+
+static char inbuf[READBUF_SIZE];
+static char outbuf[READBUF_SIZE];
+
+typedef struct _mod_ctl_buf
+{
+ rb_dlink_node node;
+ char *buf;
+ size_t buflen;
+ rb_fde_t *F[MAXPASSFD];
+ int nfds;
+} mod_ctl_buf_t;
+
+typedef struct _mod_ctl
+{
+ rb_dlink_node node;
+ int cli_count;
+ rb_fde_t *F;
+ rb_fde_t *F_pipe;
+ rb_dlink_list readq;
+ rb_dlink_list writeq;
+} mod_ctl_t;
+
+static mod_ctl_t *mod_ctl;
+
+
+#ifdef HAVE_ZLIB
+typedef struct _zlib_stream
+{
+ z_stream instream;
+ z_stream outstream;
+} zlib_stream_t;
+#endif
+
+typedef struct _conn
+{
+ rb_dlink_node node;
+ mod_ctl_t *ctl;
+ rawbuf_head_t *modbuf_out;
+ rawbuf_head_t *plainbuf_out;
+
+ rb_int32_t id;
+
+ rb_fde_t *mod_fd;
+ rb_fde_t *plain_fd;
+ unsigned long long mod_out;
+ unsigned long long mod_in;
+ unsigned long long plain_in;
+ unsigned long long plain_out;
+ rb_uint8_t flags;
+ void *stream;
+} conn_t;
+
+#define FLAG_SSL 0x01
+#define FLAG_ZIP 0x02
+#define FLAG_CORK 0x04
+#define FLAG_DEAD 0x08
+
+
+#define IsSSL(x) ((x)->flags & FLAG_SSL)
+#define IsZip(x) ((x)->flags & FLAG_ZIP)
+#define IsCork(x) ((x)->flags & FLAG_CORK)
+#define IsDead(x) ((x)->flags & FLAG_DEAD)
+
+#define SetSSL(x) ((x)->flags |= FLAG_SSL)
+#define SetZip(x) ((x)->flags |= FLAG_ZIP)
+#define SetCork(x) ((x)->flags |= FLAG_CORK)
+#define SetDead(x) ((x)->flags |= FLAG_DEAD)
+
+#define ClearSSL(x) ((x)->flags &= ~FLAG_SSL)
+#define ClearZip(x) ((x)->flags &= ~FLAG_ZIP)
+#define ClearCork(x) ((x)->flags &= ~FLAG_CORK)
+#define ClearDead(x) ((x)->flags &= ~FLAG_DEAD)
+
+#define NO_WAIT 0x0
+#define WAIT_PLAIN 0x1
+
+#define CONN_HASH_SIZE 2000
+#define connid_hash(x) (&connid_hash_table[(x % CONN_HASH_SIZE)])
+
+static rb_dlink_list connid_hash_table[CONN_HASH_SIZE];
+static rb_dlink_list dead_list;
+
+static void conn_mod_write_sendq(rb_fde_t *, void *data);
+static void conn_plain_write_sendq(rb_fde_t *, void *data);
+static void mod_write_ctl(rb_fde_t *, void *data);
+static void conn_plain_read_cb(rb_fde_t * fd, void *data);
+static void mod_cmd_write_queue(mod_ctl_t *ctl, const void *data, size_t len);
+static const char *remote_closed = "Remote host closed the connection";
+static int ssl_ok;
+#ifdef HAVE_ZLIB
+static int zlib_ok = 1;
+#else
+static int zlib_ok = 0;
+#endif
+static void *
+ssld_alloc(void *unused, size_t count, size_t size)
+{
+ return rb_malloc(count * size);
+}
+
+static void
+ssld_free(void *unused, void *ptr)
+{
+ rb_free(ptr);
+}
+
+static conn_t *
+conn_find_by_id(rb_int32_t id)
+{
+ rb_dlink_node *ptr;
+ conn_t *conn;
+
+ RB_DLINK_FOREACH(ptr, (connid_hash(id))->head)
+ {
+ conn = ptr->data;
+ if(conn->id == id && !IsDead(conn))
+ return conn;
+ }
+ return NULL;
+}
+
+static void
+conn_add_id_hash(conn_t * conn, rb_int32_t id)
+{
+ conn->id = id;
+ rb_dlinkAdd(conn, &conn->node, connid_hash(id));
+}
+
+static void
+free_conn(conn_t * conn)
+{
+ rb_free_rawbuffer(conn->modbuf_out);
+ rb_free_rawbuffer(conn->plainbuf_out);
+ if(IsZip(conn))
+ {
+ zlib_stream_t *stream = conn->stream;
+ inflateEnd(&stream->instream);
+ deflateEnd(&stream->outstream);
+ }
+ rb_free(conn);
+}
+
+static void
+clean_dead_conns(void *unused)
+{
+ conn_t *conn;
+ rb_dlink_node *ptr, *next;
+ RB_DLINK_FOREACH_SAFE(ptr, next, dead_list.head)
+ {
+ conn = ptr->data;
+ free_conn(conn);
+ }
+ dead_list.tail = dead_list.head = NULL;
+}
+
+
+static void
+close_conn(conn_t * conn, int wait_plain, const char *fmt, ...)
+{
+ va_list ap;
+ char reason[128]; /* must always be under 250 bytes */
+ char buf[256];
+ int len;
+ if(IsDead(conn))
+ return;
+
+ rb_rawbuf_flush(conn->modbuf_out, conn->mod_fd);
+ rb_rawbuf_flush(conn->plainbuf_out, conn->plain_fd);
+ rb_close(conn->mod_fd);
+ SetDead(conn);
+
+ if(!wait_plain || fmt == NULL)
+ {
+ rb_close(conn->plain_fd);
+
+ if(conn->id >= 0)
+ rb_dlinkDelete(&conn->node, connid_hash(conn->id));
+ rb_dlinkAdd(conn, &conn->node, &dead_list);
+ return;
+ }
+ rb_setselect(conn->plain_fd, RB_SELECT_WRITE|RB_SELECT_READ, NULL, NULL);
+ va_start(ap, fmt);
+ rb_vsnprintf(reason, sizeof(reason), fmt, ap);
+ va_end(ap);
+
+ buf[0] = 'D';
+ int32_to_buf(&buf[1], conn->id);
+ strcpy(&buf[5], reason);
+ len = (strlen(reason) + 1) + 5;
+ mod_cmd_write_queue(conn->ctl, buf, len);
+}
+
+static conn_t *
+make_conn(mod_ctl_t *ctl, rb_fde_t * mod_fd, rb_fde_t * plain_fd)
+{
+ conn_t *conn = rb_malloc(sizeof(conn_t));
+ conn->ctl = ctl;
+ conn->modbuf_out = rb_new_rawbuffer();
+ conn->plainbuf_out = rb_new_rawbuffer();
+ conn->mod_fd = mod_fd;
+ conn->plain_fd = plain_fd;
+ conn->id = -1;
+ conn->stream = NULL;
+ rb_set_nb(mod_fd);
+ rb_set_nb(plain_fd);
+ return conn;
+}
+
+static void
+conn_mod_write_sendq(rb_fde_t * fd, void *data)
+{
+ conn_t *conn = data;
+ const char *err;
+ int retlen;
+ if(IsDead(conn))
+ return;
+
+ while ((retlen = rb_rawbuf_flush(conn->modbuf_out, fd)) > 0)
+ conn->mod_out += retlen;
+
+ if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
+ {
+ if(retlen == 0)
+ close_conn(conn, WAIT_PLAIN, "%s", remote_closed);
+ if(IsSSL(conn) && retlen == RB_RW_SSL_ERROR)
+ err = rb_get_ssl_strerror(conn->mod_fd);
+ else
+ err = strerror(errno);
+ close_conn(conn, WAIT_PLAIN, "Write error: %s", err);
+ return;
+ }
+ if(rb_rawbuf_length(conn->modbuf_out) > 0)
+ {
+ int flags = RB_SELECT_WRITE;
+ if(retlen == RB_RW_SSL_NEED_READ)
+ flags |= RB_SELECT_READ;
+
+ rb_setselect(conn->mod_fd, flags, conn_mod_write_sendq, conn);
+ }
+ else
+ rb_setselect(conn->mod_fd, RB_SELECT_WRITE, NULL, NULL);
+
+ if(IsCork(conn) && rb_rawbuf_length(conn->modbuf_out) == 0)
+ {
+ ClearCork(conn);
+ conn_plain_read_cb(conn->plain_fd, conn);
+ }
+
+}
+
+static void
+conn_mod_write(conn_t * conn, void *data, size_t len)
+{
+ if(IsDead(conn)) /* no point in queueing to a dead man */
+ return;
+ rb_rawbuf_append(conn->modbuf_out, data, len);
+}
+
+static void
+conn_plain_write(conn_t * conn, void *data, size_t len)
+{
+ if(IsDead(conn)) /* again no point in queueing to dead men */
+ return;
+ rb_rawbuf_append(conn->plainbuf_out, data, len);
+}
+
+static void
+mod_cmd_write_queue(mod_ctl_t * ctl, const void *data, size_t len)
+{
+ mod_ctl_buf_t *ctl_buf;
+ ctl_buf = rb_malloc(sizeof(mod_ctl_buf_t));
+ ctl_buf->buf = rb_malloc(len);
+ ctl_buf->buflen = len;
+ memcpy(ctl_buf->buf, data, len);
+ ctl_buf->nfds = 0;
+ rb_dlinkAddTail(ctl_buf, &ctl_buf->node, &ctl->writeq);
+ mod_write_ctl(ctl->F, ctl);
+}
+
+#ifdef HAVE_ZLIB
+static void
+common_zlib_deflate(conn_t * conn, void *buf, size_t len)
+{
+ int ret, have;
+ z_stream *outstream = &((zlib_stream_t *)conn->stream)->outstream;
+ outstream->next_in = buf;
+ outstream->avail_in = len;
+ outstream->next_out = (Bytef *) outbuf;
+ outstream->avail_out = sizeof(outbuf);
+
+ ret = deflate(outstream, Z_SYNC_FLUSH);
+ if(ret != Z_OK)
+ {
+ /* deflate error */
+ close_conn(conn, WAIT_PLAIN, "Deflate failed: %s", zError(ret));
+ return;
+ }
+ if(outstream->avail_out == 0)
+ {
+ /* avail_out empty */
+ close_conn(conn, WAIT_PLAIN, "error compressing data, avail_out == 0");
+ return;
+ }
+ if(outstream->avail_in != 0)
+ {
+ /* avail_in isn't empty...*/
+ close_conn(conn, WAIT_PLAIN, "error compressing data, avail_in != 0");
+ return;
+ }
+ have = sizeof(outbuf) - outstream->avail_out;
+ conn_mod_write(conn, outbuf, have);
+}
+
+static void
+common_zlib_inflate(conn_t * conn, void *buf, size_t len)
+{
+ int ret, have;
+ ((zlib_stream_t *)conn->stream)->instream.next_in = buf;
+ ((zlib_stream_t *)conn->stream)->instream.avail_in = len;
+ ((zlib_stream_t *)conn->stream)->instream.next_out = (Bytef *) outbuf;
+ ((zlib_stream_t *)conn->stream)->instream.avail_out = sizeof(outbuf);
+
+ while (((zlib_stream_t *)conn->stream)->instream.avail_in)
+ {
+ ret = inflate(&((zlib_stream_t *)conn->stream)->instream, Z_NO_FLUSH);
+ if(ret != Z_OK)
+ {
+ if(!strncmp("ERROR ", buf, 6))
+ {
+ close_conn(conn, WAIT_PLAIN, "Received uncompressed ERROR");
+ return;
+ }
+ close_conn(conn, WAIT_PLAIN, "Inflate failed: %s", zError(ret));
+ return;
+ }
+ have = sizeof(outbuf) - ((zlib_stream_t *)conn->stream)->instream.avail_out;
+
+ if(((zlib_stream_t *)conn->stream)->instream.avail_in)
+ {
+ conn_plain_write(conn, outbuf, have);
+ have = 0;
+ ((zlib_stream_t *)conn->stream)->instream.next_out = (Bytef *) outbuf;
+ ((zlib_stream_t *)conn->stream)->instream.avail_out = sizeof(outbuf);
+ }
+ }
+ if(have == 0)
+ return;
+
+ conn_plain_write(conn, outbuf, have);
+}
+#endif
+
+static int
+plain_check_cork(conn_t * conn)
+{
+ if(rb_rawbuf_length(conn->modbuf_out) >= 4096)
+ {
+ /* if we have over 4k pending outbound, don't read until
+ * we've cleared the queue */
+ SetCork(conn);
+ rb_setselect(conn->plain_fd, RB_SELECT_READ, NULL, NULL);
+ /* try to write */
+ conn_mod_write_sendq(conn->mod_fd, conn);
+ return 1;
+ }
+ return 0;
+}
+
+
+static void
+conn_plain_read_cb(rb_fde_t * fd, void *data)
+{
+ conn_t *conn = data;
+ int length = 0;
+ if(conn == NULL)
+ return;
+
+ if(IsDead(conn))
+ return;
+
+ if(plain_check_cork(conn))
+ return;
+
+ while (1)
+ {
+ if(IsDead(conn))
+ return;
+
+ length = rb_read(conn->plain_fd, inbuf, sizeof(inbuf));
+
+ if(length == 0 || (length < 0 && !rb_ignore_errno(errno)))
+ {
+ close_conn(conn, NO_WAIT, NULL);
+ return;
+ }
+
+ if(length < 0)
+ {
+ rb_setselect(conn->plain_fd, RB_SELECT_READ, conn_plain_read_cb, conn);
+ conn_mod_write_sendq(conn->mod_fd, conn);
+ return;
+ }
+ conn->plain_in += length;
+
+#ifdef HAVE_ZLIB
+ if(IsZip(conn))
+ common_zlib_deflate(conn, inbuf, length);
+ else
+#endif
+ conn_mod_write(conn, inbuf, length);
+ if(IsDead(conn))
+ return;
+ if(plain_check_cork(conn))
+ return;
+ }
+}
+
+static void
+conn_mod_read_cb(rb_fde_t * fd, void *data)
+{
+ conn_t *conn = data;
+ const char *err = remote_closed;
+ int length;
+ if(conn == NULL)
+ return;
+ if(IsDead(conn))
+ return;
+
+ while (1)
+ {
+ if(IsDead(conn))
+ return;
+
+ length = rb_read(conn->mod_fd, inbuf, sizeof(inbuf));
+
+ if(length == 0 || (length < 0 && !rb_ignore_errno(errno)))
+ {
+ if(length == 0) {
+ close_conn(conn, WAIT_PLAIN, "%s", remote_closed);
+ return;
+ }
+
+ if(IsSSL(conn) && length == RB_RW_SSL_ERROR)
+ err = rb_get_ssl_strerror(conn->mod_fd);
+ else
+ err = strerror(errno);
+ close_conn(conn, WAIT_PLAIN, "Read error: %s", err);
+ return;
+ }
+ if(length < 0)
+ {
+ int flags = RB_SELECT_READ;
+ if(length == RB_RW_SSL_NEED_WRITE)
+ flags |= RB_SELECT_WRITE;
+
+ rb_setselect(conn->mod_fd, flags, conn_mod_read_cb, conn);
+ conn_plain_write_sendq(conn->plain_fd, conn);
+ return;
+ }
+ conn->mod_in += length;
+#ifdef HAVE_ZLIB
+ if(IsZip(conn))
+ common_zlib_inflate(conn, inbuf, length);
+ else
+#endif
+ conn_plain_write(conn, inbuf, length);
+ }
+}
+
+static void
+conn_plain_write_sendq(rb_fde_t * fd, void *data)
+{
+ conn_t *conn = data;
+ int retlen;
+
+ if(IsDead(conn))
+ return;
+
+ while ((retlen = rb_rawbuf_flush(conn->plainbuf_out, fd)) > 0)
+ {
+ conn->plain_out += retlen;
+ }
+ if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
+ {
+ close_conn(data, NO_WAIT, NULL);
+ return;
+ }
+
+
+ if(rb_rawbuf_length(conn->plainbuf_out) > 0)
+ rb_setselect(conn->plain_fd, RB_SELECT_WRITE, conn_plain_write_sendq, conn);
+ else
+ rb_setselect(conn->plain_fd, RB_SELECT_WRITE, NULL, NULL);
+}
+
+static int
+maxconn(void)
+{
+#if defined(RLIMIT_NOFILE) && defined(HAVE_SYS_RESOURCE_H)
+ struct rlimit limit;
+
+ if(!getrlimit(RLIMIT_NOFILE, &limit))
+ {
+ return limit.rlim_cur;
+ }
+#endif /* RLIMIT_FD_MAX */
+ return MAXCONNECTIONS;
+}
+
+static void
+ssl_process_accept_cb(rb_fde_t * F, int status, struct sockaddr *addr, rb_socklen_t len, void *data)
+{
+ conn_t *conn = data;
+ if(status == RB_OK)
+ {
+ conn_mod_read_cb(conn->mod_fd, conn);
+ conn_plain_read_cb(conn->plain_fd, conn);
+ return;
+ }
+ close_conn(conn, NO_WAIT, 0);
+ return;
+}
+
+static void
+ssl_process_connect_cb(rb_fde_t * F, int status, void *data)
+{
+ conn_t *conn = data;
+ if(status == RB_OK)
+ {
+ conn_mod_read_cb(conn->mod_fd, conn);
+ conn_plain_read_cb(conn->plain_fd, conn);
+ return;
+ }
+ close_conn(conn, NO_WAIT, 0);
+ return;
+}
+
+
+static void
+ssl_process_accept(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
+{
+ conn_t *conn;
+ rb_int32_t id;
+
+ conn = make_conn(ctl, ctlb->F[0], ctlb->F[1]);
+
+ id = buf_to_int32(&ctlb->buf[1]);
+
+ if(id >= 0)
+ conn_add_id_hash(conn, id);
+ SetSSL(conn);
+
+ if(rb_get_type(conn->mod_fd) & RB_FD_UNKNOWN)
+ {
+
+ rb_set_type(conn->mod_fd, RB_FD_SOCKET);
+ }
+ if(rb_get_type(conn->mod_fd) == RB_FD_UNKNOWN)
+ rb_set_type(conn->plain_fd, RB_FD_SOCKET);
+
+ rb_ssl_start_accepted(ctlb->F[0], ssl_process_accept_cb, conn, 10);
+}
+
+static void
+ssl_process_connect(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
+{
+ conn_t *conn;
+ rb_int32_t id;
+ conn = make_conn(ctl, ctlb->F[0], ctlb->F[1]);
+
+ id = buf_to_int32(&ctlb->buf[1]);
+
+ if(id >= 0)
+ conn_add_id_hash(conn, id);
+ SetSSL(conn);
+
+ if(rb_get_type(conn->mod_fd) == RB_FD_UNKNOWN)
+ rb_set_type(conn->mod_fd, RB_FD_SOCKET);
+
+ if(rb_get_type(conn->mod_fd) == RB_FD_UNKNOWN)
+ rb_set_type(conn->plain_fd, RB_FD_SOCKET);
+
+
+ rb_ssl_start_connected(ctlb->F[0], ssl_process_connect_cb, conn, 10);
+}
+
+static void
+process_stats(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
+{
+ char outstat[512];
+ conn_t *conn;
+ const char *odata;
+ rb_int32_t id;
+
+ id = buf_to_int32(&ctlb->buf[1]);
+
+ if(id < 0)
+ return;
+
+ odata = &ctlb->buf[5];
+ conn = conn_find_by_id(id);
+
+ if(conn == NULL)
+ return;
+
+ rb_snprintf(outstat, sizeof(outstat), "S %s %llu %llu %llu %llu", odata,
+ conn->plain_out, conn->mod_in, conn->plain_in, conn->mod_out);
+ conn->plain_out = 0;
+ conn->plain_in = 0;
+ conn->mod_in = 0;
+ conn->mod_out = 0;
+ mod_cmd_write_queue(ctl, outstat, strlen(outstat) + 1); /* +1 is so we send the \0 as well */
+}
+
+#ifdef HAVE_ZLIB
+static void
+zlib_send_zip_ready(mod_ctl_t *ctl, conn_t *conn)
+{
+ char buf[5];
+
+ buf[0] = 'R';
+ int32_to_buf(&buf[1], conn->id);
+ mod_cmd_write_queue(conn->ctl, buf, sizeof(buf));
+}
+
+static void
+zlib_process(mod_ctl_t * ctl, mod_ctl_buf_t * ctlb)
+{
+ rb_uint8_t level;
+ size_t recvqlen;
+ size_t hdr = (sizeof(rb_uint8_t) * 2) + sizeof(rb_int32_t);
+ void *recvq_start;
+ z_stream *instream, *outstream;
+ conn_t *conn;
+ rb_int32_t id;
+
+ conn = make_conn(ctl, ctlb->F[0], ctlb->F[1]);
+ if(rb_get_type(conn->mod_fd) == RB_FD_UNKNOWN)
+ rb_set_type(conn->mod_fd, RB_FD_SOCKET);
+
+ if(rb_get_type(conn->plain_fd) == RB_FD_UNKNOWN)
+ rb_set_type(conn->plain_fd, RB_FD_SOCKET);
+
+ id = buf_to_int32(&ctlb->buf[1]);
+ conn_add_id_hash(conn, id);
+
+ level = (rb_uint8_t) ctlb->buf[5];
+
+ recvqlen = ctlb->buflen - hdr;
+ recvq_start = &ctlb->buf[6];
+
+ SetZip(conn);
+ conn->stream = rb_malloc(sizeof(zlib_stream_t));
+ instream = &((zlib_stream_t *)conn->stream)->instream;
+ outstream = &((zlib_stream_t *)conn->stream)->outstream;
+
+ instream->total_in = 0;
+ instream->total_out = 0;
+ instream->zalloc = (alloc_func) ssld_alloc;
+ instream->zfree = (free_func) ssld_free;
+ instream->data_type = Z_ASCII;
+ inflateInit(&((zlib_stream_t *)conn->stream)->instream);
+
+ outstream->total_in = 0;
+ outstream->total_out = 0;
+ outstream->zalloc = (alloc_func) ssld_alloc;
+ outstream->zfree = (free_func) ssld_free;
+ outstream->data_type = Z_ASCII;
+
+ if(level > 9)
+ level = Z_DEFAULT_COMPRESSION;
+
+ deflateInit(&((zlib_stream_t *)conn->stream)->outstream, level);
+ if(recvqlen > 0)
+ common_zlib_inflate(conn, recvq_start, recvqlen);
+ zlib_send_zip_ready(ctl, conn);
+ conn_mod_read_cb(conn->mod_fd, conn);
+ conn_plain_read_cb(conn->plain_fd, conn);
+ return;
+
+}
+#endif
+
+static void
+init_prng(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
+{
+ char *path;
+ prng_seed_t seed_type;
+
+ seed_type = (prng_seed_t)ctl_buf->buf[1];
+ path = &ctl_buf->buf[2];
+ rb_init_prng(path, seed_type);
+}
+
+
+static void
+ssl_new_keys(mod_ctl_t * ctl, mod_ctl_buf_t * ctl_buf)
+{
+ char *buf;
+ char *cert, *key, *dhparam;
+
+ buf = &ctl_buf->buf[2];
+ cert = buf;
+ buf += strlen(cert) + 1;
+ key = buf;
+ buf += strlen(key) + 1;
+ dhparam = buf;
+ if(strlen(dhparam) == 0)
+ dhparam = NULL;
+
+ if(!rb_setup_ssl_server(cert, key, dhparam))
+ {
+ const char *invalid = "I";
+ mod_cmd_write_queue(ctl, invalid, strlen(invalid));
+ return;
+ }
+}
+
+static void
+send_nossl_support(mod_ctl_t *ctl, mod_ctl_buf_t *ctlb)
+{
+ static const char *nossl_cmd = "N";
+ conn_t *conn;
+ rb_int32_t id;
+
+ if(ctlb != NULL)
+ {
+ conn = make_conn(ctl, ctlb->F[0], ctlb->F[1]);
+ id = buf_to_int32(&ctlb->buf[1]);
+
+ if(id >= 0)
+ conn_add_id_hash(conn, id);
+ close_conn(conn, WAIT_PLAIN, "libratbox reports no SSL/TLS support");
+ }
+ mod_cmd_write_queue(ctl, nossl_cmd, strlen(nossl_cmd));
+}
+
+static void
+send_i_am_useless(mod_ctl_t *ctl)
+{
+ static const char *useless = "U";
+ mod_cmd_write_queue(ctl, useless, strlen(useless));
+}
+
+static void
+send_nozlib_support(mod_ctl_t *ctl, mod_ctl_buf_t *ctlb)
+{
+ static const char *nozlib_cmd = "z";
+ conn_t *conn;
+ rb_int32_t id;
+ if(ctlb != NULL)
+ {
+ conn = make_conn(ctl, ctlb->F[0], ctlb->F[1]);
+ id = buf_to_int32(&ctlb->buf[1]);
+
+ if(id >= 0)
+ conn_add_id_hash(conn, id);
+ close_conn(conn, WAIT_PLAIN, "libratbox reports no zlib support");
+ }
+ mod_cmd_write_queue(ctl, nozlib_cmd, strlen(nozlib_cmd));
+}
+
+static void
+mod_process_cmd_recv(mod_ctl_t * ctl)
+{
+ rb_dlink_node *ptr, *next;
+ mod_ctl_buf_t *ctl_buf;
+
+ RB_DLINK_FOREACH_SAFE(ptr, next, ctl->readq.head)
+ {
+ ctl_buf = ptr->data;
+
+ switch (*ctl_buf->buf)
+ {
+ case 'A':
+ {
+ if(!ssl_ok)
+ {
+ send_nossl_support(ctl, ctl_buf);
+ break;
+ }
+ ssl_process_accept(ctl, ctl_buf);
+ break;
+ }
+ case 'C':
+ {
+ if(!ssl_ok)
+ {
+ send_nossl_support(ctl, ctl_buf);
+ break;
+ }
+ ssl_process_connect(ctl, ctl_buf);
+ break;
+ }
+
+ case 'K':
+ {
+ if(!ssl_ok)
+ {
+ send_nossl_support(ctl, ctl_buf);
+ break;
+ }
+ ssl_new_keys(ctl, ctl_buf);
+ break;
+ }
+ case 'I':
+ init_prng(ctl, ctl_buf);
+ break;
+ case 'S':
+ {
+ process_stats(ctl, ctl_buf);
+ break;
+ }
+#ifdef HAVE_ZLIB
+ case 'Z':
+ {
+ /* just zlib only */
+ zlib_process(ctl, ctl_buf);
+ break;
+ }
+#else
+ case 'Y':
+ case 'Z':
+ send_nozlib_support(ctl);
+ break;
+
+#endif
+ default:
+ break;
+ /* Log unknown commands */
+ }
+ rb_dlinkDelete(ptr, &ctl->readq);
+ rb_free(ctl_buf->buf);
+ rb_free(ctl_buf);
+ }
+
+}
+
+
+
+static void
+mod_read_ctl(rb_fde_t * F, void *data)
+{
+ mod_ctl_buf_t *ctl_buf;
+ mod_ctl_t *ctl = data;
+ int retlen;
+
+ do
+ {
+ ctl_buf = rb_malloc(sizeof(mod_ctl_buf_t));
+ ctl_buf->buf = rb_malloc(READBUF_SIZE);
+ ctl_buf->buflen = READBUF_SIZE;
+ retlen = rb_recv_fd_buf(ctl->F, ctl_buf->buf, ctl_buf->buflen, ctl_buf->F,
+ MAXPASSFD);
+ if(retlen <= 0)
+ {
+ rb_free(ctl_buf->buf);
+ rb_free(ctl_buf);
+ }
+ else
+ {
+ ctl_buf->buflen = retlen;
+ rb_dlinkAddTail(ctl_buf, &ctl_buf->node, &ctl->readq);
+ }
+ }
+ while (retlen > 0);
+
+ if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
+ exit(0);
+
+ mod_process_cmd_recv(ctl);
+ rb_setselect(ctl->F, RB_SELECT_READ, mod_read_ctl, ctl);
+}
+
+static void
+mod_write_ctl(rb_fde_t * F, void *data)
+{
+ mod_ctl_t *ctl = data;
+ mod_ctl_buf_t *ctl_buf;
+ rb_dlink_node *ptr, *next;
+ int retlen, x;
+
+ RB_DLINK_FOREACH_SAFE(ptr, next, ctl->writeq.head)
+ {
+ ctl_buf = ptr->data;
+ retlen = rb_send_fd_buf(ctl->F, ctl_buf->F, ctl_buf->nfds, ctl_buf->buf,
+ ctl_buf->buflen);
+ if(retlen > 0)
+ {
+ rb_dlinkDelete(ptr, &ctl->writeq);
+ for (x = 0; x < ctl_buf->nfds; x++)
+ rb_close(ctl_buf->F[x]);
+ rb_free(ctl_buf->buf);
+ rb_free(ctl_buf);
+
+ }
+ if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
+ exit(0);
+
+ rb_setselect(ctl->F, RB_SELECT_WRITE, mod_write_ctl, ctl);
+ }
+}
+
+
+static void
+read_pipe_ctl(rb_fde_t * F, void *data)
+{
+ int retlen;
+ while ((retlen = rb_read(F, inbuf, sizeof(inbuf))) > 0)
+ {
+ ;; /* we don't do anything with the pipe really, just care if the other process dies.. */
+ }
+ if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
+ exit(0);
+ rb_setselect(F, RB_SELECT_READ, read_pipe_ctl, NULL);
+
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *s_ctlfd, *s_pipe;
+ int ctlfd, pipefd, x, maxfd;
+ maxfd = maxconn();
+ s_ctlfd = getenv("CTL_FD");
+ s_pipe = getenv("CTL_PIPE");
+
+ if(s_ctlfd == NULL || s_pipe == NULL)
+ {
+ fprintf(stderr, "This is ircd-ratbox ssld. You know you aren't supposed to run me directly?\n");
+ fprintf(stderr, "You get an Id tag for this: $Id: ssld.c 25179 2008-03-30 16:34:57Z androsyn $\n");
+ fprintf(stderr, "Have a nice life\n");
+ exit(1);
+ }
+
+ ctlfd = atoi(s_ctlfd);
+ pipefd = atoi(s_pipe);
+
+ for (x = 0; x < maxfd; x++)
+ {
+ if(x != ctlfd && x != pipefd && x > 2)
+ close(x);
+ }
+
+#if 0
+ x = open("/dev/null", O_RDWR);
+ if(x >= 0)
+ {
+ if(ctlfd != 0 && pipefd != 0)
+ dup2(x, 0);
+ if(ctlfd != 1 && pipefd != 1)
+ dup2(x, 1);
+ if(ctlfd != 2 && pipefd != 2)
+ dup2(x, 2);
+ if(x > 2)
+ close(x);
+ }
+#endif
+ setup_signals();
+ rb_lib_init(NULL, NULL, NULL, 0, maxfd, 1024, 4096);
+ rb_init_rawbuffers(1024);
+ ssl_ok = rb_supports_ssl();
+
+ mod_ctl = rb_malloc(sizeof(mod_ctl_t));
+ mod_ctl->F = rb_open(ctlfd, RB_FD_SOCKET, "ircd control socket");
+ mod_ctl->F_pipe = rb_open(pipefd, RB_FD_PIPE, "ircd pipe");
+ rb_set_nb(mod_ctl->F);
+ rb_set_nb(mod_ctl->F_pipe);
+ rb_event_addish("clean_dead_conns", clean_dead_conns, NULL, 10);
+ read_pipe_ctl(mod_ctl->F_pipe, NULL);
+ mod_read_ctl(mod_ctl->F, mod_ctl);
+ if(!zlib_ok && !ssl_ok)
+ {
+ /* this is really useless... */
+ send_i_am_useless(mod_ctl);
+ /* sleep until the ircd kills us */
+ rb_sleep(2<<30, 0);
+ exit(1);
+ }
+
+ if(!zlib_ok)
+ send_nozlib_support(mod_ctl, NULL);
+ if(!ssl_ok)
+ send_nossl_support(mod_ctl, NULL);
+ rb_lib_loop(0);
+ return 0;
+}
+
+
+
+static void
+dummy_handler(int sig)
+{
+ return;
+}
+
+static void
+setup_signals()
+{
+ struct sigaction act;
+
+ act.sa_flags = 0;
+ act.sa_handler = SIG_IGN;
+ sigemptyset(&act.sa_mask);
+ sigaddset(&act.sa_mask, SIGPIPE);
+ sigaddset(&act.sa_mask, SIGALRM);
+#ifdef SIGTRAP
+ sigaddset(&act.sa_mask, SIGTRAP);
+#endif
+
+#ifdef SIGWINCH
+ sigaddset(&act.sa_mask, SIGWINCH);
+ sigaction(SIGWINCH, &act, 0);
+#endif
+ sigaction(SIGPIPE, &act, 0);
+#ifdef SIGTRAP
+ sigaction(SIGTRAP, &act, 0);
+#endif
+
+ act.sa_handler = dummy_handler;
+ sigaction(SIGALRM, &act, 0);
+}
+