ngIRCd: patch to update 0.10.1 to 0.10.2. ChangeLog | 20 + INSTALL | 14 - NEWS | 12 - README | 6 config.guess | 47 +++- config.sub | 68 +++--- configure.in | 117 +++++++++-- contrib/Debian/changelog | 6 contrib/Debian/ngircd.init | 13 + contrib/ngircd.spec | 2 doc/Platforms.txt | 3 doc/sample-ngircd.conf | 10 doc/src/Makefile.am | 4 src/ngircd/array.c | 10 src/ngircd/channel.c | 116 ++++++++--- src/ngircd/channel.h | 14 - src/ngircd/client.c | 48 ---- src/ngircd/client.h | 5 src/ngircd/conf.c | 22 ++ src/ngircd/conf.h | 4 src/ngircd/conn-func.h | 8 src/ngircd/conn-zip.c | 73 ++++--- src/ngircd/conn.c | 202 ++++++++++--------- src/ngircd/conn.h | 3 src/ngircd/defines.h | 13 - src/ngircd/io.c | 468 +++++++++++++++++++++++++++++++++++++-------- src/ngircd/io.h | 4 src/ngircd/irc-channel.c | 8 src/ngircd/irc-mode.c | 34 +-- src/ngircd/irc-op.c | 7 src/ngircd/irc-server.c | 50 ++++ src/ngircd/lists.c | 427 ++++++++--------------------------------- src/ngircd/lists.h | 38 +-- src/ngircd/ngircd.c | 8 src/ngircd/resolve.c | 7 35 files changed, 1135 insertions(+), 756 deletions(-) Index: ChangeLog =================================================================== RCS file: /srv/cvs/ngircd/ngircd/ChangeLog,v retrieving revision 1.302.2.9 retrieving revision 1.302.2.17 diff -u -p -r1.302.2.9 -r1.302.2.17 --- ChangeLog 17 Dec 2006 13:55:29 -0000 1.302.2.9 +++ ChangeLog 8 Jun 2007 09:05:23 -0000 1.302.2.17 @@ -1,7 +1,7 @@ ngIRCd - Next Generation IRC Server - (c)2001-2006 Alexander Barton, + (c)2001-2007 Alexander Barton, alex@barton.de, http://www.barton.de/ ngIRCd is free software and published under the @@ -10,6 +10,22 @@ -- ChangeLog -- +ngIRCd 0.10.2 (2007-06-08) + + ngIRCd 0.10.2-pre2 (2007-05-19) + - Server links are allowed to use larger write buffers now (up to 50 KB). + + ngIRCd 0.10.2-pre1 (2007-05-05) + - Fix compressed server links (broken since 0.10.0). + - 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) - Fixed validation of server names containing digits. @@ -673,4 +689,4 @@ ngIRCd 0.0.1, 31.12.2001 -- -$Id: ChangeLog,v 1.302.2.9 2006/12/17 13:55:29 alex Exp $ +$Id: ChangeLog,v 1.302.2.17 2007/06/08 09:05:23 alex Exp $ Index: INSTALL =================================================================== RCS file: /srv/cvs/ngircd/ngircd/INSTALL,v retrieving revision 1.23.2.1 retrieving revision 1.23.2.2 diff -u -p -r1.23.2.1 -r1.23.2.2 --- INSTALL 2 Aug 2006 08:19:38 -0000 1.23.2.1 +++ INSTALL 3 Apr 2007 22:08:50 -0000 1.23.2.2 @@ -149,14 +149,20 @@ standard locations. The Z compression library ("libz") is required for this option. * IO Backend (autodetected by default): + --with-select[=] / --without-select + --with-poll[=] / --without-poll + --with-devpoll[=] / --without-devpoll --with-epoll[=] / --without-epoll --with-kqueue[=] / --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[=] @@ -241,4 +247,4 @@ number. In both cases the server exits a -- -$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: NEWS =================================================================== RCS file: /srv/cvs/ngircd/ngircd/NEWS,v retrieving revision 1.75.2.4 retrieving revision 1.75.2.7 diff -u -p -r1.75.2.4 -r1.75.2.7 --- NEWS 17 Dec 2006 13:55:29 -0000 1.75.2.4 +++ NEWS 8 Jun 2007 09:05:23 -0000 1.75.2.7 @@ -1,7 +1,7 @@ ngIRCd - Next Generation IRC Server - (c)2001-2006 Alexander Barton, + (c)2001-2007 Alexander Barton, alex@barton.de, http://www.barton.de/ ngIRCd is free software and published under the @@ -10,6 +10,14 @@ -- NEWS -- +ngIRCd 0.10.2 (2007-06-08) + + - Predefined channel configuration now allows specification of channel key + (mode k) and maximum user count (mode l): variables "Key" and "MaxUsers". + - When using the epoll() IO interface, compile in the select() interface as + well and fall back to it when epoll() isn't available on runtime. + - Added support for IO APIs "poll()" and "/dev/poll". + ngIRCd 0.10.1 (2006-12-17) - Allow PASS syntax defined in RFC 1459 for server links, too. @@ -229,4 +237,4 @@ ngIRCd 0.0.1, 31.12.2001 -- -$Id: NEWS,v 1.75.2.4 2006/12/17 13:55:29 alex Exp $ +$Id: NEWS,v 1.75.2.7 2007/06/08 09:05:23 alex Exp $ Index: README =================================================================== RCS file: /srv/cvs/ngircd/ngircd/README,v retrieving revision 1.21.2.1 retrieving revision 1.21.2.2 diff -u -p -r1.21.2.1 -r1.21.2.2 --- README 2 Aug 2006 08:19:38 -0000 1.21.2.1 +++ README 5 May 2007 20:25:20 -0000 1.21.2.2 @@ -1,7 +1,7 @@ ngIRCd - Next Generation IRC Server - (c)2001-2006 Alexander Barton, + (c)2001-2007 Alexander Barton, alex@barton.de, http://www.barton.de/ ngIRCd is free software and published under the @@ -19,6 +19,8 @@ Licence (URL: http://www.gnu.org/license generation IRC daemon", it's written from scratch and not deduced from the "grandfather of IRC daemons", the daemon of the IRCNet. +Please see the INSTALL document for installation and upgrade information! + II. Status ~~~~~~~~~~~ @@ -84,4 +86,4 @@ mail to . -- -$Id: README,v 1.21.2.1 2006/08/02 08:19:38 alex Exp $ +$Id: README,v 1.21.2.2 2007/05/05 20:25:20 alex Exp $ Index: config.guess =================================================================== RCS file: /srv/cvs/ngircd/ngircd/config.guess,v retrieving revision 1.9 retrieving revision 1.9.2.1 diff -u -p -r1.9 -r1.9.2.1 --- config.guess 23 Jul 2006 12:03:14 -0000 1.9 +++ config.guess 26 May 2007 10:44:51 -0000 1.9.2.1 @@ -1,9 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. -timestamp='2006-02-23' +timestamp='2007-03-06' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -160,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$ arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched @@ -210,7 +212,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) - echo powerppc-unknown-mirbsd${UNAME_RELEASE} + echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} @@ -770,6 +772,8 @@ EOF case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac @@ -777,10 +781,7 @@ EOF i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:MSYS_NT-*:*:*) + *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) @@ -790,12 +791,15 @@ EOF i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; - x86:Interix*:[345]*) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - EM64T:Interix*:[345]*) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; @@ -831,6 +835,9 @@ EOF arm*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; @@ -947,6 +954,9 @@ EOF x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; + xtensa:Linux:*:*) + echo xtensa-unknown-linux-gnu + exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent @@ -989,7 +999,7 @@ EOF LIBC=gnulibc1 # endif #else - #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun) + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout @@ -1205,6 +1215,15 @@ EOF SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; Index: config.sub =================================================================== RCS file: /srv/cvs/ngircd/ngircd/config.sub,v retrieving revision 1.9 retrieving revision 1.9.2.1 diff -u -p -r1.9 -r1.9.2.1 --- config.sub 23 Jul 2006 12:03:14 -0000 1.9 +++ config.sub 26 May 2007 10:44:51 -0000 1.9.2.1 @@ -1,9 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, +# Inc. -timestamp='2006-02-23' +timestamp='2007-01-18' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -240,15 +241,16 @@ case $basic_machine in | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ + | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ - | m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ @@ -274,21 +276,19 @@ case $basic_machine in | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b \ - | strongarm \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ - | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; - m32c) - basic_machine=$basic_machine-unknown - ;; m6811 | m68hc11 | m6812 | m68hc12) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown @@ -318,18 +318,18 @@ case $basic_machine in | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ + | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ - | m32r-* | m32rle-* \ + | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ @@ -358,23 +358,21 @@ case $basic_machine in | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa-* \ | ymp-* \ | z8k-*) ;; - m32c-*) - ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) @@ -912,6 +910,10 @@ case $basic_machine in sb1el) basic_machine=mipsisa64sb1el-unknown ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; sei) basic_machine=mips-sei os=-seiux @@ -923,6 +925,9 @@ case $basic_machine in basic_machine=sh-hitachi os=-hms ;; + sh5el) + basic_machine=sh5le-unknown + ;; sh64) basic_machine=sh64-unknown ;; @@ -1128,7 +1133,7 @@ case $basic_machine in sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; - sparc | sparcv8 | sparcv9 | sparcv9b) + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) @@ -1217,7 +1222,7 @@ case $os in | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1369,6 +1374,12 @@ else # system, and we'll never get to this point. case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; *-acorn) os=-riscix1.2 ;; @@ -1378,9 +1389,9 @@ case $basic_machine in arm*-semi) os=-aout ;; - c4x-* | tic4x-*) - os=-coff - ;; + c4x-* | tic4x-*) + os=-coff + ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 @@ -1406,6 +1417,9 @@ case $basic_machine in m68*-cisco) os=-aout ;; + mep-*) + os=-elf + ;; mips*-cisco) os=-elf ;; Index: configure.in =================================================================== RCS file: /srv/cvs/ngircd/ngircd/configure.in,v retrieving revision 1.118.2.8 retrieving revision 1.118.2.12 diff -u -p -r1.118.2.8 -r1.118.2.12 --- configure.in 17 Dec 2006 14:06:19 -0000 1.118.2.8 +++ configure.in 8 Jun 2007 09:05:23 -0000 1.118.2.12 @@ -1,6 +1,6 @@ # # ngIRCd -- The Next Generation IRC Daemon -# Copyright (c)2001-2006 Alexander Barton +# Copyright (c)2001-2007 Alexander Barton # # 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.12 2007/06/08 09:05:23 alex Exp $ # # -- Initialisation -- AC_PREREQ(2.50) -AC_INIT(ngircd, 0.10.1) +AC_INIT(ngircd, 0.10.2) 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: contrib/ngircd.spec =================================================================== RCS file: /srv/cvs/ngircd/ngircd/contrib/ngircd.spec,v retrieving revision 1.4.6.4 retrieving revision 1.4.6.5 diff -u -p -r1.4.6.4 -r1.4.6.5 --- contrib/ngircd.spec 17 Dec 2006 14:06:20 -0000 1.4.6.4 +++ contrib/ngircd.spec 8 Jun 2007 09:05:23 -0000 1.4.6.5 @@ -1,5 +1,5 @@ %define name ngircd -%define version 0.10.1 +%define version 0.10.2 %define release 1 %define prefix %{_prefix} Index: contrib/Debian/changelog =================================================================== RCS file: /srv/cvs/ngircd/ngircd/contrib/Debian/changelog,v retrieving revision 1.12.2.7 retrieving revision 1.12.2.8 diff -u -p -r1.12.2.7 -r1.12.2.8 --- contrib/Debian/changelog 17 Dec 2006 14:06:21 -0000 1.12.2.7 +++ contrib/Debian/changelog 8 Jun 2007 09:05:24 -0000 1.12.2.8 @@ -1,3 +1,9 @@ +ngircd (0.10.2-0ab1) unstable; urgency=low + + * New "upstream" release: 0.10.2 + + -- Alexander Barton Fri, 8 Jun 2007 10:49:36 +0200 + ngircd (0.10.1-0ab1) unstable; urgency=low * New "upstream" release: 0.10.1 Index: contrib/Debian/ngircd.init =================================================================== RCS file: /srv/cvs/ngircd/ngircd/contrib/Debian/ngircd.init,v retrieving revision 1.6 retrieving revision 1.6.2.1 diff -u -p -r1.6 -r1.6.2.1 --- contrib/Debian/ngircd.init 26 Jul 2005 19:37:18 -0000 1.6 +++ contrib/Debian/ngircd.init 3 Apr 2007 22:08:50 -0000 1.6.2.1 @@ -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: doc/Platforms.txt =================================================================== RCS file: /srv/cvs/ngircd/ngircd/doc/Platforms.txt,v retrieving revision 1.14.2.1 retrieving revision 1.14.2.2 diff -u -p -r1.14.2.1 -r1.14.2.2 --- doc/Platforms.txt 9 Sep 2006 18:10:56 -0000 1.14.2.1 +++ doc/Platforms.txt 3 Apr 2007 22:08:51 -0000 1.14.2.2 @@ -51,6 +51,7 @@ powerpc/apple/darwin7.4.0 gcc 3.3 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: doc/sample-ngircd.conf =================================================================== RCS file: /srv/cvs/ngircd/ngircd/doc/sample-ngircd.conf,v retrieving revision 1.37.2.1 retrieving revision 1.37.2.2 diff -u -p -r1.37.2.1 -r1.37.2.2 --- doc/sample-ngircd.conf 2 Dec 2006 13:10:43 -0000 1.37.2.1 +++ doc/sample-ngircd.conf 3 Apr 2007 22:08:51 -0000 1.37.2.2 @@ -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 ... Index: doc/src/Makefile.am =================================================================== RCS file: /srv/cvs/ngircd/ngircd/doc/src/Makefile.am,v retrieving revision 1.2 retrieving revision 1.2.2.1 diff -u -p -r1.2 -r1.2.2.1 --- doc/src/Makefile.am 8 Apr 2006 16:35:03 -0000 1.2 +++ doc/src/Makefile.am 3 Apr 2007 22:08:52 -0000 1.2.2.1 @@ -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: src/ngircd/array.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/array.c,v retrieving revision 1.11.2.1 retrieving revision 1.11.2.3 diff -u -p -r1.11.2.1 -r1.11.2.3 --- src/ngircd/array.c 2 Dec 2006 13:00:25 -0000 1.11.2.1 +++ src/ngircd/array.c 3 Apr 2007 22:08:52 -0000 1.11.2.3 @@ -12,7 +12,7 @@ #include "array.h" -static char UNUSED id[] = "$Id: array.c,v 1.11.2.1 2006/12/02 13:00:25 fw Exp $"; +static char UNUSED id[] = "$Id: array.c,v 1.11.2.3 2007/04/03 22:08:52 fw Exp $"; #include @@ -247,19 +247,21 @@ void * array_get(array * a, size_t membersize, size_t pos) { size_t totalsize; + size_t posplus1 = pos + 1; assert(membersize > 0); assert(a != NULL); - if (array_UNUSABLE(a)) + if (!posplus1 || array_UNUSABLE(a)) return NULL; - if (!safemult_sizet(pos, membersize, &totalsize)) + if (!safemult_sizet(posplus1, membersize, &totalsize)) return NULL; if (a->allocated < totalsize) return NULL; + totalsize = pos * membersize; return a->mem + totalsize; } @@ -268,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: src/ngircd/channel.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/channel.c,v retrieving revision 1.56.2.1 retrieving revision 1.56.2.3 diff -u -p -r1.56.2.1 -r1.56.2.3 --- src/ngircd/channel.c 2 Dec 2006 13:08:02 -0000 1.56.2.1 +++ src/ngircd/channel.c 3 Apr 2007 22:08:52 -0000 1.56.2.3 @@ -17,7 +17,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: channel.c,v 1.56.2.1 2006/12/02 13:08:02 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 @@ -70,6 +70,22 @@ Channel_Init( void ) } /* Channel_Init */ +GLOBAL struct list_head * +Channel_GetListBans(CHANNEL *c) +{ + assert(c != NULL); + return &c->list_bans; +} + + +GLOBAL struct list_head * +Channel_GetListInvites(CHANNEL *c) +{ + assert(c != NULL); + return &c->list_invites; +} + + GLOBAL void Channel_InitPredefined( void ) { @@ -115,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 ); } @@ -129,7 +148,7 @@ Channel_Exit( void ) { CHANNEL *c, *c_next; CL2CHAN *cl2chan, *cl2chan_next; - + /* Channel-Strukturen freigeben */ c = My_Channels; while( c ) @@ -320,24 +339,6 @@ Channel_CountForUser( CLIENT *Client ) } /* Channel_CountForUser */ -GLOBAL int -Channel_PCount( void ) -{ - /* Count the number of persistent (mode 'P') channels */ - - CHANNEL *chan; - int count = 0; - - chan = My_Channels; - while( chan ) - { - if( strchr( chan->modes, 'P' )) count++; - chan = chan->next; - } - - return count; -} /* Channel_PCount */ - GLOBAL const char * Channel_Name( const CHANNEL *Chan ) @@ -601,9 +602,7 @@ Channel_IsMemberOf( CHANNEL *Chan, CLIEN assert( Chan != NULL ); assert( Client != NULL ); - - if( Get_Cl2Chan( Chan, Client )) return true; - else return false; + return Get_Cl2Chan(Chan, Client); } /* Channel_IsMemberOf */ @@ -716,7 +715,7 @@ Channel_Write( CHANNEL *Chan, CLIENT *Fr if( strchr( Channel_Modes( Chan ), 'm' ) && ( ! is_op ) && ( ! has_voice )) ok = false; /* Is the client banned? */ - if( Lists_CheckBanned( From, Chan )) + if( Lists_Check(&Chan->list_bans, From)) { /* Client is banned, but is he channel operator or has voice? */ if(( ! has_voice ) && ( ! is_op )) ok = false; @@ -881,6 +880,68 @@ Remove_Client( int Type, CHANNEL *Chan, } /* Remove_Client */ +GLOBAL bool +Channel_AddBan(CHANNEL *c, const char *mask ) +{ + struct list_head *h = Channel_GetListBans(c); + return Lists_Add(h, mask, false); +} + + +GLOBAL bool +Channel_AddInvite(CHANNEL *c, const char *mask, bool onlyonce) +{ + struct list_head *h = Channel_GetListInvites(c); + return Lists_Add(h, mask, onlyonce); +} + + +static bool +ShowInvitesBans(struct list_head *head, CLIENT *Client, CHANNEL *Channel, bool invite) +{ + struct list_elem *e; + char *msg = invite ? RPL_INVITELIST_MSG : RPL_BANLIST_MSG; + char *msg_end; + + assert( Client != NULL ); + assert( Channel != NULL ); + + e = Lists_GetFirst(head); + while (e) { + if( ! IRC_WriteStrClient( Client, msg, Client_ID( Client ), + Channel_Name( Channel ), Lists_GetMask(e) )) return DISCONNECTED; + e = Lists_GetNext(e); + } + + msg_end = invite ? RPL_ENDOFINVITELIST_MSG : RPL_ENDOFBANLIST_MSG; + return IRC_WriteStrClient( Client, msg_end, Client_ID( Client ), Channel_Name( Channel )); +} + + +GLOBAL bool +Channel_ShowBans( CLIENT *Client, CHANNEL *Channel ) +{ + struct list_head *h; + + assert( Channel != NULL ); + + h = Channel_GetListBans(Channel); + return ShowInvitesBans(h, Client, Channel, false); +} + + +GLOBAL bool +Channel_ShowInvites( CLIENT *Client, CHANNEL *Channel ) +{ + struct list_head *h; + + assert( Channel != NULL ); + + h = Channel_GetListInvites(Channel); + return ShowInvitesBans(h, Client, Channel, true); +} + + static CL2CHAN * Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan ) { @@ -910,7 +971,7 @@ static bool Delete_Channel( CHANNEL *Chan ) { /* Channel-Struktur loeschen */ - + CHANNEL *chan, *last_chan; last_chan = NULL; @@ -926,13 +987,14 @@ Delete_Channel( CHANNEL *Chan ) Log( LOG_DEBUG, "Freed channel structure for \"%s\".", Chan->name ); /* Invite- und Ban-Lists aufraeumen */ - Lists_DeleteChannel( chan ); + Lists_Free( &chan->list_bans ); + Lists_Free( &chan->list_invites ); /* Neu verketten und freigeben */ if( last_chan ) last_chan->next = chan->next; else My_Channels = chan->next; free( chan ); - + return true; } /* Delete_Channel */ Index: src/ngircd/channel.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/channel.h,v retrieving revision 1.29.2.1 retrieving revision 1.29.2.2 diff -u -p -r1.29.2.1 -r1.29.2.2 --- src/ngircd/channel.h 2 Dec 2006 13:08:02 -0000 1.29.2.1 +++ src/ngircd/channel.h 3 Apr 2007 20:23:31 -0000 1.29.2.2 @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: channel.h,v 1.29.2.1 2006/12/02 13:08:02 fw Exp $ + * $Id: channel.h,v 1.29.2.2 2007/04/03 20:23:31 fw Exp $ * * Channel management (header) */ @@ -20,6 +20,7 @@ #if defined(__channel_c__) | defined(S_SPLINT_S) +#include "lists.h" #include "defines.h" #include "array.h" @@ -36,6 +37,8 @@ typedef struct _CHANNEL #endif char key[CLIENT_PASS_LEN]; /* Channel key ("password", mode "k" ) */ unsigned long maxusers; /* Maximum number of members (mode "l") */ + struct list_head list_bans; /* list head of banned users */ + struct list_head list_invites; /* list head of invited users */ } CHANNEL; typedef struct _CLIENT2CHAN @@ -53,6 +56,8 @@ typedef POINTER CL2CHAN; #endif +GLOBAL struct list_head *Channel_GetListBans PARAMS((CHANNEL *c)); +GLOBAL struct list_head *Channel_GetListInvites PARAMS((CHANNEL *c)); GLOBAL void Channel_Init PARAMS(( void )); GLOBAL void Channel_InitPredefined PARAMS(( void )); @@ -68,7 +73,6 @@ GLOBAL void Channel_Kick PARAMS(( CLIEN GLOBAL unsigned long Channel_Count PARAMS(( void )); GLOBAL unsigned long Channel_MemberCount PARAMS(( CHANNEL *Chan )); GLOBAL int Channel_CountForUser PARAMS(( CLIENT *Client )); -GLOBAL int Channel_PCount PARAMS(( void )); GLOBAL const char *Channel_Name PARAMS(( const CHANNEL *Chan )); GLOBAL char *Channel_Modes PARAMS(( CHANNEL *Chan )); @@ -114,8 +118,10 @@ GLOBAL unsigned int Channel_TopicTime PA GLOBAL char *Channel_TopicWho PARAMS(( CHANNEL *Chan )); #endif +GLOBAL bool Channel_AddInvite PARAMS((CHANNEL *c, const char *Mask, bool OnlyOnce )); +GLOBAL bool Channel_AddBan PARAMS((CHANNEL *c, const char *Mask )); +GLOBAL bool Channel_ShowBans PARAMS((CLIENT *client, CHANNEL *c)); +GLOBAL bool Channel_ShowInvites PARAMS((CLIENT *client, CHANNEL *c)); #endif - - /* -eof- */ Index: src/ngircd/client.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/client.c,v retrieving revision 1.91.2.1 retrieving revision 1.91.2.2 diff -u -p -r1.91.2.1 -r1.91.2.2 --- src/ngircd/client.c 2 Dec 2006 14:00:00 -0000 1.91.2.1 +++ src/ngircd/client.c 3 Apr 2007 22:08:52 -0000 1.91.2.2 @@ -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 @@ -68,10 +68,6 @@ static CLIENT *Init_New_Client PARAMS((C 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; @@ -337,42 +333,13 @@ Client_Destroy( CLIENT *Client, char *Lo 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: src/ngircd/client.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/client.h,v retrieving revision 1.42.2.2 retrieving revision 1.42.2.3 diff -u -p -r1.42.2.2 -r1.42.2.3 --- src/ngircd/client.h 2 Dec 2006 14:26:53 -0000 1.42.2.2 +++ src/ngircd/client.h 3 Apr 2007 22:08:52 -0000 1.42.2.3 @@ -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 PA 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: src/ngircd/conf.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/conf.c,v retrieving revision 1.92.2.3 retrieving revision 1.92.2.4 diff -u -p -r1.92.2.3 -r1.92.2.4 --- src/ngircd/conf.c 2 Dec 2006 13:10:43 -0000 1.92.2.3 +++ src/ngircd/conf.c 3 Apr 2007 22:08:52 -0000 1.92.2.4 @@ -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 @@ -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, cha 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: src/ngircd/conf.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/conf.h,v retrieving revision 1.40.2.1 retrieving revision 1.40.2.2 diff -u -p -r1.40.2.1 -r1.40.2.2 --- src/ngircd/conf.h 2 Dec 2006 13:10:43 -0000 1.40.2.1 +++ src/ngircd/conf.h 3 Apr 2007 22:08:52 -0000 1.40.2.2 @@ -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: src/ngircd/conn-func.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/conn-func.h,v retrieving revision 1.5 retrieving revision 1.5.2.1 diff -u -p -r1.5 -r1.5.2.1 --- src/ngircd/conn-func.h 10 May 2006 21:24:01 -0000 1.5 +++ src/ngircd/conn-func.h 3 Apr 2007 22:08:52 -0000 1.5.2.1 @@ -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 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: src/ngircd/conn-zip.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/conn-zip.c,v retrieving revision 1.11 retrieving revision 1.11.2.1 diff -u -p -r1.11 -r1.11.2.1 --- src/ngircd/conn-zip.c 23 Jul 2006 15:19:20 -0000 1.11 +++ src/ngircd/conn-zip.c 18 May 2007 22:11:19 -0000 1.11.2.1 @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2006 Alexander Barton (alex@barton.de) + * Copyright (c)2001-2007 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 @@ -22,7 +22,7 @@ /* enable more zlib related debug messages: */ /* #define DEBUG_ZLIB */ -static char UNUSED id[] = "$Id: conn-zip.c,v 1.11 2006/07/23 15:19:20 alex Exp $"; +static char UNUSED id[] = "$Id: conn-zip.c,v 1.11.2.1 2007/05/18 22:11:19 alex Exp $"; #include "imp.h" #include @@ -82,47 +82,63 @@ Zip_InitConn( CONN_ID Idx ) } /* Zip_InitConn */ +/** + * Copy data to the compression buffer of a connection. We do collect + * some data there until it's full so that we can achieve better + * compression ratios. + * If the (pre-)compression buffer is full, we try to flush it ("actually + * compress some data") and to add the new (uncompressed) data afterwards. + * @param Idx Connection handle. + * @param Data Pointer to the data. + * @param Len Length of the data to add. + * @return true on success, false otherwise. */ GLOBAL bool Zip_Buffer( CONN_ID Idx, char *Data, size_t Len ) { - /* Daten zum Komprimieren im "Kompressions-Puffer" sammeln. - * Es wird true bei Erfolg, sonst false geliefert. */ + size_t buflen; assert( Idx > NONE ); assert( Data != NULL ); assert( Len > 0 ); - assert( Len <= ZWRITEBUFFER_LEN ); - if (Len > ZWRITEBUFFER_LEN) - return false; - - if ( array_bytes( &My_Connections[Idx].zip.wbuf ) >= ZWRITEBUFFER_LEN ) { + buflen = array_bytes(&My_Connections[Idx].zip.wbuf); + if (buflen + Len >= WRITEBUFFER_SLINK_LEN) { /* compression buffer is full, flush */ if( ! Zip_Flush( Idx )) return false; } + /* check again; if zip buf is still too large do not append data: + * otherwise the zip wbuf would grow too large */ + buflen = array_bytes(&My_Connections[Idx].zip.wbuf); + if (buflen + Len >= WRITEBUFFER_SLINK_LEN) + return false; + return array_catb(&My_Connections[Idx].zip.wbuf, Data, Len); } /* Zip_Buffer */ +/** + * Compress data in ZIP buffer and move result to the write buffer of + * the connection. + * @param Idx Connection handle. + * @retrun true on success, false otherwise. + */ GLOBAL bool Zip_Flush( CONN_ID Idx ) { - /* Daten komprimieren und in Schreibpuffer kopieren. - * Es wird true bei Erfolg, sonst false geliefert. */ - int result; - unsigned char zipbuf[WRITEBUFFER_LEN]; + unsigned char zipbuf[WRITEBUFFER_SLINK_LEN]; int zipbuf_used = 0; z_stream *out; out = &My_Connections[Idx].zip.out; - out->next_in = array_start(&My_Connections[Idx].zip.wbuf); - if (!out->next_in) - return false; - out->avail_in = (uInt)array_bytes(&My_Connections[Idx].zip.wbuf); + if (!out->avail_in) + return true; /* nothing to do. */ + + out->next_in = array_start(&My_Connections[Idx].zip.wbuf); + assert(out->next_in != NULL); out->next_out = zipbuf; out->avail_out = (uInt)sizeof zipbuf; @@ -139,14 +155,26 @@ Zip_Flush( CONN_ID Idx ) return false; } - assert(out->avail_out <= WRITEBUFFER_LEN); - zipbuf_used = WRITEBUFFER_LEN - out->avail_out; + if (out->avail_out <= 0) { + /* Not all data was compressed, because data became + * bigger while compressing it. */ + Log (LOG_ALERT, "Compression error: buffer overvlow!?"); + Conn_Close(Idx, "Compression error!", NULL, false); + return false; + } + + assert(out->avail_out <= WRITEBUFFER_SLINK_LEN); + + zipbuf_used = WRITEBUFFER_SLINK_LEN - out->avail_out; #ifdef DEBUG_ZIP Log(LOG_DEBUG, "zipbuf_used: %d", zipbuf_used); #endif if (!array_catb(&My_Connections[Idx].wbuf, - (char *)zipbuf, (size_t) zipbuf_used)) + (char *)zipbuf, (size_t) zipbuf_used)) { + Log (LOG_ALERT, "Compression error: can't copy data!?"); + Conn_Close(Idx, "Compression error!", NULL, false); return false; + } My_Connections[Idx].bytes_out += zipbuf_used; My_Connections[Idx].zip.bytes_out += array_bytes(&My_Connections[Idx].zip.wbuf); @@ -178,10 +206,9 @@ Unzip_Buffer( CONN_ID Idx ) return true; in = &My_Connections[Idx].zip.in; - + in->next_in = array_start(&My_Connections[Idx].zip.rbuf); - if (!in->next_in) - return false; + assert(in->next_in != NULL); in->avail_in = z_rdatalen; in->next_out = unzipbuf; Index: src/ngircd/conn.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/conn.c,v retrieving revision 1.198 retrieving revision 1.198.2.6 diff -u -p -r1.198 -r1.198.2.6 --- src/ngircd/conn.c 23 Jul 2006 23:05:20 -0000 1.198 +++ src/ngircd/conn.c 18 May 2007 22:11:19 -0000 1.198.2.6 @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2005 Alexander Barton + * Copyright (c)2001-2007 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 @@ -17,7 +17,7 @@ #include "portab.h" #include "io.h" -static char UNUSED id[] = "$Id: conn.c,v 1.198 2006/07/23 23:05:20 alex Exp $"; +static char UNUSED id[] = "$Id: conn.c,v 1.198.2.6 2007/05/18 22:11:19 alex Exp $"; #include "imp.h" #include @@ -83,6 +83,7 @@ static char UNUSED id[] = "$Id: conn.c,v static bool Handle_Write PARAMS(( CONN_ID Idx )); +static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len )); static int New_Connection PARAMS(( int Sock )); static CONN_ID Socket2Index PARAMS(( int Sock )); static void Read_Request PARAMS(( CONN_ID Idx )); @@ -123,7 +124,6 @@ cb_connserver(int sock, UNUSED short wha { 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 +150,7 @@ cb_connserver(int sock, UNUSED short wha 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 +377,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; } @@ -615,51 +608,74 @@ va_dcl } /* Conn_WriteStr */ -GLOBAL bool +/** + * Append Data to the outbound write buffer of a connection. + * @param Idx Index of the connection. + * @param Data pointer to the data. + * @param Len length of Data. + * @return true on success, false otherwise. + */ +static bool Conn_Write( CONN_ID Idx, char *Data, size_t Len ) { - /* Daten in Socket schreiben. Bei "fatalen" Fehlern wird - * der Client disconnectiert und false geliefert. */ - + CLIENT *c; + size_t writebuf_limit = WRITEBUFFER_LEN; assert( Idx > NONE ); assert( Data != NULL ); assert( Len > 0 ); - /* Ist der entsprechende Socket ueberhaupt noch offen? In einem - * "Handler-Durchlauf" kann es passieren, dass dem nicht mehr so - * ist, wenn einer von mehreren Conn_Write()'s fehlgeschlagen ist. - * In diesem Fall wird hier einfach ein Fehler geliefert. */ + c = Conn_GetClient(Idx); + assert( c != NULL); + + /* Servers do get special write buffer limits, so they can generate + * all the messages that are required while peering. */ + if (Client_Type(c) == CLIENT_SERVER) + writebuf_limit = WRITEBUFFER_SLINK_LEN; + + /* Is the socket still open? A previous call to Conn_Write() + * may have closed the connection due to a fatal error. + * In this case it is sufficient to return an error, as well. */ if( My_Connections[Idx].sock <= NONE ) { - LogDebug("Skipped write on closed socket (connection %d).", Idx ); + LogDebug("Skipped write on closed socket (connection %d).", Idx); return false; } - /* Pruefen, ob im Schreibpuffer genuegend Platz ist. Ziel ist es, - * moeglichts viel im Puffer zu haben und _nicht_ gleich alles auf den - * Socket zu schreiben (u.a. wg. Komprimierung). */ - if( array_bytes(&My_Connections[Idx].wbuf) >= WRITEBUFFER_LEN) { - /* Der Puffer ist dummerweise voll. Jetzt versuchen, den Puffer - * zu schreiben, wenn das nicht klappt, haben wir ein Problem ... */ - if( ! Handle_Write( Idx )) return false; - - /* check again: if our writebuf is twice als large as the initial limit: Kill connection */ - if( array_bytes(&My_Connections[Idx].wbuf) >= (WRITEBUFFER_LEN*2)) { - Log( LOG_NOTICE, "Write buffer overflow (connection %d)!", Idx ); - Conn_Close( Idx, "Write buffer overflow!", NULL, false ); - return false; - } - } - #ifdef ZLIB if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) { - /* Daten komprimieren und in Puffer kopieren */ - if( ! Zip_Buffer( Idx, Data, Len )) return false; + /* Compressed link: + * Zip_Buffer() does all the dirty work for us: it flushes + * the (pre-)compression buffers if required and handles + * all error conditions. */ + if (!Zip_Buffer(Idx, Data, Len)) + return false; } else #endif { - /* Daten in Puffer kopieren */ - if (!array_catb( &My_Connections[Idx].wbuf, Data, Len )) + /* Uncompressed link: + * Check if outbound buffer has enough space for the data. */ + if (array_bytes(&My_Connections[Idx].wbuf) + Len >= + writebuf_limit) { + /* Buffer is full, flush it. Handle_Write deals with + * low-level errors, if any. */ + if (!Handle_Write(Idx)) + return false; + } + + /* When the write buffer is still too big after flushing it, + * the connection will be killed. */ + if (array_bytes(&My_Connections[Idx].wbuf) + Len >= + writebuf_limit) { + Log(LOG_NOTICE, + "Write buffer overflow (connection %d, size %lu byte)!", + Idx, + (unsigned long)array_bytes(&My_Connections[Idx].wbuf)); + Conn_Close(Idx, "Write buffer overflow!", NULL, false); + return false; + } + + /* Copy data to write buffer */ + if (!array_catb(&My_Connections[Idx].wbuf, Data, Len)) return false; My_Connections[Idx].bytes_out += Len; @@ -700,7 +716,7 @@ Conn_Close( CONN_ID Idx, char *LogMsg, c /* Mark link as "closing" */ Conn_OPTION_ADD( &My_Connections[Idx], CONN_ISCLOSING ); - + if (LogMsg) txt = LogMsg; else @@ -728,7 +744,6 @@ Conn_Close( CONN_ID Idx, char *LogMsg, c (double)My_Connections[Idx].bytes_out / 1024); } #endif - /* Send ERROR to client (see RFC!) */ if (FwdMsg) Conn_WriteStr(Idx, "ERROR :%s", FwdMsg); @@ -872,24 +887,23 @@ Handle_Write( CONN_ID Idx ) wdatalen = array_bytes(&My_Connections[Idx].wbuf ); #ifdef ZLIB - if (wdatalen == 0 && !array_bytes(&My_Connections[Idx].zip.wbuf)) { - io_event_del(My_Connections[Idx].sock, IO_WANTWRITE ); - return true; + if (wdatalen == 0) { + /* Write buffer is empty, so we try to flush the compression + * buffer and get some data to work with from there :-) */ + if (!Zip_Flush(Idx)) + return false; + + /* Now the write buffer most probably has changed: */ + wdatalen = array_bytes(&My_Connections[Idx].wbuf); } +#endif - /* write buffer empty, but not compression buffer? - * -> flush compression buffer! */ - if (wdatalen == 0) - Zip_Flush(Idx); -#else if (wdatalen == 0) { + /* Still no data, fine. */ io_event_del(My_Connections[Idx].sock, IO_WANTWRITE ); return true; } -#endif - /* Zip_Flush() may have changed the write buffer ... */ - wdatalen = array_bytes(&My_Connections[Idx].wbuf); LogDebug ("Handle_Write() called for connection %d, %ld bytes pending ...", Idx, wdatalen); @@ -995,11 +1009,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 +1030,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 ); @@ -1050,47 +1065,52 @@ Socket2Index( int Sock ) } /* Socket2Index */ +/** + * Read data from the network to the read buffer. If an error occures, + * the socket of this connection will be shut down. + */ static void Read_Request( CONN_ID Idx ) { - /* Daten von Socket einlesen und entsprechend behandeln. - * Tritt ein Fehler auf, so wird der Socket geschlossen. */ - ssize_t len; - char readbuf[1024]; + char readbuf[READBUFFER_LEN]; CLIENT *c; - assert( Idx > NONE ); assert( My_Connections[Idx].sock > NONE ); #ifdef ZLIB - if (( array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN ) || - ( array_bytes(&My_Connections[Idx].zip.rbuf) >= ZREADBUFFER_LEN )) + if ((array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN) || + (array_bytes(&My_Connections[Idx].zip.rbuf) >= READBUFFER_LEN)) #else - if ( array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN ) + if (array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN) #endif { - /* Der Lesepuffer ist voll */ - Log( LOG_ERR, "Receive buffer overflow (connection %d): %d bytes!", Idx, - array_bytes(&My_Connections[Idx].rbuf)); + /* Read buffer is full */ + Log(LOG_ERR, + "Receive buffer overflow (connection %d): %d bytes!", + Idx, array_bytes(&My_Connections[Idx].rbuf)); Conn_Close( Idx, "Receive buffer overflow!", NULL, false ); return; } - len = read( My_Connections[Idx].sock, readbuf, sizeof readbuf -1 ); - if( len == 0 ) { - Log( LOG_INFO, "%s:%d (%s) is closing the connection ...", - My_Connections[Idx].host, ntohs( My_Connections[Idx].addr.sin_port), - inet_ntoa( My_Connections[Idx].addr.sin_addr )); - Conn_Close( Idx, "Socket closed!", "Client closed connection", false ); + len = read(My_Connections[Idx].sock, readbuf, sizeof(readbuf)); + if (len == 0) { + Log(LOG_INFO, "%s:%d (%s) is closing the connection ...", + My_Connections[Idx].host, + ntohs(My_Connections[Idx].addr.sin_port), + inet_ntoa( My_Connections[Idx].addr.sin_addr)); + Conn_Close(Idx, + "Socket closed!", "Client closed connection", + false); return; } - if( len < 0 ) { + if (len < 0) { if( errno == EAGAIN ) return; - Log( LOG_ERR, "Read error on connection %d (socket %d): %s!", Idx, - My_Connections[Idx].sock, strerror( errno )); - Conn_Close( Idx, "Read error!", "Client closed connection", false ); + Log(LOG_ERR, "Read error on connection %d (socket %d): %s!", + Idx, My_Connections[Idx].sock, strerror(errno)); + Conn_Close(Idx, "Read error!", "Client closed connection", + false); return; } #ifdef ZLIB @@ -1107,8 +1127,7 @@ Read_Request( CONN_ID Idx ) } else #endif { - readbuf[len] = 0; - if (!array_cats( &My_Connections[Idx].rbuf, readbuf )) { + if (!array_catb( &My_Connections[Idx].rbuf, readbuf, len)) { Log( LOG_ERR, "Could not append recieved data to input buffer (connn %d): %d bytes!", Idx, len ); Conn_Close( Idx, "Receive buffer overflow!", NULL, false ); } @@ -1227,11 +1246,6 @@ Handle_Buffer( CONN_ID Idx ) /* The last Command activated Socket-Compression. * Data that was read after that needs to be copied to Unzip-buf * for decompression */ - if( array_bytes(&My_Connections[Idx].rbuf)> ZREADBUFFER_LEN ) { - Log( LOG_ALERT, "Connection %d: No space left in unzip buf (need %u bytes)!", - Idx, array_bytes(&My_Connections[Idx].rbuf )); - return false; - } if (!array_copy( &My_Connections[Idx].zip.rbuf, &My_Connections[Idx].rbuf )) return false; @@ -1639,9 +1653,9 @@ Conn_GetClient( CONN_ID Idx ) assert( Idx >= 0 ); c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx); - + assert(c != NULL); - + return c ? c->client : NULL; } Index: src/ngircd/conn.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/conn.h,v retrieving revision 1.42 retrieving revision 1.42.2.1 diff -u -p -r1.42 -r1.42.2.1 --- src/ngircd/conn.h 10 May 2006 21:24:01 -0000 1.42 +++ src/ngircd/conn.h 9 May 2007 13:21:38 -0000 1.42.2.1 @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: conn.h,v 1.42 2006/05/10 21:24:01 alex Exp $ + * $Id: conn.h,v 1.42.2.1 2007/05/09 13:21:38 fw Exp $ * * Connection management (header) */ @@ -88,7 +88,6 @@ GLOBAL void Conn_ExitListeners PARAMS(( GLOBAL void Conn_Handler PARAMS(( void )); -GLOBAL bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len )); GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, char *Format, ... )); GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, char *LogMsg, char *FwdMsg, bool InformClient )); Index: src/ngircd/defines.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/defines.h,v retrieving revision 1.58 retrieving revision 1.58.2.1 diff -u -p -r1.58 -r1.58.2.1 --- src/ngircd/defines.h 15 Jun 2006 20:28:15 -0000 1.58 +++ src/ngircd/defines.h 18 May 2007 22:11:19 -0000 1.58.2.1 @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2005 Alexander Barton (alex@barton.de) + * Copyright (c)2001-2007 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,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: defines.h,v 1.58 2006/06/15 20:28:15 alex Exp $ + * $Id: defines.h,v 1.58.2.1 2007/05/18 22:11:19 alex Exp $ */ @@ -70,13 +70,8 @@ connection in bytes. */ #define WRITEBUFFER_LEN 4096 /* Size of the write buffer of a connection in bytes. */ - -#ifdef ZLIB -#define ZREADBUFFER_LEN 1024 /* Size of the compressed read buffer - of a connection in bytes. */ -#define ZWRITEBUFFER_LEN 4096 /* Size of the compressed write buffer - of a connection in bytes. */ -#endif +#define WRITEBUFFER_SLINK_LEN 51200 /* Size of the write buffer of a + server link connection in bytes. */ #define PROTOVER "0210" /* Implemented IRC protocol version, see RFC 2813 section 4.1.1. */ Index: src/ngircd/io.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/io.c,v retrieving revision 1.16 retrieving revision 1.16.2.1 diff -u -p -r1.16 -r1.16.2.1 --- src/ngircd/io.c 23 Jul 2006 23:11:44 -0000 1.16 +++ src/ngircd/io.c 3 Apr 2007 22:08:52 -0000 1.16.2.1 @@ -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 #include @@ -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 -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 tim static bool io_event_change_kqueue(int, short, const int action); #endif +#ifdef IO_USE_POLL +#include + +static array pollfds; +static int poll_maxfd; + +static bool io_event_change_poll(int fd, short what); +#endif + +#ifdef IO_USE_DEVPOLL +#include +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 -#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; +#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; - return ret; + library_initialized = true; + } +} #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 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 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 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 wha 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: src/ngircd/io.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/io.h,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -u -p -r1.3 -r1.3.2.1 --- src/ngircd/io.h 14 Jul 2005 09:15:58 -0000 1.3 +++ src/ngircd/io.h 3 Apr 2007 22:08:52 -0000 1.3.2.1 @@ -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: src/ngircd/irc-channel.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/irc-channel.c,v retrieving revision 1.35.2.2 retrieving revision 1.35.2.3 diff -u -p -r1.35.2.2 -r1.35.2.3 --- src/ngircd/irc-channel.c 2 Dec 2006 13:33:52 -0000 1.35.2.2 +++ src/ngircd/irc-channel.c 3 Apr 2007 20:23:31 -0000 1.35.2.3 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-channel.c,v 1.35.2.2 2006/12/02 13:33:52 fw Exp $"; +static char UNUSED id[] = "$Id: irc-channel.c,v 1.35.2.3 2007/04/03 20:23:31 fw Exp $"; #include "imp.h" #include @@ -122,8 +122,8 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req ) chan = Channel_Search( channame ); assert( chan != NULL ); - is_banned = Lists_CheckBanned( target, chan ); - is_invited = Lists_CheckInvited( target, chan ); + is_banned = Lists_Check(Channel_GetListBans(chan), target ); + is_invited = Lists_Check(Channel_GetListInvites(chan), target ); /* Testen, ob Client gebanned ist */ if(( is_banned == true) && ( is_invited == false )) @@ -178,7 +178,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req ) * commands) in this list become deleted when a user * joins a channel this way. */ chan = Channel_Search( channame ); - if( chan != NULL ) (void)Lists_CheckInvited( target, chan ); + if( chan != NULL ) (void)Lists_Check(Channel_GetListInvites(chan), target); } /* Channel joinen (und ggf. anlegen) */ Index: src/ngircd/irc-mode.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/irc-mode.c,v retrieving revision 1.45.2.1 retrieving revision 1.45.2.2 diff -u -p -r1.45.2.1 -r1.45.2.2 --- src/ngircd/irc-mode.c 2 Dec 2006 14:21:26 -0000 1.45.2.1 +++ src/ngircd/irc-mode.c 3 Apr 2007 20:23:31 -0000 1.45.2.2 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-mode.c,v 1.45.2.1 2006/12/02 14:21:26 fw Exp $"; +static char UNUSED id[] = "$Id: irc-mode.c,v 1.45.2.2 2007/04/03 20:23:31 fw Exp $"; #include "imp.h" #include @@ -477,7 +477,7 @@ Channel_Mode( CLIENT *Client, REQUEST *R Req->argv[arg_arg][0] = '\0'; arg_arg++; } - else Lists_ShowInvites( Origin, Channel ); + else Channel_ShowInvites( Origin, Channel ); break; case 'b': /* Ban lists */ @@ -493,7 +493,7 @@ Channel_Mode( CLIENT *Client, REQUEST *R Req->argv[arg_arg][0] = '\0'; arg_arg++; } - else Lists_ShowBans( Origin, Channel ); + else Channel_ShowBans( Origin, Channel ); break; default: @@ -644,11 +644,13 @@ Add_Invite( CLIENT *Prefix, CLIENT *Clie mask = Lists_MakeMask( Pattern ); - already = Lists_IsInviteEntry( mask, Channel ); - - if( ! Lists_AddInvited( mask, Channel, false )) return CONNECTED; - - if(( Client_Type( Prefix ) == CLIENT_SERVER ) && ( already == true)) return CONNECTED; + already = Lists_CheckDupeMask(Channel_GetListInvites(Channel), mask ); + if (!already) { + if( ! Channel_AddInvite(Channel, mask, false )) + return CONNECTED; + } + if ( already && ( Client_Type( Prefix ) == CLIENT_SERVER )) + return CONNECTED; return Send_ListChange( "+I", Prefix, Client, Channel, mask ); } /* Add_Invite */ @@ -666,11 +668,13 @@ Add_Ban( CLIENT *Prefix, CLIENT *Client, mask = Lists_MakeMask( Pattern ); - already = Lists_IsBanEntry( mask, Channel ); - - if( ! Lists_AddBanned( mask, Channel )) return CONNECTED; - - if(( Client_Type( Prefix ) == CLIENT_SERVER ) && ( already == true)) return CONNECTED; + already = Lists_CheckDupeMask(Channel_GetListBans(Channel), mask ); + if (!already) { + if( ! Channel_AddBan(Channel, mask)) + return CONNECTED; + } + if ( already && ( Client_Type( Prefix ) == CLIENT_SERVER )) + return CONNECTED; return Send_ListChange( "+b", Prefix, Client, Channel, mask ); } /* Add_Ban */ @@ -686,7 +690,7 @@ Del_Invite( CLIENT *Prefix, CLIENT *Clie assert( Pattern != NULL ); mask = Lists_MakeMask( Pattern ); - Lists_DelInvited( mask, Channel ); + Lists_Del(Channel_GetListInvites(Channel), mask); return Send_ListChange( "-I", Prefix, Client, Channel, mask ); } /* Del_Invite */ @@ -701,7 +705,7 @@ Del_Ban( CLIENT *Prefix, CLIENT *Client, assert( Pattern != NULL ); mask = Lists_MakeMask( Pattern ); - Lists_DelBanned( mask, Channel ); + Lists_Del(Channel_GetListBans(Channel), mask); return Send_ListChange( "-b", Prefix, Client, Channel, mask ); } /* Del_Ban */ Index: src/ngircd/irc-op.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/irc-op.c,v retrieving revision 1.15.4.1 retrieving revision 1.15.4.2 diff -u -p -r1.15.4.1 -r1.15.4.2 --- src/ngircd/irc-op.c 2 Dec 2006 14:21:26 -0000 1.15.4.1 +++ src/ngircd/irc-op.c 3 Apr 2007 20:23:31 -0000 1.15.4.2 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-op.c,v 1.15.4.1 2006/12/02 14:21:26 fw Exp $"; +static char UNUSED id[] = "$Id: irc-op.c,v 1.15.4.2 2007/04/03 20:23:31 fw Exp $"; #include "imp.h" #include @@ -99,11 +99,12 @@ IRC_INVITE( CLIENT *Client, REQUEST *Req if( Channel_IsMemberOf( chan, target )) return IRC_WriteStrClient( from, ERR_USERONCHANNEL_MSG, Client_ID( from ), Req->argv[0], Req->argv[1] ); /* If the target user is banned on that channel: remember invite */ - if( Lists_CheckBanned( target, chan )) remember = true; + if( Lists_Check(Channel_GetListBans(chan), target )) remember = true; if (remember) { /* We must remember this invite */ - if( ! Lists_AddInvited( Client_Mask( target ), chan, true)) return CONNECTED; + if( ! Channel_AddInvite(chan, Client_Mask( target ), true)) + return CONNECTED; } } Index: src/ngircd/irc-server.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/irc-server.c,v retrieving revision 1.39.2.2 retrieving revision 1.39.2.3 diff -u -p -r1.39.2.2 -r1.39.2.3 --- src/ngircd/irc-server.c 2 Dec 2006 14:26:53 -0000 1.39.2.2 +++ src/ngircd/irc-server.c 3 Apr 2007 20:23:31 -0000 1.39.2.3 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-server.c,v 1.39.2.2 2006/12/02 14:26:53 fw Exp $"; +static char UNUSED id[] = "$Id: irc-server.c,v 1.39.2.3 2007/04/03 20:23:31 fw Exp $"; #include "imp.h" #include @@ -41,6 +41,50 @@ static char UNUSED id[] = "$Id: irc-serv #include "irc-server.h" +#ifdef IRCPLUS +static bool +Synchronize_Lists( CLIENT *Client ) +{ + CHANNEL *c; + struct list_head *head; + struct list_elem *elem; + + assert( Client != NULL ); + + c = Channel_First(); + + while (c) { + head = Channel_GetListBans(c); + + elem = Lists_GetFirst(head); + while (elem) { + if( ! IRC_WriteStrClient( Client, "MODE %s +b %s", + Channel_Name(c), Lists_GetMask(elem))) + { + return false; + } + elem = Lists_GetNext(elem); + } + + head = Channel_GetListInvites(c); + elem = Lists_GetFirst(head); + while (elem) { + if( ! IRC_WriteStrClient( Client, "MODE %s +I %s", + Channel_Name( c ), Lists_GetMask(elem))) + { + return false; + } + elem = Lists_GetNext(elem); + } + c = Channel_Next(c); + } + return true; +} +#endif + + + + /** * Handler for the IRC command "SERVER". * See RFC 2813 section 4.1.2. @@ -268,9 +312,7 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req "Synchronizing INVITE- and BAN-lists ..."); #endif /* Synchronize INVITE- and BAN-lists */ - if (! Lists_SendInvites(Client)) - return DISCONNECTED; - if (! Lists_SendBans(Client)) + if (!Synchronize_Lists(Client)) return DISCONNECTED; } #endif Index: src/ngircd/lists.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/lists.c,v retrieving revision 1.18.2.1 retrieving revision 1.18.2.3 diff -u -p -r1.18.2.1 -r1.18.2.3 --- src/ngircd/lists.c 2 Dec 2006 13:05:38 -0000 1.18.2.1 +++ src/ngircd/lists.c 3 Apr 2007 22:08:52 -0000 1.18.2.3 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: lists.c,v 1.18.2.1 2006/12/02 13:05:38 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 @@ -35,326 +35,131 @@ static char UNUSED id[] = "$Id: lists.c, #include "exp.h" #include "lists.h" - #define MASK_LEN (2*CLIENT_HOST_LEN) - -typedef struct _C2C -{ - struct _C2C *next; +struct list_elem { + struct list_elem *next; char mask[MASK_LEN]; - CHANNEL *channel; bool onlyonce; -} C2C; - - -static C2C *My_Invites, *My_Bans; - - -static C2C *New_C2C PARAMS(( char *Mask, CHANNEL *Chan, bool OnlyOnce )); - -static bool Check_List PARAMS(( C2C **Cl2Chan, CLIENT *Client, CHANNEL *Chan )); -static bool Already_Registered PARAMS(( C2C *Cl2Chan, char *Mask, CHANNEL *Chan )); +}; - -GLOBAL void -Lists_Init( void ) +GLOBAL const char * +Lists_GetMask(const struct list_elem *e) { - /* Modul initialisieren */ + return e->mask; +} - My_Invites = My_Bans = NULL; -} /* Lists_Init */ - -GLOBAL void -Lists_Exit( void ) +GLOBAL struct list_elem* +Lists_GetFirst(const struct list_head *h) { - /* Modul abmelden */ + return h->first; +} - C2C *c2c, *next; - - /* Invite-Lists freigeben */ - c2c = My_Invites; - while( c2c ) - { - next = c2c->next; - free( c2c ); - c2c = next; - } - /* Ban-Lists freigeben */ - c2c = My_Bans; - while( c2c ) - { - next = c2c->next; - free( c2c ); - c2c = next; - } -} /* Lists_Exit */ - - -GLOBAL bool -Lists_CheckInvited( CLIENT *Client, CHANNEL *Chan ) +GLOBAL struct list_elem* +Lists_GetNext(const struct list_elem *e) { - return Check_List( &My_Invites, Client, Chan ); -} /* Lists_CheckInvited */ + return e->next; +} -GLOBAL bool -Lists_IsInviteEntry( char *Mask, CHANNEL *Chan ) +bool +Lists_Add(struct list_head *header, const char *Mask, bool OnlyOnce ) { - assert( Mask != NULL ); - assert( Chan != NULL ); + struct list_elem *e, *newelem; - return Already_Registered( My_Invites, Mask, Chan ); -} /* Lists_IsInviteEntry */ + assert( header != NULL ); + assert( Mask != NULL ); + if (Lists_CheckDupeMask(header, Mask )) return true; -GLOBAL bool -Lists_AddInvited( char *Mask, CHANNEL *Chan, bool OnlyOnce ) -{ - C2C *c2c; + e = Lists_GetFirst(header); - assert( Mask != NULL ); - assert( Chan != NULL ); - - if( Already_Registered( My_Invites, Mask, Chan )) return true; - - c2c = New_C2C( Mask, Chan, OnlyOnce ); - if( ! c2c ) - { - Log( LOG_ERR, "Can't add new invite list entry!" ); + newelem = malloc(sizeof(struct list_elem)); + if( ! newelem ) { + Log( LOG_EMERG, "Can't allocate memory for new Ban/Invite entry!" ); return false; } - /* verketten */ - c2c->next = My_Invites; - My_Invites = c2c; + strlcpy( newelem->mask, Mask, sizeof( newelem->mask )); + newelem->onlyonce = OnlyOnce; + newelem->next = e; + header->first = newelem; - Log( LOG_DEBUG, "Added \"%s\" to invite list for \"%s\".", Mask, Channel_Name( Chan )); + LogDebug("Added \"%s\" to invite list", Mask); return true; -} /* Lists_AddInvited */ +} -GLOBAL void -Lists_DelInvited( char *Mask, CHANNEL *Chan ) +static void +Lists_Unlink(struct list_head *header, struct list_elem *p, struct list_elem *victim) { - C2C *c2c, *last, *next; + assert(victim != NULL); + assert(header != NULL); - assert( Mask != NULL ); - assert( Chan != NULL ); - - last = NULL; - c2c = My_Invites; - while( c2c ) - { - next = c2c->next; - if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 )) - { - /* dieser Eintrag muss geloescht werden */ - Log( LOG_DEBUG, "Deleted \"%s\" from invite list for \"%s\"." , c2c->mask, Channel_Name( Chan )); - if( last ) last->next = next; - else My_Invites = next; - free( c2c ); - } - else last = c2c; - c2c = next; - } -} /* Lists_DelInvited */ - - -GLOBAL bool -Lists_ShowInvites( CLIENT *Client, CHANNEL *Channel ) -{ - C2C *c2c; - - assert( Client != NULL ); - assert( Channel != NULL ); - - c2c = My_Invites; - while( c2c ) - { - if( c2c->channel == Channel ) - { - /* Eintrag fuer Channel gefunden; ausgeben: */ - if( ! IRC_WriteStrClient( Client, RPL_INVITELIST_MSG, Client_ID( Client ), Channel_Name( Channel ), c2c->mask )) return DISCONNECTED; - } - c2c = c2c->next; - } - return IRC_WriteStrClient( Client, RPL_ENDOFINVITELIST_MSG, Client_ID( Client ), Channel_Name( Channel )); -} /* Lists_ShowInvites */ - - -GLOBAL bool -Lists_SendInvites( CLIENT *Client ) -{ - C2C *c2c; - - assert( Client != NULL ); - - c2c = My_Invites; - while( c2c ) - { - if( ! IRC_WriteStrClient( Client, "MODE %s +I %s", Channel_Name( c2c->channel ), c2c->mask )) return DISCONNECTED; - c2c = c2c->next; - } - return CONNECTED; -} /* Lists_SendInvites */ + if (p) p->next = victim->next; + else header->first = victim->next; - -GLOBAL bool -Lists_SendBans( CLIENT *Client ) -{ - C2C *c2c; - - assert( Client != NULL ); - - c2c = My_Bans; - while( c2c ) - { - if( ! IRC_WriteStrClient( Client, "MODE %s +b %s", Channel_Name( c2c->channel ), c2c->mask )) return DISCONNECTED; - c2c = c2c->next; - } - return CONNECTED; -} /* Lists_SendBans */ - - -GLOBAL bool -Lists_CheckBanned( CLIENT *Client, CHANNEL *Chan ) -{ - return Check_List( &My_Bans, Client, Chan ); -} /* Lists_CheckBanned */ - - -GLOBAL bool -Lists_IsBanEntry( char *Mask, CHANNEL *Chan ) -{ - assert( Mask != NULL ); - assert( Chan != NULL ); - - return Already_Registered( My_Bans, Mask, Chan ); -} /* Lists_IsBanEntry */ - - -GLOBAL bool -Lists_AddBanned( char *Mask, CHANNEL *Chan ) -{ - C2C *c2c; - - assert( Mask != NULL ); - assert( Chan != NULL ); - - if( Already_Registered( My_Bans, Mask, Chan )) return true; - - c2c = New_C2C( Mask, Chan, false ); - if( ! c2c ) - { - Log( LOG_ERR, "Can't add new ban list entry!" ); - return false; - } - - /* verketten */ - c2c->next = My_Bans; - My_Bans = c2c; - - Log( LOG_DEBUG, "Added \"%s\" to ban list for \"%s\".", Mask, Channel_Name( Chan )); - return true; -} /* Lists_AddBanned */ + free(victim); +} GLOBAL void -Lists_DelBanned( char *Mask, CHANNEL *Chan ) +Lists_Del(struct list_head *header, const char *Mask) { - C2C *c2c, *last, *next; + struct list_elem *e, *last, *victim; + assert( header != NULL ); assert( Mask != NULL ); - assert( Chan != NULL ); last = NULL; - c2c = My_Bans; - while( c2c ) - { - next = c2c->next; - if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 )) - { - /* dieser Eintrag muss geloescht werden */ - Log( LOG_DEBUG, "Deleted \"%s\" from ban list for \"%s\"." , c2c->mask, Channel_Name( Chan )); - if( last ) last->next = next; - else My_Bans = next; - free( c2c ); + e = Lists_GetFirst(header); + while( e ) { + if(strcasecmp( e->mask, Mask ) == 0 ) { + LogDebug("Deleted \"%s\" from list", e->mask); + victim = e; + e = victim->next; + Lists_Unlink(header, last, victim); + continue; } - else last = c2c; - c2c = next; + last = e; + e = e->next; } -} /* Lists_DelBanned */ +} -GLOBAL bool -Lists_ShowBans( CLIENT *Client, CHANNEL *Channel ) +GLOBAL void +Lists_Free(struct list_head *head) { - C2C *c2c; + struct list_elem *e, *victim; - assert( Client != NULL ); - assert( Channel != NULL ); + assert(head != NULL); - c2c = My_Bans; - while( c2c ) - { - if( c2c->channel == Channel ) - { - /* Eintrag fuer Channel gefunden; ausgeben: */ - if( ! IRC_WriteStrClient( Client, RPL_BANLIST_MSG, Client_ID( Client ), Channel_Name( Channel ), c2c->mask )) return DISCONNECTED; - } - c2c = c2c->next; + e = head->first; + head->first = NULL; + while (e) { + LogDebug("Deleted \"%s\" from invite list" , e->mask); + victim = e; + e = e->next; + free( victim ); } - return IRC_WriteStrClient( Client, RPL_ENDOFBANLIST_MSG, Client_ID( Client ), Channel_Name( Channel )); -} /* Lists_ShowBans */ +} -GLOBAL void -Lists_DeleteChannel( CHANNEL *Chan ) +GLOBAL bool +Lists_CheckDupeMask(const struct list_head *h, const char *Mask ) { - /* Channel wurde geloescht, Invite- und Ban-Lists aufraeumen */ - - C2C *c2c, *last, *next; - - /* Invite-List */ - last = NULL; - c2c = My_Invites; - while( c2c ) - { - next = c2c->next; - if( c2c->channel == Chan ) - { - /* dieser Eintrag muss geloescht werden */ - Log( LOG_DEBUG, "Deleted \"%s\" from invite list for \"%s\"." , c2c->mask, Channel_Name( Chan )); - if( last ) last->next = next; - else My_Invites = next; - free( c2c ); - } - else last = c2c; - c2c = next; - } - - /* Ban-List */ - last = NULL; - c2c = My_Bans; - while( c2c ) - { - next = c2c->next; - if( c2c->channel == Chan ) - { - /* dieser Eintrag muss geloescht werden */ - Log( LOG_DEBUG, "Deleted \"%s\" from ban list for \"%s\"." , c2c->mask, Channel_Name( Chan )); - if( last ) last->next = next; - else My_Bans = next; - free( c2c ); - } - else last = c2c; - c2c = next; + struct list_elem *e; + e = h->first; + while (e) { + if (strcasecmp( e->mask, Mask ) == 0 ) + return true; + e = e->next; } -} /* Lists_DeleteChannel */ + return false; +} GLOBAL char * @@ -407,82 +212,30 @@ Lists_MakeMask( char *Pattern ) } /* Lists_MakeMask */ -static C2C * -New_C2C( char *Mask, CHANNEL *Chan, bool OnlyOnce ) -{ - C2C *c2c; - - assert( Mask != NULL ); - assert( Chan != NULL ); - - /* Speicher fuer Eintrag anfordern */ - c2c = (C2C *)malloc( sizeof( C2C )); - if( ! c2c ) - { - Log( LOG_EMERG, "Can't allocate memory! [New_C2C]" ); - return NULL; - } - - strlcpy( c2c->mask, Mask, sizeof( c2c->mask )); - c2c->channel = Chan; - c2c->onlyonce = OnlyOnce; - - return c2c; -} /* New_C2C */ - -static bool -Check_List( C2C **Cl2Chan, CLIENT *Client, CHANNEL *Chan ) +bool +Lists_Check( struct list_head *header, CLIENT *Client) { - C2C *c2c, *last; + struct list_elem *e, *last; - assert( Cl2Chan != NULL ); - assert( Client != NULL ); - assert( Chan != NULL ); + assert( header != NULL ); - c2c = *Cl2Chan; + e = header->first; last = NULL; - while( c2c ) - { - if( c2c->channel == Chan ) - { - /* Ok, richtiger Channel. Passt die Maske? */ - if( Match( c2c->mask, Client_Mask( Client ))) - { - /* Treffer! */ - if( c2c->onlyonce ) - { - /* Eintrag loeschen */ - Log( LOG_DEBUG, "Deleted \"%s\" from %s list for \"%s\".", c2c->mask, *Cl2Chan == My_Invites ? "invite" : "ban", Channel_Name( Chan )); - if( last ) last->next = c2c->next; - else *Cl2Chan = c2c->next; - free( c2c ); - } - return true; + while( e ) { + if( Match( e->mask, Client_Mask( Client ))) { + if( e->onlyonce ) { /* delete entry */ + LogDebug("Deleted \"%s\" from list", e->mask); + Lists_Unlink(header, last, e); } + return true; } - last = c2c; - c2c = c2c->next; + last = e; + e = e->next; } return false; -} /* Check_List */ - - -static bool -Already_Registered( C2C *List, char *Mask, CHANNEL *Chan ) -{ - C2C *c2c; - - c2c = List; - while( c2c ) - { - if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 )) return true; - c2c = c2c->next; - } - return false; -} /* Already_Registered */ - +} /* -eof- */ Index: src/ngircd/lists.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/lists.h,v retrieving revision 1.12 retrieving revision 1.12.4.1 diff -u -p -r1.12 -r1.12.4.1 --- src/ngircd/lists.h 19 Mar 2005 18:43:49 -0000 1.12 +++ src/ngircd/lists.h 3 Apr 2007 20:23:31 -0000 1.12.4.1 @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: lists.h,v 1.12 2005/03/19 18:43:49 fw Exp $ + * $Id: lists.h,v 1.12.4.1 2007/04/03 20:23:31 fw Exp $ * * Management of IRC lists: ban, invite, ... (header) */ @@ -16,31 +16,31 @@ #ifndef __lists_h__ #define __lists_h__ +#include "portab.h" +#include "client.h" +struct list_elem; -GLOBAL void Lists_Init PARAMS(( void )); -GLOBAL void Lists_Exit PARAMS(( void )); +struct list_head { + struct list_elem *first; +}; -GLOBAL bool Lists_CheckInvited PARAMS(( CLIENT *Client, CHANNEL *Chan )); -GLOBAL bool Lists_AddInvited PARAMS(( char *Mask, CHANNEL *Chan, bool OnlyOnce )); -GLOBAL void Lists_DelInvited PARAMS(( char *Mask, CHANNEL *Chan )); -GLOBAL bool Lists_ShowInvites PARAMS(( CLIENT *Client, CHANNEL *Channel )); -GLOBAL bool Lists_SendInvites PARAMS(( CLIENT *Client )); -GLOBAL bool Lists_IsInviteEntry PARAMS(( char *Mask, CHANNEL *Chan )); - -GLOBAL bool Lists_CheckBanned PARAMS(( CLIENT *Client, CHANNEL *Chan )); -GLOBAL bool Lists_AddBanned PARAMS(( char *Mask, CHANNEL *Chan )); -GLOBAL void Lists_DelBanned PARAMS(( char *Mask, CHANNEL *Chan )); -GLOBAL bool Lists_ShowBans PARAMS(( CLIENT *Client, CHANNEL *Channel )); -GLOBAL bool Lists_SendBans PARAMS(( CLIENT *Client )); -GLOBAL bool Lists_IsBanEntry PARAMS(( char *Mask, CHANNEL *Chan )); -GLOBAL void Lists_DeleteChannel PARAMS(( CHANNEL *Chan )); +GLOBAL struct list_elem *Lists_GetFirst PARAMS((const struct list_head *)); +GLOBAL struct list_elem *Lists_GetNext PARAMS((const struct list_elem *)); -GLOBAL char *Lists_MakeMask PARAMS(( char *Pattern )); +GLOBAL bool Lists_Check PARAMS((struct list_head *head, CLIENT *client )); +GLOBAL bool Lists_CheckDupeMask PARAMS((const struct list_head *head, const char *mask )); +GLOBAL bool Lists_Add PARAMS((struct list_head *header, const char *Mask, bool OnlyOnce )); +GLOBAL void Lists_Del PARAMS((struct list_head *head, const char *Mask )); -#endif +GLOBAL bool Lists_AlreadyRegistered PARAMS(( const struct list_head *head, const char *Mask)); +GLOBAL void Lists_Free PARAMS(( struct list_head *head )); +GLOBAL char *Lists_MakeMask PARAMS(( char *Pattern )); +GLOBAL const char *Lists_GetMask PARAMS(( const struct list_elem *e )); + +#endif /* -eof- */ Index: src/ngircd/ngircd.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/ngircd.c,v retrieving revision 1.113 retrieving revision 1.113.2.2 diff -u -p -r1.113 -r1.113.2.2 --- src/ngircd/ngircd.c 23 Jul 2006 12:07:33 -0000 1.113 +++ src/ngircd/ngircd.c 5 May 2007 20:25:47 -0000 1.113.2.2 @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2006 Alexander Barton (alex@barton.de). + * Copyright (c)2001-2007 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 @@ -12,7 +12,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: ngircd.c,v 1.113 2006/07/23 12:07:33 alex Exp $"; +static char UNUSED id[] = "$Id: ngircd.c,v 1.113.2.2 2007/05/05 20:25:47 alex Exp $"; /** * @file @@ -271,7 +271,6 @@ main( int argc, const char *argv[] ) /* Initialize modules, part II: these functions are eventually * called with already dropped privileges ... */ - Lists_Init( ); Channel_Init( ); Client_Init( ); #ifdef ZEROCONF @@ -328,7 +327,6 @@ main( int argc, const char *argv[] ) #endif Client_Exit( ); Channel_Exit( ); - Lists_Exit( ); Log_Exit( ); } Pidfile_Delete( ); @@ -548,7 +546,7 @@ static void Show_Version( void ) { puts( NGIRCd_Version ); - puts( "Copyright (c)2001-2006 Alexander Barton () and Contributors." ); + puts( "Copyright (c)2001-2007 Alexander Barton () and Contributors." ); puts( "Homepage: \n" ); puts( "This is free software; see the source for copying conditions. There is NO" ); puts( "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." ); Index: src/ngircd/resolve.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/resolve.c,v retrieving revision 1.24.2.1 retrieving revision 1.24.2.2 diff -u -p -r1.24.2.1 -r1.24.2.2 --- src/ngircd/resolve.c 2 Dec 2006 13:00:25 -0000 1.24.2.1 +++ src/ngircd/resolve.c 17 Dec 2006 22:59:56 -0000 1.24.2.2 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: resolve.c,v 1.24.2.1 2006/12/02 13:00:25 fw Exp $"; +static char UNUSED id[] = "$Id: resolve.c,v 1.24.2.2 2006/12/17 22:59:56 fw Exp $"; #include "imp.h" #include @@ -313,7 +313,8 @@ register_callback( RES_STAT *s, void (*c return true; Log( LOG_CRIT, "Resolver: Could not register callback function: %s!", strerror(errno)); - Resolve_Shutdown(s); + close(s->resolver_fd); + Resolve_Init(s); return false; } @@ -333,7 +334,7 @@ Resolve_Shutdown( RES_STAT *s) return ret; } - + /** * Read result of resolver sub-process from pipe */