mirror of
				https://github.com/osmarks/ngircd.git
				synced 2025-10-31 14:02:59 +00:00 
			
		
		
		
	sync with HEAD.
This commit is contained in:
		
							
								
								
									
										10
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								ChangeLog
									
									
									
									
									
								
							| @@ -11,6 +11,14 @@ | ||||
|  | ||||
|  | ||||
| ngIRCd 0.10.2 | ||||
|  | ||||
|   - Predefined Channel configuration now allows specification of channel key | ||||
|     (mode k) and maximum user count (mode l). | ||||
|   - When using epoll() IO interface, compile in the select() interface as | ||||
|     well and fall back to it when epoll() isn't available on runtime. | ||||
|   - New configure option "--without-select" to disable select() IO API | ||||
|     (even when using epoll(), see above). | ||||
|   - Added support for IO APIs "poll()" and "/dev/poll". | ||||
|   - Reorganized internal handling of invite and ban lists. | ||||
|  | ||||
| ngIRCd 0.10.1 (2006-12-17) | ||||
| @@ -676,4 +684,4 @@ ngIRCd 0.0.1, 31.12.2001 | ||||
|  | ||||
|  | ||||
| --  | ||||
| $Id: ChangeLog,v 1.302.2.10 2007/04/03 20:23:30 fw Exp $ | ||||
| $Id: ChangeLog,v 1.302.2.11 2007/04/03 22:08:50 fw Exp $ | ||||
|   | ||||
							
								
								
									
										14
									
								
								INSTALL
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								INSTALL
									
									
									
									
									
								
							| @@ -149,14 +149,20 @@ standard locations. | ||||
|   The Z compression library ("libz") is required for this option. | ||||
|    | ||||
| * IO Backend (autodetected by default): | ||||
|   --with-select[=<path>] / --without-select | ||||
|   --with-poll[=<path>] / --without-poll | ||||
|   --with-devpoll[=<path>] / --without-devpoll | ||||
|   --with-epoll[=<path>] / --without-epoll | ||||
|   --with-kqueue[=<path>] / --without-kqueue   | ||||
|  | ||||
|   ngIRCd can use three different IO "backends": the "old school" select() | ||||
|   ngIRCd can use different IO "backends": the "old school" select() and poll() | ||||
|   API which should be supported by most UNIX-like operating systems, or the | ||||
|   more efficient and flexible epoll() (Linux 2.6) or kqueue() (BSD) APIs. | ||||
|   more efficient and flexible epoll() (Linux >=2.6), kqueue() (BSD) and | ||||
|   /dev/poll APIs. | ||||
|   By default the IO backend is autodetected, but you can use "--without-xxx" | ||||
|   to disable a more enhanced API and force the daemon to use select(). | ||||
|   to disable a more enhanced API. | ||||
|   When using the epoll() API, support for select() is compiled in as well by | ||||
|   default to enable the binary to run on older Linux kernels (<2.6), too. | ||||
|  | ||||
| * IDENT-Support: | ||||
|   --with-ident[=<path>] | ||||
| @@ -241,4 +247,4 @@ number. In both cases the server exits after the output. | ||||
|  | ||||
|  | ||||
| --  | ||||
| $Id: INSTALL,v 1.23.2.1 2006/08/02 08:19:38 alex Exp $ | ||||
| $Id: INSTALL,v 1.23.2.2 2007/04/03 22:08:50 fw Exp $ | ||||
|   | ||||
							
								
								
									
										117
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								configure.in
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | ||||
| # | ||||
| # ngIRCd -- The Next Generation IRC Daemon | ||||
| # Copyright (c)2001-2006 Alexander Barton <alex@barton.de> | ||||
| # Copyright (c)2001-2005 Alexander Barton <alex@barton.de> | ||||
| # | ||||
| # 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 | ||||
| @@ -8,13 +8,13 @@ | ||||
| # (at your option) any later version. | ||||
| # Please read the file COPYING, README and AUTHORS for more information. | ||||
| # | ||||
| # $Id: configure.in,v 1.118.2.8 2006/12/17 14:06:19 alex Exp $ | ||||
| # $Id: configure.in,v 1.118.2.9 2007/04/03 22:08:50 fw Exp $ | ||||
| # | ||||
|  | ||||
| # -- Initialisation -- | ||||
|  | ||||
| AC_PREREQ(2.50) | ||||
| AC_INIT(ngircd, 0.10.1) | ||||
| AC_INIT(ngircd, CVSHEAD) | ||||
| AC_CONFIG_SRCDIR(src/ngircd/ngircd.c) | ||||
| AC_CANONICAL_TARGET | ||||
| AM_INIT_AUTOMAKE(1.6) | ||||
| @@ -143,12 +143,10 @@ AC_CHECK_FUNCS([ \ | ||||
|  | ||||
| AC_CHECK_FUNCS(inet_aton isdigit sigaction snprintf vsnprintf strdup strlcpy strlcat) | ||||
|  | ||||
| AC_CHECK_FUNCS(select,[AC_CHECK_HEADERS(sys/select.h)], | ||||
| 	AC_MSG_ERROR([required function select() is missing!]) | ||||
| ) | ||||
|  | ||||
| # -- Configuration options -- | ||||
|  | ||||
| # use syslog? | ||||
|  | ||||
| x_syslog_on=no | ||||
| AC_ARG_WITH(syslog, | ||||
| 	[  --without-syslog        disable syslog (autodetected by default)], | ||||
| @@ -174,6 +172,8 @@ if test "$x_syslog_on" = "yes"; then | ||||
| 	AC_CHECK_HEADERS(syslog.h,,AC_MSG_ERROR([required C header missing!])) | ||||
| fi | ||||
|  | ||||
| # use zlib compression? | ||||
|  | ||||
| x_zlib_on=no | ||||
| AC_ARG_WITH(zlib, | ||||
| 	[  --without-zlib          disable zlib compression (autodetected by default)], | ||||
| @@ -198,29 +198,83 @@ if test "$x_zlib_on" = "yes"; then | ||||
| 	AC_CHECK_HEADERS(zlib.h,,AC_MSG_ERROR([required C header missing!])) | ||||
| fi | ||||
|  | ||||
| # detect which IO API to use: | ||||
|  | ||||
| x_io_backend=select\(\) | ||||
| AC_ARG_WITH(epoll, | ||||
| 	[  --without-epoll         disable epoll support (autodetected by default)], | ||||
| x_io_backend=none | ||||
|  | ||||
| AC_ARG_WITH(select, | ||||
| 	[  --without-select        disable select IO support (autodetected by default)], | ||||
| 	[	if test "$withval" != "no"; then | ||||
| 			if test "$withval" != "yes"; then | ||||
| 				CFLAGS="-I$withval/include $CFLAGS" | ||||
| 				CPPFLAGS="-I$withval/include $CPPFLAGS" | ||||
| 				LDFLAGS="-L$withval/lib $LDFLAGS" | ||||
| 			fi | ||||
| 			AC_CHECK_FUNCS(epoll_create, x_io_backend=epoll\(\), | ||||
| 				AC_MSG_ERROR([Can't enable epoll support!]) | ||||
| 			AC_CHECK_FUNCS(select, x_io_select=yes, | ||||
| 				AC_MSG_ERROR([Can't enable select IO support!]) | ||||
| 			) | ||||
| 		fi | ||||
| 	], | ||||
| 	[ | ||||
| 		AC_CHECK_FUNCS(epoll_create, x_io_backend=epoll\(\)) | ||||
| 		AC_CHECK_FUNCS(select, x_io_select=yes) | ||||
| 	] | ||||
| ) | ||||
|  | ||||
| AC_ARG_WITH(poll, | ||||
| 	[  --without-poll          disable poll support (autodetected by default)], | ||||
| 	[	if test "$withval" != "no"; then | ||||
| 			if test "$withval" != "yes"; then | ||||
| 				CFLAGS="-I$withval/include $CFLAGS" | ||||
| 				CPPFLAGS="-I$withval/include $CPPFLAGS" | ||||
| 				LDFLAGS="-L$withval/lib $LDFLAGS" | ||||
| 			fi | ||||
| 			AC_CHECK_FUNCS(poll, x_io_backend=poll\(\), | ||||
| 				AC_MSG_ERROR([Can't enable poll IO support!]) | ||||
| 			) | ||||
| 		fi | ||||
| 	], | ||||
| 	[ | ||||
| 		AC_CHECK_FUNCS(poll, x_io_backend=poll\(\)) | ||||
| 	] | ||||
| ) | ||||
|  | ||||
| AC_ARG_WITH(devpoll, | ||||
| 	[  --without-devpoll       disable /dev/poll IO support (autodetected by default)], | ||||
| 	[	if test "$withval" != "no"; then | ||||
| 			if test "$withval" != "yes"; then | ||||
| 				CFLAGS="-I$withval/include $CFLAGS" | ||||
| 				CPPFLAGS="-I$withval/include $CPPFLAGS" | ||||
| 				LDFLAGS="-L$withval/lib $LDFLAGS" | ||||
| 			fi | ||||
|  | ||||
| 				AC_CHECK_HEADERS(sys/devpoll.h,,AC_MSG_ERROR([required C header missing!])) | ||||
| 		fi | ||||
| 	], | ||||
| 	[ | ||||
| 		AC_CHECK_HEADERS(sys/devpoll.h, x_io_backend=/dev/poll) | ||||
| 	] | ||||
| ) | ||||
|  | ||||
| AC_ARG_WITH(epoll, | ||||
| 	[  --without-epoll         disable epoll IO support (autodetected by default)], | ||||
| 	[	if test "$withval" != "no"; then | ||||
| 			if test "$withval" != "yes"; then | ||||
| 				CFLAGS="-I$withval/include $CFLAGS" | ||||
| 				CPPFLAGS="-I$withval/include $CPPFLAGS" | ||||
| 				LDFLAGS="-L$withval/lib $LDFLAGS" | ||||
| 			fi | ||||
| 			AC_CHECK_FUNCS(epoll_create, x_io_epoll=yes, | ||||
| 				AC_MSG_ERROR([Can't enable epoll IO support!]) | ||||
| 			) | ||||
| 		fi | ||||
| 	], | ||||
| 	[ | ||||
| 		AC_CHECK_FUNCS(epoll_create, x_io_epoll=yes) | ||||
| 	] | ||||
| ) | ||||
|  | ||||
| AC_ARG_WITH(kqueue, | ||||
| 	[  --without-kqueue        disable kqueue support (autodetected by default)], | ||||
| 	[  --without-kqueue        disable kqueue IO support (autodetected by default)], | ||||
| 	[	if test "$withval" != "no"; then | ||||
| 			if test "$withval" != "yes"; then | ||||
| 				CFLAGS="-I$withval/include $CFLAGS" | ||||
| @@ -228,7 +282,7 @@ AC_ARG_WITH(kqueue, | ||||
| 				LDFLAGS="-L$withval/lib $LDFLAGS" | ||||
| 			fi | ||||
| 			AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue\(\), | ||||
| 				AC_MSG_ERROR([Can't enable kqueue support!]) | ||||
| 				AC_MSG_ERROR([Can't enable kqueue IO support!]) | ||||
| 			) | ||||
| 		fi | ||||
| 	], | ||||
| @@ -237,6 +291,27 @@ AC_ARG_WITH(kqueue, | ||||
| 	] | ||||
| ) | ||||
|  | ||||
| if test "$x_io_epoll" = "yes" -a "$x_io_select" = "yes"; then | ||||
| 	# when epoll() and select() are available, we'll use both! | ||||
| 	x_io_backend="epoll(), select()" | ||||
| else | ||||
| 	if test "$x_io_epoll" = "yes"; then | ||||
| 		# we prefere epoll() if it is available | ||||
| 		x_io_backend="epoll()" | ||||
| 	else | ||||
| 		if test "$x_io_select" = "yes" -a "$x_io_backend" = "none"; then | ||||
| 			# we'll use select, when available and no "better" | ||||
| 			# interface has been detected ... | ||||
| 			x_io_backend="select()" | ||||
| 		fi | ||||
| 	fi | ||||
| fi | ||||
|  | ||||
| if test "$x_io_backend" = "none"; then | ||||
| 	AC_MSG_ERROR([No useabe IO API activated/found!?]) | ||||
| fi | ||||
|  | ||||
| # use TCP wrappers? | ||||
|  | ||||
| x_tcpwrap_on=no | ||||
| AC_ARG_WITH(tcp-wrappers, | ||||
| @@ -267,6 +342,8 @@ int deny_severity = 0; | ||||
| 	] | ||||
| ) | ||||
|  | ||||
| # include support for "zeroconf"? | ||||
|  | ||||
| x_zeroconf_on=no | ||||
| AC_ARG_WITH(zeroconf, | ||||
| 	[  --with-zeroconf         enable support for "Zeroconf"], | ||||
| @@ -315,6 +392,8 @@ if test "$x_zeroconf_on" = "howl"; then | ||||
| 	AC_DEFINE(ZEROCONF, 1) | ||||
| fi | ||||
|  | ||||
| # do IDENT requests using libident? | ||||
|  | ||||
| x_identauth_on=no | ||||
| AC_ARG_WITH(ident, | ||||
| 	[  --with-ident            enable "IDENT" ("AUTH") protocol support], | ||||
| @@ -336,6 +415,8 @@ if test "$x_identauth_on" = "yes"; then | ||||
| 	AC_CHECK_HEADERS(ident.h,,AC_MSG_ERROR([required C header missing!])) | ||||
| fi | ||||
|  | ||||
| # compile in IRC+ protocol support? | ||||
|  | ||||
| x_ircplus_on=yes | ||||
| AC_ARG_ENABLE(ircplus, | ||||
| 	[  --disable-ircplus       disable IRC+ protocol], | ||||
| @@ -345,6 +426,8 @@ if test "$x_ircplus_on" = "yes"; then | ||||
| 	AC_DEFINE(IRCPLUS, 1) | ||||
| fi | ||||
|  | ||||
| # compile in IRC "sniffer"? | ||||
|  | ||||
| x_sniffer_on=no; x_debug_on=no | ||||
| AC_ARG_ENABLE(sniffer, | ||||
| 	[  --enable-sniffer        enable IRC traffic sniffer (enables debug mode)], | ||||
| @@ -354,6 +437,8 @@ AC_ARG_ENABLE(sniffer, | ||||
| 	fi | ||||
| ) | ||||
|  | ||||
| # enable additional debugging code? | ||||
|  | ||||
| AC_ARG_ENABLE(debug, | ||||
| 	[  --enable-debug          show additional debug output], | ||||
| 	if test "$enableval" = "yes"; then x_debug_on=yes; fi | ||||
| @@ -363,6 +448,8 @@ if test "$x_debug_on" = "yes"; then | ||||
| 	test "$GCC" = "yes" && CFLAGS="-pedantic $CFLAGS" | ||||
| fi | ||||
|  | ||||
| # enable "strict RFC rules"? | ||||
|  | ||||
| x_strict_rfc_on=no | ||||
| AC_ARG_ENABLE(strict-rfc, | ||||
| 	[  --enable-strict-rfc     strict RFC conformance -- may break clients!], | ||||
|   | ||||
| @@ -2,9 +2,20 @@ | ||||
| # | ||||
| # ngIRCd start and stop script for Debian-based systems | ||||
| # | ||||
| # $Id: ngircd.init,v 1.6 2005/07/26 19:37:18 alex Exp $ | ||||
| # $Id: ngircd.init,v 1.6.2.1 2007/04/03 22:08:50 fw Exp $ | ||||
| # | ||||
|  | ||||
| ### BEGIN INIT INFO | ||||
| # Provides:		ircd | ||||
| # Required-Start:	$local_fs | ||||
| # Required-Stop:	$local_fs | ||||
| # Should-Start:		$syslog $network | ||||
| # Should-Stop:		$syslog $network | ||||
| # Default-Start:	2 3 4 5 | ||||
| # Default-Stop:		0 1 6 | ||||
| # Short-Description:	Next Generation IRC Server | ||||
| ### END INIT INFO | ||||
|  | ||||
| PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin | ||||
| DAEMON=/usr/sbin/ngircd | ||||
| NAME=ngIRCd | ||||
|   | ||||
| @@ -51,6 +51,7 @@ powerpc/apple/darwin7.4.0   gcc 3.3      0.8.0      04-05-30 alex   Y Y Y Y | ||||
| powerpc/apple/darwin7.9.0   gcc 3.3      CVSHEAD    06-05-07 fw     Y Y Y Y (3) | ||||
| powerpc/apple/darwin8.1.0   gcc 4.0      0.9.x-CVS  05-06-27 alex   Y Y Y Y | ||||
| powerpc/unknown/linux-gnu   gcc 3.3.3    0.8.0      04-05-30 alex   Y Y Y Y | ||||
| powerpc/unknown/openbsd3.6  gcc 2.95.3   0.10.0     06-10-08 alex   Y Y n Y | ||||
| sparc/sun/solaris2.6        gcc 2.95.3   0.7.x-CVS  03-04-22 alex   Y Y Y Y | ||||
| sparc/sun/solaris2.7        gcc 3.3      0.8.0      04-05-30 alex   Y Y Y Y | ||||
| sparc/unkn./netbsdelf1.6.1  gcc 2.95.3   0.8.0      04-05-30 alex   Y Y Y Y | ||||
| @@ -73,4 +74,4 @@ Notes | ||||
| (3) Using the kqueue() IO interface. | ||||
|  | ||||
| --  | ||||
| $Id: Platforms.txt,v 1.14.2.1 2006/09/09 18:10:56 alex Exp $ | ||||
| $Id: Platforms.txt,v 1.14.2.2 2007/04/03 22:08:51 fw Exp $ | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| # $Id: sample-ngircd.conf,v 1.37.2.1 2006/12/02 13:10:43 fw Exp $ | ||||
| # $Id: sample-ngircd.conf,v 1.37.2.2 2007/04/03 22:08:51 fw Exp $ | ||||
|  | ||||
| # | ||||
| # This is a sample configuration file for the ngIRCd, which must be adepted | ||||
| @@ -178,7 +178,13 @@ | ||||
| 	;Topic = a great topic | ||||
|  | ||||
| 	# Initial channel modes | ||||
| 	;Modes = tn | ||||
| 	;Modes = tnk | ||||
|  | ||||
| 	# initial channel password (mode k) | ||||
| 	;Key = Secret | ||||
|  | ||||
| 	# maximum users per channel (mode l) | ||||
| 	;MaxUsers = 23 | ||||
|  | ||||
| [Channel] | ||||
| 	# More [Channel] sections, if you like ... | ||||
|   | ||||
| @@ -8,14 +8,14 @@ | ||||
| # (at your option) any later version. | ||||
| # Please read the file COPYING, README and AUTHORS for more information. | ||||
| # | ||||
| # $Id: Makefile.am,v 1.2 2006/04/08 16:35:03 alex Exp $ | ||||
| # $Id: Makefile.am,v 1.2.2.1 2007/04/03 22:08:52 fw Exp $ | ||||
| # | ||||
|  | ||||
| maintainer-clean-local: | ||||
| 	rm -f Makefile Makefile.in | ||||
|  | ||||
| distclean-local: | ||||
| 	rm -f html | ||||
| 	rm -rf html | ||||
|  | ||||
| srcdoc: | ||||
| 	@doxygen --version >/dev/null 2>&1 \ | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
|  | ||||
| #include "array.h" | ||||
|  | ||||
| static char UNUSED id[] = "$Id: array.c,v 1.11.2.2 2006/12/17 23:00:17 fw Exp $"; | ||||
| static char UNUSED id[] = "$Id: array.c,v 1.11.2.3 2007/04/03 22:08:52 fw Exp $"; | ||||
|  | ||||
| #include <assert.h> | ||||
|  | ||||
| @@ -270,7 +270,7 @@ void | ||||
| array_free(array * a) | ||||
| { | ||||
| 	assert(a != NULL); | ||||
| #ifdef DEBUG | ||||
| #ifdef DEBUG_ARRAY | ||||
| 	Log(LOG_DEBUG, | ||||
| 	    "array_free(): %u bytes free'd (%u bytes still used at time of free()).", | ||||
| 	    a->allocated, a->used); | ||||
|   | ||||
| @@ -17,7 +17,7 @@ | ||||
|  | ||||
| #include "portab.h" | ||||
|  | ||||
| static char UNUSED id[] = "$Id: channel.c,v 1.56.2.2 2007/04/03 20:23:31 fw Exp $"; | ||||
| static char UNUSED id[] = "$Id: channel.c,v 1.56.2.3 2007/04/03 22:08:52 fw Exp $"; | ||||
|  | ||||
| #include "imp.h" | ||||
| #include <assert.h> | ||||
| @@ -131,6 +131,9 @@ Channel_InitPredefined( void ) | ||||
| 			while (*c) | ||||
| 				Channel_ModeAdd(chan, *c++); | ||||
|  | ||||
| 			Channel_SetKey(chan, Conf_Channel[i].key); | ||||
| 			Channel_SetMaxUsers(chan, Conf_Channel[i].maxusers); | ||||
|  | ||||
| 			Log(LOG_INFO, "Created pre-defined channel \"%s\".", | ||||
| 							Conf_Channel[i].name ); | ||||
| 		} | ||||
| @@ -145,7 +148,7 @@ Channel_Exit( void ) | ||||
| { | ||||
| 	CHANNEL *c, *c_next; | ||||
| 	CL2CHAN *cl2chan, *cl2chan_next; | ||||
| 	 | ||||
|  | ||||
| 	/* Channel-Strukturen freigeben */ | ||||
| 	c = My_Channels; | ||||
| 	while( c ) | ||||
|   | ||||
| @@ -17,7 +17,7 @@ | ||||
|  | ||||
| #include "portab.h" | ||||
|  | ||||
| static char UNUSED id[] = "$Id: client.c,v 1.91.2.1 2006/12/02 14:00:00 fw Exp $"; | ||||
| static char UNUSED id[] = "$Id: client.c,v 1.91.2.2 2007/04/03 22:08:52 fw Exp $"; | ||||
|  | ||||
| #include "imp.h" | ||||
| #include <assert.h> | ||||
| @@ -68,10 +68,6 @@ static CLIENT *Init_New_Client PARAMS((CONN_ID Idx, CLIENT *Introducer, | ||||
|  CLIENT *TopServer, int Type, char *ID, char *User, char *Hostname, | ||||
|  char *Info, int Hops, int Token, char *Modes, bool Idented)); | ||||
|  | ||||
| #ifndef Client_DestroyNow | ||||
| GLOBAL void Client_DestroyNow PARAMS((CLIENT *Client )); | ||||
| #endif | ||||
|  | ||||
|  | ||||
| long Max_Users = 0, My_Max_Users = 0; | ||||
|  | ||||
| @@ -336,43 +332,14 @@ Client_Destroy( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit ) | ||||
| } /* Client_Destroy */ | ||||
|  | ||||
|  | ||||
| GLOBAL void | ||||
| Client_DestroyNow( CLIENT *Client ) | ||||
| { | ||||
| 	/* Destroy client structure immediately. This function is only | ||||
| 	 * intended for the connection layer to remove client structures | ||||
| 	 * of connections that can't be established! */ | ||||
|  | ||||
| 	CLIENT *last, *c; | ||||
|  | ||||
| 	assert( Client != NULL ); | ||||
|  | ||||
| 	last = NULL; | ||||
| 	c = My_Clients; | ||||
| 	while( c ) | ||||
| 	{ | ||||
| 		if( c == Client ) | ||||
| 		{ | ||||
| 			/* Wir haben den Client gefunden: entfernen */ | ||||
| 			if( last ) last->next = c->next; | ||||
| 			else My_Clients = (CLIENT *)c->next; | ||||
| 			free( c ); | ||||
| 			break; | ||||
| 		} | ||||
| 		last = c; | ||||
| 		c = (CLIENT *)c->next; | ||||
| 	} | ||||
| } /* Client_DestroyNow */ | ||||
|  | ||||
|  | ||||
| GLOBAL void | ||||
| Client_SetHostname( CLIENT *Client, char *Hostname ) | ||||
| { | ||||
| 	/* Hostname eines Clients setzen */ | ||||
| 	 | ||||
|  | ||||
| 	assert( Client != NULL ); | ||||
| 	assert( Hostname != NULL ); | ||||
| 	 | ||||
|  | ||||
| 	strlcpy( Client->host, Hostname, sizeof( Client->host )); | ||||
| } /* Client_SetHostname */ | ||||
|  | ||||
| @@ -661,8 +628,7 @@ GLOBAL char * | ||||
| Client_User( CLIENT *Client ) | ||||
| { | ||||
| 	assert( Client != NULL ); | ||||
| 	if( Client->user[0] ) return Client->user; | ||||
| 	else return "~"; | ||||
| 	return Client->user[0] ? Client->user : "~"; | ||||
| } /* Client_User */ | ||||
|  | ||||
|  | ||||
| @@ -916,9 +882,8 @@ GLOBAL unsigned long | ||||
| Client_MyServerCount( void ) | ||||
| { | ||||
| 	CLIENT *c; | ||||
| 	unsigned long cnt; | ||||
| 	unsigned long cnt = 0; | ||||
|  | ||||
| 	cnt = 0; | ||||
| 	c = My_Clients; | ||||
| 	while( c ) | ||||
| 	{ | ||||
| @@ -933,9 +898,8 @@ GLOBAL unsigned long | ||||
| Client_OperCount( void ) | ||||
| { | ||||
| 	CLIENT *c; | ||||
| 	unsigned long cnt; | ||||
| 	unsigned long cnt = 0; | ||||
|  | ||||
| 	cnt = 0; | ||||
| 	c = My_Clients; | ||||
| 	while( c ) | ||||
| 	{ | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|  * (at your option) any later version. | ||||
|  * Please read the file COPYING, README and AUTHORS for more information. | ||||
|  * | ||||
|  * $Id: client.h,v 1.42.2.2 2006/12/02 14:26:53 fw Exp $ | ||||
|  * $Id: client.h,v 1.42.2.3 2007/04/03 22:08:52 fw Exp $ | ||||
|  * | ||||
|  * Client management (header) | ||||
|  */ | ||||
| @@ -80,9 +80,6 @@ GLOBAL CLIENT *Client_NewRemoteServer PARAMS(( CLIENT *Introducer, char *Hostnam | ||||
| GLOBAL CLIENT *Client_NewRemoteUser PARAMS(( CLIENT *Introducer, char *Nick, int Hops, char *User, char *Hostname, int Token, char *Modes, char *Info, bool Idented )); | ||||
|  | ||||
| GLOBAL void Client_Destroy PARAMS(( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit )); | ||||
| #ifdef CONN_MODULE | ||||
| GLOBAL void Client_DestroyNow PARAMS(( CLIENT *Client )); | ||||
| #endif | ||||
|  | ||||
| GLOBAL CLIENT *Client_ThisServer PARAMS(( void )); | ||||
|  | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
|  | ||||
| #include "portab.h" | ||||
|  | ||||
| static char UNUSED id[] = "$Id: conf.c,v 1.92.2.3 2006/12/02 13:10:43 fw Exp $"; | ||||
| static char UNUSED id[] = "$Id: conf.c,v 1.92.2.4 2007/04/03 22:08:52 fw Exp $"; | ||||
|  | ||||
| #include "imp.h" | ||||
| #include <assert.h> | ||||
| @@ -240,6 +240,8 @@ Conf_Test( void ) | ||||
| 		puts( "[CHANNEL]" ); | ||||
| 		printf( "  Name = %s\n", Conf_Channel[i].name ); | ||||
| 		printf( "  Modes = %s\n", Conf_Channel[i].modes ); | ||||
| 		printf( "  Key = %s\n", Conf_Channel[i].key ); | ||||
| 		printf( "  MaxUsers = %lu\n", Conf_Channel[i].maxusers ); | ||||
|  | ||||
| 		topic = (char*)array_start(&Conf_Channel[i].topic); | ||||
| 		printf( "  Topic = %s\n\n", topic ? topic : ""); | ||||
| @@ -555,6 +557,8 @@ Read_Config( void ) | ||||
| 					/* Initialize new channel structure */ | ||||
| 					strcpy( Conf_Channel[Conf_Channel_Count].name, "" ); | ||||
| 					strcpy( Conf_Channel[Conf_Channel_Count].modes, "" ); | ||||
| 					strcpy( Conf_Channel[Conf_Channel_Count].key, "" ); | ||||
| 					Conf_Channel[Conf_Channel_Count].maxusers = 0; | ||||
| 					array_free(&Conf_Channel[Conf_Channel_Count].topic); | ||||
| 					Conf_Channel_Count++; | ||||
| 				} | ||||
| @@ -968,6 +972,22 @@ Handle_CHANNEL( int Line, char *Var, char *Arg ) | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if( strcasecmp( Var, "Key" ) == 0 ) { | ||||
| 		/* Initial Channel Key (mode k) */ | ||||
| 		len = strlcpy(Conf_Channel[chancount].key, Arg, sizeof(Conf_Channel[chancount].key)); | ||||
| 		if (len >= sizeof( Conf_Channel[chancount].key )) | ||||
| 			Config_Error_TooLong(Line, Var); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if( strcasecmp( Var, "MaxUsers" ) == 0 ) { | ||||
| 		/* maximum user limit, mode l */ | ||||
| 		Conf_Channel[chancount].maxusers = (unsigned long) atol(Arg); | ||||
| 		if (Conf_Channel[chancount].maxusers == 0) | ||||
| 			Config_Error_NaN(Line, Var); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	Config_Error( LOG_ERR, "%s, line %d (section \"Channel\"): Unknown variable \"%s\"!", | ||||
| 								NGIRCd_ConfFile, Line, Var ); | ||||
| } /* Handle_CHANNEL */ | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|  * (at your option) any later version. | ||||
|  * Please read the file COPYING, README and AUTHORS for more information. | ||||
|  * | ||||
|  * $Id: conf.h,v 1.40.2.1 2006/12/02 13:10:43 fw Exp $ | ||||
|  * $Id: conf.h,v 1.40.2.2 2007/04/03 22:08:52 fw Exp $ | ||||
|  * | ||||
|  * Configuration management (header) | ||||
|  */ | ||||
| @@ -49,6 +49,8 @@ typedef struct _Conf_Channel | ||||
| { | ||||
| 	char name[CHANNEL_NAME_LEN];	/* Name of the channel */ | ||||
| 	char modes[CHANNEL_MODE_LEN];	/* Initial channel modes */ | ||||
| 	char key[CLIENT_PASS_LEN];      /* Channel key ("password", mode "k" ) */ | ||||
| 	unsigned long maxusers;		/* maximum usercount for this channel, mode "l" */ | ||||
| 	array topic;			/* Initial topic */ | ||||
| } CONF_CHANNEL; | ||||
|  | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|  * (at your option) any later version. | ||||
|  * Please read the file COPYING, README and AUTHORS for more information. | ||||
|  * | ||||
|  * $Id: conn-func.h,v 1.5 2006/05/10 21:24:01 alex Exp $ | ||||
|  * $Id: conn-func.h,v 1.5.2.1 2007/04/03 22:08:52 fw Exp $ | ||||
|  * | ||||
|  * Connection management: Global functions (header) | ||||
|  */ | ||||
| @@ -52,9 +52,9 @@ GLOBAL UINT16 Conn_Options PARAMS(( CONN_ID Idx )); | ||||
| GLOBAL void Conn_ResetWCounter PARAMS(( void )); | ||||
| GLOBAL long Conn_WCounter PARAMS(( void )); | ||||
|  | ||||
| #define Conn_OPTION_ADD( x, opt )   ( (x)->options |= opt )  | ||||
| #define Conn_OPTION_DEL( x, opt )   ( (x)->options &= ~opt ) | ||||
| #define Conn_OPTION_ISSET( x, opt ) ( (x)->options & opt ) | ||||
| #define Conn_OPTION_ADD( x, opt )   ( (x)->options |= (opt) ) | ||||
| #define Conn_OPTION_DEL( x, opt )   ( (x)->options &= ~(opt) ) | ||||
| #define Conn_OPTION_ISSET( x, opt ) ( ((x)->options & (opt)) != 0) | ||||
|  | ||||
| #endif | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,7 @@ | ||||
| #include "portab.h" | ||||
| #include "io.h" | ||||
|  | ||||
| static char UNUSED id[] = "$Id: conn.c,v 1.198.2.2 2006/12/17 23:06:29 fw Exp $"; | ||||
| static char UNUSED id[] = "$Id: conn.c,v 1.198.2.3 2007/04/03 22:08:52 fw Exp $"; | ||||
|  | ||||
| #include "imp.h" | ||||
| #include <assert.h> | ||||
| @@ -123,7 +123,6 @@ cb_connserver(int sock, UNUSED short what) | ||||
| { | ||||
| 	int res, err; | ||||
| 	socklen_t sock_len; | ||||
| 	CLIENT *c; | ||||
| 	CONN_ID idx = Socket2Index( sock ); | ||||
| 	if (idx <= NONE) { | ||||
| 		LogDebug("cb_connserver wants to write on unknown socket?!"); | ||||
| @@ -150,14 +149,7 @@ cb_connserver(int sock, UNUSED short what) | ||||
|  			    Conf_Server[Conf_GetServer(idx)].port, | ||||
|  			    idx, strerror(err)); | ||||
|  | ||||
| 		/* Clean up the CLIENT structure (to avoid silly log | ||||
|  		 * messages) and call Conn_Close() to do the rest. */ | ||||
|  		c = Conn_GetClient(idx); | ||||
|  		if (c) | ||||
| 			Client_DestroyNow(c); | ||||
|   | ||||
|  		Conn_Close(idx, "Can't connect!", NULL, false); | ||||
|   | ||||
| 		Conn_Close(idx, "Can't connect!", NULL, false); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| @@ -384,7 +376,7 @@ NewListener( const UINT16 Port ) | ||||
| 	if( ! Init_Socket( sock )) return -1; | ||||
|  | ||||
| 	if (bind(sock, (struct sockaddr *)&addr, (socklen_t)sizeof(addr)) != 0) { | ||||
| 		Log( LOG_CRIT, "Can't bind socket: %s!", strerror( errno )); | ||||
| 		Log( LOG_CRIT, "Can't bind socket (port %d) : %s!", Port, strerror( errno )); | ||||
| 		close( sock ); | ||||
| 		return -1; | ||||
| 	} | ||||
| @@ -995,11 +987,19 @@ New_Connection( int Sock ) | ||||
| 			Init_Conn_Struct(Pool_Size++); | ||||
| 	} | ||||
|  | ||||
| 	/* register callback */ | ||||
| 	if (!io_event_create( new_sock, IO_WANTREAD, cb_clientserver)) { | ||||
| 		Log(LOG_ALERT, "Can't accept connection: io_event_create failed!"); | ||||
| 		Simple_Message(new_sock, "ERROR :Internal error"); | ||||
| 		close(new_sock); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	c = Client_NewLocal( new_sock, inet_ntoa( new_addr.sin_addr ), CLIENT_UNKNOWN, false ); | ||||
| 	if( ! c ) { | ||||
| 		Log( LOG_ALERT, "Can't accept connection: can't create client structure!" ); | ||||
| 		Simple_Message( new_sock, "ERROR :Internal error" ); | ||||
| 		close( new_sock ); | ||||
| 		Log(LOG_ALERT, "Can't accept connection: can't create client structure!"); | ||||
| 		Simple_Message(new_sock, "ERROR :Internal error"); | ||||
| 		io_close(new_sock); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| @@ -1008,13 +1008,6 @@ New_Connection( int Sock ) | ||||
| 	My_Connections[new_sock].addr = new_addr; | ||||
| 	My_Connections[new_sock].client = c; | ||||
|  | ||||
| 	/* register callback */ | ||||
| 	if (!io_event_create( new_sock, IO_WANTREAD, cb_clientserver)) { | ||||
| 		Simple_Message( new_sock, "ERROR :Internal error" ); | ||||
| 		Conn_Close( new_sock, "io_event_create() failed", NULL, false ); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	Log( LOG_INFO, "Accepted connection %d from %s:%d on socket %d.", new_sock, | ||||
| 			inet_ntoa( new_addr.sin_addr ), ntohs( new_addr.sin_port), Sock ); | ||||
|  | ||||
|   | ||||
							
								
								
									
										484
									
								
								src/ngircd/io.c
									
									
									
									
									
								
							
							
						
						
									
										484
									
								
								src/ngircd/io.c
									
									
									
									
									
								
							| @@ -12,7 +12,7 @@ | ||||
|  | ||||
| #include "portab.h" | ||||
|  | ||||
| static char UNUSED id[] = "$Id: io.c,v 1.16 2006/07/23 23:11:44 alex Exp $"; | ||||
| static char UNUSED id[] = "$Id: io.c,v 1.16.2.1 2007/04/03 22:08:52 fw Exp $"; | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <stdlib.h> | ||||
| @@ -34,25 +34,40 @@ typedef struct { | ||||
|  short what; | ||||
| } io_event; | ||||
|  | ||||
| #define INIT_IOEVENT    { NULL, -1, 0, NULL } | ||||
| #define IO_ERROR        4 | ||||
| #define INIT_IOEVENT		{ NULL, -1, 0, NULL } | ||||
| #define IO_ERROR		4 | ||||
|  | ||||
| #ifdef HAVE_EPOLL_CREATE | ||||
| #define IO_USE_EPOLL    1 | ||||
| #  define IO_USE_EPOLL		1 | ||||
| #  ifdef HAVE_SELECT | ||||
| #    define IO_USE_SELECT	1 | ||||
| #  endif | ||||
| #else | ||||
| # ifdef HAVE_KQUEUE | ||||
| #define IO_USE_KQUEUE   1 | ||||
| # else | ||||
| #define IO_USE_SELECT   1 | ||||
| #endif | ||||
| #endif | ||||
| #  ifdef HAVE_KQUEUE | ||||
| #    define IO_USE_KQUEUE	1 | ||||
| #  else | ||||
| #    ifdef HAVE_SYS_DEVPOLL_H | ||||
| #      define IO_USE_DEVPOLL	1 | ||||
| #    else | ||||
| #      ifdef HAVE_POLL | ||||
| #        define IO_USE_POLL	1 | ||||
| #      else | ||||
| #        ifdef HAVE_SELECT | ||||
| #          define IO_USE_SELECT	1 | ||||
| #        else | ||||
| #          error "no IO API available!?" | ||||
| #        endif /* HAVE_SELECT */ | ||||
| #      endif /* HAVE_POLL */ | ||||
| #    endif /* HAVE_SYS_DEVPOLL_H */ | ||||
| #  endif /* HAVE_KQUEUE */ | ||||
| #endif /* HAVE_EPOLL_CREATE */ | ||||
|  | ||||
| static bool library_initialized; | ||||
| static bool library_initialized = false; | ||||
|  | ||||
| #ifdef IO_USE_EPOLL | ||||
| #include <sys/epoll.h> | ||||
|  | ||||
| static int io_masterfd; | ||||
| static int io_masterfd = -1; | ||||
| static bool io_event_change_epoll(int fd, short what, const int action); | ||||
| static int io_dispatch_epoll(struct timeval *tv); | ||||
| #endif | ||||
| @@ -67,6 +82,22 @@ static int io_dispatch_kqueue(struct timeval *tv); | ||||
| static bool io_event_change_kqueue(int, short, const int action); | ||||
| #endif | ||||
|  | ||||
| #ifdef IO_USE_POLL | ||||
| #include <poll.h> | ||||
|  | ||||
| static array pollfds; | ||||
| static int poll_maxfd; | ||||
|  | ||||
| static bool io_event_change_poll(int fd, short what); | ||||
| #endif | ||||
|  | ||||
| #ifdef IO_USE_DEVPOLL | ||||
| #include <sys/devpoll.h> | ||||
| static int io_masterfd; | ||||
|  | ||||
| static bool io_event_change_devpoll(int fd, short what); | ||||
| #endif | ||||
|  | ||||
| #ifdef IO_USE_SELECT | ||||
| #include "defines.h"	/* for conn.h */ | ||||
| #include "conn.h"	/* for CONN_IDX (needed by resolve.h) */ | ||||
| @@ -77,7 +108,11 @@ static fd_set readers; | ||||
| static fd_set writers; | ||||
| static int select_maxfd;		/* the select() interface sucks badly */ | ||||
| static int io_dispatch_select(struct timeval *tv); | ||||
|  | ||||
| #ifndef IO_USE_EPOLL | ||||
| #define io_masterfd -1 | ||||
| #endif | ||||
| #endif /* IO_USE_SELECT */ | ||||
|  | ||||
| static array io_events; | ||||
|  | ||||
| @@ -98,40 +133,45 @@ io_event_get(int fd) | ||||
| } | ||||
|  | ||||
|  | ||||
| bool | ||||
| io_library_init(unsigned int eventsize) | ||||
| #ifdef IO_USE_DEVPOLL | ||||
| static void | ||||
| io_library_init_devpoll(unsigned int eventsize) | ||||
| { | ||||
| #if defined(IO_USE_EPOLL) || defined(IO_USE_KQUEUE) | ||||
| 	bool ret; | ||||
| 	io_masterfd = open("/dev/poll", O_RDWR); | ||||
| 	if (io_masterfd >= 0) | ||||
| 		library_initialized = true; | ||||
| 	Log(LOG_INFO, "IO subsystem: /dev/poll (initial maxfd %u, masterfd %d).", | ||||
| 		eventsize, io_masterfd); | ||||
| } | ||||
| #endif | ||||
| #ifdef IO_USE_EPOLL | ||||
| 	int ecreate_hint = (int)eventsize; | ||||
| 	if (ecreate_hint <= 0) | ||||
| 		ecreate_hint = 128; | ||||
|  | ||||
|  | ||||
| #ifdef IO_USE_POLL | ||||
| static void | ||||
| io_library_init_poll(unsigned int eventsize) | ||||
| { | ||||
| 	struct pollfd *p; | ||||
| 	array_init(&pollfds); | ||||
| 	poll_maxfd = 0; | ||||
| 	Log(LOG_INFO, "IO subsystem: poll (initial maxfd %u).", | ||||
| 	    eventsize); | ||||
| 	p = array_alloc(&pollfds, sizeof(struct pollfd), eventsize); | ||||
| 	if (p) { | ||||
| 		unsigned i; | ||||
| 		p = array_start(&pollfds); | ||||
| 		for (i = 0; i < eventsize; i++) | ||||
| 			p[i].fd = -1; | ||||
|  | ||||
| 		library_initialized = true; | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
| 	if (library_initialized) | ||||
| 		return true; | ||||
|  | ||||
|  | ||||
| #ifdef IO_USE_SELECT | ||||
| #ifdef FD_SETSIZE | ||||
| 	if (eventsize >= FD_SETSIZE) | ||||
| 		eventsize = FD_SETSIZE - 1; | ||||
| #endif | ||||
| #endif | ||||
| 	if ((eventsize > 0) && !array_alloc(&io_events, sizeof(io_event), (size_t)eventsize)) | ||||
| 		eventsize = 0; | ||||
|  | ||||
| #ifdef IO_USE_EPOLL | ||||
| 	io_masterfd = epoll_create(ecreate_hint); | ||||
| 	Log(LOG_INFO, | ||||
| 	    "IO subsystem: epoll (hint size %d, initial maxfd %u, masterfd %d).", | ||||
| 	    ecreate_hint, eventsize, io_masterfd); | ||||
| 	ret = io_masterfd >= 0; | ||||
| 	if (ret) library_initialized = true; | ||||
|  | ||||
| 	return ret; | ||||
| #endif | ||||
| #ifdef IO_USE_SELECT | ||||
| static void | ||||
| io_library_init_select(unsigned int eventsize) | ||||
| { | ||||
| 	Log(LOG_INFO, "IO subsystem: select (initial maxfd %u).", | ||||
| 	    eventsize); | ||||
| 	FD_ZERO(&readers); | ||||
| @@ -144,24 +184,82 @@ io_library_init(unsigned int eventsize) | ||||
|  | ||||
| 		Conf_MaxConnections = FD_SETSIZE - 1; | ||||
| 	} | ||||
| #else | ||||
| 	Log(LOG_WARNING, | ||||
| 	    "FD_SETSIZE undefined, don't know how many descriptors select() can handle on your platform ..."); | ||||
| #endif /* FD_SETSIZE */ | ||||
| 	library_initialized = true; | ||||
| 	return true; | ||||
| } | ||||
| #endif /* SELECT */ | ||||
|  | ||||
|  | ||||
| #ifdef IO_USE_EPOLL | ||||
| static void | ||||
| io_library_init_epoll(unsigned int eventsize) | ||||
| { | ||||
| 	int ecreate_hint = (int)eventsize; | ||||
| 	if (ecreate_hint <= 0) | ||||
| 		ecreate_hint = 128; | ||||
| 	io_masterfd = epoll_create(ecreate_hint); | ||||
| 	if (io_masterfd >= 0) { | ||||
| 		library_initialized = true; | ||||
| 		Log(LOG_INFO, | ||||
| 		    "IO subsystem: epoll (hint size %d, initial maxfd %u, masterfd %d).", | ||||
| 		    ecreate_hint, eventsize, io_masterfd); | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #ifdef IO_USE_KQUEUE | ||||
| static void | ||||
| io_library_init_kqueue(unsigned int eventsize) | ||||
| { | ||||
| 	io_masterfd = kqueue(); | ||||
|  | ||||
| 	Log(LOG_INFO, | ||||
| 	    "IO subsystem: kqueue (initial maxfd %u, masterfd %d)", | ||||
| 	    eventsize, io_masterfd); | ||||
| 	ret = io_masterfd >= 0; | ||||
| 	if (ret) library_initialized = true; | ||||
|  | ||||
| 	return ret; | ||||
| 	if (io_masterfd >= 0) | ||||
| 		library_initialized = true; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| bool | ||||
| io_library_init(unsigned int eventsize) | ||||
| { | ||||
| 	if (library_initialized) | ||||
| 		return true; | ||||
| #ifdef IO_USE_SELECT | ||||
| #ifndef FD_SETSIZE | ||||
| 	Log(LOG_WARNING, | ||||
| 	    "FD_SETSIZE undefined, don't know how many descriptors select() can handle on your platform ..."); | ||||
| #else | ||||
| 	if (eventsize >= FD_SETSIZE) | ||||
| 		eventsize = FD_SETSIZE - 1; | ||||
| #endif /* FD_SETSIZE */ | ||||
| #endif /* IO_USE_SELECT */ | ||||
| 	if ((eventsize > 0) && !array_alloc(&io_events, sizeof(io_event), (size_t)eventsize)) | ||||
| 		eventsize = 0; | ||||
| #ifdef IO_USE_EPOLL | ||||
| 	io_library_init_epoll(eventsize); | ||||
| #ifdef IO_USE_SELECT | ||||
| 	if (io_masterfd < 0) | ||||
| 		Log(LOG_INFO, "Can't initialize epoll() IO interface, falling back to select() ..."); | ||||
| #endif | ||||
| #endif | ||||
| #ifdef IO_USE_KQUEUE | ||||
| 	io_library_init_kqueue(eventsize); | ||||
| #endif | ||||
| #ifdef IO_USE_DEVPOLL | ||||
| 	io_library_init_devpoll(eventsize); | ||||
| #endif | ||||
| #ifdef IO_USE_POLL | ||||
| 	io_library_init_poll(eventsize); | ||||
| #endif | ||||
| #ifdef IO_USE_SELECT | ||||
| 	if (! library_initialized) | ||||
| 		io_library_init_select(eventsize); | ||||
| #endif | ||||
| 	return library_initialized; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -171,11 +269,15 @@ io_library_shutdown(void) | ||||
| #ifdef IO_USE_SELECT | ||||
| 	FD_ZERO(&readers); | ||||
| 	FD_ZERO(&writers); | ||||
| #else | ||||
| 	close(io_masterfd);	/* kqueue, epoll */ | ||||
| #endif | ||||
| #ifdef IO_USE_EPOLL | ||||
| 	if (io_masterfd >= 0) | ||||
| 		close(io_masterfd); | ||||
| 	io_masterfd = -1; | ||||
| #endif | ||||
| #ifdef IO_USE_KQUEUE | ||||
| 	close(io_masterfd); | ||||
| 	io_masterfd = -1; | ||||
| 	array_free(&io_evcache); | ||||
| #endif | ||||
| 	library_initialized = false; | ||||
| @@ -201,18 +303,14 @@ io_event_create(int fd, short what, void (*cbfunc) (int, short)) | ||||
| 	io_event *i; | ||||
|  | ||||
| 	assert(fd >= 0); | ||||
|  | ||||
| #ifdef IO_USE_SELECT | ||||
| #ifdef FD_SETSIZE | ||||
| #if defined(IO_USE_SELECT) && defined(FD_SETSIZE) | ||||
| 	if (fd >= FD_SETSIZE) { | ||||
| 		Log(LOG_ERR, | ||||
| 		    "fd %d exceeds FD_SETSIZE (%u) (select can't handle more file descriptors)", | ||||
| 		    fd, FD_SETSIZE); | ||||
| 		return false; | ||||
| 	} | ||||
| #endif				/* FD_SETSIZE */ | ||||
| #endif				/* IO_USE_SELECT */ | ||||
|  | ||||
| #endif | ||||
| 	i = (io_event *) array_alloc(&io_events, sizeof(io_event), (size_t) fd); | ||||
| 	if (!i) { | ||||
| 		Log(LOG_WARNING, | ||||
| @@ -223,6 +321,12 @@ io_event_create(int fd, short what, void (*cbfunc) (int, short)) | ||||
|  | ||||
| 	i->callback = cbfunc; | ||||
| 	i->what = 0; | ||||
| #ifdef IO_USE_DEVPOLL | ||||
| 	ret = io_event_change_devpoll(fd, what); | ||||
| #endif | ||||
| #ifdef IO_USE_POLL | ||||
| 	ret = io_event_change_poll(fd, what); | ||||
| #endif | ||||
| #ifdef IO_USE_EPOLL | ||||
| 	ret = io_event_change_epoll(fd, what, EPOLL_CTL_ADD); | ||||
| #endif | ||||
| @@ -230,13 +334,57 @@ io_event_create(int fd, short what, void (*cbfunc) (int, short)) | ||||
| 	ret = io_event_change_kqueue(fd, what, EV_ADD|EV_ENABLE); | ||||
| #endif | ||||
| #ifdef IO_USE_SELECT | ||||
| 	ret = io_event_add(fd, what); | ||||
| 	if (io_masterfd < 0) | ||||
| 		ret = io_event_add(fd, what); | ||||
| #endif | ||||
| 	if (ret) i->what = what; | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifdef IO_USE_DEVPOLL | ||||
| static bool | ||||
| io_event_change_devpoll(int fd, short what) | ||||
| { | ||||
| 	struct pollfd p; | ||||
|  | ||||
| 	p.events = 0; | ||||
|  | ||||
| 	if (what & IO_WANTREAD) | ||||
| 		p.events = POLLIN | POLLPRI; | ||||
| 	if (what & IO_WANTWRITE) | ||||
| 		p.events |= POLLOUT; | ||||
|  | ||||
| 	p.fd = fd; | ||||
| 	return write(io_masterfd, &p, sizeof p) == (ssize_t)sizeof p; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| #ifdef IO_USE_POLL | ||||
| static bool | ||||
| io_event_change_poll(int fd, short what) | ||||
| { | ||||
| 	struct pollfd *p; | ||||
| 	short events = 0; | ||||
|  | ||||
| 	if (what & IO_WANTREAD) | ||||
| 		events = POLLIN | POLLPRI; | ||||
| 	if (what & IO_WANTWRITE) | ||||
| 		events |= POLLOUT; | ||||
|  | ||||
| 	p = array_alloc(&pollfds, sizeof *p, fd); | ||||
| 	if (p) { | ||||
| 		p->events = events; | ||||
| 		p->fd = fd; | ||||
| 		if (fd > poll_maxfd) | ||||
| 			poll_maxfd = fd; | ||||
| 	} | ||||
| 	return p != NULL; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #ifdef IO_USE_EPOLL | ||||
| static bool | ||||
| io_event_change_epoll(int fd, short what, const int action) | ||||
| @@ -260,7 +408,7 @@ io_event_kqueue_commit_cache(void) | ||||
| 	struct kevent *events; | ||||
| 	bool ret; | ||||
| 	int len = (int) array_length(&io_evcache, sizeof (struct kevent)); | ||||
|   | ||||
|  | ||||
| 	if (!len) /* nothing to do */ | ||||
| 		return true; | ||||
|  | ||||
| @@ -293,7 +441,7 @@ io_event_change_kqueue(int fd, short what, const int action) | ||||
| 		ret = array_catb(&io_evcache, (char*) &kev, sizeof (kev)); | ||||
| 		if (!ret) | ||||
| 			ret = kevent(io_masterfd, &kev,1, NULL, 0, NULL) == 0; | ||||
| 	}	 | ||||
| 	} | ||||
|  | ||||
| 	if (ret && (what & IO_WANTWRITE)) { | ||||
| 		EV_SET(&kev, fd, EVFILT_WRITE, action, 0, 0, 0); | ||||
| @@ -315,19 +463,27 @@ io_event_add(int fd, short what) | ||||
| 	io_event *i = io_event_get(fd); | ||||
|  | ||||
| 	if (!i) return false; | ||||
| 	if (i->what == what) return true; | ||||
|  | ||||
| 	if ((i->what & what) == what) /* event type is already registered */ | ||||
| 		return true; | ||||
| #ifdef DEBUG_IO | ||||
| 	Log(LOG_DEBUG, "io_event_add(): fd %d (arg: %d), what %d.", i->fd, fd, what); | ||||
| 	Log(LOG_DEBUG, "io_event_add(): fd %d, what %d.", fd, what); | ||||
| #endif | ||||
| 	i->what |= what; | ||||
| #ifdef IO_USE_EPOLL | ||||
| 	return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD); | ||||
| 	if (io_masterfd >= 0) | ||||
| 		return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD); | ||||
| #endif | ||||
|  | ||||
| #ifdef IO_USE_KQUEUE | ||||
| 	return io_event_change_kqueue(fd, what, EV_ADD | EV_ENABLE); | ||||
| #endif | ||||
|  | ||||
| #ifdef IO_USE_DEVPOLL | ||||
| 	return io_event_change_devpoll(fd, i->what); | ||||
| #endif | ||||
| #ifdef IO_USE_POLL | ||||
| 	return io_event_change_poll(fd, i->what); | ||||
| #endif | ||||
| #ifdef IO_USE_SELECT | ||||
| 	if (fd > select_maxfd) | ||||
| 		select_maxfd = fd; | ||||
| @@ -358,22 +514,77 @@ io_setnonblock(int fd) | ||||
| } | ||||
|  | ||||
|  | ||||
| #ifdef IO_USE_DEVPOLL | ||||
| static void | ||||
| io_close_devpoll(int fd) | ||||
| { | ||||
| 	struct pollfd p; | ||||
| 	p.events = POLLREMOVE; | ||||
| 	p.fd = fd; | ||||
| 	write(io_masterfd, &p, sizeof p); | ||||
| } | ||||
| #else | ||||
| static inline void io_close_devpoll(int UNUSED x) { /* NOTHING */ } | ||||
| #endif | ||||
|  | ||||
|  | ||||
|  | ||||
| #ifdef IO_USE_POLL | ||||
| static void | ||||
| io_close_poll(int fd) | ||||
| { | ||||
| 	struct pollfd *p; | ||||
| 	p = array_get(&pollfds, sizeof *p, fd); | ||||
| 	if (!p) return; | ||||
|  | ||||
| 	p->fd = -1; | ||||
| 	if (fd == poll_maxfd) { | ||||
| 		while (poll_maxfd > 0) { | ||||
| 			--poll_maxfd; | ||||
| 			p = array_get(&pollfds, sizeof *p, poll_maxfd); | ||||
| 			if (p && p->fd >= 0) | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| #else | ||||
| static inline void io_close_poll(int UNUSED x) { /* NOTHING */ } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #ifdef IO_USE_SELECT | ||||
| static void | ||||
| io_close_select(int fd) | ||||
| { | ||||
| 	io_event *i; | ||||
|  | ||||
| 	if (io_masterfd >= 0)	/* Are we using epoll()? */ | ||||
| 		return; | ||||
|  | ||||
| 	FD_CLR(fd, &writers); | ||||
| 	FD_CLR(fd, &readers); | ||||
|  | ||||
| 	i = io_event_get(fd); | ||||
| 	if (!i) return; | ||||
|  | ||||
| 	if (fd == select_maxfd) { | ||||
| 		while (select_maxfd>0) { | ||||
| 			--select_maxfd; /* find largest fd */ | ||||
| 			i = io_event_get(select_maxfd); | ||||
| 			if (i && i->callback) break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| #else | ||||
| static inline void io_close_select(int UNUSED x) { /* NOTHING */ } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| bool | ||||
| io_close(int fd) | ||||
| { | ||||
| 	io_event *i; | ||||
| #ifdef IO_USE_SELECT | ||||
| 	FD_CLR(fd, &writers); | ||||
| 	FD_CLR(fd, &readers); | ||||
|  | ||||
| 	if (fd == select_maxfd) { | ||||
| 		while (select_maxfd>0) { | ||||
| 			--select_maxfd; /* find largest fd */   | ||||
| 			i = io_event_get(select_maxfd); | ||||
| 			if (i && i->callback) break; | ||||
| 		}	 | ||||
| 	}	 | ||||
| #endif | ||||
| 	i = io_event_get(fd); | ||||
| #ifdef IO_USE_KQUEUE | ||||
| 	if (array_length(&io_evcache, sizeof (struct kevent)))	/* pending data in cache? */ | ||||
| @@ -385,8 +596,13 @@ io_close(int fd) | ||||
| 	if (i) { | ||||
| 		io_event_change_kqueue(fd, i->what, EV_DELETE); | ||||
| 		io_event_kqueue_commit_cache(); | ||||
| 	}	 | ||||
| 	} | ||||
| #endif | ||||
|  | ||||
| 	io_close_devpoll(fd); | ||||
| 	io_close_poll(fd); | ||||
| 	io_close_select(fd); | ||||
|  | ||||
| #ifdef IO_USE_EPOLL | ||||
| 	io_event_change_epoll(fd, 0, EPOLL_CTL_DEL); | ||||
| #endif | ||||
| @@ -409,8 +625,15 @@ io_event_del(int fd, short what) | ||||
|  | ||||
| 	i->what &= ~what; | ||||
|  | ||||
| #ifdef IO_USE_DEVPOLL | ||||
| 	return io_event_change_devpoll(fd, i->what); | ||||
| #endif | ||||
| #ifdef IO_USE_POLL | ||||
| 	return io_event_change_poll(fd, i->what); | ||||
| #endif | ||||
| #ifdef IO_USE_EPOLL | ||||
| 	return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD); | ||||
| 	if (io_masterfd >= 0) | ||||
| 		return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD); | ||||
| #endif | ||||
|  | ||||
| #ifdef IO_USE_KQUEUE | ||||
| @@ -465,6 +688,92 @@ io_dispatch_select(struct timeval *tv) | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #ifdef IO_USE_DEVPOLL | ||||
| static int | ||||
| io_dispatch_devpoll(struct timeval *tv) | ||||
| { | ||||
| 	struct dvpoll dvp; | ||||
| 	time_t sec = tv->tv_sec * 1000; | ||||
| 	int i, total, ret, timeout = tv->tv_usec + sec; | ||||
| 	short what; | ||||
| 	struct pollfd p[100]; | ||||
|  | ||||
| 	if (timeout < 0) | ||||
| 		timeout = 1000; | ||||
|  | ||||
| 	total = 0; | ||||
| 	do { | ||||
| 		dvp.dp_timeout = timeout; | ||||
| 		dvp.dp_nfds = 100; | ||||
| 		dvp.dp_fds = p; | ||||
| 		ret = ioctl(io_masterfd, DP_POLL, &dvp); | ||||
| 		total += ret; | ||||
| 		if (ret <= 0) | ||||
| 			return total; | ||||
| 		for (i=0; i < ret ; i++) { | ||||
| 			what = 0; | ||||
| 			if (p[i].revents & (POLLIN|POLLPRI)) | ||||
| 				what = IO_WANTREAD; | ||||
|  | ||||
| 			if (p[i].revents & POLLOUT) | ||||
| 				what |= IO_WANTWRITE; | ||||
|  | ||||
| 			if (p[i].revents && !what) { | ||||
| 				/* other flag is set, probably POLLERR */ | ||||
| 				what = IO_ERROR; | ||||
| 			} | ||||
| 			io_docallback(p[i].fd, what); | ||||
| 		} | ||||
| 	} while (ret == 100); | ||||
|  | ||||
| 	return total; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #ifdef IO_USE_POLL | ||||
| static int | ||||
| io_dispatch_poll(struct timeval *tv) | ||||
| { | ||||
| 	time_t sec = tv->tv_sec * 1000; | ||||
| 	int i, ret, timeout = tv->tv_usec + sec; | ||||
| 	int fds_ready; | ||||
| 	short what; | ||||
| 	struct pollfd *p = array_start(&pollfds); | ||||
|  | ||||
| 	if (timeout < 0) | ||||
| 		timeout = 1000; | ||||
|  | ||||
| 	ret = poll(p, poll_maxfd + 1, timeout); | ||||
| 	if (ret <= 0) | ||||
| 		return ret; | ||||
|  | ||||
| 	fds_ready = ret; | ||||
| 	for (i=0; i <= poll_maxfd; i++) { | ||||
| 		what = 0; | ||||
| 		if (p[i].revents & (POLLIN|POLLPRI)) | ||||
| 			what = IO_WANTREAD; | ||||
|  | ||||
| 		if (p[i].revents & POLLOUT) | ||||
| 			what |= IO_WANTWRITE; | ||||
|  | ||||
| 		if (p[i].revents && !what) { | ||||
| 			/* other flag is set, probably POLLERR */ | ||||
| 			what = IO_ERROR; | ||||
| 		} | ||||
| 		if (what) { | ||||
| 			fds_ready--; | ||||
| 			io_docallback(i, what); | ||||
| 		} | ||||
| 		if (fds_ready <= 0) | ||||
| 			break; | ||||
| 	} | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #ifdef IO_USE_EPOLL | ||||
| static int | ||||
| io_dispatch_epoll(struct timeval *tv) | ||||
| @@ -516,7 +825,7 @@ io_dispatch_kqueue(struct timeval *tv) | ||||
| 	int newevents_len; | ||||
| 	ts.tv_sec = tv->tv_sec; | ||||
| 	ts.tv_nsec = tv->tv_usec * 1000; | ||||
| 	 | ||||
|  | ||||
| 	do { | ||||
| 		newevents_len = (int) array_length(&io_evcache, sizeof (struct kevent)); | ||||
| 		newevents = (newevents_len > 0) ? array_start(&io_evcache) : NULL; | ||||
| @@ -541,10 +850,10 @@ io_dispatch_kqueue(struct timeval *tv) | ||||
| #ifdef DEBUG | ||||
| 				LogDebug("kev.flag has EV_EOF set, setting IO_ERROR", | ||||
| 					kev[i].filter, kev[i].ident); | ||||
| #endif				 | ||||
| #endif | ||||
| 				io_docallback((int)kev[i].ident, IO_ERROR); | ||||
| 				continue; | ||||
| 			}	 | ||||
| 			} | ||||
|  | ||||
| 			switch (kev[i].filter) { | ||||
| 				case EVFILT_READ: | ||||
| @@ -575,14 +884,21 @@ io_dispatch_kqueue(struct timeval *tv) | ||||
| int | ||||
| io_dispatch(struct timeval *tv) | ||||
| { | ||||
| #ifdef IO_USE_EPOLL | ||||
| 	if (io_masterfd >= 0) | ||||
| 		return io_dispatch_epoll(tv); | ||||
| #endif | ||||
| #ifdef IO_USE_SELECT | ||||
| 	return io_dispatch_select(tv); | ||||
| #endif | ||||
| #ifdef IO_USE_KQUEUE | ||||
| 	return io_dispatch_kqueue(tv); | ||||
| #endif | ||||
| #ifdef IO_USE_EPOLL | ||||
| 	return io_dispatch_epoll(tv); | ||||
| #ifdef IO_USE_DEVPOLL | ||||
| 	return io_dispatch_devpoll(tv); | ||||
| #endif | ||||
| #ifdef IO_USE_POLL | ||||
| 	return io_dispatch_poll(tv); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @@ -597,9 +913,9 @@ io_docallback(int fd, short what) | ||||
| #endif | ||||
| 	i = io_event_get(fd); | ||||
|  | ||||
| 	if (i->callback) {	/* callback might be NULL if a previous callback function  | ||||
| 	if (i->callback) {	/* callback might be NULL if a previous callback function | ||||
| 				   called io_close on this fd */ | ||||
| 		i->callback(fd, (what & IO_ERROR) ? i->what : what); | ||||
| 	}	 | ||||
| 	} | ||||
| 	/* if error indicator is set, we return the event(s) that were registered */ | ||||
| } | ||||
|   | ||||
| @@ -7,10 +7,10 @@ | ||||
|  * | ||||
|  * I/O abstraction interface header | ||||
|  * | ||||
|  * $Id: io.h,v 1.3 2005/07/14 09:15:58 alex Exp $ | ||||
|  * $Id: io.h,v 1.3.2.1 2007/04/03 22:08:52 fw Exp $ | ||||
|  */ | ||||
|  | ||||
| #ifndef io_H_inclucded | ||||
| #ifndef io_H_included | ||||
| #define io_H_included | ||||
|  | ||||
| #include "portab.h" | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
|  | ||||
| #include "portab.h" | ||||
|  | ||||
| static char UNUSED id[] = "$Id: lists.c,v 1.18.2.2 2007/04/03 20:23:31 fw Exp $"; | ||||
| static char UNUSED id[] = "$Id: lists.c,v 1.18.2.3 2007/04/03 22:08:52 fw Exp $"; | ||||
|  | ||||
| #include "imp.h" | ||||
| #include <assert.h> | ||||
| @@ -80,7 +80,7 @@ Lists_Add(struct list_head *header, const char *Mask, bool OnlyOnce ) | ||||
| 	newelem = malloc(sizeof(struct list_elem)); | ||||
| 	if( ! newelem ) { | ||||
| 		Log( LOG_EMERG, "Can't allocate memory for new Ban/Invite entry!" ); | ||||
| 		return NULL; | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	strlcpy( newelem->mask, Mask, sizeof( newelem->mask )); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Florian Westphal
					Florian Westphal