]> arthur.barton.de Git - ngircd-alex.git/commitdiff
sync with HEAD.
authorFlorian Westphal <fw@strlen.de>
Tue, 3 Apr 2007 22:08:50 +0000 (22:08 +0000)
committerFlorian Westphal <fw@strlen.de>
Tue, 3 Apr 2007 22:08:50 +0000 (22:08 +0000)
18 files changed:
ChangeLog
INSTALL
configure.in
contrib/Debian/ngircd.init
doc/Platforms.txt
doc/sample-ngircd.conf
doc/src/Makefile.am
src/ngircd/array.c
src/ngircd/channel.c
src/ngircd/client.c
src/ngircd/client.h
src/ngircd/conf.c
src/ngircd/conf.h
src/ngircd/conn-func.h
src/ngircd/conn.c
src/ngircd/io.c
src/ngircd/io.h
src/ngircd/lists.c

index fbce09f68a8fd0fda303107ba4d8e0380ea428a9..ab1191cf4ef7b95c0adfa0868bd2c65c636dc624 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 
 
 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 $
diff --git a/INSTALL b/INSTALL
index 19b554242453fcc6095a7b3409bb34d7b778a1cc..fdf324471ff27613c6024293c2f8448012aefa5e 100644 (file)
--- a/INSTALL
+++ b/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 $
index b5c9cb7c653eda56b8d3b07e47ce78d718466a4d..0391335fc3e48db443a59db75bd8bcc6a7b958d4 100644 (file)
@@ -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!],
index 62373868818b6882e72048481202b270959cdee9..74435aa8861eb31b788141269dc865cafd0549d1 100755 (executable)
@@ -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
index 18e4d900cf7334a9b3b7f93f003cdbf5c3142e39..2b731aac22d96d08a96930fcba9319cfb04f6377 100644 (file)
@@ -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 $
index 87dbe8bdae302ca7e52b44aedc5779d988113d09..5d5bc1cc0eccb7cef605af40fec047bcf287ca0d 100644 (file)
@@ -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
        ;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 ...
index 40a0c09d239db29a150c3e3f5ae84d72605097c7..b2d0fb553b3be566b7de1da801e604e448eedd6f 100644 (file)
@@ -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 \
index bd18cd6f47ae2ceb43cce96869176484c5961686..b523240694a2e965346c6feea58d942d5a3bb681 100644 (file)
@@ -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);
index 294e90673326adb03fd7cdb0c21b65209b2adef6..94993d4c12578bf957ba0a6dabd1638cef048817 100644 (file)
@@ -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 )
index e92d7c3ae18b441667d80fc30b0becde862b061b..3795b0e98c0bba13d29de6c400e15fb6f43bccd1 100644 (file)
@@ -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 )
        {
index 3e81a01faf7ae02a790c2ff9ece2626ba02d1f4d..9c8013737018ad329cc09d3f718735fac58879ae 100644 (file)
@@ -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 ));
 
index 10821292fd78f6d17bffd3151bb2079d6f240c35..6dc99772330d36ead686e9ab41b369b78d11f889 100644 (file)
@@ -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 */
index 391adef3f70652a63f5c6d7ee4e13614830766ae..5ef603c6e335bf0c634ecda3b850544a1c67610e 100644 (file)
@@ -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;
 
index 9da3dfb80418591d247c39b3adff6d031177d0ae..3259c3907e6be438d12e0f8a4b5fa53a4c374b2d 100644 (file)
@@ -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
 
index f5799e7f041523cbe6abaeea3b8d3a7db97e6160..03163e5577bf7e4953693bde5cbdae7984b8dcef 100644 (file)
@@ -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 );
 
index dd9b05f89e074e34052d66f81d2e95bac063ed6c..4733fd5240f0918ec5ace97affe2cc0e7aa29315 100644 (file)
@@ -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
-
-static bool library_initialized;
+#  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 = 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;
-#endif
-#ifdef IO_USE_EPOLL
-       int ecreate_hint = (int)eventsize;
-       if (ecreate_hint <= 0)
-               ecreate_hint = 128;
+       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
-       if (library_initialized)
-               return true;
 
-#ifdef IO_USE_SELECT
-#ifdef FD_SETSIZE
-       if (eventsize >= FD_SETSIZE)
-               eventsize = FD_SETSIZE - 1;
-#endif
+
+#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 ((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;
+       if (io_masterfd >= 0)
+               library_initialized = true;
+}
+#endif
 
-       return ret;
+
+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)
 }
 
 
-bool
-io_close(int fd)
+#ifdef IO_USE_DEVPOLL
+static void
+io_close_devpoll(int fd)
 {
-       io_event *i;
+       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 */  
+                       --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;
+
        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 */
 }
index dfc27b076fe740f8008cfe1e45c32c56fe1fa15c..150cc5186dbdc44cf44bd253b4d1ddf5bca0d189 100644 (file)
@@ -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"
index 217b79aa0bbdc9e4c3f3ed25e811a2fa29871c35..2f27687a61d04fbce2624807537c26b99726b611 100644 (file)
@@ -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 ));