diff options
| author | Přemysl Janouch <p.janouch@gmail.com> | 2014-07-14 20:54:47 +0200 | 
|---|---|---|
| committer | Přemysl Janouch <p.janouch@gmail.com> | 2014-07-14 22:15:56 +0200 | 
| commit | b0cf09fb4c3db2457141a48847dd99973dfd68cb (patch) | |
| tree | 42436950ea3a8d03c748d927c8c60aacdf6ce5af | |
| parent | cc4ca46cc3cf447c26bf72fa88268ad970bccbff (diff) | |
| download | xK-b0cf09fb4c3db2457141a48847dd99973dfd68cb.tar.gz xK-b0cf09fb4c3db2457141a48847dd99973dfd68cb.tar.xz xK-b0cf09fb4c3db2457141a48847dd99973dfd68cb.zip | |
Rename `struct connection' to `struct client'
It is shorter and makes more sense.  Also replaced "conn" with "c"
to keep it even more concise, and thus clearer.
| -rw-r--r-- | src/kike.c | 292 | 
1 files changed, 144 insertions, 148 deletions
| @@ -219,11 +219,10 @@ enum  	IRC_USER_MODE_RX_SERVER_NOTICES  = (1 << 4)  }; -// TODO: rename to client? -struct connection +struct client  { -	struct connection *next;            ///< The next link in a chain -	struct connection *prev;            ///< The previous link in a chain +	struct client *next;                ///< The next link in a chain +	struct client *prev;                ///< The previous link in a chain  	struct server_context *ctx;         ///< Server context @@ -249,7 +248,7 @@ struct connection  };  static void -connection_init (struct connection *self) +client_init (struct client *self)  {  	memset (self, 0, sizeof *self); @@ -259,7 +258,7 @@ connection_init (struct connection *self)  }  static void -connection_free (struct connection *self) +client_free (struct client *self)  {  	if (!soft_assert (self->socket_fd == -1))  		xclose (self->socket_fd); @@ -351,11 +350,11 @@ struct server_context  	struct str_map config;              ///< Server configuration  	int listen_fd;                      ///< Listening socket FD -	struct connection *clients;         ///< Client connections +	struct client *clients;             ///< Clients  	SSL_CTX *ssl_ctx;                   ///< SSL context  	char *server_name;                  ///< Our server name -	struct str_map users;               ///< Maps nicknames to connections +	struct str_map users;               ///< Maps nicknames to clients  	struct str_map channels;            ///< Maps channel names to data  	struct str_map handlers;            ///< Message handlers @@ -405,11 +404,11 @@ server_context_free (struct server_context *self)  		SSL_CTX_free (self->ssl_ctx);  	// TODO: terminate the connections properly before this is called -	struct connection *link, *tmp; +	struct client *link, *tmp;  	for (link = self->clients; link; link = tmp)  	{  		tmp = link->next; -		connection_free (link); +		client_free (link);  		free (link);  	} @@ -436,40 +435,40 @@ enum  };  static void -connection_kill (struct connection *conn, const char *reason) +client_kill (struct client *c, const char *reason)  {  	// TODO: multicast a QUIT message with `reason' || "Client exited"  	(void) reason;  	// TODO: do further cleanup if the client has successfully registered etc. -	struct server_context *ctx = conn->ctx; -	ssize_t i = poller_find_by_fd (&ctx->poller, conn->socket_fd); +	struct server_context *ctx = c->ctx; +	ssize_t i = poller_find_by_fd (&ctx->poller, c->socket_fd);  	if (i != -1)  		poller_remove_at_index (&ctx->poller, i); -	xclose (conn->socket_fd); -	conn->socket_fd = -1; -	connection_free (conn); -	LIST_UNLINK (ctx->clients, conn); -	free (conn); +	xclose (c->socket_fd); +	c->socket_fd = -1; +	client_free (c); +	LIST_UNLINK (ctx->clients, c); +	free (c);  }  static void -irc_send_str (struct connection *conn, const struct str *s) +irc_send_str (struct client *c, const struct str *s)  {  	// TODO: kill the connection above some "SendQ" threshold (careful!) -	str_append_data (&conn->write_buffer, s->str, +	str_append_data (&c->write_buffer, s->str,  		s->len > IRC_MAX_MESSAGE_LENGTH ? IRC_MAX_MESSAGE_LENGTH : s->len); -	str_append (&conn->write_buffer, "\r\n"); +	str_append (&c->write_buffer, "\r\n");  } -static void irc_send (struct connection *conn, +static void irc_send (struct client *c,  	const char *format, ...) ATTRIBUTE_PRINTF (2, 3);  static void -irc_send (struct connection *conn, const char *format, ...) +irc_send (struct client *c, const char *format, ...)  {  	struct str tmp;  	str_init (&tmp); @@ -479,7 +478,7 @@ irc_send (struct connection *conn, const char *format, ...)  	str_append_vprintf (&tmp, format, ap);  	va_end (ap); -	irc_send_str (conn, &tmp); +	irc_send_str (c, &tmp);  	str_free (&tmp);  } @@ -541,7 +540,7 @@ static const char *g_default_replies[] =  // XXX: this way we cannot typecheck the arguments, so we must be careful  static void -irc_send_reply (struct connection *conn, int id, ...) +irc_send_reply (struct client *c, int id, ...)  {  	struct str tmp;  	str_init (&tmp); @@ -549,115 +548,112 @@ irc_send_reply (struct connection *conn, int id, ...)  	va_list ap;  	va_start (ap, id);  	str_append_printf (&tmp, ":%s %03d %s ", -		conn->ctx->server_name, id, conn->nickname ? conn->nickname : ""); +		c->ctx->server_name, id, c->nickname ? c->nickname : "");  	str_append_vprintf (&tmp, -		irc_get_text (conn->ctx, id, g_default_replies[id]), ap); +		irc_get_text (c->ctx, id, g_default_replies[id]), ap);  	va_end (ap); -	irc_send_str (conn, &tmp); +	irc_send_str (c, &tmp);  	str_free (&tmp);  }  static void -irc_send_motd (struct connection *conn) +irc_send_motd (struct client *c)  { -	struct server_context *ctx = conn->ctx; +	struct server_context *ctx = c->ctx;  	if (!ctx->motd.len)  	{ -		irc_send_reply (conn, IRC_ERR_NOMOTD); +		irc_send_reply (c, IRC_ERR_NOMOTD);  		return;  	} -	irc_send_reply (conn, IRC_RPL_MOTDSTART, ctx->server_name); +	irc_send_reply (c, IRC_RPL_MOTDSTART, ctx->server_name);  	for (size_t i = 0; i < ctx->motd.len; i++) -		irc_send_reply (conn, IRC_RPL_MOTD, ctx->motd.vector[i]); -	irc_send_reply (conn, IRC_RPL_ENDOFMOTD); +		irc_send_reply (c, IRC_RPL_MOTD, ctx->motd.vector[i]); +	irc_send_reply (c, IRC_RPL_ENDOFMOTD);  }  static void -irc_try_finish_registration (struct connection *conn) +irc_try_finish_registration (struct client *c)  { -	if (!conn->nickname || !conn->username || !conn->realname) +	if (!c->nickname || !c->username || !c->realname)  		return; -	conn->registered = true; -	irc_send_reply (conn, IRC_RPL_WELCOME, -		conn->nickname, conn->username, conn->hostname); +	c->registered = true; +	irc_send_reply (c, IRC_RPL_WELCOME, c->nickname, c->username, c->hostname); -	irc_send_reply (conn, IRC_RPL_YOURHOST, -		conn->ctx->server_name, PROGRAM_VERSION); +	irc_send_reply (c, IRC_RPL_YOURHOST, c->ctx->server_name, PROGRAM_VERSION);  	// The purpose of this message eludes me -	irc_send_reply (conn, IRC_RPL_CREATED, __DATE__); -	irc_send_reply (conn, IRC_RPL_MYINFO, -		conn->ctx->server_name, PROGRAM_VERSION, +	irc_send_reply (c, IRC_RPL_CREATED, __DATE__); +	irc_send_reply (c, IRC_RPL_MYINFO, c->ctx->server_name, PROGRAM_VERSION,  		IRC_SUPPORTED_USER_MODES, IRC_SUPPORTED_CHAN_MODES);  	// Although not strictly required, bots often need this to work -	irc_send_motd (conn); +	irc_send_motd (c);  }  static void -irc_handle_pass (const struct irc_message *msg, struct connection *conn) +irc_handle_pass (const struct irc_message *msg, struct client *c)  { -	if (conn->registered) -		irc_send_reply (conn, IRC_ERR_ALREADYREGISTERED); +	if (c->registered) +		irc_send_reply (c, IRC_ERR_ALREADYREGISTERED);  	else if (msg->params.len < 1) -		irc_send_reply (conn, IRC_ERR_NEEDMOREPARAMS, msg->command); +		irc_send_reply (c, IRC_ERR_NEEDMOREPARAMS, msg->command);  	// We have SSL client certificates for this purpose; ignoring  }  static void -irc_handle_nick (const struct irc_message *msg, struct connection *conn) +irc_handle_nick (const struct irc_message *msg, struct client *c)  { -	struct server_context *ctx = conn->ctx; +	struct server_context *ctx = c->ctx; -	if (conn->registered) +	if (c->registered)  	{ -		irc_send_reply (conn, IRC_ERR_ALREADYREGISTERED); +		irc_send_reply (c, IRC_ERR_ALREADYREGISTERED);  		return;  	}  	if (msg->params.len < 1)  	{ -		irc_send_reply (conn, IRC_ERR_NONICKNAMEGIVEN); +		irc_send_reply (c, IRC_ERR_NONICKNAMEGIVEN);  		return;  	}  	const char *nickname = msg->params.vector[0];  	if (irc_validate_nickname (nickname) != VALIDATION_OK)  	{ -		irc_send_reply (conn, IRC_ERR_ERRONEOUSNICKNAME, nickname); +		irc_send_reply (c, IRC_ERR_ERRONEOUSNICKNAME, nickname);  		return;  	}  	if (str_map_find (&ctx->users, nickname))  	{ -		irc_send_reply (conn, IRC_ERR_NICKNAMEINUSE, nickname); +		irc_send_reply (c, IRC_ERR_NICKNAMEINUSE, nickname);  		return;  	} -	if (conn->nickname) +	if (c->nickname)  	{ -		str_map_set (&ctx->users, conn->nickname, NULL); -		free (conn->nickname); +		str_map_set (&ctx->users, c->nickname, NULL); +		free (c->nickname);  	}  	// Allocate the nickname -	conn->nickname = xstrdup (nickname); -	str_map_set (&ctx->users, nickname, conn); +	c->nickname = xstrdup (nickname); +	str_map_set (&ctx->users, nickname, c); -	irc_try_finish_registration (conn); +	irc_try_finish_registration (c);  }  static void -irc_handle_user (const struct irc_message *msg, struct connection *conn) +irc_handle_user (const struct irc_message *msg, struct client *c)  { -	if (conn->registered) +	if (c->registered)  	{ -		irc_send_reply (conn, IRC_ERR_ALREADYREGISTERED); +		irc_send_reply (c, IRC_ERR_ALREADYREGISTERED);  		return;  	}  	if (msg->params.len < 4)  	{ -		irc_send_reply (conn, IRC_ERR_NEEDMOREPARAMS, msg->command); +		irc_send_reply (c, IRC_ERR_NEEDMOREPARAMS, msg->command);  		return;  	} @@ -669,30 +665,30 @@ irc_handle_user (const struct irc_message *msg, struct connection *conn)  	if (!irc_is_valid_user (username))  		username = "xxx"; -	free (conn->username); -	conn->username = xstrdup (username); -	free (conn->realname); -	conn->realname = xstrdup (realname); +	free (c->username); +	c->username = xstrdup (username); +	free (c->realname); +	c->realname = xstrdup (realname);  	unsigned long m;  	if (xstrtoul (&m, mode, 10))  	{ -		if (m & 4)  conn->mode |= IRC_USER_MODE_RX_WALLOPS; -		if (m & 8)  conn->mode |= IRC_USER_MODE_INVISIBLE; +		if (m & 4)  c->mode |= IRC_USER_MODE_RX_WALLOPS; +		if (m & 8)  c->mode |= IRC_USER_MODE_INVISIBLE;  	} -	irc_try_finish_registration (conn); +	irc_try_finish_registration (c);  }  static void -irc_handle_ping (const struct irc_message *msg, struct connection *conn) +irc_handle_ping (const struct irc_message *msg, struct client *c)  {  	// XXX: the RFC is pretty incomprehensible about the exact usage  	if (msg->params.len < 1) -		irc_send_reply (conn, IRC_ERR_NOORIGIN); +		irc_send_reply (c, IRC_ERR_NOORIGIN);  	else -		irc_send (conn, ":%s PONG :%s", -			conn->ctx->server_name, msg->params.vector[0]); +		irc_send (c, ":%s PONG :%s", +			c->ctx->server_name, msg->params.vector[0]);  }  // ----------------------------------------------------------------------------- @@ -701,7 +697,7 @@ struct irc_command  {  	const char *name;  	bool requires_registration; -	void (*handler) (const struct irc_message *, struct connection *); +	void (*handler) (const struct irc_message *, struct client *);  };  static void @@ -730,44 +726,44 @@ irc_process_message (const struct irc_message *msg,  	(void) raw;  	// XXX: we may want to discard everything following a QUIT etc. -	//   We can set a flag within the connection object. +	//   We can set a flag within the client object.  	// TODO: see RFC 2812 :! -	struct connection *conn = user_data; -	struct irc_command *cmd = str_map_find (&conn->ctx->handlers, msg->command); +	struct client *c = user_data; +	struct irc_command *cmd = str_map_find (&c->ctx->handlers, msg->command);  	if (!cmd) -		irc_send_reply (conn, IRC_ERR_UNKNOWNCOMMAND, +		irc_send_reply (c, IRC_ERR_UNKNOWNCOMMAND,  			"%s: Unknown command", msg->command); -	else if (cmd->requires_registration && !conn->registered) -		irc_send_reply (conn, IRC_ERR_NOTREGISTERED); +	else if (cmd->requires_registration && !c->registered) +		irc_send_reply (c, IRC_ERR_NOTREGISTERED);  	else -		cmd->handler (msg, conn); +		cmd->handler (msg, c);  }  // --- Network I/O -------------------------------------------------------------  static bool -irc_try_read (struct connection *conn) +irc_try_read (struct client *c)  { -	struct str *buf = &conn->read_buffer; +	struct str *buf = &c->read_buffer;  	ssize_t n_read;  	while (true)  	{  		str_ensure_space (buf, 512); -		n_read = recv (conn->socket_fd, buf->str + buf->len, +		n_read = recv (c->socket_fd, buf->str + buf->len,  			buf->alloc - buf->len - 1 /* null byte */, 0);  		if (n_read > 0)  		{  			buf->str[buf->len += n_read] = '\0';  			// TODO: discard characters above the 512 character limit -			irc_process_buffer (buf, irc_process_message, conn); +			irc_process_buffer (buf, irc_process_message, c);  			continue;  		}  		if (n_read == 0)  		{ -			connection_kill (conn, NULL); +			client_kill (c, NULL);  			return false;  		} @@ -777,60 +773,60 @@ irc_try_read (struct connection *conn)  			continue;  		print_debug ("%s: %s: %s", __func__, "recv", strerror (errno)); -		connection_kill (conn, strerror (errno)); +		client_kill (c, strerror (errno));  		return false;  	}  }  static bool -irc_try_read_ssl (struct connection *conn) +irc_try_read_ssl (struct client *c)  { -	if (conn->ssl_tx_want_rx) +	if (c->ssl_tx_want_rx)  		return true; -	struct str *buf = &conn->read_buffer; -	conn->ssl_rx_want_tx = false; +	struct str *buf = &c->read_buffer; +	c->ssl_rx_want_tx = false;  	while (true)  	{  		str_ensure_space (buf, 512); -		int n_read = SSL_read (conn->ssl, buf->str + buf->len, +		int n_read = SSL_read (c->ssl, buf->str + buf->len,  			buf->alloc - buf->len - 1 /* null byte */);  		const char *error_info = NULL; -		switch (xssl_get_error (conn->ssl, n_read, &error_info)) +		switch (xssl_get_error (c->ssl, n_read, &error_info))  		{  		case SSL_ERROR_NONE:  			buf->str[buf->len += n_read] = '\0';  			// TODO: discard characters above the 512 character limit -			irc_process_buffer (buf, irc_process_message, conn); +			irc_process_buffer (buf, irc_process_message, c);  			continue;  		case SSL_ERROR_ZERO_RETURN: -			connection_kill (conn, NULL); +			client_kill (c, NULL);  			return false;  		case SSL_ERROR_WANT_READ:  			return true;  		case SSL_ERROR_WANT_WRITE: -			conn->ssl_rx_want_tx = true; +			c->ssl_rx_want_tx = true;  			return true;  		case XSSL_ERROR_TRY_AGAIN:  			continue;  		default:  			print_debug ("%s: %s: %s", __func__, "SSL_read", error_info); -			connection_kill (conn, error_info); +			client_kill (c, error_info);  			return false;  		}  	}  }  static bool -irc_try_write (struct connection *conn) +irc_try_write (struct client *c)  { -	struct str *buf = &conn->write_buffer; +	struct str *buf = &c->write_buffer;  	ssize_t n_written;  	while (buf->len)  	{ -		n_written = send (conn->socket_fd, buf->str, buf->len, 0); +		n_written = send (c->socket_fd, buf->str, buf->len, 0);  		if (n_written >= 0)  		{  			str_remove_slice (buf, 0, n_written); @@ -843,43 +839,43 @@ irc_try_write (struct connection *conn)  			continue;  		print_debug ("%s: %s: %s", __func__, "send", strerror (errno)); -		connection_kill (conn, strerror (errno)); +		client_kill (c, strerror (errno));  		return false;  	}  	return true;  }  static bool -irc_try_write_ssl (struct connection *conn) +irc_try_write_ssl (struct client *c)  { -	if (conn->ssl_rx_want_tx) +	if (c->ssl_rx_want_tx)  		return true; -	struct str *buf = &conn->write_buffer; -	conn->ssl_tx_want_rx = false; +	struct str *buf = &c->write_buffer; +	c->ssl_tx_want_rx = false;  	while (buf->len)  	{ -		int n_written = SSL_write (conn->ssl, buf->str, buf->len); +		int n_written = SSL_write (c->ssl, buf->str, buf->len);  		const char *error_info = NULL; -		switch (xssl_get_error (conn->ssl, n_written, &error_info)) +		switch (xssl_get_error (c->ssl, n_written, &error_info))  		{  		case SSL_ERROR_NONE:  			str_remove_slice (buf, 0, n_written);  			continue;  		case SSL_ERROR_ZERO_RETURN: -			connection_kill (conn, NULL); +			client_kill (c, NULL);  			return false;  		case SSL_ERROR_WANT_WRITE:  			return true;  		case SSL_ERROR_WANT_READ: -			conn->ssl_tx_want_rx = true; +			c->ssl_tx_want_rx = true;  			return true;  		case XSSL_ERROR_TRY_AGAIN:  			continue;  		default:  			print_debug ("%s: %s: %s", __func__, "SSL_write", error_info); -			connection_kill (conn, error_info); +			client_kill (c, error_info);  			return false;  		}  	} @@ -887,7 +883,7 @@ irc_try_write_ssl (struct connection *conn)  }  static bool -irc_autodetect_ssl (struct connection *conn) +irc_autodetect_ssl (struct client *c)  {  	// Trivial SSL/TLS autodetection.  The first block of data returned by  	// recv() must be at least three bytes long for this to work reliably, @@ -903,7 +899,7 @@ irc_autodetect_ssl (struct connection *conn)  	char buf[3];  start: -	switch (recv (conn->socket_fd, buf, sizeof buf, MSG_PEEK)) +	switch (recv (c->socket_fd, buf, sizeof buf, MSG_PEEK))  	{  	case 3:  		if ((buf[0] & 0x80) && buf[2] == 1) @@ -926,81 +922,81 @@ start:  }  static bool -connection_initialize_ssl (struct connection *conn) +client_initialize_ssl (struct client *c)  {  	// SSL support not enabled -	if (!conn->ctx->ssl_ctx) +	if (!c->ctx->ssl_ctx)  		return false; -	conn->ssl = SSL_new (conn->ctx->ssl_ctx); -	if (!conn->ssl) +	c->ssl = SSL_new (c->ctx->ssl_ctx); +	if (!c->ssl)  		goto error_ssl_1; -	if (!SSL_set_fd (conn->ssl, conn->socket_fd)) +	if (!SSL_set_fd (c->ssl, c->socket_fd))  		goto error_ssl_2; -	SSL_set_accept_state (conn->ssl); +	SSL_set_accept_state (c->ssl);  	return true;  error_ssl_2: -	SSL_free (conn->ssl); -	conn->ssl = NULL; +	SSL_free (c->ssl); +	c->ssl = NULL;  error_ssl_1:  	// XXX: these error strings are really nasty; also there could be  	//   multiple errors on the OpenSSL stack.  	print_debug ("%s: %s: %s", "could not initialize SSL", -		conn->hostname, ERR_error_string (ERR_get_error (), NULL)); +		c->hostname, ERR_error_string (ERR_get_error (), NULL));  	return false;  }  static void  on_irc_client_ready (const struct pollfd *pfd, void *user_data)  { -	struct connection *conn = user_data; -	if (!conn->initialized) +	struct client *c = user_data; +	if (!c->initialized)  	{  		hard_assert (pfd->events == POLLIN); -		if (irc_autodetect_ssl (conn) && !connection_initialize_ssl (conn)) +		if (irc_autodetect_ssl (c) && !client_initialize_ssl (c))  		{ -			connection_kill (conn, NULL); +			client_kill (c, NULL);  			return;  		} -		conn->initialized = true; +		c->initialized = true;  	}  	int new_events = 0; -	if (conn->ssl) +	if (c->ssl)  	{  		// Reads may want to write, writes may want to read, poll() may  		// return unexpected things in `revents'... let's try both -		if (!irc_try_read_ssl (conn) || !irc_try_write_ssl (conn)) +		if (!irc_try_read_ssl (c) || !irc_try_write_ssl (c))  			return;  		new_events |= POLLIN; -		if (conn->write_buffer.len || conn->ssl_rx_want_tx) +		if (c->write_buffer.len || c->ssl_rx_want_tx)  			new_events |= POLLOUT;  		// While we're waiting for an opposite event, we ignore the original -		if (conn->ssl_rx_want_tx)  new_events &= ~POLLIN; -		if (conn->ssl_tx_want_rx)  new_events &= ~POLLOUT; +		if (c->ssl_rx_want_tx)  new_events &= ~POLLIN; +		if (c->ssl_tx_want_rx)  new_events &= ~POLLOUT;  	}  	else  	{ -		if (!irc_try_read (conn) || !irc_try_write (conn)) +		if (!irc_try_read (c) || !irc_try_write (c))  			return;  		new_events |= POLLIN; -		if (conn->write_buffer.len) +		if (c->write_buffer.len)  			new_events |= POLLOUT;  	}  	hard_assert (new_events != 0);  	if (pfd->events != new_events) -		poller_set (&conn->ctx->poller, conn->socket_fd, new_events, -			(poller_dispatcher_func) on_irc_client_ready, conn); +		poller_set (&c->ctx->poller, c->socket_fd, new_events, +			(poller_dispatcher_func) on_irc_client_ready, c);  }  static void -on_irc_connection_available (const struct pollfd *pfd, void *user_data) +on_irc_client_available (const struct pollfd *pfd, void *user_data)  {  	(void) pfd;  	struct server_context *ctx = user_data; @@ -1038,16 +1034,16 @@ on_irc_connection_available (const struct pollfd *pfd, void *user_data)  			print_debug ("%s: %s", "getnameinfo", gai_strerror (err));  		print_debug ("accepted connection from %s:%s", host, port); -		struct connection *conn = xmalloc (sizeof *conn); -		connection_init (conn); -		conn->socket_fd = fd; -		conn->hostname = xstrdup (host); -		LIST_PREPEND (ctx->clients, conn); +		struct client *c = xmalloc (sizeof *c); +		client_init (c); +		c->socket_fd = fd; +		c->hostname = xstrdup (host); +		LIST_PREPEND (ctx->clients, c);  		// TODO: set a timeout on the socket, something like 3 minutes, then we  		//   should terminate the connection. -		poller_set (&ctx->poller, conn->socket_fd, POLLIN, -			(poller_dispatcher_func) on_irc_client_ready, conn); +		poller_set (&ctx->poller, c->socket_fd, POLLIN, +			(poller_dispatcher_func) on_irc_client_ready, c);  	}  } @@ -1279,7 +1275,7 @@ irc_listen (struct server_context *ctx, struct error **e)  	ctx->listen_fd = sockfd;  	poller_set (&ctx->poller, ctx->listen_fd, POLLIN, -		(poller_dispatcher_func) on_irc_connection_available, ctx); +		(poller_dispatcher_func) on_irc_client_available, ctx);  	print_status ("listening at %s:%s", real_host, real_port);  	return true; | 
