Index: ChangeLog =================================================================== RCS file: /srv/cvs/ngircd/ngircd/ChangeLog,v retrieving revision 1.276.2.12 retrieving revision 1.302.2.1 diff -u -r1.276.2.12 -r1.302.2.1 --- ChangeLog 15 Oct 2005 12:44:08 -0000 1.276.2.12 +++ ChangeLog 2 Aug 2006 08:19:38 -0000 1.302.2.1 @@ -1,7 +1,7 @@ ngIRCd - Next Generation IRC Server - (c)2001-2005 Alexander Barton, + (c)2001-2006 Alexander Barton, alex@barton.de, http://www.barton.de/ ngIRCd is free software and published under the @@ -10,9 +10,34 @@ -- ChangeLog -- +ngIRCd 0.10.0-pre1 (2006-08-02) + + - Validate "ServerName" (see RFC 2812, section 2.3.1). + - Enhanced DIE to accept a single parameter ("comment text") which is sent + to all locally connected clients before the server goes down. + - The ngIRCd handles time shifts backwards more gracefully now (the + timeout handling doesn't disconnect clients by mistake any more). + - Internal: Restructured connection handling (the connection ID is equal + to the file descriptor of the connection). + - Internal: Simplified resolver code. + - JOIN now supports more than one channel key at a time. + - Implemented numeric "333": Time and user name who set a channel topic. + - Enhanced the handler for PING and PONG commands: fix forwarding and enable + back-passing of a client supplied additional argument of PING. + - Changed handling of timeouts for unregistered connections: don't reset + the counter if data is received and disconnect clients earlier. + - Removed unnecessary #define of "LOCAL", now use plain C "static" instead. + - Channel topics are no longer limited to 127 characters: now the only limit + is the maximum length of an IRC command, i. e. 512 bytes (in practice, this + limits the topic to about 490 characters due to protocol overhead). + - Reverse DNS lookup code now checks the result by doing an additional + lookup to prevent spoofing. + - Added new IO layer which (optionally) supports epoll() and kqueue() in + addition to the select() interface. + ngIRCd 0.9.2 (2005-10-15) - - Fixed a bug that could cause the damon to crash when outgoing server + - Fixed a bug that could cause the daemon to crash when outgoing server connections can't be established. - Fixed a bug that caused the daemon to leak file descriptors when no resolver subprocesses could be created. @@ -32,7 +57,7 @@ ngIRCd 0.9.0-pre1 (2005-07-09) - Fixed maximum length of user names, now allow up to 9 characters. - Cut off oversized IRC messages that should be sent to the network instead - of shuttding down the (wrong) connection. + of shutting down the (wrong) connection. - Don't generate error messages for unknown commands received before the client is registered with the server (like the original ircd). - Never run with root privileges but always switch the user ID. @@ -629,4 +654,4 @@ -- -$Id: ChangeLog,v 1.276.2.12 2005/10/15 12:44:08 alex Exp $ +$Id: ChangeLog,v 1.302.2.1 2006/08/02 08:19:38 alex Exp $ Index: INSTALL =================================================================== RCS file: /srv/cvs/ngircd/ngircd/INSTALL,v retrieving revision 1.21 retrieving revision 1.23.2.1 diff -u -r1.21 -r1.23.2.1 --- INSTALL 10 Feb 2005 08:20:09 -0000 1.21 +++ INSTALL 2 Aug 2006 08:19:38 -0000 1.23.2.1 @@ -1,7 +1,7 @@ ngIRCd - Next Generation IRC Server - (c)2001-2004 by Alexander Barton, + (c)2001-2006 by Alexander Barton, alex@barton.de, http://www.barton.de/ ngIRCd is free software and published under the @@ -14,6 +14,12 @@ I. Upgrade Information ~~~~~~~~~~~~~~~~~~~~~~ +Differences to version 0.9.x + +- The option of the configure script to enable support for Zeroconf/Bonjour/ + Rendezvous/WhateverItIsNamedToday has been renamed: + --with-rendezvous -> --with-zeroconf + Differences to version 0.8.x - The maximum length of passwords has been raised to 20 characters (instead @@ -121,7 +127,59 @@ - /usr/local/share/doc/ngircd/: documentation -II. Useful make-targets +III. Additional features +~~~~~~~~~~~~~~~~~~~~~~~~ + +The following optional features can be compiled into the daemon by passing +options to the "configure" script. Most options can handle a argument +which will be used to search for the required libraries and header files in +the given paths ("/lib/...", "/include/...") in addition to the +standard locations. + +* Syslog Logging (autodetected by default): + --with-syslog[=] / --without-syslog + + Enable (disable) support for logging to "syslog", which should be + available on most modern UNIX-like operating systems by default. + +* ZLib Compression (autodetected by default): + --with-zlib[=] / --without-zlib + + Enable (disable) support for compressed server-server links. + The Z compression library ("libz") is required for this option. + +* IO Backend (autodetected by default): + --with-epoll[=] / --without-epoll + --with-kqueue[=] / --without-kqueue + + ngIRCd can use three different IO "backends": the "old school" select() + 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. + 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(). + +* IDENT-Support: + --with-ident[=] + + Include support for IDENT ("AUTH") lookups. The "ident" library is + required for this option. + +* ZeroConf Support: + --with-zeroconf[=] + + Compile ngIRCd with support for ZeroConf multicast DNS service registration. + Either the Apple ZeroConf implementation (e. g. Mac OS X) or the Howl + library is required. Which one is available is autodetected. + +* TCP-Wrappers: + --with-tcp-wrappers[=] + + Include support for Wietse Venemas "TCP Wrappers" to limit client access + to the daemon, for example by using "/etc/hosts.{allow|deny}". + The "libwrap" is required for this option. + + +IV. Useful make-targets ~~~~~~~~~~~~~~~~~~~~~~~ The Makefile produced by the configure-script contains always these useful @@ -137,8 +195,8 @@ next step: -> ./autogen.sh -III. Sample configuration file ngircd.conf -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +V. Sample configuration file ngircd.conf +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In the sample configuration file, there are comments beginning with "#" OR ";" -- this is only for the better understanding of the file. @@ -158,7 +216,7 @@ and in the "ngircd.conf" manual page. -IV. Command line options +VI. Command line options ~~~~~~~~~~~~~~~~~~~~~~~~ These parameters could be passed to the ngIRCd: @@ -183,4 +241,4 @@ -- -$Id: INSTALL,v 1.21 2005/02/10 08:20:09 alex Exp $ +$Id: INSTALL,v 1.23.2.1 2006/08/02 08:19:38 alex Exp $ Index: Makefile.am =================================================================== RCS file: /srv/cvs/ngircd/ngircd/Makefile.am,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- Makefile.am 9 Apr 2005 12:27:40 -0000 1.16 +++ Makefile.am 22 Jul 2005 21:01:52 -0000 1.17 @@ -8,7 +8,7 @@ # (at your option) any later version. # Please read the file COPYING, README and AUTHORS for more information. # -# $Id: Makefile.am,v 1.16 2005/04/09 12:27:40 alex Exp $ +# $Id: Makefile.am,v 1.17 2005/07/22 21:01:52 alex Exp $ # AUTOMAKE_OPTIONS = gnu @@ -28,7 +28,7 @@ make -C src/ngircd lint srcdoc: - make -C src srcdoc + make -C doc srcdoc xcode: @xcodebuild -project contrib/MacOSX/ngIRCd.xcode -list >/dev/null 2>&1 \ Index: NEWS =================================================================== RCS file: /srv/cvs/ngircd/ngircd/NEWS,v retrieving revision 1.74.2.1 retrieving revision 1.75.2.1 diff -u -r1.74.2.1 -r1.75.2.1 --- NEWS 24 Jul 2005 21:39:45 -0000 1.74.2.1 +++ NEWS 2 Aug 2006 08:19:38 -0000 1.75.2.1 @@ -1,7 +1,7 @@ ngIRCd - Next Generation IRC Server - (c)2001-2005 Alexander Barton, + (c)2001-2006 Alexander Barton, alex@barton.de, http://www.barton.de/ ngIRCd is free software and published under the @@ -10,6 +10,20 @@ -- NEWS -- +ngIRCd 0.10.0-pre1 (2006-08-02) + + - Enhanced DIE to accept a single parameter ("comment text") which is sent + to all locally connected clients before the server goes down. + - JOIN now supports more than one channel key at a time. + - Implemented numeric "333": Time and user name who set a channel topic. + - Channel topics are no longer limited to 127 characters: now the only limit + is the maximum length of an IRC command, i. e. 512 bytes (in practice, this + limits the topic to about 490 characters due to protocol overhead). + - Reverse DNS lookup code now checks the result by doing an additional + lookup to prevent spoofing. + - Added new IO layer which (optionally) supports epoll() and kqueue() in + addition to the select() interface. + ngIRCd 0.9.0 (2005-07-24) - Never run with root privileges but always switch the user ID. @@ -208,4 +222,4 @@ -- -$Id: NEWS,v 1.74.2.1 2005/07/24 21:39:45 alex Exp $ +$Id: NEWS,v 1.75.2.1 2006/08/02 08:19:38 alex Exp $ Index: README =================================================================== RCS file: /srv/cvs/ngircd/ngircd/README,v retrieving revision 1.20.2.1 retrieving revision 1.21.2.1 diff -u -r1.20.2.1 -r1.21.2.1 --- README 9 Jul 2005 14:41:39 -0000 1.20.2.1 +++ README 2 Aug 2006 08:19:38 -0000 1.21.2.1 @@ -1,7 +1,7 @@ ngIRCd - Next Generation IRC Server - (c)2001-2005 Alexander Barton, + (c)2001-2006 Alexander Barton, alex@barton.de, http://www.barton.de/ ngIRCd is free software and published under the @@ -84,4 +84,4 @@ -- -$Id: README,v 1.20.2.1 2005/07/09 14:41:39 alex Exp $ +$Id: README,v 1.21.2.1 2006/08/02 08:19:38 alex Exp $ Index: config.guess =================================================================== RCS file: /srv/cvs/ngircd/ngircd/config.guess,v retrieving revision 1.6.2.2 retrieving revision 1.9 diff -u -r1.6.2.2 -r1.9 --- config.guess 15 Oct 2005 12:59:00 -0000 1.6.2.2 +++ config.guess 23 Jul 2006 12:03:14 -0000 1.9 @@ -3,7 +3,7 @@ # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -timestamp='2005-08-03' +timestamp='2006-02-23' # 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 @@ -106,7 +106,7 @@ trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; @@ -206,6 +206,9 @@ *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; macppc:MirBSD:*:*) echo powerppc-unknown-mirbsd${UNAME_RELEASE} exit ;; @@ -764,7 +767,12 @@ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin @@ -772,6 +780,9 @@ i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; + i*:MSYS_NT-*:*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 @@ -779,8 +790,11 @@ i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; - x86:Interix*:[34]*) - echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' + x86:Interix*:[345]*) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T:Interix*:[345]*) + echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks @@ -851,7 +865,11 @@ #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) @@ -870,7 +888,11 @@ #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) @@ -919,6 +941,9 @@ sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; @@ -964,7 +989,7 @@ LIBC=gnulibc1 # endif #else - #ifdef __INTEL_COMPILER + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun) LIBC=gnu #else LIBC=gnuaout @@ -974,7 +999,11 @@ LIBC=dietlibc #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit @@ -1185,7 +1214,6 @@ *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in - *86) UNAME_PROCESSOR=i686 ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} @@ -1264,6 +1292,9 @@ i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 Index: config.sub =================================================================== RCS file: /srv/cvs/ngircd/ngircd/config.sub,v retrieving revision 1.6.2.2 retrieving revision 1.9 diff -u -r1.6.2.2 -r1.9 --- config.sub 15 Oct 2005 12:59:00 -0000 1.6.2.2 +++ config.sub 23 Jul 2006 12:03:14 -0000 1.9 @@ -3,7 +3,7 @@ # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. -timestamp='2005-07-08' +timestamp='2006-02-23' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -119,8 +119,9 @@ # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ - kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; @@ -171,6 +172,10 @@ -hiux*) os=-hiuxwe2 ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -187,6 +192,10 @@ # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -239,7 +248,7 @@ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ - | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ + | m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ @@ -257,8 +266,9 @@ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ - | ms1 \ + | mt \ | msp430 \ + | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ @@ -286,6 +296,9 @@ ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; + ms1) + basic_machine=mt-unknown + ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and @@ -336,8 +349,9 @@ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ - | ms1-* \ + | mt-* \ | msp430-* \ + | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ @@ -696,6 +710,9 @@ basic_machine=i386-pc os=-msdos ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; mvs) basic_machine=i370-ibm os=-mvs @@ -803,6 +820,12 @@ pc532 | pc532-*) basic_machine=ns32k-pc532 ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; @@ -859,6 +882,10 @@ basic_machine=i586-unknown os=-pw32 ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; rom68k) basic_machine=m68k-rom68k os=-coff @@ -1174,21 +1201,23 @@ | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku*) + | -skyos* | -haiku* | -rdos*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) Index: configure.in =================================================================== RCS file: /srv/cvs/ngircd/ngircd/configure.in,v retrieving revision 1.111.2.6 retrieving revision 1.118.2.2 diff -u -r1.111.2.6 -r1.118.2.2 --- configure.in 15 Oct 2005 12:44:08 -0000 1.111.2.6 +++ configure.in 2 Aug 2006 10:29:11 -0000 1.118.2.2 @@ -1,6 +1,6 @@ # # ngIRCd -- The Next Generation IRC Daemon -# Copyright (c)2001-2005 Alexander Barton +# Copyright (c)2001-2006 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.111.2.6 2005/10/15 12:44:08 alex Exp $ +# $Id: configure.in,v 1.118.2.2 2006/08/02 10:29:11 alex Exp $ # # -- Initialisation -- AC_PREREQ(2.50) -AC_INIT(ngircd, 0.9.2) +AC_INIT(ngircd, 0.10.0-pre1) AC_CONFIG_SRCDIR(src/ngircd/ngircd.c) AC_CANONICAL_TARGET AM_INIT_AUTOMAKE(1.6) @@ -30,7 +30,7 @@ AH_TEMPLATE([ZLIB], [Define if zlib compression should be enabled]) AH_TEMPLATE([TCPWRAP], [Define if TCP wrappers should be used]) AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used]) -AH_TEMPLATE([RENDEZVOUS], [Define if Rendezvous support should be included]) +AH_TEMPLATE([ZEROCONF], [Define if support for Zeroconf should be included]) AH_TEMPLATE([IDENTAUTH], [Define if the server should do IDENT requests]) AH_TEMPLATE([TARGET_OS], [Target operating system name]) @@ -61,6 +61,25 @@ CFLAGS="$CFLAGS -pipe -W -Wall -Wpointer-arith -Wstrict-prototypes" fi + +AC_DEFUN([GCC_STACK_PROTECT_CC],[ + ssp_cc=yes + if test "X$CC" != "X"; then + AC_MSG_CHECKING([whether ${CC} accepts -fstack-protector]) + ssp_old_cflags="$CFLAGS" + CFLAGS="$CFLAGS -fstack-protector" + AC_TRY_COMPILE(,,, ssp_cc=no) + echo $ssp_cc + if test "X$ssp_cc" = "Xno"; then + CFLAGS="$ssp_old_cflags" + else + AC_DEFINE([ENABLE_SSP_CC], 1, [Define if SSP C support is enabled.]) + fi + fi +]) + +GCC_STACK_PROTECT_CC + case "$target_os" in hpux*) # This is HP/UX, we need to define _XOPEN_SOURCE_EXTENDED @@ -105,6 +124,7 @@ AC_TYPE_SIGNAL AC_TYPE_SIZE_T + # -- Libraries -- AC_CHECK_LIB(UTIL,memmove) @@ -178,6 +198,45 @@ AC_CHECK_HEADERS(zlib.h,,AC_MSG_ERROR([required C header missing!])) fi + +x_io_backend=select +AC_ARG_WITH(epoll, + [ --without-epoll disable epoll 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!]) + ) + fi + ], + [ + AC_CHECK_FUNCS(epoll_create, x_io_backend=epoll) + ] +) + +AC_ARG_WITH(kqueue, + [ --without-kqueue disable kqueue 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(kqueue, x_io_backend=kqueue, + AC_MSG_ERROR([Can't enable kqueue support!]) + ) + fi + ], + [ + AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue) + ] +) + + x_tcpwrap_on=no AC_ARG_WITH(tcp-wrappers, [ --with-tcp-wrappers enable TCP wrappers support], @@ -207,34 +266,35 @@ ] ) -x_rendezvous_on=no -AC_ARG_WITH(rendezvous, - [ --with-rendezvous enable support for "Rendezvous"], +x_zeroconf_on=no +AC_ARG_WITH(zeroconf, + [ --with-zeroconf enable support for "Zeroconf"], [ 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(DNSServiceRegistrationCreate, x_rendezvous_on=osx, + AC_CHECK_FUNCS(DNSServiceRegistrationCreate, x_zeroconf_on=osx, [ AC_CHECK_LIB(pthread, pthread_mutexattr_init) AC_CHECK_LIB(howl, sw_discovery_init) AC_CHECK_FUNCS(sw_discovery_init, \ - x_rendezvous_on=howl, \ - AC_MSG_ERROR([Can't enable Rendezvous!])) + x_zeroconf_on=howl, \ + AC_MSG_ERROR([Can't enable Zeroconf!])) ]) fi ] ) -if test "$x_rendezvous_on" = "osx"; then +if test "$x_zeroconf_on" = "osx"; then AC_CHECK_HEADERS([DNSServiceDiscovery/DNSServiceDiscovery.h \ mach/port.h],,AC_MSG_ERROR([required C header missing!])) - AC_DEFINE(RENDEZVOUS, 1) + AC_DEFINE(ZEROCONF, 1) fi -if test "$x_rendezvous_on" = "howl"; then +if test "$x_zeroconf_on" = "howl"; then for dir in /usr/local/include /usr/local/include/howl* \ - /usr/include /usr/include/howl*; do + /usr/include /usr/include/howl* \ + /usr/local/include/avahi* /usr/include/avahi*; do test -d "$dir" || continue AC_MSG_CHECKING([for Howl headers in $dir]) if test -f "$dir/rendezvous/rendezvous.h"; then @@ -251,7 +311,7 @@ done AC_CHECK_HEADERS([rendezvous/rendezvous.h],, \ AC_MSG_ERROR([required C header missing!])) - AC_DEFINE(RENDEZVOUS, 1) + AC_DEFINE(ZEROCONF, 1) fi x_identauth_on=no @@ -326,6 +386,7 @@ AC_OUTPUT([ \ Makefile \ doc/Makefile \ + doc/src/Makefile \ src/Makefile \ src/portab/Makefile \ src/tool/Makefile \ @@ -374,8 +435,8 @@ echo $ECHO_N " Syslog support: $ECHO_C" test "$x_syslog_on" = "yes" \ - && echo $ECHO_N "yes $ECHO_C" \ - || echo $ECHO_N "no $ECHO_C" + && echo $ECHO_N "yes $ECHO_C" \ + || echo $ECHO_N "no $ECHO_C" echo $ECHO_N " Enable debug code: $ECHO_C" test "$x_debug_on" = "yes" \ && echo "yes" \ @@ -383,8 +444,8 @@ echo $ECHO_N " zlib compression: $ECHO_C" test "$x_zlib_on" = "yes" \ - && echo $ECHO_N "yes $ECHO_C" \ - || echo $ECHO_N "no $ECHO_C" + && echo $ECHO_N "yes $ECHO_C" \ + || echo $ECHO_N "no $ECHO_C" echo $ECHO_N " IRC sniffer: $ECHO_C" test "$x_sniffer_on" = "yes" \ && echo "yes" \ @@ -392,17 +453,25 @@ echo $ECHO_N " Use TCP Wrappers: $ECHO_C" test "$x_tcpwrap_on" = "yes" \ - && echo $ECHO_N "yes $ECHO_C" \ - || echo $ECHO_N "no $ECHO_C" + && echo $ECHO_N "yes $ECHO_C" \ + || echo $ECHO_N "no $ECHO_C" echo $ECHO_N " Strict RFC mode: $ECHO_C" test "$x_strict_rfc_on" = "yes" \ && echo "yes" \ || echo "no" -echo $ECHO_N " Rendezvous support: $ECHO_C" -test "$x_rendezvous_on" = "osx" -o "$x_rendezvous_on" = "howl" \ - && echo $ECHO_N "yes $ECHO_C" \ - || echo $ECHO_N "no $ECHO_C" +echo $ECHO_N " Zeroconf support: $ECHO_C" +case "$x_zeroconf_on" in + osx) + echo $ECHO_N "Apple $ECHO_C" + ;; + howl) + echo $ECHO_N "Howl $ECHO_C" + ;; + *) + echo $ECHO_N "no $ECHO_C" + ;; +esac echo $ECHO_N " IRC+ protocol: $ECHO_C" test "$x_ircplus_on" = "yes" \ && echo "yes" \ @@ -410,9 +479,11 @@ echo $ECHO_N " IDENT support: $ECHO_C" test "$x_identauth_on" = "yes" \ - && echo $ECHO_N "yes $ECHO_C" \ - || echo $ECHO_N "no $ECHO_C" + && echo $ECHO_N "yes $ECHO_C" \ + || echo $ECHO_N "no $ECHO_C" +echo $ECHO_N " I/O backend: $ECHO_C" + echo "\"$x_io_backend()\"" -echo; echo +echo # -eof- Index: contrib/README =================================================================== RCS file: /srv/cvs/ngircd/ngircd/contrib/README,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- contrib/README 28 Apr 2004 12:18:50 -0000 1.1 +++ contrib/README 23 Jul 2006 11:34:32 -0000 1.3 @@ -1,7 +1,7 @@ ngIRCd - Next Generation IRC Server - (c)2001-2004 by Alexander Barton, + (c)2001-2005 Alexander Barton, alex@barton.de, http://www.barton.de/ ngIRCd is free software and published under the @@ -10,11 +10,17 @@ -- Contributions -- +Debian/ + - Various files for building Debian GNU/Linux packages (".deb's"). + MacOSX/ - - Project file for XCode "project builder" of Mac OS X. + - Project files for XCode, the "project builder" of Apple Mac OS X. -Debian/ - - Various files for building Debian packages. +ngindent + - Script to indent the code of ngIRCd in the "standard way". + +ngircd.sh + - Start script for FreeBSD. ngircd.spec - RPM "spec" file. @@ -24,4 +30,4 @@ -- -$Id: README,v 1.1 2004/04/28 12:18:50 alex Exp $ +$Id: README,v 1.3 2006/07/23 11:34:32 alex Exp $ Index: contrib/ngindent =================================================================== RCS file: contrib/ngindent diff -N contrib/ngindent --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/ngindent 23 Jul 2006 11:34:32 -0000 1.1 @@ -0,0 +1,16 @@ +#/bin/sh + +INDENTARGS="-kr -i8 -ts8 -l80 -c3 -cd41 -ss -ncs -psl" + +# check if indent(1) is available +type indent >/dev/null 2>&1 && INDENT="indent" +type gnuindent >/dev/null 2>&1 && INDENT="gnuindent" + +if [ -z "$INDENT" ]; then + echo "Error: GNU \"indent\" not found!" + exit 1 +fi + +$INDENT -v $INDENTARGS $* + +# -eof- Index: contrib/ngircd.sh =================================================================== RCS file: contrib/ngircd.sh diff -N contrib/ngircd.sh --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/ngircd.sh 12 Aug 2005 21:32:45 -0000 1.1 @@ -0,0 +1,51 @@ +#!/bin/sh + +# PROVIDE: ngircd +# REQUIRE: NETWORKING SERVERS +# BEFORE: DAEMON +# KEYWORD: FreeBSD shutdown + +# Add the following line to /etc/rc.conf to enable `ngircd': +# +#ngircd_enable="YES" +# + +. "/etc/rc.subr" + +name="ngircd" +rcvar=`set_rcvar` + +command="/usr/local/sbin/ngircd" +command_args="" + +load_rc_config "$name" +: ${ngircd_enable="NO"} +: ${ngircd_flags=""} + +required_files="/usr/local/etc/$name.conf" +pidfile="${ngircd_pidfile:-/var/run/${name}/${name}.pid}" + +if [ ! x"${ngircd_chrootdir}" = x ];then + # Mount a devfs in the chroot directory if needed + if [ ! -c ${ngircd_chrootdir}/dev/random \ + -o ! -c ${ngircd_chrootdir}/dev/null ]; then + umount ${ngircd_chrootdir}/dev 2>/dev/null + mount_devfs devfs ${ngircd_chrootdir}/dev + fi + + devfs -m ${ngircd_chrootdir}/dev rule apply hide + devfs -m ${ngircd_chrootdir}/dev rule apply path null unhide + devfs -m ${ngircd_chrootdir}/dev rule apply path random unhide + + # Copy local timezone information if it is not up to date. + if [ -f /etc/localtime ]; then + cmp -s /etc/localtime "${named_chrootdir}/etc/localtime" || \ + cp -p /etc/localtime "${named_chrootdir}/etc/localtime" + fi + + pidfile="${ngircd_chrootdir}${pidfile}" +fi + +run_rc_command "$1" + +# -eof- Index: contrib/ngircd.spec =================================================================== RCS file: /srv/cvs/ngircd/ngircd/contrib/ngircd.spec,v retrieving revision 1.4.4.3 retrieving revision 1.4.6.1 diff -u -r1.4.4.3 -r1.4.6.1 --- contrib/ngircd.spec 15 Oct 2005 12:44:09 -0000 1.4.4.3 +++ contrib/ngircd.spec 2 Aug 2006 10:29:12 -0000 1.4.6.1 @@ -1,5 +1,5 @@ %define name ngircd -%define version 0.9.2 +%define version 0.10.0-pre1 %define release 1 %define prefix %{_prefix} Index: contrib/Debian/changelog =================================================================== RCS file: /srv/cvs/ngircd/ngircd/contrib/Debian/changelog,v retrieving revision 1.11.2.8 retrieving revision 1.12.2.2 diff -u -r1.11.2.8 -r1.12.2.2 --- contrib/Debian/changelog 15 Oct 2005 12:59:19 -0000 1.11.2.8 +++ contrib/Debian/changelog 2 Aug 2006 10:29:12 -0000 1.12.2.2 @@ -1,3 +1,9 @@ +ngircd (0.10.0-0ab0-pre1) unstable; urgency=low + + * Prerelease of upcoming new "upstream release". + + -- Alexander Barton Wed, 2 Aug 2006 12:01:07 +0200 + ngircd (0.9.2-0ab1) unstable; urgency=low * New "upstream release" fixing a few bugs in 0.9.1. Index: contrib/Debian/ngircd.init =================================================================== RCS file: /srv/cvs/ngircd/ngircd/contrib/Debian/ngircd.init,v retrieving revision 1.5.2.1 retrieving revision 1.6 diff -u -r1.5.2.1 -r1.6 --- contrib/Debian/ngircd.init 26 Jul 2005 19:30:54 -0000 1.5.2.1 +++ contrib/Debian/ngircd.init 26 Jul 2005 19:37:18 -0000 1.6 @@ -2,7 +2,7 @@ # # ngIRCd start and stop script for Debian-based systems # -# $Id: ngircd.init,v 1.5.2.1 2005/07/26 19:30:54 alex Exp $ +# $Id: ngircd.init,v 1.6 2005/07/26 19:37:18 alex Exp $ # PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin Index: contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj =================================================================== RCS file: contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj diff -N contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj 3 Sep 2005 15:13:14 -0000 1.2 @@ -0,0 +1,843 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 42; + objects = { + +/* Begin PBXBuildFile section */ + FA2329EE08C9E7A30093207B /* array.c in Sources */ = {isa = PBXBuildFile; fileRef = FA2329EC08C9E7A30093207B /* array.c */; }; + FA2329EF08C9E7A30093207B /* array.h in Headers */ = {isa = PBXBuildFile; fileRef = FA2329ED08C9E7A30093207B /* array.h */; }; + FA2329F208C9E7C40093207B /* io.c in Sources */ = {isa = PBXBuildFile; fileRef = FA2329F008C9E7C40093207B /* io.c */; }; + FA2329F308C9E7C40093207B /* io.h in Headers */ = {isa = PBXBuildFile; fileRef = FA2329F108C9E7C40093207B /* io.h */; }; + FA2329F508C9E8070093207B /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = FA2329F408C9E8070093207B /* strdup.c */; }; + FA2329F708C9E81A0093207B /* portab.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B5705F14AB40081A16E /* portab.h */; }; + FA232A7D08C9F0480093207B /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B8F05F14C6C0081A16E /* config.h */; }; + FA83332B0627391D00A909F0 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA83332A0627391D00A909F0 /* libz.dylib */; }; + FADE2B2305F14A960081A16E /* irc-server.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2AF205F14A960081A16E /* irc-server.h */; }; + FADE2B2405F14A960081A16E /* irc-op.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2AF305F14A960081A16E /* irc-op.c */; }; + FADE2B2505F14A960081A16E /* irc-login.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2AF405F14A960081A16E /* irc-login.c */; }; + FADE2B2605F14A960081A16E /* conn-zip.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2AF505F14A960081A16E /* conn-zip.h */; }; + FADE2B2705F14A960081A16E /* match.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2AF605F14A960081A16E /* match.h */; }; + FADE2B2805F14A960081A16E /* irc-oper.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2AF705F14A960081A16E /* irc-oper.c */; }; + FADE2B2905F14A960081A16E /* irc-mode.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2AF805F14A960081A16E /* irc-mode.c */; }; + FADE2B2A05F14A960081A16E /* conn.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2AF905F14A960081A16E /* conn.h */; }; + FADE2B2B05F14A960081A16E /* messages.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2AFA05F14A960081A16E /* messages.h */; }; + FADE2B2C05F14A960081A16E /* irc.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2AFB05F14A960081A16E /* irc.h */; }; + FADE2B2D05F14A960081A16E /* conf.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2AFC05F14A960081A16E /* conf.c */; }; + FADE2B2E05F14A960081A16E /* irc.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2AFD05F14A960081A16E /* irc.c */; }; + FADE2B2F05F14A960081A16E /* hash.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2AFE05F14A960081A16E /* hash.h */; }; + FADE2B3005F14A960081A16E /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2AFF05F14A960081A16E /* parse.c */; }; + FADE2B3105F14A960081A16E /* resolve.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B0005F14A960081A16E /* resolve.c */; }; + FADE2B3205F14A960081A16E /* channel.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B0105F14A960081A16E /* channel.c */; }; + FADE2B3305F14A960081A16E /* defines.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B0205F14A960081A16E /* defines.h */; }; + FADE2B3405F14A960081A16E /* conf.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B0305F14A960081A16E /* conf.h */; }; + FADE2B3505F14A960081A16E /* rendezvous.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B0405F14A960081A16E /* rendezvous.c */; }; + FADE2B3605F14A960081A16E /* lists.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B0505F14A960081A16E /* lists.h */; }; + FADE2B3705F14A960081A16E /* ngircd.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B0605F14A960081A16E /* ngircd.h */; }; + FADE2B3805F14A960081A16E /* irc-channel.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B0705F14A960081A16E /* irc-channel.h */; }; + FADE2B3905F14A960081A16E /* channel.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B0805F14A960081A16E /* channel.h */; }; + FADE2B3A05F14A960081A16E /* irc-server.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B0905F14A960081A16E /* irc-server.c */; }; + FADE2B3B05F14A960081A16E /* log.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B0A05F14A960081A16E /* log.h */; }; + FADE2B3C05F14A960081A16E /* irc-mode.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B0B05F14A960081A16E /* irc-mode.h */; }; + FADE2B3D05F14A960081A16E /* irc-info.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B0C05F14A960081A16E /* irc-info.h */; }; + FADE2B3E05F14A960081A16E /* conn-zip.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B0D05F14A960081A16E /* conn-zip.c */; }; + FADE2B3F05F14A960081A16E /* irc-write.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B0E05F14A960081A16E /* irc-write.c */; }; + FADE2B4005F14A960081A16E /* match.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B0F05F14A960081A16E /* match.c */; }; + FADE2B4105F14A960081A16E /* irc-op.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B1005F14A960081A16E /* irc-op.h */; }; + FADE2B4205F14A960081A16E /* irc-login.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B1105F14A960081A16E /* irc-login.h */; }; + FADE2B4305F14A960081A16E /* conn.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B1205F14A960081A16E /* conn.c */; }; + FADE2B4405F14A960081A16E /* client.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B1305F14A960081A16E /* client.h */; }; + FADE2B4505F14A960081A16E /* irc-write.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B1405F14A960081A16E /* irc-write.h */; }; + FADE2B4605F14A960081A16E /* irc-oper.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B1505F14A960081A16E /* irc-oper.h */; }; + FADE2B4705F14A960081A16E /* rendezvous.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B1605F14A960081A16E /* rendezvous.h */; }; + FADE2B4805F14A960081A16E /* ngircd.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B1705F14A960081A16E /* ngircd.c */; }; + FADE2B4905F14A960081A16E /* irc-channel.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B1805F14A960081A16E /* irc-channel.c */; }; + FADE2B4A05F14A960081A16E /* parse.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B1905F14A960081A16E /* parse.h */; }; + FADE2B4B05F14A960081A16E /* lists.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B1A05F14A960081A16E /* lists.c */; }; + FADE2B4C05F14A960081A16E /* resolve.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B1B05F14A960081A16E /* resolve.h */; }; + FADE2B4D05F14A960081A16E /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B1C05F14A960081A16E /* hash.c */; }; + FADE2B4E05F14A960081A16E /* irc-info.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B1D05F14A960081A16E /* irc-info.c */; }; + FADE2B4F05F14A960081A16E /* conn-func.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B1E05F14A960081A16E /* conn-func.c */; }; + FADE2B5005F14A960081A16E /* log.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B1F05F14A960081A16E /* log.c */; }; + FADE2B5105F14A960081A16E /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B2005F14A960081A16E /* client.c */; }; + FADE2B5205F14A960081A16E /* conn-func.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B2105F14A960081A16E /* conn-func.h */; }; + FADE2BBD05F14DEF0081A16E /* exp.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B5805F14AB40081A16E /* exp.h */; }; + FADE2BBF05F14DEF0081A16E /* imp.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B5405F14AB40081A16E /* imp.h */; }; + FADE2BC105F14DF10081A16E /* portab.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B5705F14AB40081A16E /* portab.h */; }; + FADE2BC305F14DF40081A16E /* strlcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B5905F14AB40081A16E /* strlcpy.c */; }; + FADE2BC505F14DF50081A16E /* vsnprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B5C05F14AB40081A16E /* vsnprintf.c */; }; + FADE2CB205F151490081A16E /* exp.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B5805F14AB40081A16E /* exp.h */; }; + FADE2CB305F151490081A16E /* imp.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B5405F14AB40081A16E /* imp.h */; }; + FADE2CB405F151490081A16E /* portabtest.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B5A05F14AB40081A16E /* portabtest.c */; }; + FADE2CC005F152770081A16E /* tool.c in Sources */ = {isa = PBXBuildFile; fileRef = FADE2B7805F14B530081A16E /* tool.c */; }; + FADE2CC205F152780081A16E /* tool.h in Headers */ = {isa = PBXBuildFile; fileRef = FADE2B7905F14B530081A16E /* tool.h */; }; +/* End PBXBuildFile section */ + +/* Begin PBXBuildStyle section */ + 014CEA520018CE5811CA2923 /* Development */ = { + isa = PBXBuildStyle; + buildSettings = { + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + ZERO_LINK = YES; + }; + name = Development; + }; + FA2002770807EE21005A2F4C /* Deployment */ = { + isa = PBXBuildStyle; + buildSettings = { + }; + name = Deployment; + }; +/* End PBXBuildStyle section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 8DD76FAF0486AB0100D96B5E /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + FADE2C9805F1511B0081A16E /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + FA2329E908C9E74D0093207B /* config.guess */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = config.guess; path = ../../config.guess; sourceTree = SOURCE_ROOT; }; + FA2329EA08C9E74D0093207B /* config.sub */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = config.sub; path = ../../config.sub; sourceTree = SOURCE_ROOT; }; + FA2329EC08C9E7A30093207B /* array.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = array.c; path = ../../src/ngircd/array.c; sourceTree = SOURCE_ROOT; }; + FA2329ED08C9E7A30093207B /* array.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = array.h; path = ../../src/ngircd/array.h; sourceTree = SOURCE_ROOT; }; + FA2329F008C9E7C40093207B /* io.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = io.c; path = ../../src/ngircd/io.c; sourceTree = SOURCE_ROOT; }; + FA2329F108C9E7C40093207B /* io.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = io.h; path = ../../src/ngircd/io.h; sourceTree = SOURCE_ROOT; }; + FA2329F408C9E8070093207B /* strdup.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = strdup.c; path = ../../src/portab/strdup.c; sourceTree = SOURCE_ROOT; }; + FA2329FA08C9E8450093207B /* functions.inc */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = functions.inc; path = ../../src/testsuite/functions.inc; sourceTree = SOURCE_ROOT; }; + FA2329FB08C9E85D0093207B /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = README; path = ../../src/testsuite/README; sourceTree = SOURCE_ROOT; }; + FA2329FC08C9E8700093207B /* test-loop.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = "test-loop.sh"; path = "../../src/testsuite/test-loop.sh"; sourceTree = SOURCE_ROOT; }; + FA2329FD08C9E87B0093207B /* wait-tests.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = "wait-tests.sh"; path = "../../src/testsuite/wait-tests.sh"; sourceTree = SOURCE_ROOT; }; + FA232A0108C9E8BF0093207B /* Doxyfile */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Doxyfile; path = ../../doc/src/Doxyfile; sourceTree = SOURCE_ROOT; }; + FA232A0208C9E8BF0093207B /* footer.inc.html */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.html; name = footer.inc.html; path = ../../doc/src/footer.inc.html; sourceTree = SOURCE_ROOT; }; + FA232A0308C9E8BF0093207B /* header.inc.html */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.html; name = header.inc.html; path = ../../doc/src/header.inc.html; sourceTree = SOURCE_ROOT; }; + FA232A0408C9E8BF0093207B /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ../../doc/src/Makefile.am; sourceTree = SOURCE_ROOT; }; + FA232A0508C9E8BF0093207B /* ngircd-doc.css */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = "ngircd-doc.css"; path = "../../doc/src/ngircd-doc.css"; sourceTree = SOURCE_ROOT; }; + FA232A0708C9E8EC0093207B /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ../Makefile.am; sourceTree = SOURCE_ROOT; }; + FA232A0808C9E8EC0093207B /* ngircd.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = ngircd.sh; path = ../ngircd.sh; sourceTree = SOURCE_ROOT; }; + FA232A0908C9E8EC0093207B /* ngircd.spec */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = ngircd.spec; path = ../ngircd.spec; sourceTree = SOURCE_ROOT; }; + FA232A0A08C9E8EC0093207B /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = README; path = ../README; sourceTree = SOURCE_ROOT; }; + FA232A0B08C9E8EC0093207B /* systrace.policy */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = systrace.policy; path = ../systrace.policy; sourceTree = SOURCE_ROOT; }; + FA83332A0627391D00A909F0 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = ""; }; + FA8B5EFD08C9E4C900B781D4 /* SSL.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = SSL.txt; path = ../../doc/SSL.txt; sourceTree = SOURCE_ROOT; }; + FA8B5EFE08C9E4C900B781D4 /* Zeroconf.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Zeroconf.txt; path = ../../doc/Zeroconf.txt; sourceTree = SOURCE_ROOT; }; + FAC0DF4A05F25A150024C8CE /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = SOURCE_ROOT; }; + FADE2AA705F1499A0081A16E /* autogen.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = autogen.sh; path = ../../autogen.sh; sourceTree = SOURCE_ROOT; }; + FADE2AA805F1499A0081A16E /* COPYING */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = COPYING; path = ../../COPYING; sourceTree = SOURCE_ROOT; }; + FADE2AA905F1499A0081A16E /* NEWS */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = NEWS; path = ../../NEWS; sourceTree = SOURCE_ROOT; }; + FADE2AAA05F1499A0081A16E /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = README; path = ../../README; sourceTree = SOURCE_ROOT; }; + FADE2AAB05F1499A0081A16E /* configure.in */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = configure.in; path = ../../configure.in; sourceTree = SOURCE_ROOT; }; + FADE2AAC05F1499A0081A16E /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = ChangeLog; path = ../../ChangeLog; sourceTree = SOURCE_ROOT; }; + FADE2AAD05F1499A0081A16E /* INSTALL */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = INSTALL; path = ../../INSTALL; sourceTree = SOURCE_ROOT; }; + FADE2AAE05F1499A0081A16E /* AUTHORS */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = AUTHORS; path = ../../AUTHORS; sourceTree = SOURCE_ROOT; }; + FADE2AB705F149C50081A16E /* README-BeOS.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = "README-BeOS.txt"; path = "../../doc/README-BeOS.txt"; sourceTree = SOURCE_ROOT; }; + FADE2AB805F149C50081A16E /* FAQ.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = FAQ.txt; path = ../../doc/FAQ.txt; sourceTree = SOURCE_ROOT; }; + FADE2AB905F149C50081A16E /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ../../doc/Makefile.am; sourceTree = SOURCE_ROOT; }; + FADE2ABA05F149C50081A16E /* README-AUX.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = "README-AUX.txt"; path = "../../doc/README-AUX.txt"; sourceTree = SOURCE_ROOT; }; + FADE2ABB05F149C50081A16E /* sample-ngircd.conf */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = "sample-ngircd.conf"; path = "../../doc/sample-ngircd.conf"; sourceTree = SOURCE_ROOT; }; + FADE2ABC05F149C50081A16E /* RFC.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = RFC.txt; path = ../../doc/RFC.txt; sourceTree = SOURCE_ROOT; }; + FADE2ABD05F149C50081A16E /* Protocol.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Protocol.txt; path = ../../doc/Protocol.txt; sourceTree = SOURCE_ROOT; }; + FADE2ABE05F149C50081A16E /* CVS.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = CVS.txt; path = ../../doc/CVS.txt; sourceTree = SOURCE_ROOT; }; + FADE2ABF05F149C50081A16E /* Platforms.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Platforms.txt; path = ../../doc/Platforms.txt; sourceTree = SOURCE_ROOT; }; + FADE2AC905F149D70081A16E /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ../../Makefile.am; sourceTree = SOURCE_ROOT; }; + FADE2ACB05F149EA0081A16E /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ../../man/Makefile.am; sourceTree = SOURCE_ROOT; }; + FADE2ACC05F149EA0081A16E /* ngircd.conf.5 */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = ngircd.conf.5; path = ../../man/ngircd.conf.5; sourceTree = SOURCE_ROOT; }; + FADE2ACD05F149EA0081A16E /* ngircd.8 */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = ngircd.8; path = ../../man/ngircd.8; sourceTree = SOURCE_ROOT; }; + FADE2AD305F14A0B0081A16E /* copyright */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = copyright; path = ../Debian/copyright; sourceTree = SOURCE_ROOT; }; + FADE2AD405F14A0B0081A16E /* rules */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = rules; path = ../Debian/rules; sourceTree = SOURCE_ROOT; }; + FADE2AD505F14A0B0081A16E /* ngircd.postinst */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = ngircd.postinst; path = ../Debian/ngircd.postinst; sourceTree = SOURCE_ROOT; }; + FADE2AD605F14A0B0081A16E /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ../Debian/Makefile.am; sourceTree = SOURCE_ROOT; }; + FADE2AD705F14A0B0081A16E /* control */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = control; path = ../Debian/control; sourceTree = SOURCE_ROOT; }; + FADE2AD805F14A0B0081A16E /* ngircd.init */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = ngircd.init; path = ../Debian/ngircd.init; sourceTree = SOURCE_ROOT; }; + FADE2AD905F14A0B0081A16E /* compat */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = compat; path = ../Debian/compat; sourceTree = SOURCE_ROOT; }; + FADE2ADA05F14A0B0081A16E /* ngircd.default */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = ngircd.default; path = ../Debian/ngircd.default; sourceTree = SOURCE_ROOT; }; + FADE2ADB05F14A0B0081A16E /* changelog */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = changelog; path = ../Debian/changelog; sourceTree = SOURCE_ROOT; }; + FADE2AF105F14A960081A16E /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ../../src/ngircd/Makefile.am; sourceTree = SOURCE_ROOT; }; + FADE2AF205F14A960081A16E /* irc-server.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = "irc-server.h"; path = "../../src/ngircd/irc-server.h"; sourceTree = SOURCE_ROOT; }; + FADE2AF305F14A960081A16E /* irc-op.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "irc-op.c"; path = "../../src/ngircd/irc-op.c"; sourceTree = SOURCE_ROOT; }; + FADE2AF405F14A960081A16E /* irc-login.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "irc-login.c"; path = "../../src/ngircd/irc-login.c"; sourceTree = SOURCE_ROOT; }; + FADE2AF505F14A960081A16E /* conn-zip.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = "conn-zip.h"; path = "../../src/ngircd/conn-zip.h"; sourceTree = SOURCE_ROOT; }; + FADE2AF605F14A960081A16E /* match.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = match.h; path = ../../src/ngircd/match.h; sourceTree = SOURCE_ROOT; }; + FADE2AF705F14A960081A16E /* irc-oper.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "irc-oper.c"; path = "../../src/ngircd/irc-oper.c"; sourceTree = SOURCE_ROOT; }; + FADE2AF805F14A960081A16E /* irc-mode.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "irc-mode.c"; path = "../../src/ngircd/irc-mode.c"; sourceTree = SOURCE_ROOT; }; + FADE2AF905F14A960081A16E /* conn.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = conn.h; path = ../../src/ngircd/conn.h; sourceTree = SOURCE_ROOT; }; + FADE2AFA05F14A960081A16E /* messages.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = messages.h; path = ../../src/ngircd/messages.h; sourceTree = SOURCE_ROOT; }; + FADE2AFB05F14A960081A16E /* irc.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = irc.h; path = ../../src/ngircd/irc.h; sourceTree = SOURCE_ROOT; }; + FADE2AFC05F14A960081A16E /* conf.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = conf.c; path = ../../src/ngircd/conf.c; sourceTree = SOURCE_ROOT; }; + FADE2AFD05F14A960081A16E /* irc.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = irc.c; path = ../../src/ngircd/irc.c; sourceTree = SOURCE_ROOT; }; + FADE2AFE05F14A960081A16E /* hash.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = hash.h; path = ../../src/ngircd/hash.h; sourceTree = SOURCE_ROOT; }; + FADE2AFF05F14A960081A16E /* parse.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = parse.c; path = ../../src/ngircd/parse.c; sourceTree = SOURCE_ROOT; }; + FADE2B0005F14A960081A16E /* resolve.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = resolve.c; path = ../../src/ngircd/resolve.c; sourceTree = SOURCE_ROOT; }; + FADE2B0105F14A960081A16E /* channel.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = channel.c; path = ../../src/ngircd/channel.c; sourceTree = SOURCE_ROOT; }; + FADE2B0205F14A960081A16E /* defines.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = defines.h; path = ../../src/ngircd/defines.h; sourceTree = SOURCE_ROOT; }; + FADE2B0305F14A960081A16E /* conf.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = conf.h; path = ../../src/ngircd/conf.h; sourceTree = SOURCE_ROOT; }; + FADE2B0405F14A960081A16E /* rendezvous.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = rendezvous.c; path = ../../src/ngircd/rendezvous.c; sourceTree = SOURCE_ROOT; }; + FADE2B0505F14A960081A16E /* lists.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = lists.h; path = ../../src/ngircd/lists.h; sourceTree = SOURCE_ROOT; }; + FADE2B0605F14A960081A16E /* ngircd.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = ngircd.h; path = ../../src/ngircd/ngircd.h; sourceTree = SOURCE_ROOT; }; + FADE2B0705F14A960081A16E /* irc-channel.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = "irc-channel.h"; path = "../../src/ngircd/irc-channel.h"; sourceTree = SOURCE_ROOT; }; + FADE2B0805F14A960081A16E /* channel.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = channel.h; path = ../../src/ngircd/channel.h; sourceTree = SOURCE_ROOT; }; + FADE2B0905F14A960081A16E /* irc-server.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "irc-server.c"; path = "../../src/ngircd/irc-server.c"; sourceTree = SOURCE_ROOT; }; + FADE2B0A05F14A960081A16E /* log.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = log.h; path = ../../src/ngircd/log.h; sourceTree = SOURCE_ROOT; }; + FADE2B0B05F14A960081A16E /* irc-mode.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = "irc-mode.h"; path = "../../src/ngircd/irc-mode.h"; sourceTree = SOURCE_ROOT; }; + FADE2B0C05F14A960081A16E /* irc-info.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = "irc-info.h"; path = "../../src/ngircd/irc-info.h"; sourceTree = SOURCE_ROOT; }; + FADE2B0D05F14A960081A16E /* conn-zip.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "conn-zip.c"; path = "../../src/ngircd/conn-zip.c"; sourceTree = SOURCE_ROOT; }; + FADE2B0E05F14A960081A16E /* irc-write.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "irc-write.c"; path = "../../src/ngircd/irc-write.c"; sourceTree = SOURCE_ROOT; }; + FADE2B0F05F14A960081A16E /* match.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = match.c; path = ../../src/ngircd/match.c; sourceTree = SOURCE_ROOT; }; + FADE2B1005F14A960081A16E /* irc-op.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = "irc-op.h"; path = "../../src/ngircd/irc-op.h"; sourceTree = SOURCE_ROOT; }; + FADE2B1105F14A960081A16E /* irc-login.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = "irc-login.h"; path = "../../src/ngircd/irc-login.h"; sourceTree = SOURCE_ROOT; }; + FADE2B1205F14A960081A16E /* conn.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = conn.c; path = ../../src/ngircd/conn.c; sourceTree = SOURCE_ROOT; }; + FADE2B1305F14A960081A16E /* client.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = client.h; path = ../../src/ngircd/client.h; sourceTree = SOURCE_ROOT; }; + FADE2B1405F14A960081A16E /* irc-write.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = "irc-write.h"; path = "../../src/ngircd/irc-write.h"; sourceTree = SOURCE_ROOT; }; + FADE2B1505F14A960081A16E /* irc-oper.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = "irc-oper.h"; path = "../../src/ngircd/irc-oper.h"; sourceTree = SOURCE_ROOT; }; + FADE2B1605F14A960081A16E /* rendezvous.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = rendezvous.h; path = ../../src/ngircd/rendezvous.h; sourceTree = SOURCE_ROOT; }; + FADE2B1705F14A960081A16E /* ngircd.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = ngircd.c; path = ../../src/ngircd/ngircd.c; sourceTree = SOURCE_ROOT; }; + FADE2B1805F14A960081A16E /* irc-channel.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "irc-channel.c"; path = "../../src/ngircd/irc-channel.c"; sourceTree = SOURCE_ROOT; }; + FADE2B1905F14A960081A16E /* parse.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = parse.h; path = ../../src/ngircd/parse.h; sourceTree = SOURCE_ROOT; }; + FADE2B1A05F14A960081A16E /* lists.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = lists.c; path = ../../src/ngircd/lists.c; sourceTree = SOURCE_ROOT; }; + FADE2B1B05F14A960081A16E /* resolve.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = resolve.h; path = ../../src/ngircd/resolve.h; sourceTree = SOURCE_ROOT; }; + FADE2B1C05F14A960081A16E /* hash.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = hash.c; path = ../../src/ngircd/hash.c; sourceTree = SOURCE_ROOT; }; + FADE2B1D05F14A960081A16E /* irc-info.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "irc-info.c"; path = "../../src/ngircd/irc-info.c"; sourceTree = SOURCE_ROOT; }; + FADE2B1E05F14A960081A16E /* conn-func.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = "conn-func.c"; path = "../../src/ngircd/conn-func.c"; sourceTree = SOURCE_ROOT; }; + FADE2B1F05F14A960081A16E /* log.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = log.c; path = ../../src/ngircd/log.c; sourceTree = SOURCE_ROOT; }; + FADE2B2005F14A960081A16E /* client.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = client.c; path = ../../src/ngircd/client.c; sourceTree = SOURCE_ROOT; }; + FADE2B2105F14A960081A16E /* conn-func.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = "conn-func.h"; path = "../../src/ngircd/conn-func.h"; sourceTree = SOURCE_ROOT; }; + FADE2B5305F14AB40081A16E /* splint.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = splint.h; path = ../../src/portab/splint.h; sourceTree = SOURCE_ROOT; }; + FADE2B5405F14AB40081A16E /* imp.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = imp.h; path = ../../src/portab/imp.h; sourceTree = SOURCE_ROOT; }; + FADE2B5505F14AB40081A16E /* ansi2knr.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = ansi2knr.c; path = ../../src/portab/ansi2knr.c; sourceTree = SOURCE_ROOT; }; + FADE2B5605F14AB40081A16E /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ../../src/portab/Makefile.am; sourceTree = SOURCE_ROOT; }; + FADE2B5705F14AB40081A16E /* portab.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = portab.h; path = ../../src/portab/portab.h; sourceTree = SOURCE_ROOT; }; + FADE2B5805F14AB40081A16E /* exp.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = exp.h; path = ../../src/portab/exp.h; sourceTree = SOURCE_ROOT; }; + FADE2B5905F14AB40081A16E /* strlcpy.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = strlcpy.c; path = ../../src/portab/strlcpy.c; sourceTree = SOURCE_ROOT; }; + FADE2B5A05F14AB40081A16E /* portabtest.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = portabtest.c; path = ../../src/portab/portabtest.c; sourceTree = SOURCE_ROOT; }; + FADE2B5B05F14AB40081A16E /* ansi2knr.1 */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.man; name = ansi2knr.1; path = ../../src/portab/ansi2knr.1; sourceTree = SOURCE_ROOT; }; + FADE2B5C05F14AB40081A16E /* vsnprintf.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = vsnprintf.c; path = ../../src/portab/vsnprintf.c; sourceTree = SOURCE_ROOT; }; + FADE2B6805F14B300081A16E /* tests.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = tests.sh; path = ../../src/testsuite/tests.sh; sourceTree = SOURCE_ROOT; }; + FADE2B6905F14B300081A16E /* stress-server.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = "stress-server.sh"; path = "../../src/testsuite/stress-server.sh"; sourceTree = SOURCE_ROOT; }; + FADE2B6A05F14B300081A16E /* channel-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = "channel-test.e"; path = "../../src/testsuite/channel-test.e"; sourceTree = SOURCE_ROOT; }; + FADE2B6B05F14B300081A16E /* stop-server.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = "stop-server.sh"; path = "../../src/testsuite/stop-server.sh"; sourceTree = SOURCE_ROOT; }; + FADE2B6C05F14B300081A16E /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ../../src/testsuite/Makefile.am; sourceTree = SOURCE_ROOT; }; + FADE2B6D05F14B300081A16E /* getpid.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = getpid.sh; path = ../../src/testsuite/getpid.sh; sourceTree = SOURCE_ROOT; }; + FADE2B6E05F14B300081A16E /* connect-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = "connect-test.e"; path = "../../src/testsuite/connect-test.e"; sourceTree = SOURCE_ROOT; }; + FADE2B6F05F14B300081A16E /* check-idle.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = "check-idle.e"; path = "../../src/testsuite/check-idle.e"; sourceTree = SOURCE_ROOT; }; + FADE2B7005F14B300081A16E /* ngircd-test.conf */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = "ngircd-test.conf"; path = "../../src/testsuite/ngircd-test.conf"; sourceTree = SOURCE_ROOT; }; + FADE2B7105F14B300081A16E /* stress-A.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = "stress-A.e"; path = "../../src/testsuite/stress-A.e"; sourceTree = SOURCE_ROOT; }; + FADE2B7205F14B300081A16E /* stress-B.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = "stress-B.e"; path = "../../src/testsuite/stress-B.e"; sourceTree = SOURCE_ROOT; }; + FADE2B7305F14B300081A16E /* mode-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = "mode-test.e"; path = "../../src/testsuite/mode-test.e"; sourceTree = SOURCE_ROOT; }; + FADE2B7405F14B300081A16E /* start-server.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; name = "start-server.sh"; path = "../../src/testsuite/start-server.sh"; sourceTree = SOURCE_ROOT; }; + FADE2B7705F14B530081A16E /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ../../src/tool/Makefile.am; sourceTree = SOURCE_ROOT; }; + FADE2B7805F14B530081A16E /* tool.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = tool.c; path = ../../src/tool/tool.c; sourceTree = SOURCE_ROOT; }; + FADE2B7905F14B530081A16E /* tool.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = tool.h; path = ../../src/tool/tool.h; sourceTree = SOURCE_ROOT; }; + FADE2B7B05F14B9F0081A16E /* ngIRCd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ngIRCd; sourceTree = BUILT_PRODUCTS_DIR; }; + FADE2B8F05F14C6C0081A16E /* config.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = config.h; path = ../../src/config.h; sourceTree = SOURCE_ROOT; }; + FADE2B9005F14C6C0081A16E /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ../../src/Makefile.am; sourceTree = SOURCE_ROOT; }; + FADE2C9905F1511B0081A16E /* portabtest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = portabtest; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8DD76FAD0486AB0100D96B5E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + FA83332B0627391D00A909F0 /* libz.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FADE2C9605F1511B0081A16E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* ngIRCd */ = { + isa = PBXGroup; + children = ( + 08FB7795FE84155DC02AAC07 /* src */, + C6A0FF2B0290797F04C91782 /* doc */, + FADE2AA505F149580081A16E /* man */, + FADE2AA605F1495F0081A16E /* contrib */, + FADE2AC905F149D70081A16E /* Makefile.am */, + FADE2AAE05F1499A0081A16E /* AUTHORS */, + FADE2AAC05F1499A0081A16E /* ChangeLog */, + FADE2AA805F1499A0081A16E /* COPYING */, + FADE2AAD05F1499A0081A16E /* INSTALL */, + FADE2AA905F1499A0081A16E /* NEWS */, + FADE2AAA05F1499A0081A16E /* README */, + FADE2AA705F1499A0081A16E /* autogen.sh */, + FADE2AAB05F1499A0081A16E /* configure.in */, + FA2329E908C9E74D0093207B /* config.guess */, + FA2329EA08C9E74D0093207B /* config.sub */, + 1AB674ADFE9D54B511CA2CBB /* Products */, + ); + name = ngIRCd; + sourceTree = ""; + }; + 08FB7795FE84155DC02AAC07 /* src */ = { + isa = PBXGroup; + children = ( + FADE2B9005F14C6C0081A16E /* Makefile.am */, + FADE2AED05F14A6A0081A16E /* ngircd */, + FADE2AEE05F14A700081A16E /* portab */, + FADE2AEF05F14A760081A16E /* testsuite */, + FADE2AF005F14A840081A16E /* tool */, + FADE2B8F05F14C6C0081A16E /* config.h */, + ); + name = src; + sourceTree = ""; + }; + 1AB674ADFE9D54B511CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + FADE2B7B05F14B9F0081A16E /* ngIRCd */, + FADE2C9905F1511B0081A16E /* portabtest */, + FA83332A0627391D00A909F0 /* libz.dylib */, + ); + name = Products; + sourceTree = ""; + }; + C6A0FF2B0290797F04C91782 /* doc */ = { + isa = PBXGroup; + children = ( + FA2329FF08C9E8AC0093207B /* src */, + FADE2AB905F149C50081A16E /* Makefile.am */, + FADE2ABE05F149C50081A16E /* CVS.txt */, + FADE2AB805F149C50081A16E /* FAQ.txt */, + FADE2ABF05F149C50081A16E /* Platforms.txt */, + FADE2ABD05F149C50081A16E /* Protocol.txt */, + FADE2AB705F149C50081A16E /* README-BeOS.txt */, + FADE2ABA05F149C50081A16E /* README-AUX.txt */, + FADE2ABC05F149C50081A16E /* RFC.txt */, + FA8B5EFD08C9E4C900B781D4 /* SSL.txt */, + FA8B5EFE08C9E4C900B781D4 /* Zeroconf.txt */, + FADE2ABB05F149C50081A16E /* sample-ngircd.conf */, + ); + name = doc; + sourceTree = ""; + }; + FA2329FF08C9E8AC0093207B /* src */ = { + isa = PBXGroup; + children = ( + FA232A0408C9E8BF0093207B /* Makefile.am */, + FA232A0108C9E8BF0093207B /* Doxyfile */, + FA232A0208C9E8BF0093207B /* footer.inc.html */, + FA232A0308C9E8BF0093207B /* header.inc.html */, + FA232A0508C9E8BF0093207B /* ngircd-doc.css */, + ); + name = src; + sourceTree = ""; + }; + FADE2AA505F149580081A16E /* man */ = { + isa = PBXGroup; + children = ( + FADE2ACB05F149EA0081A16E /* Makefile.am */, + FADE2ACC05F149EA0081A16E /* ngircd.conf.5 */, + FADE2ACD05F149EA0081A16E /* ngircd.8 */, + ); + name = man; + sourceTree = ""; + }; + FADE2AA605F1495F0081A16E /* contrib */ = { + isa = PBXGroup; + children = ( + FA232A0708C9E8EC0093207B /* Makefile.am */, + FADE2AD205F149FD0081A16E /* Mac OS X */, + FADE2AD105F149F70081A16E /* Debian */, + FA232A0808C9E8EC0093207B /* ngircd.sh */, + FA232A0908C9E8EC0093207B /* ngircd.spec */, + FA232A0A08C9E8EC0093207B /* README */, + FA232A0B08C9E8EC0093207B /* systrace.policy */, + ); + name = contrib; + sourceTree = ""; + }; + FADE2AD105F149F70081A16E /* Debian */ = { + isa = PBXGroup; + children = ( + FADE2AD605F14A0B0081A16E /* Makefile.am */, + FADE2ADB05F14A0B0081A16E /* changelog */, + FADE2AD905F14A0B0081A16E /* compat */, + FADE2AD705F14A0B0081A16E /* control */, + FADE2AD305F14A0B0081A16E /* copyright */, + FADE2ADA05F14A0B0081A16E /* ngircd.default */, + FADE2AD805F14A0B0081A16E /* ngircd.init */, + FADE2AD505F14A0B0081A16E /* ngircd.postinst */, + FADE2AD405F14A0B0081A16E /* rules */, + ); + name = Debian; + sourceTree = ""; + }; + FADE2AD205F149FD0081A16E /* Mac OS X */ = { + isa = PBXGroup; + children = ( + FAC0DF4A05F25A150024C8CE /* Makefile.am */, + ); + name = "Mac OS X"; + sourceTree = ""; + }; + FADE2AED05F14A6A0081A16E /* ngircd */ = { + isa = PBXGroup; + children = ( + FADE2AF105F14A960081A16E /* Makefile.am */, + FA2329EC08C9E7A30093207B /* array.c */, + FA2329ED08C9E7A30093207B /* array.h */, + FADE2B0105F14A960081A16E /* channel.c */, + FADE2B0805F14A960081A16E /* channel.h */, + FADE2B2005F14A960081A16E /* client.c */, + FADE2B1305F14A960081A16E /* client.h */, + FADE2AFC05F14A960081A16E /* conf.c */, + FADE2B0305F14A960081A16E /* conf.h */, + FADE2B1E05F14A960081A16E /* conn-func.c */, + FADE2B2105F14A960081A16E /* conn-func.h */, + FADE2B0D05F14A960081A16E /* conn-zip.c */, + FADE2AF505F14A960081A16E /* conn-zip.h */, + FADE2B1205F14A960081A16E /* conn.c */, + FADE2AF905F14A960081A16E /* conn.h */, + FADE2B0205F14A960081A16E /* defines.h */, + FADE2B1C05F14A960081A16E /* hash.c */, + FADE2AFE05F14A960081A16E /* hash.h */, + FA2329F008C9E7C40093207B /* io.c */, + FA2329F108C9E7C40093207B /* io.h */, + FADE2B1805F14A960081A16E /* irc-channel.c */, + FADE2B0705F14A960081A16E /* irc-channel.h */, + FADE2B1D05F14A960081A16E /* irc-info.c */, + FADE2B0C05F14A960081A16E /* irc-info.h */, + FADE2AF405F14A960081A16E /* irc-login.c */, + FADE2B1105F14A960081A16E /* irc-login.h */, + FADE2AF805F14A960081A16E /* irc-mode.c */, + FADE2B0B05F14A960081A16E /* irc-mode.h */, + FADE2AF305F14A960081A16E /* irc-op.c */, + FADE2B1005F14A960081A16E /* irc-op.h */, + FADE2AF705F14A960081A16E /* irc-oper.c */, + FADE2B1505F14A960081A16E /* irc-oper.h */, + FADE2B0905F14A960081A16E /* irc-server.c */, + FADE2AF205F14A960081A16E /* irc-server.h */, + FADE2B0E05F14A960081A16E /* irc-write.c */, + FADE2B1405F14A960081A16E /* irc-write.h */, + FADE2AFD05F14A960081A16E /* irc.c */, + FADE2AFB05F14A960081A16E /* irc.h */, + FADE2B1A05F14A960081A16E /* lists.c */, + FADE2B0505F14A960081A16E /* lists.h */, + FADE2B1F05F14A960081A16E /* log.c */, + FADE2B0A05F14A960081A16E /* log.h */, + FADE2B0F05F14A960081A16E /* match.c */, + FADE2AF605F14A960081A16E /* match.h */, + FADE2AFA05F14A960081A16E /* messages.h */, + FADE2B1705F14A960081A16E /* ngircd.c */, + FADE2B0605F14A960081A16E /* ngircd.h */, + FADE2AFF05F14A960081A16E /* parse.c */, + FADE2B1905F14A960081A16E /* parse.h */, + FADE2B0405F14A960081A16E /* rendezvous.c */, + FADE2B1605F14A960081A16E /* rendezvous.h */, + FADE2B0005F14A960081A16E /* resolve.c */, + FADE2B1B05F14A960081A16E /* resolve.h */, + ); + name = ngircd; + sourceTree = ""; + }; + FADE2AEE05F14A700081A16E /* portab */ = { + isa = PBXGroup; + children = ( + FADE2B5605F14AB40081A16E /* Makefile.am */, + FADE2B5B05F14AB40081A16E /* ansi2knr.1 */, + FADE2B5505F14AB40081A16E /* ansi2knr.c */, + FADE2B5805F14AB40081A16E /* exp.h */, + FADE2B5405F14AB40081A16E /* imp.h */, + FADE2B5705F14AB40081A16E /* portab.h */, + FADE2B5A05F14AB40081A16E /* portabtest.c */, + FADE2B5305F14AB40081A16E /* splint.h */, + FA2329F408C9E8070093207B /* strdup.c */, + FADE2B5905F14AB40081A16E /* strlcpy.c */, + FADE2B5C05F14AB40081A16E /* vsnprintf.c */, + ); + name = portab; + sourceTree = ""; + }; + FADE2AEF05F14A760081A16E /* testsuite */ = { + isa = PBXGroup; + children = ( + FADE2B6C05F14B300081A16E /* Makefile.am */, + FA2329FB08C9E85D0093207B /* README */, + FADE2B6A05F14B300081A16E /* channel-test.e */, + FADE2B6F05F14B300081A16E /* check-idle.e */, + FADE2B6E05F14B300081A16E /* connect-test.e */, + FA2329FA08C9E8450093207B /* functions.inc */, + FADE2B6D05F14B300081A16E /* getpid.sh */, + FADE2B7305F14B300081A16E /* mode-test.e */, + FADE2B7005F14B300081A16E /* ngircd-test.conf */, + FADE2B7405F14B300081A16E /* start-server.sh */, + FADE2B6B05F14B300081A16E /* stop-server.sh */, + FADE2B7105F14B300081A16E /* stress-A.e */, + FADE2B7205F14B300081A16E /* stress-B.e */, + FADE2B6905F14B300081A16E /* stress-server.sh */, + FA2329FC08C9E8700093207B /* test-loop.sh */, + FADE2B6805F14B300081A16E /* tests.sh */, + FA2329FD08C9E87B0093207B /* wait-tests.sh */, + ); + name = testsuite; + sourceTree = ""; + }; + FADE2AF005F14A840081A16E /* tool */ = { + isa = PBXGroup; + children = ( + FADE2B7705F14B530081A16E /* Makefile.am */, + FADE2B7805F14B530081A16E /* tool.c */, + FADE2B7905F14B530081A16E /* tool.h */, + ); + name = tool; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 8DD76FAA0486AB0100D96B5E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + FADE2B2305F14A960081A16E /* irc-server.h in Headers */, + FADE2B2605F14A960081A16E /* conn-zip.h in Headers */, + FADE2B2705F14A960081A16E /* match.h in Headers */, + FADE2B2A05F14A960081A16E /* conn.h in Headers */, + FADE2B2B05F14A960081A16E /* messages.h in Headers */, + FADE2B2C05F14A960081A16E /* irc.h in Headers */, + FADE2B2F05F14A960081A16E /* hash.h in Headers */, + FADE2B3305F14A960081A16E /* defines.h in Headers */, + FADE2B3405F14A960081A16E /* conf.h in Headers */, + FADE2B3605F14A960081A16E /* lists.h in Headers */, + FADE2B3705F14A960081A16E /* ngircd.h in Headers */, + FADE2B3805F14A960081A16E /* irc-channel.h in Headers */, + FADE2B3905F14A960081A16E /* channel.h in Headers */, + FADE2B3B05F14A960081A16E /* log.h in Headers */, + FADE2B3C05F14A960081A16E /* irc-mode.h in Headers */, + FADE2B3D05F14A960081A16E /* irc-info.h in Headers */, + FADE2B4105F14A960081A16E /* irc-op.h in Headers */, + FADE2B4205F14A960081A16E /* irc-login.h in Headers */, + FADE2B4405F14A960081A16E /* client.h in Headers */, + FADE2B4505F14A960081A16E /* irc-write.h in Headers */, + FADE2B4605F14A960081A16E /* irc-oper.h in Headers */, + FADE2B4705F14A960081A16E /* rendezvous.h in Headers */, + FADE2B4A05F14A960081A16E /* parse.h in Headers */, + FADE2B4C05F14A960081A16E /* resolve.h in Headers */, + FADE2B5205F14A960081A16E /* conn-func.h in Headers */, + FADE2BBD05F14DEF0081A16E /* exp.h in Headers */, + FADE2BBF05F14DEF0081A16E /* imp.h in Headers */, + FADE2BC105F14DF10081A16E /* portab.h in Headers */, + FADE2CC205F152780081A16E /* tool.h in Headers */, + FA2329EF08C9E7A30093207B /* array.h in Headers */, + FA2329F308C9E7C40093207B /* io.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FADE2C5F05F1511B0081A16E /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + FADE2CB205F151490081A16E /* exp.h in Headers */, + FADE2CB305F151490081A16E /* imp.h in Headers */, + FA2329F708C9E81A0093207B /* portab.h in Headers */, + FA232A7D08C9F0480093207B /* config.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 8DD76FA90486AB0100D96B5E /* ngIRCd */ = { + isa = PBXNativeTarget; + buildConfigurationList = FA8B5E9508C9DB5600B781D4 /* Build configuration list for PBXNativeTarget "ngIRCd" */; + buildPhases = ( + 8DD76FAA0486AB0100D96B5E /* Headers */, + 8DD76FAB0486AB0100D96B5E /* Sources */, + 8DD76FAD0486AB0100D96B5E /* Frameworks */, + 8DD76FAE0486AB0100D96B5E /* Rez */, + 8DD76FAF0486AB0100D96B5E /* CopyFiles */, + ); + buildRules = ( + ); + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = "SYSCONFDIR='\"/opt/ngircd/etc\"'"; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VALUE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PRODUCT_NAME = ngIRCd; + WARNING_CFLAGS = "-Wall"; + }; + dependencies = ( + ); + name = ngIRCd; + productInstallPath = "$(HOME)/bin"; + productName = ngIRCd; + productReference = FADE2B7B05F14B9F0081A16E /* ngIRCd */; + productType = "com.apple.product-type.tool"; + }; + FADE2C5E05F1511B0081A16E /* portabtest */ = { + isa = PBXNativeTarget; + buildConfigurationList = FA8B5E9908C9DB5600B781D4 /* Build configuration list for PBXNativeTarget "portabtest" */; + buildPhases = ( + FADE2C5F05F1511B0081A16E /* Headers */, + FADE2C7C05F1511B0081A16E /* Sources */, + FADE2C9605F1511B0081A16E /* Frameworks */, + FADE2C9705F1511B0081A16E /* Rez */, + FADE2C9805F1511B0081A16E /* CopyFiles */, + ); + buildRules = ( + ); + buildSettings = { + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VALUE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PRODUCT_NAME = portabtest; + WARNING_CFLAGS = "-Wall"; + }; + dependencies = ( + ); + name = portabtest; + productInstallPath = "$(HOME)/bin"; + productName = ngIRCd; + productReference = FADE2C9905F1511B0081A16E /* portabtest */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = FA8B5E9D08C9DB5600B781D4 /* Build configuration list for PBXProject "ngIRCd" */; + buildSettings = { + }; + buildStyles = ( + 014CEA520018CE5811CA2923 /* Development */, + FA2002770807EE21005A2F4C /* Deployment */, + ); + hasScannedForEncodings = 1; + mainGroup = 08FB7794FE84155DC02AAC07 /* ngIRCd */; + projectDirPath = ""; + targets = ( + 8DD76FA90486AB0100D96B5E /* ngIRCd */, + FADE2C5E05F1511B0081A16E /* portabtest */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXRezBuildPhase section */ + 8DD76FAE0486AB0100D96B5E /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FADE2C9705F1511B0081A16E /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8DD76FAB0486AB0100D96B5E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FADE2B2405F14A960081A16E /* irc-op.c in Sources */, + FADE2B2505F14A960081A16E /* irc-login.c in Sources */, + FADE2B2805F14A960081A16E /* irc-oper.c in Sources */, + FADE2B2905F14A960081A16E /* irc-mode.c in Sources */, + FADE2B2D05F14A960081A16E /* conf.c in Sources */, + FADE2B2E05F14A960081A16E /* irc.c in Sources */, + FADE2B3005F14A960081A16E /* parse.c in Sources */, + FADE2B3105F14A960081A16E /* resolve.c in Sources */, + FADE2B3205F14A960081A16E /* channel.c in Sources */, + FADE2B3505F14A960081A16E /* rendezvous.c in Sources */, + FADE2B3A05F14A960081A16E /* irc-server.c in Sources */, + FADE2B3E05F14A960081A16E /* conn-zip.c in Sources */, + FADE2B3F05F14A960081A16E /* irc-write.c in Sources */, + FADE2B4005F14A960081A16E /* match.c in Sources */, + FADE2B4305F14A960081A16E /* conn.c in Sources */, + FADE2B4805F14A960081A16E /* ngircd.c in Sources */, + FADE2B4905F14A960081A16E /* irc-channel.c in Sources */, + FADE2B4B05F14A960081A16E /* lists.c in Sources */, + FADE2B4D05F14A960081A16E /* hash.c in Sources */, + FADE2B4E05F14A960081A16E /* irc-info.c in Sources */, + FADE2B4F05F14A960081A16E /* conn-func.c in Sources */, + FADE2B5005F14A960081A16E /* log.c in Sources */, + FADE2B5105F14A960081A16E /* client.c in Sources */, + FADE2BC305F14DF40081A16E /* strlcpy.c in Sources */, + FADE2BC505F14DF50081A16E /* vsnprintf.c in Sources */, + FADE2CC005F152770081A16E /* tool.c in Sources */, + FA2329EE08C9E7A30093207B /* array.c in Sources */, + FA2329F208C9E7C40093207B /* io.c in Sources */, + FA2329F508C9E8070093207B /* strdup.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FADE2C7C05F1511B0081A16E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FADE2CB405F151490081A16E /* portabtest.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + FA8B5E9608C9DB5600B781D4 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + PRODUCT_NAME = ngIRCd; + ZERO_LINK = YES; + }; + name = Development; + }; + FA8B5E9708C9DB5600B781D4 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_OPTIMIZATION_LEVEL = 2; + PRODUCT_NAME = ngIRCd; + ZERO_LINK = NO; + }; + name = Deployment; + }; + FA8B5E9A08C9DB5600B781D4 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + PRODUCT_NAME = portabtest; + ZERO_LINK = YES; + }; + name = Development; + }; + FA8B5E9B08C9DB5600B781D4 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_OPTIMIZATION_LEVEL = 2; + GCC_TREAT_WARNINGS_AS_ERRORS = NO; + PRODUCT_NAME = portabtest; + ZERO_LINK = NO; + }; + name = Deployment; + }; + FA8B5E9E08C9DB5600B781D4 /* Development */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = "SYSCONFDIR='\"/opt/ngircd/etc\"'"; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_PEDANTIC = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES; + GCC_WARN_UNINITIALIZED_AUTOS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VALUE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + WARNING_CFLAGS = "-Wall"; + }; + name = Development; + }; + FA8B5E9F08C9DB5600B781D4 /* Deployment */ = { + isa = XCBuildConfiguration; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = "SYSCONFDIR='\"/opt/ngircd/etc\"'"; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_MISSING_PARENTHESES = YES; + GCC_WARN_PEDANTIC = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_SIGN_COMPARE = YES; + GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES; + GCC_WARN_UNINITIALIZED_AUTOS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + GCC_WARN_UNUSED_VALUE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + WARNING_CFLAGS = "-Wall"; + }; + name = Deployment; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + FA8B5E9508C9DB5600B781D4 /* Build configuration list for PBXNativeTarget "ngIRCd" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA8B5E9608C9DB5600B781D4 /* Development */, + FA8B5E9708C9DB5600B781D4 /* Deployment */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Development; + }; + FA8B5E9908C9DB5600B781D4 /* Build configuration list for PBXNativeTarget "portabtest" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA8B5E9A08C9DB5600B781D4 /* Development */, + FA8B5E9B08C9DB5600B781D4 /* Deployment */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Development; + }; + FA8B5E9D08C9DB5600B781D4 /* Build configuration list for PBXProject "ngIRCd" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA8B5E9E08C9DB5600B781D4 /* Development */, + FA8B5E9F08C9DB5600B781D4 /* Deployment */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Development; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} Index: doc/CVS.txt =================================================================== RCS file: /srv/cvs/ngircd/ngircd/doc/CVS.txt,v retrieving revision 1.7 retrieving revision 1.8.2.1 diff -u -r1.7 -r1.8.2.1 --- doc/CVS.txt 26 Mar 2003 22:34:33 -0000 1.7 +++ doc/CVS.txt 2 Aug 2006 09:04:20 -0000 1.8.2.1 @@ -1,7 +1,7 @@ ngIRCd - Next Generation IRC Server - (c)2001-2003 by Alexander Barton, + (c)2001-2006 Alexander Barton, alex@barton.de, http://www.barton.de/ ngIRCd is free software and published under the @@ -21,18 +21,19 @@ Login to the CVS server: - $ cvs -d:pserver:anonymous@arthur.ath.cx:/usr/local/CVS/ngircd login + $ cvs -d:pserver:anonymous@ngircd.barton.de:/srv/cvs/ngircd login Use "anonymous" as user name and no password (just hit Return). Now you can check out the sources: - $ cvs -d:pserver:anonymous@arthur.ath.cx:/usr/local/CVS/ngircd checkout ngircd + $ cvs -d:pserver:anonymous@ngircd.barton.de:/srv/cvs/ngircd checkout ngircd Thereby a new folder "ngircd" will be created containing all the individual -source files. +source files. (Substitute the last "ngircd" with "website" to check out all +the files of the homepage of ngIRCd.) -This is the "working folder", all CVS commands will be executed from within -this folder in the future. +The newly created folder ("ngircd" or "website") is the "working folder", all +CVS commands will be executed from within this folder in the future. Please note: When checking out a fresh copy of ngIRCd from CVS, the configure script doesn't exist; you have to run the autogen.sh shell script @@ -46,11 +47,11 @@ You can update a single file or the complete source tree. -III. Write Access -~~~~~~~~~~~~~~~~~ +II. Write Access +~~~~~~~~~~~~~~~~ If you want to contribute a couple of patches and write access to the CVS repository would be handy, please contact Alex Barton, . -- -$Id: CVS.txt,v 1.7 2003/03/26 22:34:33 alex Exp $ +$Id: CVS.txt,v 1.8.2.1 2006/08/02 09:04:20 alex Exp $ Index: doc/FAQ.txt =================================================================== RCS file: /srv/cvs/ngircd/ngircd/doc/FAQ.txt,v retrieving revision 1.7.4.1 retrieving revision 1.11 diff -u -r1.7.4.1 -r1.11 --- doc/FAQ.txt 9 Jul 2005 14:41:39 -0000 1.7.4.1 +++ doc/FAQ.txt 9 Dec 2005 21:14:56 -0000 1.11 @@ -62,6 +62,15 @@ is to either disable chroot support or to link against dietlibc instead of glibc. (tnx to Sebastian Siewior) +Q: I am running Linux and ngircd dies on startup with the follwing errors: + IO subsystem: epoll (hint size 100, initial maxfd 100, masterfd -1). + Cannot initialize IO routines: Function not implemented + Server isn't listening on a single port! + ngircd exiting due to fatal errors! +A: epoll is only supported on 2.6 Linux kernels. Either use a 2.6 kernel, or + re-run configure with the --without-epoll parameter. After configure + completed, you should see select() being listed as IO backend: + '(I/O backend: "select()"'). IV. Bugs!? ~~~~~~~~~~ @@ -76,4 +85,4 @@ -- -$Id: FAQ.txt,v 1.7.4.1 2005/07/09 14:41:39 alex Exp $ +$Id: FAQ.txt,v 1.11 2005/12/09 21:14:56 fw Exp $ Index: doc/Makefile.am =================================================================== RCS file: /srv/cvs/ngircd/ngircd/doc/Makefile.am,v retrieving revision 1.18 retrieving revision 1.21 diff -u -r1.18 -r1.21 --- doc/Makefile.am 27 Apr 2005 07:52:29 -0000 1.18 +++ doc/Makefile.am 29 Nov 2005 20:59:57 -0000 1.21 @@ -9,18 +9,17 @@ # Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste # der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS. # -# $Id: Makefile.am,v 1.18 2005/04/27 07:52:29 alex Exp $ +# $Id: Makefile.am,v 1.21 2005/11/29 20:59:57 alex Exp $ # -EXTRA_DIST = CVS.txt FAQ.txt Protocol.txt Platforms.txt \ - README-AUX.txt README-BeOS.txt RFC.txt sample-ngircd.conf +SUBDIRS = src + +EXTRA_DIST = CVS.txt FAQ.txt Protocol.txt Platforms.txt README-AUX.txt \ + README-BeOS.txt RFC.txt Zeroconf.txt sample-ngircd.conf maintainer-clean-local: rm -f Makefile Makefile.in -distclean-local: - rm -rf src - docdir = $(datadir)/doc/$(PACKAGE) documents = $(EXTRA_DIST) ../AUTHORS ../COPYING ../ChangeLog ../INSTALL \ @@ -39,4 +38,7 @@ uninstall-hook: rm -rf $(DESTDIR)$(docdir) +srcdoc: + make -C src srcdoc + # -eof- Index: doc/Platforms.txt =================================================================== RCS file: /srv/cvs/ngircd/ngircd/doc/Platforms.txt,v retrieving revision 1.13.2.2 retrieving revision 1.14 diff -u -r1.13.2.2 -r1.14 --- doc/Platforms.txt 9 Jul 2005 11:16:38 -0000 1.13.2.2 +++ doc/Platforms.txt 7 May 2006 11:07:13 -0000 1.14 @@ -1,7 +1,7 @@ ngIRCd - Next Generation IRC Server - (c)2001-2005 Alexander Barton + (c)2001-2004 Alexander Barton alex@barton.de, http://www.barton.de/ ngIRCd is free software and published under the @@ -26,22 +26,23 @@ | | | | Platform Compiler ngIRCd Date Tester C M T R See --------------------------- ------------ ---------- -------- ------ - - - - --- +alpha/unknown/netbsd3.0 gcc 3.3.3 CVSHEAD 06-05-07 fw Y Y Y Y (3) hppa/unknown/openbsd3.5 gcc 2.95.3 CVSHEAD 04-05-25 alex Y Y Y Y hppa1.1/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y -hppa2.0/unknown/linux-gnu gcc 3.3.5 0.9.x-CVS 05-06-27 alex Y Y Y Y i386/pc/solaris2.9 gcc 3.2.2 CVSHEAD 04-02-24 alex Y Y Y Y i386/unknown/freebsd5.2.1 gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y +i386/unknown/freebsd6.1 gcc 3.4.4 CVSHEAD 06-05-07 fw Y Y Y Y (4) i386/unknown/gnu0.3 gcc 3.3.3 0.8.0 04-05-30 alex Y Y n Y i386/unknown/netbsdelf1.6.1 gcc 2.95.3 CVSHEAD 04-02-24 alex Y Y Y Y -i686/pc/cygwin gcc 3.3.1 0.9.x-CVS 05-07-08 alex Y Y n Y +i686/pc/cygwin gcc 3.3.1 0.8.0 04-05-30 alex Y Y n Y i686/pc/linux-gnu gcc 2.95.4 0.8.0 04-05-30 alex Y Y Y Y (1) -i686/pc/linux-gnu gcc 3.3.5 0.9.x-CVS 05-07-09 alex Y Y Y Y (1) +i686/pc/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y (1) m68k/apple/aux3.1.1 Orig. A/UX 0.7.x-CVS 03-04-22 alex Y Y Y Y (2) m68k/hp/hp-ux9.10 Orig. HPUX 0.7.x-CVS 03-04-30 goetz Y Y Y Y m88k/dg/dgux5.4R3.10 gcc 2.5.8 CVSHEAD 04-03-15 alex Y Y ? ? powerpc/apple/darwin6.5 gcc 3.1 0.7.x-CVS 03-04-23 alex Y Y Y Y powerpc/apple/darwin7.4.0 gcc 3.3 0.8.0 04-05-30 alex Y Y Y Y -powerpc/apple/darwin8.1.0 gcc 4.0 0.9.x-CVS 05-06-27 alex Y Y Y Y +powerpc/apple/darwin7.9.0 gcc 3.3 CVSHEAD 06-05-07 fw Y Y Y Y (3) powerpc/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y 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 @@ -59,7 +60,7 @@ (2) This compiler is an pre-ANSI C compiler, therefore the source code is automatically converted using the included ansi2knr tool while building. - - +(3) kqueue io backend +(4) 6.1-PRERELEASE -- -$Id: Platforms.txt,v 1.13.2.2 2005/07/09 11:16:38 alex Exp $ +$Id: Platforms.txt,v 1.14 2006/05/07 11:07:13 fw Exp $ Index: doc/Protocol.txt =================================================================== RCS file: /srv/cvs/ngircd/ngircd/doc/Protocol.txt,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- doc/Protocol.txt 25 Apr 2004 15:44:10 -0000 1.12 +++ doc/Protocol.txt 27 Aug 2005 19:00:06 -0000 1.13 @@ -93,7 +93,7 @@ II.2 Exchange channel-modes, topics, and persistent channels Command: CHANINFO - Parameters: + [] + Parameters: + [] Used by: servers only CHANINFO is used by servers to inform each other about a channel: its @@ -115,4 +115,4 @@ -- -$Id: Protocol.txt,v 1.12 2004/04/25 15:44:10 alex Exp $ +$Id: Protocol.txt,v 1.13 2005/08/27 19:00:06 alex Exp $ Index: doc/README-AUX.txt =================================================================== RCS file: /srv/cvs/ngircd/ngircd/doc/README-AUX.txt,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- doc/README-AUX.txt 24 Jun 2005 20:59:13 -0000 1.9 +++ doc/README-AUX.txt 23 Jul 2006 12:19:57 -0000 1.10 @@ -22,7 +22,7 @@ - GNU sed Source: http://www.rezepte-im-web.de/appleux/sed-3.02.tar.gz - ftp://arthur.barton.de/pub/UNIX/AUX/Tools/sed-3.02.tar.gz + ftp://arthur.barton.de/pub/unix/aux/tools/sed-3.02.tar.gz A/UX comes with /bin/sed which isn't supporting all functions needed by GNU automake/autoconf. @@ -34,7 +34,7 @@ - libUTIL.a Source: ftp://ftp.mayn.de/pub/really_old_stuff/apple/apple_unix/Sys_stuff/libUTIL-2.1.tar.gz> - ftp://arthur.barton.de/pub/UNIX/AUX/Libraries/libUTIL-2.1.tar.gz + ftp://arthur.barton.de/pub/unix/aux/libraries/libUTIL-2.1.tar.gz This library contains functions that are common on other UNIX systems but not on A/UX e.g. memmove(), strerror() und strdup(). @@ -50,7 +50,7 @@ (so 'configure' uses its own shell script) or use a fully functionable one. There's at least one binary "out there" causing problems. The one of the GNU fileutils works fine: - ftp://arthur.barton.de/pub/UNIX/AUX/Software/Tools/fileutils-4.0.tar.gz + ftp://arthur.barton.de/pub/unix/aux/tools/fileutils-4.0.tar.gz - The precompiled binary of the old 'bash' shouldn't be installed within /bin (better do this in /usr/local/bin) because 'configure' would @@ -64,4 +64,4 @@ even if you don't use ngIRCd. -- -$Id: README-AUX.txt,v 1.9 2005/06/24 20:59:13 alex Exp $ +$Id: README-AUX.txt,v 1.10 2006/07/23 12:19:57 alex Exp $ Index: doc/Zeroconf.txt =================================================================== RCS file: doc/Zeroconf.txt diff -N doc/Zeroconf.txt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ doc/Zeroconf.txt 2 Aug 2006 09:04:20 -0000 1.1.2.1 @@ -0,0 +1,40 @@ + + ngIRCd - Next Generation IRC Server + + (c)2001-2006 Alexander Barton + alex@barton.de, http://www.barton.de/ + + ngIRCd is free software and published under the + terms of the GNU General Public License. + + -- Zeroconf.txt -- + + +ngIRCd supports one aspect of Zeroconf Networking[1]: Multicast DNS (mDNS[2]) +with DNS Service Discovery (DNS-SD[3]). + +To use this features you can use one of two APIs: + + a) Apple "Bonjour" API as used by Mac OS X, + b) the Howl[4] Zeroconf library or the Howl compatibility layer + of the newer Avahi[5] library. + +When calling the configure script using the "--with-zeroconf" switch the +avalable API will be autodetected and the required additional libraries will +be linked to the ngircd binary as required. + +ngIRCd then registers a DNS-SD service for each port it is listening on using +the service type "_ircu._tcp.". + + +Links: + + [1] http://www.zeroconf.org/ + [2] http://www.multicastdns.org/ + [3] http://www.dns-sd.org/ + [4] http://www.porchdogsoft.com/products/howl/ + [5] http://avahi.org/ + + +-- +$Id: Zeroconf.txt,v 1.1.2.1 2006/08/02 09:04:20 alex Exp $ Index: doc/sample-ngircd.conf =================================================================== RCS file: /srv/cvs/ngircd/ngircd/doc/sample-ngircd.conf,v retrieving revision 1.33 retrieving revision 1.37 diff -u -r1.33 -r1.37 --- doc/sample-ngircd.conf 15 Mar 2005 16:58:01 -0000 1.33 +++ doc/sample-ngircd.conf 9 Apr 2006 12:27:23 -0000 1.37 @@ -1,4 +1,4 @@ -# $Id: sample-ngircd.conf,v 1.33 2005/03/15 16:58:01 alex Exp $ +# $Id: sample-ngircd.conf,v 1.37 2006/04/09 12:27:23 alex Exp $ # # This is a sample configuration file for the ngIRCd, which must be adepted @@ -7,25 +7,25 @@ # Comments are started with "#" or ";". # # Use "ngircd --configtest" (see manual page ngircd(8)) to validate that the -# server interpreted the configuration file as expected! +# server interprets the configuration file as expected! # [Global] # The [Global] section of this file is used to define the main # configuration of the server, like the server name and the ports # on which the server should be listening. - + # Server name in the IRC network, must contain at least one dot # (".") and be unique in the IRC network. Required! Name = irc.the.net - + # Info text of the server. This will be shown by WHOIS and # LINKS requests for example. Info = Server Info Text # Global password for all users needed to connect to the server ;Password = abc - + # Information about the server and the administrator, used by the # ADMIN command. Not required by server but by RFC! ;AdminInfo1 = Description @@ -39,7 +39,7 @@ # IP address on which the server should listen. (Default: empty, # so the server listens on all IP addresses of the system) ;Listen = 1.2.3.4 - + # Text file with the "message of the day" (MOTD). This message will # be shown to all users connecting to the server: ;MotdFile = /usr/local/etc/ngircd.motd @@ -92,11 +92,11 @@ # Mask IRC Operator mode requests as if they were coming from the # server? (This is a compatibility hack for ircd-irc2 servers) ;OperServerMode = no - + # Maximum number of simultaneous connection the server is allowed # to accept (<=0: unlimited): ;MaxConnections = -1 - + # Maximum number of simultaneous connections from a single IP address # the server will accept (<=0: unlimited): ;MaxConnectionsIP = 5 @@ -107,7 +107,7 @@ [Operator] # [Operator] sections are used to define IRC Operators. There may be # more than one [Operator] block, one for each local operator. - + # ID of the operator (may be different of the nick name) ;Name = TheOper @@ -125,7 +125,7 @@ # configure a port for the connection, then this ngircd tries to # connect to to the other server on the given port; if not it waits # for the other server to connect. - # There may be more than one server block. + # There may be more than one server block, one for each server. # # Server Groups: # The ngIRCd allows "server groups": You can assign an "ID" to every @@ -133,16 +133,18 @@ # group won't answer, the ngIRCd tries to connect to the next server # in the given group. But the ngircd never tries to connect to two # servers with the same group ID. - - # IRC name of the server + + # IRC name of the remote server, must match the "Name" variable in + # the [Global] section of the other server (when using ngIRCd). ;Name = irc2.the.net - - # Internet host name of the peer + + # Internet host name or IP address of the peer (only required when + # this server should establish the connection). ;Host = connect-to-host.the.net # Port of the server to which the ngIRCd should connect. If you # assign no port the ngIRCd waits for incoming connections. - ;Port = 6666 + ;Port = 6667 # Own password for the connection. This password has to be configured # as "PeerPassword" on the other server. @@ -151,7 +153,7 @@ # Foreign password for this connection. This password has to be # configured as "MyPassword" on the other server. ;PeerPassword = PeerSecret - + # Group of this server (optional) ;Group = 123 @@ -164,14 +166,14 @@ # persist when there are no more members left. # Persistent channels are marked with the mode 'P', which can be set # and unset by IRC operators like other modes on the fly. - # There may be more than one [Channel] block. - + # There may be more than one [Channel] block, one for each channel. + # Name of the channel ;Name = #TheName # Topic for this channel ;Topic = a great topic - + # Initial channel modes ;Modes = tn Index: doc/src/Doxyfile =================================================================== RCS file: doc/src/Doxyfile diff -N doc/src/Doxyfile --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ doc/src/Doxyfile 23 Jul 2005 00:48:38 -0000 1.2 @@ -0,0 +1,153 @@ +# +# ngIRCd -- The Next Generation IRC Daemon +# Copyright (c)2001-2005 Alexander Barton (alex@barton.de) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# Please read the file COPYING, README and AUTHORS for more information. +# +# $Id: Doxyfile,v 1.2 2005/07/23 00:48:38 alex Exp $ +# + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for ngIRCd. + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = ngIRCd + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = . + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = ../.. + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that +# contain documented source files. You may enter file names like "myfile.cpp" +# or directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../../src + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +#--------------------------------------------------------------------------- +# Output formats +#--------------------------------------------------------------------------- + +GENERATE_HTML = YES + +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = header.inc.html +HTML_FOOTER = footer.inc.html +HTML_STYLESHEET = ngircd-doc.css + +GENERATE_HTMLHELP = NO +GENERATE_LATEX = NO +GENERATE_RTF = NO +GENERATE_MAN = NO +GENERATE_XML = NO +GENERATE_AUTOGEN_DEF = NO +GENERATE_PERLMOD = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = CONN_MODULE __client_c__ + +# -eof- Index: doc/src/Makefile.am =================================================================== RCS file: doc/src/Makefile.am diff -N doc/src/Makefile.am --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ doc/src/Makefile.am 8 Apr 2006 16:35:03 -0000 1.2 @@ -0,0 +1,25 @@ +# +# ngIRCd -- The Next Generation IRC Daemon +# Copyright (c)2001-2006 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 +# the Free Software Foundation; either version 2 of the License, or +# (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 $ +# + +maintainer-clean-local: + rm -f Makefile Makefile.in + +distclean-local: + rm -f html + +srcdoc: + @doxygen --version >/dev/null 2>&1 \ + || ( echo; echo "Error: \"doxygen\" not found!"; echo; exit 1 ) + doxygen + +# -eof- Index: doc/src/footer.inc.html =================================================================== RCS file: doc/src/footer.inc.html diff -N doc/src/footer.inc.html --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ doc/src/footer.inc.html 22 Jul 2005 20:58:22 -0000 1.1 @@ -0,0 +1,11 @@ + + +

+ ngIRCd + Homepage, + CVS-Repository, + Bug-Tracker. +

+ + + Index: doc/src/header.inc.html =================================================================== RCS file: doc/src/header.inc.html diff -N doc/src/header.inc.html --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ doc/src/header.inc.html 22 Jul 2005 20:58:22 -0000 1.1 @@ -0,0 +1,10 @@ + + + + + + ngIRCd Source Documentation + + + + Index: doc/src/ngircd-doc.css =================================================================== RCS file: doc/src/ngircd-doc.css diff -N doc/src/ngircd-doc.css --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ doc/src/ngircd-doc.css 22 Jul 2005 21:23:22 -0000 1.2 @@ -0,0 +1,77 @@ +/* + * Cascading Style Sheet for the ngIRCd source documentation + * + * $Id: ngircd-doc.css,v 1.2 2005/07/22 21:23:22 alex Exp $ + */ + +BODY { + background-color: white; + color: black; + margin: 30px; + font-family: Geneva, sans-serif; + font-size: 12px; +} + +A:visited { color: purple; background: transparent; } +A:link { color: navy; background: transparent; } +A:active { color: red; background: transparent; } +A:hover { background: #ffa; } + +H1, H2, H3 { + font-family: Verdana, sans-serif; + background-color: white; + color: #005555; +} +H1 { margin-bottom: 10px; } +H2 { + margin-top: 20px; + margin-bottom: 10px; +} + +P, LI, TD, TH, DT { + font-family: Geneva, sans-serif; + font-size: 12px; + line-height: 1.2 +} + +DD { margin-bottom: 1em; } + +UL { list-style-type: square; } + +HR { margin: 2em 0px; } + +BODY>TABLE { padding: 1em 0px; } + +TD.mdRow { + border: 1px dotted silver; + background-color: #fff9dd; +} + +TD.md { font-weight: bold; } + +TD.memItemLeft { padding-top: 4px; } +TD.memItemRight { padding-top: 4px; } +TD.mdescRight { font-style: italic; } + +DIV.qindex { + background-color: #eee; + border: 1px dotted silver; + padding: 3px; + margin-bottom: 2px; +} + +DIV.nav { + margin: 1em 0px; +} + +HR.footer { margin-top: 50px; } + +.comment { + color: gray; + font-style: italic; +} +.preprocessor { color: #f90; } +.keyword, .keywordflow, .keywordtype { color: red; } +.stringliteral { color: green; } + +/* -eof- */ Index: man/ngircd.8 =================================================================== RCS file: /srv/cvs/ngircd/ngircd/man/ngircd.8,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- man/ngircd.8 4 Jun 2005 13:39:20 -0000 1.10 +++ man/ngircd.8 12 Aug 2005 13:20:54 -0000 1.11 @@ -1,7 +1,7 @@ .\" -.\" $Id: ngircd.8,v 1.10 2005/06/04 13:39:20 alex Exp $ +.\" $Id: ngircd.8,v 1.11 2005/08/12 13:20:54 alex Exp $ .\" -.TH ngircd 8 "Juni 2005" ngircd "ngIRCd Manual" +.TH ngircd 8 "August 2005" ngircd "ngIRCd Manual" .SH NAME ngIRCd \- the next generation IRC daemon .SH SYNOPSIS @@ -70,8 +70,8 @@ .UE .br Homepage: -.UR http://arthur.ath.cx/~alex/ngircd/ -http://arthur.ath.cx/~alex/ngircd/ +.UR http://ngircd.barton.de/ +http://ngircd.barton.de/ .UE .SH "SEE ALSO" .BR ngircd.conf (5), Index: man/ngircd.conf.5 =================================================================== RCS file: /srv/cvs/ngircd/ngircd/man/ngircd.conf.5,v retrieving revision 1.18 retrieving revision 1.20 diff -u -r1.18 -r1.20 --- man/ngircd.conf.5 4 Jun 2005 13:39:20 -0000 1.18 +++ man/ngircd.conf.5 2 Sep 2005 14:39:00 -0000 1.20 @@ -1,16 +1,17 @@ .\" -.\" $Id: ngircd.conf.5,v 1.18 2005/06/04 13:39:20 alex Exp $ +.\" $Id: ngircd.conf.5,v 1.20 2005/09/02 14:39:00 fw Exp $ .\" -.TH ngircd.conf 5 "Juni 2005" ngircd "ngIRCd Manual" +.TH ngircd.conf 5 "August 2005" ngircd "ngIRCd Manual" .SH NAME ngircd.conf \- configuration file of ngIRCd .SH SYNOPSIS .B /usr/local/etc/ngircd.conf .SH DESCRIPTION .BR ngircd.conf -is the configuration file for +is the configuration file of the .BR ngircd (8) -which you should adept to your local preferences and needs. +Internet Relay Chat (IRC) daemon which you should adept to your local +preferences and needs. .SH "FILE FORMAT" The file consists of sections and parameters. A section begins with the name of the section in square brackets and continues until the next section @@ -24,8 +25,8 @@ .I value .RE .PP -Any line beginning with a semicolon (';') or a hash ('#') character is -treated as a comment and ignored. +Empty lines and any line beginning with a semicolon (';') or a hash ('#') +character is treated as a comment and will be ignored. .PP The file format is line-based - that means, each newline-terminated line represents either a comment, a section name or a parameter. @@ -200,7 +201,7 @@ .TP \fBMyPassword\fR Own password for this connection. This password has to be configured as -"PeerPassword" on the other server. +"PeerPassword" on the other server. Must not have ':' as first character. .TP \fBPeerPassword\fR Foreign password for this connection. This password has to be configured as @@ -241,8 +242,8 @@ .UE .br Homepage: -.UR http://arthur.ath.cx/~alex/ngircd/ -http://arthur.ath.cx/~alex/ngircd/ +.UR http://ngircd.barton.de/ +http://ngircd.barton.de/ .UE .SH "SEE ALSO" .BR ngircd (8) Index: src/Doxyfile =================================================================== RCS file: src/Doxyfile diff -N src/Doxyfile --- src/Doxyfile 9 Apr 2005 12:21:51 -0000 1.1 +++ /dev/null 1 Jan 1970 00:00:00 -0000 @@ -1,137 +0,0 @@ -# -# ngIRCd -- The Next Generation IRC Daemon -# Copyright (c)2001-2005 Alexander Barton (alex@barton.de) -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# Please read the file COPYING, README and AUTHORS for more information. -# -# $Id: Doxyfile,v 1.1 2005/04/09 12:21:51 alex Exp $ -# - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for ngIRCd. - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = ngIRCd - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = ../doc/src - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explicit @brief command for a brief description. - -JAVADOC_AUTOBRIEF = YES - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = YES - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that -# contain documented source files. You may enter file names like "myfile.cpp" -# or directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = ngircd portab tool - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = YES - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = YES - -#--------------------------------------------------------------------------- -# Output formats -#--------------------------------------------------------------------------- - -GENERATE_HTML = YES -GENERATE_HTMLHELP = NO -GENERATE_LATEX = NO -GENERATE_RTF = NO -GENERATE_MAN = NO -GENERATE_XML = NO -GENERATE_AUTOGEN_DEF = NO -GENERATE_PERLMOD = NO - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = CONN_MODULE __client_c__ - -# -eof- Index: src/Makefile.am =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/Makefile.am,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- src/Makefile.am 9 Apr 2005 12:22:41 -0000 1.6 +++ src/Makefile.am 22 Jul 2005 21:01:03 -0000 1.7 @@ -8,7 +8,7 @@ # (at your option) any later version. # Please read the file COPYING, README and AUTHORS for more information. # -# $Id: Makefile.am,v 1.6 2005/04/09 12:22:41 alex Exp $ +# $Id: Makefile.am,v 1.7 2005/07/22 21:01:03 alex Exp $ # SUBDIRS = portab tool ngircd testsuite @@ -16,9 +16,4 @@ maintainer-clean-local: rm -f Makefile Makefile.in config.h config.h.in stamp-h.in -srcdoc: - @doxygen --version >/dev/null 2>&1 \ - || ( echo; echo "Error: \"doxygen\" not found!"; echo; exit 1 ) - doxygen - # -eof- Index: src/ngircd/Makefile.am =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/Makefile.am,v retrieving revision 1.46 retrieving revision 1.49 diff -u -r1.46 -r1.49 --- src/ngircd/Makefile.am 23 May 2005 00:11:15 -0000 1.46 +++ src/ngircd/Makefile.am 11 Mar 2006 01:48:50 -0000 1.49 @@ -8,7 +8,7 @@ # (at your option) any later version. # Please read the file COPYING, README and AUTHORS for more information. # -# $Id: Makefile.am,v 1.46 2005/05/23 00:11:15 alex Exp $ +# $Id: Makefile.am,v 1.49 2006/03/11 01:48:50 alex Exp $ # AUTOMAKE_OPTIONS = ../portab/ansi2knr @@ -20,20 +20,20 @@ sbin_PROGRAMS = ngircd -ngircd_SOURCES = ngircd.c channel.c client.c conf.c conn.c conn-zip.c conn-func.c \ - hash.c irc.c irc-channel.c irc-info.c irc-login.c irc-mode.c irc-op.c \ - irc-oper.c irc-server.c irc-write.c lists.c log.c match.c parse.c \ - rendezvous.c resolve.c +ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.c \ + conn-zip.c hash.c io.c irc.c irc-channel.c irc-info.c irc-login.c \ + irc-mode.c irc-op.c irc-oper.c irc-server.c irc-write.c lists.c log.c \ + match.c parse.c rendezvous.c resolve.c ngircd_LDFLAGS = -L../portab -L../tool ngircd_LDADD = -lngportab -lngtool -noinst_HEADERS = ngircd.h channel.h client.h conf.h conn.h conn-zip.h conn-func.h \ - hash.h irc.h irc-channel.h irc-info.h irc-login.h irc-mode.h irc-op.h \ - irc-oper.h irc-server.h irc-write.h lists.h log.h match.h parse.h \ - rendezvous.h resolve.h \ - messages.h defines.h +noinst_HEADERS = ngircd.h array.h channel.h client.h conf.h conn.h conn-func.h \ + conn-zip.h hash.h io.h irc.h irc-channel.h irc-info.h irc-login.h \ + irc-mode.h irc-op.h irc-oper.h irc-server.h irc-write.h lists.h log.h \ + match.h parse.h rendezvous.h resolve.h \ + defines.h messages.h clean-local: rm -f check-version check-help lint.out cvs-version.* @@ -43,12 +43,12 @@ check-version: Makefile echo "#!/bin/sh" > check-version - echo "./ngircd --version | grep ngircd > /dev/null 2>&1" >> check-version + echo "./ngircd --version | grep ngircd >/dev/null 2>&1" >>check-version chmod 755 check-version check-help: Makefile echo "#!/bin/sh" > check-help - echo "./ngircd --help | grep help > /dev/null 2>&1" >> check-help + echo "./ngircd --help | grep help >/dev/null 2>&1" >>check-help chmod 755 check-help lint: @@ -63,7 +63,7 @@ if [ $$? -ne 0 ]; then \ waswarning=1; \ echo; grep -v "^Command Line: " lint.out; echo; \ - w=$$( grep "code warning" lint.out | awk "{ print \$$4 }" ); \ + w=$$( grep "code warning" lint.out | $(AWK) "{ print \$$4 }" ); \ [ "$$w" -gt 0 ] && warnings=`expr $$warnings + $$w`; \ files=`expr $$files + 1`; \ else \ Index: src/ngircd/array.c =================================================================== RCS file: src/ngircd/array.c diff -N src/ngircd/array.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/ngircd/array.c 1 Jul 2006 22:11:48 -0000 1.11 @@ -0,0 +1,359 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * Please read the file COPYING, README and AUTHORS for more information. + * + * functions to dynamically allocate arrays. + * Copyright (c) 2005 Florian Westphal (westphal@foo.fh-furtwangen.de) + * + */ + +#include "array.h" + +static char UNUSED id[] = "$Id: array.c,v 1.11 2006/07/01 22:11:48 fw Exp $"; + +#include + +#include +#include + +#include "log.h" + +/* Enable more Debug messages in alloc / append / memmove code. */ +/* #define DEBUG_ARRAY */ + + + +#define array_UNUSABLE(x) ( !(x)->mem || (0 == (x)->allocated) ) + +#define ALIGN_32U(x) (((x)+31U ) & ~(31U)) +#define ALIGN_1024U(x) (((x)+1023U) & ~(1023U)) +#define ALIGN_4096U(x) (((x)+4095U) & ~(4095U)) + + +static bool +safemult_sizet(size_t a, size_t b, size_t *res) +{ + size_t tmp = a * b; + + if (b && (tmp / b != a)) + return false; + + *res = tmp; + return true; +} + + +void +array_init(array *a) +{ + assert(a != NULL); + a->mem = NULL; + a->allocated = 0; + a->used = 0; +} + + +/* if realloc() fails, array_alloc return NULL. otherwise return pointer to elem pos in array */ +void * +array_alloc(array * a, size_t size, size_t pos) +{ + size_t alloc, pos_plus1 = pos + 1; + size_t aligned = 0; + char *tmp; + + assert(size > 0); + + if (pos_plus1 < pos) + return NULL; + + if (!safemult_sizet(size, pos_plus1, &alloc)) + return NULL; + + if (a->allocated < alloc) { + if (alloc < 128) { + aligned = ALIGN_32U(alloc); + } else { + if (alloc < 4096) { + aligned = ALIGN_1024U(alloc); + } else { + aligned = ALIGN_4096U(alloc); + } + } +#ifdef DEBUG_ARRAY + Log(LOG_DEBUG, "array_alloc(): rounded %u to %u bytes.", alloc, aligned); +#endif + + assert(aligned >= alloc); + + if (aligned < alloc) /* rounding overflow */ + return NULL; + + alloc = aligned; +#ifdef DEBUG_ARRAY + Log(LOG_DEBUG, "array_alloc(): changing size from %u to %u bytes.", + a->allocated, aligned); +#endif + + tmp = realloc(a->mem, alloc); + if (!tmp) + return NULL; + + a->mem = tmp; + a->allocated = alloc; + + assert(a->allocated > a->used); + + memset(a->mem + a->used, 0, a->allocated - a->used); + + a->used = alloc; + } + return a->mem + (pos * size); +} + + +/*return number of initialized ELEMS in a. */ +size_t +array_length(const array * const a, size_t membersize) +{ + assert(a != NULL); + assert(membersize > 0); + + if (array_UNUSABLE(a)) + return 0; + + return membersize ? a->used / membersize : 0; +} + + +/* copy array src to array dest */ +bool +array_copy(array * dest, const array * const src) +{ + if (array_UNUSABLE(src)) + return false; + + return array_copyb(dest, src->mem, src->used); +} + + +/* return false on failure (realloc failure, invalid src/dest array) */ +bool +array_copyb(array * dest, const char *src, size_t len) +{ + assert(dest != NULL); + assert(src != NULL ); + + if (!src || !dest) + return false; + + array_trunc(dest); + return array_catb(dest, src, len); +} + + +/* copy string to dest */ +bool +array_copys(array * dest, const char *src) +{ + return array_copyb(dest, src, strlen(src)); +} + + +/* append len bytes from src to the array dest. +return false if we could not append all bytes (realloc failure, invalid src/dest array) */ +bool +array_catb(array * dest, const char *src, size_t len) +{ + size_t tmp; + size_t used; + char *ptr; + + assert(dest != NULL); + assert(src != NULL); + + if (!len) + return true; + + if (!src || !dest) + return false; + + used = dest->used; + tmp = used + len; + + if (tmp < used || tmp < len) /* integer overflow */ + return false; + + if (!array_alloc(dest, 1, tmp)) + return false; + + ptr = dest->mem; + + assert(ptr != NULL); + +#ifdef DEBUG_ARRAY + Log(LOG_DEBUG, + "array_catb(): appending %u bytes to array (now %u bytes in array).", + len, tmp); +#endif + memcpy(ptr + used, src, len); + dest->used = tmp; + return true; +} + + +/* append string to dest */ +bool +array_cats(array * dest, const char *src) +{ + return array_catb(dest, src, strlen(src)); +} + + +/* append trailing NUL byte to array */ +bool +array_cat0(array * a) +{ + return array_catb(a, "", 1); +} + + +/* append trailing NUL byte to array, but do not count it. */ +bool +array_cat0_temporary(array * a) +{ + char *endpos = array_alloc(a, 1, array_bytes(a)); + if (!endpos) + return false; + + *endpos = '\0'; + return true; +} + +/* add contents of array src to array dest. */ +bool +array_cat(array * dest, const array * const src) +{ + if (array_UNUSABLE(src)) + return false; + + return array_catb(dest, src->mem, src->used); +} + + +/* return pointer to the element at pos. + return NULL if the array is unallocated, or if pos is larger than + the number of elements stored int the array. */ +void * +array_get(array * a, size_t membersize, size_t pos) +{ + size_t totalsize; + + assert(membersize > 0); + assert(a != NULL); + + if (array_UNUSABLE(a)) + return NULL; + + if (!safemult_sizet(pos, membersize, &totalsize)) + return NULL; + + if (a->allocated < totalsize) + return NULL; + + return a->mem + pos * membersize; +} + + +void +array_free(array * a) +{ + assert(a != NULL); +#ifdef DEBUG + Log(LOG_DEBUG, + "array_free(): %u bytes free'd (%u bytes still used at time of free()).", + a->allocated, a->used); +#endif + free(a->mem); + a->mem = NULL; + a->allocated = 0; + a->used = 0; +} + + +void +array_free_wipe(array * a) +{ + if (!array_UNUSABLE(a)) + memset(a->mem, 0, a->allocated); + + array_free(a); +} + + +void * +array_start(const array * const a) +{ + assert(a != NULL); + return a->mem; +} + + +void +array_trunc(array * a) +{ + assert(a != NULL); + a->used = 0; +} + + +void +array_truncate(array * a, size_t membersize, size_t len) +{ + size_t newlen; + assert(a != NULL); + if (!safemult_sizet(membersize, len, &newlen)) + return; + + if (newlen <= a->allocated) + a->used = newlen; +} + + +/* move elements starting at pos to beginning of array */ +void +array_moveleft(array * a, size_t membersize, size_t pos) +{ + size_t bytepos; + + assert(a != NULL); + assert(membersize > 0); + + if (!pos) + return; + + if (!safemult_sizet(membersize, pos, &bytepos)) { + a->used = 0; + return; + } + + if (!bytepos) + return; /* nothing to do */ + +#ifdef DEBUG_ARRAY + Log(LOG_DEBUG, + "array_moveleft(): %u bytes used in array, starting at position %u.", + a->used, bytepos); +#endif + if (a->used <= bytepos) { + a->used = 0; + return; + } + + a->used -= bytepos; + memmove(a->mem, a->mem + bytepos, a->used); +} + +/* -eof- */ Index: src/ngircd/array.h =================================================================== RCS file: src/ngircd/array.h diff -N src/ngircd/array.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/ngircd/array.h 30 Aug 2005 13:36:32 -0000 1.4 @@ -0,0 +1,101 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * Please read the file COPYING, README and AUTHORS for more information. + * + * libarray - dynamically allocate arrays. + * Copyright (c) 2005 Florian Westphal (westphal@foo.fh-furtwangen.de) + * + * $Id: array.h,v 1.4 2005/08/30 13:36:32 fw Exp $ + */ + +#ifndef array_h_included +#define array_h_included + +#include "portab.h" + +typedef struct { + char * mem; + size_t allocated; + size_t used; +} array; + +/* allocated: mem != NULL, used >= 0 && used <= allocated, allocated > 0 + unallocated: mem == NULL, allocated == 0, used == 0 */ + +#define array_unallocated(x) (array_bytes(x)==0) +#define INIT_ARRAY { NULL, 0, 0 } + +/* set all variables in a to 0 */ +extern void array_init PARAMS((array *a)); + +/* allocates space for at least nmemb+1 elements of size bytes each. + return pointer to elem at pos, or NULL if realloc() fails */ +extern void * array_alloc PARAMS((array *a, size_t size, size_t pos)); + +/* returns the number of initialized BYTES in a. */ +#define array_bytes(array) ( (array)->used ) + +/* returns the number of initialized ELEMS in a. */ +extern size_t array_length PARAMS((const array* const a, size_t elemsize)); + +/* _copy functions: copy src to dest. + return true if OK, else false (e. g. realloc failure, invalid src/dest + array, ...). In that case dest is left unchanged. */ + +/* copy array src to dest */ +extern bool array_copy PARAMS((array* dest, const array* const src)); + +/* copy len bytes from src to array dest. */ +extern bool array_copyb PARAMS((array* dest, const char* src, size_t len)); + +/* copy string to dest */ +extern bool array_copys PARAMS((array* dest, const char* src)); + +/* _cat functions: append src to dest. + return true if OK, else false (e. g. realloc failure, invalid src/dest + array, ...). In that case dest is left unchanged. */ + +/* append len bytes from src to array dest. */ +extern bool array_catb PARAMS((array* dest, const char* src, size_t len)); + +/* append string to dest */ +extern bool array_cats PARAMS((array* dest, const char* src)); + +/* append NUL byte to dest */ +extern bool array_cat0 PARAMS((array* dest)); + +/* append NUL byte to dest, but do not count null byte */ +extern bool array_cat0_temporary PARAMS((array* dest)); + +/* append contents of array src to array dest. */ +extern bool array_cat PARAMS((array* dest, const array* const src)); + +/* return pointer to element at pos. + return NULL if the array is unallocated or if pos is larger than the number + of elements stored int the array. */ +extern void* array_get PARAMS((array* a, size_t membersize, size_t pos)); + +/* free the contents of this array. */ +extern void array_free PARAMS((array* a)); + +/* overwrite array with zeroes before free */ +extern void array_free_wipe PARAMS((array* a)); + +/* return pointer to first element in this array */ +extern void* array_start PARAMS((const array* const a)); + +/* reset this array (the memory is not free'd */ +extern void array_trunc PARAMS((array* a)); + +/* set number of used elements in this array to len */ +extern void array_truncate PARAMS((array* a, size_t membersize, size_t len)); + +/* move elements starting at pos to beginning of array */ +extern void array_moveleft PARAMS((array* a, size_t membersize, size_t pos)); + +#endif + +/* -eof- */ Index: src/ngircd/channel.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/channel.c,v retrieving revision 1.50 retrieving revision 1.56 diff -u -r1.50 -r1.56 --- src/ngircd/channel.c 18 Jun 2005 08:57:37 -0000 1.50 +++ src/ngircd/channel.c 24 Jul 2006 22:54:09 -0000 1.56 @@ -17,12 +17,13 @@ #include "portab.h" -static char UNUSED id[] = "$Id: channel.c,v 1.50 2005/06/18 08:57:37 fw Exp $"; +static char UNUSED id[] = "$Id: channel.c,v 1.56 2006/07/24 22:54:09 alex Exp $"; #include "imp.h" #include #include #include +#include #include #include "defines.h" @@ -49,16 +50,16 @@ #define REMOVE_KICK 2 -LOCAL CHANNEL *My_Channels; -LOCAL CL2CHAN *My_Cl2Chan; +static CHANNEL *My_Channels; +static CL2CHAN *My_Cl2Chan; -LOCAL CL2CHAN *Get_Cl2Chan PARAMS(( CHANNEL *Chan, CLIENT *Client )); -LOCAL CL2CHAN *Add_Client PARAMS(( CHANNEL *Chan, CLIENT *Client )); -LOCAL bool Remove_Client PARAMS(( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, char *Reason, bool InformServer )); -LOCAL CL2CHAN *Get_First_Cl2Chan PARAMS(( CLIENT *Client, CHANNEL *Chan )); -LOCAL CL2CHAN *Get_Next_Cl2Chan PARAMS(( CL2CHAN *Start, CLIENT *Client, CHANNEL *Chan )); -LOCAL bool Delete_Channel PARAMS(( CHANNEL *Chan )); +static CL2CHAN *Get_Cl2Chan PARAMS(( CHANNEL *Chan, CLIENT *Client )); +static CL2CHAN *Add_Client PARAMS(( CHANNEL *Chan, CLIENT *Client )); +static bool Remove_Client PARAMS(( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, char *Reason, bool InformServer )); +static CL2CHAN *Get_First_Cl2Chan PARAMS(( CLIENT *Client, CHANNEL *Chan )); +static CL2CHAN *Get_Next_Cl2Chan PARAMS(( CL2CHAN *Start, CLIENT *Client, CHANNEL *Chan )); +static bool Delete_Channel PARAMS(( CHANNEL *Chan )); GLOBAL void @@ -76,7 +77,7 @@ CHANNEL *chan; char *c; - int i; + unsigned int i; for( i = 0; i < Conf_Channel_Count; i++ ) { @@ -87,6 +88,7 @@ if( ! Channel_IsValidName( Conf_Channel[i].name )) { Log( LOG_ERR, "Can't create pre-defined channel: invalid name: \"%s\"!", Conf_Channel[i].name ); + array_free(&Conf_Channel[i].topic); continue; } @@ -95,20 +97,29 @@ if( chan ) { Log( LOG_INFO, "Can't create pre-defined channel \"%s\": name already in use.", Conf_Channel[i].name ); + array_free(&Conf_Channel[i].topic); continue; } - - /* Channel anlegen */ - chan = Channel_Create( Conf_Channel[i].name ); - if( chan ) - { - Channel_ModeAdd( chan, 'P' ); - Channel_SetTopic( chan, Conf_Channel[i].topic ); + + /* Create channel */ + chan = Channel_Create(Conf_Channel[i].name); + if (chan) { + Channel_ModeAdd(chan, 'P'); + + if (array_start(&Conf_Channel[i].topic) != NULL) + Channel_SetTopic(chan, NULL, + array_start(&Conf_Channel[i].topic)); + array_free(&Conf_Channel[i].topic); + c = Conf_Channel[i].modes; - while( *c ) Channel_ModeAdd( chan, *c++ ); - Log( LOG_INFO, "Created pre-defined channel \"%s\".", Conf_Channel[i].name ); + while (*c) + Channel_ModeAdd(chan, *c++); + + Log(LOG_INFO, "Created pre-defined channel \"%s\".", + Conf_Channel[i].name ); } - else Log( LOG_ERR, "Can't create pre-defined channel \"%s\"!", Conf_Channel[i].name ); + else Log(LOG_ERR, "Can't create pre-defined channel \"%s\"!", + Conf_Channel[i].name ); } } /* Channel_InitPredefined */ @@ -124,6 +135,7 @@ while( c ) { c_next = c->next; + array_free(&c->topic); free( c ); c = c_next; } @@ -147,17 +159,13 @@ assert( Client != NULL ); assert( Name != NULL ); - /* Valider Channel-Name? */ - if( ! Channel_IsValidName( Name )) - { + if( ! Channel_IsValidName( Name )) { IRC_WriteStrClient( Client, ERR_NOSUCHCHANNEL_MSG, Client_ID( Client ), Name ); return false; } - /* Channel suchen */ chan = Channel_Search( Name ); - if( chan ) - { + if( chan ) { /* Ist der Client bereits Mitglied? */ if( Get_Cl2Chan( chan, Client )) return false; } @@ -183,7 +191,6 @@ assert( Name != NULL ); assert( Reason != NULL ); - /* Channel suchen */ chan = Channel_Search( Name ); if(( ! chan ) || ( ! Get_Cl2Chan( chan, Client ))) { @@ -215,21 +222,20 @@ return; } - /* Ist der User Mitglied in dem Channel? */ if( ! Channel_IsMemberOf( chan, Origin )) { IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG, Client_ID( Origin ), Name ); return; } - /* Ist der User Channel-Operator? */ + /* Is User Channel-Operator? */ if( ! strchr( Channel_UserModes( chan, Origin ), 'o' )) { IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Name); return; } - /* Ist der Ziel-User Mitglied im Channel? */ + /* Ist the kickED User member of channel? */ if( ! Channel_IsMemberOf( chan, Client )) { IRC_WriteStrClient( Origin, ERR_USERNOTINCHANNEL_MSG, Client_ID( Origin ), Client_ID( Client ), Name ); @@ -509,13 +515,11 @@ * if the mode was removed return true. * if the channel did not have the mode, return false. */ - char x[2], *p; + char *p; assert( Chan != NULL ); - x[0] = Mode; x[1] = '\0'; - - p = strchr( Chan->modes, x[0] ); + p = strchr( Chan->modes, Mode ); if( ! p ) return false; /* Channel has mode -> delete */ @@ -565,7 +569,7 @@ */ CL2CHAN *cl2chan; - char x[2], *p; + char *p; assert( Chan != NULL ); assert( Client != NULL ); @@ -573,9 +577,7 @@ cl2chan = Get_Cl2Chan( Chan, Client ); assert( cl2chan != NULL ); - x[0] = Mode; x[1] = '\0'; - - p = strchr( cl2chan->modes, x[0] ); + p = strchr( cl2chan->modes, Mode ); if( ! p ) return false; /* Client has Mode -> delete */ @@ -621,18 +623,61 @@ GLOBAL char * Channel_Topic( CHANNEL *Chan ) { + char *ret; assert( Chan != NULL ); - return Chan->topic; + ret = array_start(&Chan->topic); + return ret ? ret : ""; } /* Channel_Topic */ + +#ifndef STRICT_RFC + +GLOBAL unsigned int +Channel_TopicTime(CHANNEL *Chan) +{ + assert(Chan != NULL); + return (unsigned int) Chan->topic_time; +} /* Channel_TopicTime */ + + +GLOBAL char * +Channel_TopicWho(CHANNEL *Chan) +{ + assert(Chan != NULL); + return Chan->topic_who; +} /* Channel_TopicWho */ + +#endif + GLOBAL void -Channel_SetTopic( CHANNEL *Chan, char *Topic ) +Channel_SetTopic(CHANNEL *Chan, CLIENT *Client, char *Topic) { + size_t len; assert( Chan != NULL ); assert( Topic != NULL ); - - strlcpy( Chan->topic, Topic, sizeof( Chan->topic )); + + len = strlen(Topic); + if (len < array_bytes(&Chan->topic)) + array_free(&Chan->topic); + + if (!array_copyb(&Chan->topic, Topic, len)) + Log(LOG_WARNING, "could not set new Topic \"%s\" on %s: %s", + Topic, Chan->name, strerror(errno)); + + array_cat0(&Chan->topic); + +#ifndef STRICT_RFC + Chan->topic_time = time(NULL); + if (Client != NULL && Client_Type(Client) != CLIENT_SERVER) + strlcpy(Chan->topic_who, Client_ID(Client), + sizeof Chan->topic_who); + else + strlcpy(Chan->topic_who, DEFAULT_TOPIC_ID, + sizeof Chan->topic_who); +#else + (void) Client; +#endif } /* Channel_SetTopic */ @@ -689,7 +734,7 @@ /* Is the client banned? */ if( Lists_CheckBanned( From, Chan )) { - /* Client is banned, bus is he channel operator or has voice? */ + /* Client is banned, but is he channel operator or has voice? */ if(( ! has_voice ) && ( ! is_op )) ok = false; } @@ -720,14 +765,14 @@ c->hash = Hash( c->name ); c->next = My_Channels; My_Channels = c; - +#ifdef DEBUG Log( LOG_DEBUG, "Created new channel structure for \"%s\".", Name ); - +#endif return c; } /* Channel_Create */ -LOCAL CL2CHAN * +static CL2CHAN * Get_Cl2Chan( CHANNEL *Chan, CLIENT *Client ) { CL2CHAN *cl2chan; @@ -745,7 +790,7 @@ } /* Get_Cl2Chan */ -LOCAL CL2CHAN * +static CL2CHAN * Add_Client( CHANNEL *Chan, CLIENT *Client ) { CL2CHAN *cl2chan; @@ -774,7 +819,7 @@ } /* Add_Client */ -LOCAL bool +static bool Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, char *Reason, bool InformServer ) { CL2CHAN *cl2chan, *last_cl2chan; @@ -837,14 +882,14 @@ } /* Remove_Client */ -LOCAL CL2CHAN * +static CL2CHAN * Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan ) { return Get_Next_Cl2Chan( My_Cl2Chan, Client, Chan ); } /* Get_First_Cl2Chan */ -LOCAL CL2CHAN * +static CL2CHAN * Get_Next_Cl2Chan( CL2CHAN *Start, CLIENT *Client, CHANNEL *Channel ) { CL2CHAN *cl2chan; @@ -862,7 +907,7 @@ } /* Get_Next_Cl2Chan */ -LOCAL bool +static bool Delete_Channel( CHANNEL *Chan ) { /* Channel-Struktur loeschen */ Index: src/ngircd/channel.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/channel.h,v retrieving revision 1.27 retrieving revision 1.29 diff -u -r1.27 -r1.29 --- src/ngircd/channel.h 19 Mar 2005 18:43:48 -0000 1.27 +++ src/ngircd/channel.h 2 Sep 2005 12:50:25 -0000 1.29 @@ -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.27 2005/03/19 18:43:48 fw Exp $ + * $Id: channel.h,v 1.29 2005/09/02 12:50:25 alex Exp $ * * Channel management (header) */ @@ -21,6 +21,7 @@ #if defined(__channel_c__) | defined(S_SPLINT_S) #include "defines.h" +#include "array.h" typedef struct _CHANNEL { @@ -28,7 +29,11 @@ char name[CHANNEL_NAME_LEN]; /* Name of the channel */ UINT32 hash; /* Hash of the (lowecase!) name */ char modes[CHANNEL_MODE_LEN]; /* Channel modes */ - char topic[CHANNEL_TOPIC_LEN]; /* Topic of the channel */ + array topic; /* Topic of the channel */ +#ifndef STRICT_RFC + time_t topic_time; /* Time when topic was set */ + char topic_who[CLIENT_NICK_LEN];/* Nickname of user that set topic */ +#endif char key[CLIENT_PASS_LEN]; /* Channel key ("password", mode "k" ) */ long maxusers; /* Maximum number of members (mode "l") */ } CHANNEL; @@ -71,7 +76,7 @@ GLOBAL char *Channel_Key PARAMS(( CHANNEL *Chan )); GLOBAL long Channel_MaxUsers PARAMS(( CHANNEL *Chan )); -GLOBAL void Channel_SetTopic PARAMS(( CHANNEL *Chan, char *Topic )); +GLOBAL void Channel_SetTopic PARAMS(( CHANNEL *Chan, CLIENT *Client, char *Topic )); GLOBAL void Channel_SetModes PARAMS(( CHANNEL *Chan, char *Modes )); GLOBAL void Channel_SetKey PARAMS(( CHANNEL *Chan, char *Key )); GLOBAL void Channel_SetMaxUsers PARAMS(( CHANNEL *Chan, long Count )); @@ -104,6 +109,11 @@ GLOBAL CHANNEL *Channel_Create PARAMS(( char *Name )); +#ifndef STRICT_RFC +GLOBAL unsigned int Channel_TopicTime PARAMS(( CHANNEL *Chan )); +GLOBAL char *Channel_TopicWho PARAMS(( CHANNEL *Chan )); +#endif + #endif Index: src/ngircd/client.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/client.c,v retrieving revision 1.84 retrieving revision 1.91 diff -u -r1.84 -r1.91 --- src/ngircd/client.c 12 Jun 2005 16:39:42 -0000 1.84 +++ src/ngircd/client.c 23 Apr 2006 10:37:27 -0000 1.91 @@ -17,7 +17,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: client.c,v 1.84 2005/06/12 16:39:42 alex Exp $"; +static char UNUSED id[] = "$Id: client.c,v 1.91 2006/04/23 10:37:27 fw Exp $"; #include "imp.h" #include @@ -50,19 +50,23 @@ #define GETID_LEN (CLIENT_NICK_LEN-1) + 1 + (CLIENT_USER_LEN-1) + 1 + (CLIENT_HOST_LEN-1) + 1 -LOCAL CLIENT *This_Server, *My_Clients; -LOCAL char GetID_Buffer[GETID_LEN]; +static CLIENT *This_Server, *My_Clients; +static char GetID_Buffer[GETID_LEN]; -LOCAL WHOWAS My_Whowas[MAX_WHOWAS]; -LOCAL int Last_Whowas = -1; +static WHOWAS My_Whowas[MAX_WHOWAS]; +static int Last_Whowas = -1; -LOCAL long Count PARAMS(( CLIENT_TYPE Type )); -LOCAL long MyCount PARAMS(( CLIENT_TYPE Type )); +static long Count PARAMS(( CLIENT_TYPE Type )); +static long MyCount PARAMS(( CLIENT_TYPE Type )); -LOCAL CLIENT *New_Client_Struct PARAMS(( void )); -LOCAL void Generate_MyToken PARAMS(( CLIENT *Client )); -LOCAL void Adjust_Counters PARAMS(( CLIENT *Client )); +static CLIENT *New_Client_Struct PARAMS(( void )); +static void Generate_MyToken PARAMS(( CLIENT *Client )); +static void Adjust_Counters PARAMS(( CLIENT *Client )); + +static CLIENT *Init_New_Client PARAMS((CONN_ID Idx, CLIENT *Introducer, + CLIENT *TopServer, int Type, char *ID, char *User, char *Hostname, + char *Info, int Hops, int Token, char *Modes, bool Idented)); #ifndef Client_DestroyNow GLOBAL void Client_DestroyNow PARAMS((CLIENT *Client )); @@ -135,32 +139,53 @@ } /* Client_ThisServer */ +/** + * Initialize new local client; wrapper function for Init_New_Client(). + * @return New CLIENT structure. + */ GLOBAL CLIENT * -Client_NewLocal( CONN_ID Idx, char *Hostname, int Type, bool Idented ) +Client_NewLocal(CONN_ID Idx, char *Hostname, int Type, bool Idented) { - /* Neuen lokalen Client erzeugen: Wrapper-Funktion fuer Client_New(). */ - return Client_New( Idx, This_Server, NULL, Type, NULL, NULL, Hostname, NULL, 0, 0, NULL, Idented ); + return Init_New_Client(Idx, This_Server, NULL, Type, NULL, NULL, + Hostname, NULL, 0, 0, NULL, Idented); } /* Client_NewLocal */ +/** + * Initialize new remote server; wrapper function for Init_New_Client(). + * @return New CLIENT structure. + */ GLOBAL CLIENT * -Client_NewRemoteServer( CLIENT *Introducer, char *Hostname, CLIENT *TopServer, int Hops, int Token, char *Info, bool Idented ) +Client_NewRemoteServer(CLIENT *Introducer, char *Hostname, CLIENT *TopServer, + int Hops, int Token, char *Info, bool Idented) { - /* Neuen Remote-Client erzeugen: Wrapper-Funktion fuer Client_New (). */ - return Client_New( NONE, Introducer, TopServer, CLIENT_SERVER, Hostname, NULL, Hostname, Info, Hops, Token, NULL, Idented ); + return Init_New_Client(NONE, Introducer, TopServer, CLIENT_SERVER, + Hostname, NULL, Hostname, Info, Hops, Token, NULL, Idented); } /* Client_NewRemoteServer */ +/** + * Initialize new remote client; wrapper function for Init_New_Client(). + * @return New CLIENT structure. + */ GLOBAL CLIENT * -Client_NewRemoteUser( CLIENT *Introducer, char *Nick, int Hops, char *User, char *Hostname, int Token, char *Modes, char *Info, bool Idented ) +Client_NewRemoteUser(CLIENT *Introducer, char *Nick, int Hops, char *User, + char *Hostname, int Token, char *Modes, char *Info, bool Idented) { - /* Neuen Remote-Client erzeugen: Wrapper-Funktion fuer Client_New (). */ - return Client_New( NONE, Introducer, NULL, CLIENT_USER, Nick, User, Hostname, Info, Hops, Token, Modes, Idented ); + return Init_New_Client(NONE, Introducer, NULL, CLIENT_USER, Nick, + User, Hostname, Info, Hops, Token, Modes, Idented); } /* Client_NewRemoteUser */ -GLOBAL CLIENT * -Client_New( CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, int Type, char *ID, char *User, char *Hostname, char *Info, int Hops, int Token, char *Modes, bool Idented ) +/** + * Initialize new client and set up the given parameters like client type, + * user name, host name, introducing server etc. ... + * @return New CLIENT structure. + */ +static CLIENT * +Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, + int Type, char *ID, char *User, char *Hostname, char *Info, int Hops, + int Token, char *Modes, bool Idented) { CLIENT *client; @@ -197,7 +222,7 @@ Adjust_Counters( client ); return client; -} /* Client_New */ +} /* Init_New_Client */ GLOBAL void @@ -296,11 +321,9 @@ { if( c->id[0] ) Log( LOG_NOTICE, "Client \"%s\" unregistered (connection %d): %s", c->id, c->conn_id, txt ); else Log( LOG_NOTICE, "Client unregistered (connection %d): %s", c->conn_id, txt ); - } - else - { - if( c->id[0] ) Log( LOG_WARNING, "Unregistered unknown client \"%s\": %s", c->id, txt ); - else Log( LOG_WARNING, "Unregistered unknown client: %s", c->id, txt ); + } else { + Log(LOG_WARNING, "Unregistered unknown client \"%s\": %s", + c->id[0] ? c->id : "(No Nick)", txt ); } } @@ -541,27 +564,6 @@ GLOBAL CLIENT * -Client_GetFromConn( CONN_ID Idx ) -{ - /* return Client-Structure that belongs to the local Connection Idx gehoert. - * If none is found, return NULL. - */ - - CLIENT *c; - - assert( Idx >= 0 ); - - c = My_Clients; - while( c ) - { - if( c->conn_id == Idx ) return c; - c = (CLIENT *)c->next; - } - return NULL; -} /* Client_GetFromConn */ - - -GLOBAL CLIENT * Client_Search( char *Nick ) { /* return Client-Structure that has the corresponding Nick. @@ -1035,7 +1037,7 @@ } /* Client_Uptime */ -LOCAL long +static long Count( CLIENT_TYPE Type ) { CLIENT *c; @@ -1052,7 +1054,7 @@ } /* Count */ -LOCAL long +static long MyCount( CLIENT_TYPE Type ) { CLIENT *c; @@ -1069,7 +1071,7 @@ } /* MyCount */ -LOCAL CLIENT * +static CLIENT * New_Client_Struct( void ) { /* Neue CLIENT-Struktur pre-initialisieren */ @@ -1096,7 +1098,7 @@ } /* New_Client */ -LOCAL void +static void Generate_MyToken( CLIENT *Client ) { CLIENT *c; @@ -1120,7 +1122,7 @@ } /* Generate_MyToken */ -LOCAL void +static void Adjust_Counters( CLIENT *Client ) { long count; @@ -1150,11 +1152,13 @@ Client_RegisterWhowas( CLIENT *Client ) { int slot; + time_t now; assert( Client != NULL ); + now = time(NULL); /* Don't register clients that were connected less than 30 seconds. */ - if( time(NULL) - Client->starttime < 30 ) + if( now - Client->starttime < 30 ) return; slot = Last_Whowas + 1; @@ -1164,7 +1168,7 @@ Log( LOG_DEBUG, "Saving WHOWAS information to slot %d ...", slot ); #endif - My_Whowas[slot].time = time( NULL ); + My_Whowas[slot].time = now; strlcpy( My_Whowas[slot].id, Client_ID( Client ), sizeof( My_Whowas[slot].id )); strlcpy( My_Whowas[slot].user, Client_User( Client ), Index: src/ngircd/client.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/client.h,v retrieving revision 1.39 retrieving revision 1.42 diff -u -r1.39 -r1.42 --- src/ngircd/client.h 12 Jun 2005 16:18:49 -0000 1.39 +++ src/ngircd/client.h 23 Apr 2006 10:37:27 -0000 1.42 @@ -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.39 2005/06/12 16:18:49 alex Exp $ + * $Id: client.h,v 1.42 2006/04/23 10:37:27 fw Exp $ * * Client management (header) */ @@ -30,6 +30,7 @@ #define CLIENT_TYPE int +#include "defines.h" #if defined(__client_c__) | defined(S_SPLINT_S) @@ -78,7 +79,6 @@ GLOBAL CLIENT *Client_NewLocal PARAMS(( CONN_ID Idx, char *Hostname, int Type, bool Idented )); GLOBAL CLIENT *Client_NewRemoteServer PARAMS(( CLIENT *Introducer, char *Hostname, CLIENT *TopServer, int Hops, int Token, char *Info, bool Idented )); GLOBAL CLIENT *Client_NewRemoteUser PARAMS(( CLIENT *Introducer, char *Nick, int Hops, char *User, char *Hostname, int Token, char *Modes, char *Info, bool Idented )); -GLOBAL CLIENT *Client_New PARAMS(( CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, int Type, char *ID, char *User, char *Hostname, char *Info, int Hops, int Token, char *Modes, bool Idented )); GLOBAL void Client_Destroy PARAMS(( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit )); #ifdef CONN_MODULE @@ -87,7 +87,6 @@ GLOBAL CLIENT *Client_ThisServer PARAMS(( void )); -GLOBAL CLIENT *Client_GetFromConn PARAMS(( CONN_ID Idx )); GLOBAL CLIENT *Client_GetFromToken PARAMS(( CLIENT *Client, int Token )); GLOBAL CLIENT *Client_Search PARAMS(( char *ID )); Index: src/ngircd/conf.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/conf.c,v retrieving revision 1.77.2.1 retrieving revision 1.92 diff -u -r1.77.2.1 -r1.92 --- src/ngircd/conf.c 11 Oct 2005 19:28:47 -0000 1.77.2.1 +++ src/ngircd/conf.c 23 Jul 2006 16:42:45 -0000 1.92 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: conf.c,v 1.77.2.1 2005/10/11 19:28:47 alex Exp $"; +static char UNUSED id[] = "$Id: conf.c,v 1.92 2006/07/23 16:42:45 alex Exp $"; #include "imp.h" #include @@ -38,6 +38,7 @@ # include #endif +#include "array.h" #include "ngircd.h" #include "conn.h" #include "client.h" @@ -50,26 +51,84 @@ #include "conf.h" -LOCAL bool Use_Log = true; -LOCAL CONF_SERVER New_Server; -LOCAL int New_Server_Idx; +static bool Use_Log = true; +static CONF_SERVER New_Server; +static int New_Server_Idx; -LOCAL void Set_Defaults PARAMS(( bool InitServers )); -LOCAL void Read_Config PARAMS(( void )); -LOCAL void Validate_Config PARAMS(( bool TestOnly )); +static void Set_Defaults PARAMS(( bool InitServers )); +static void Read_Config PARAMS(( void )); +static void Validate_Config PARAMS(( bool TestOnly, bool Rehash )); -LOCAL void Handle_GLOBAL PARAMS(( int Line, char *Var, char *Arg )); -LOCAL void Handle_OPERATOR PARAMS(( int Line, char *Var, char *Arg )); -LOCAL void Handle_SERVER PARAMS(( int Line, char *Var, char *Arg )); -LOCAL void Handle_CHANNEL PARAMS(( int Line, char *Var, char *Arg )); +static void Handle_GLOBAL PARAMS(( int Line, char *Var, char *Arg )); +static void Handle_OPERATOR PARAMS(( int Line, char *Var, char *Arg )); +static void Handle_SERVER PARAMS(( int Line, char *Var, char *Arg )); +static void Handle_CHANNEL PARAMS(( int Line, char *Var, char *Arg )); -LOCAL void Config_Error PARAMS(( const int Level, const char *Format, ... )); +static void Config_Error PARAMS(( const int Level, const char *Format, ... )); -LOCAL void Config_Error_NaN PARAMS(( const int LINE, const char *Value )); -LOCAL void Config_Error_TooLong PARAMS(( const int LINE, const char *Value )); +static void Config_Error_NaN PARAMS(( const int LINE, const char *Value )); +static void Config_Error_TooLong PARAMS(( const int LINE, const char *Value )); -LOCAL void Init_Server_Struct PARAMS(( CONF_SERVER *Server )); +static void Init_Server_Struct PARAMS(( CONF_SERVER *Server )); + + +static char * +strdup_warn(const char *str) +{ + char *ptr = strdup(str); + if (!ptr) + Config_Error(LOG_ERR, "Could not allocate mem for string: %s", str); + return ptr; +} + + +static void +ports_puts(array *a) +{ + size_t len; + UINT16 *ports; + len = array_length(a, sizeof(UINT16)); + if (len--) { + ports = (UINT16*) array_start(a); + printf("%u", (unsigned int) *ports); + while (len--) { + ports++; + printf(", %u", (unsigned int) *ports); + } + } + putc('\n', stdout); +} + + +static void +ports_parse(array *a, int Line, char *Arg) +{ + char *ptr; + int port; + UINT16 port16; + + array_trunc(a); + + /* Ports on that the server should listen. More port numbers + * must be separated by "," */ + ptr = strtok( Arg, "," ); + while (ptr) { + ngt_TrimStr( ptr ); + port = atol( ptr ); + if (port > 0 && port < 0xFFFF) { + port16 = (UINT16) port; + if (!array_catb(a, (char*)&port16, sizeof port16)) + Config_Error(LOG_ERR, "%s, line %d Could not add port number %ld: %s", + NGIRCd_ConfFile, Line, port, strerror(errno)); + } else { + Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Illegal port number %ld!", + NGIRCd_ConfFile, Line, port ); + } + + ptr = strtok( NULL, "," ); + } +} GLOBAL void @@ -77,7 +136,7 @@ { Set_Defaults( true ); Read_Config( ); - Validate_Config( false ); + Validate_Config(false, false); } /* Config_Init */ @@ -86,7 +145,7 @@ { Set_Defaults( false ); Read_Config( ); - Validate_Config( false ); + Validate_Config(false, true); } /* Config_Rehash */ @@ -97,22 +156,23 @@ struct passwd *pwd; struct group *grp; - int i; + unsigned int i; + char *topic; Use_Log = false; Set_Defaults( true ); Read_Config( ); - Validate_Config( true ); + Validate_Config(true, false); /* If stdin and stdout ("you can read our nice message and we can * read in your keypress") are valid tty's, wait for a key: */ - if( isatty( fileno( stdin )) && isatty( fileno( stdout ))) - { + if( isatty( fileno( stdin )) && isatty( fileno( stdout ))) { puts( "OK, press enter to see a dump of your service configuration ..." ); getchar( ); + } else { + puts( "Ok, dump of your server configuration follows:\n" ); } - else puts( "Ok, dump of your server configuration follows:\n" ); puts( "[GLOBAL]" ); printf( " Name = %s\n", Conf_ServerName ); @@ -125,13 +185,10 @@ printf( " MotdPhrase = %s\n", Conf_MotdPhrase ); printf( " ChrootDir = %s\n", Conf_Chroot ); printf( " PidFile = %s\n", Conf_PidFile); - printf( " Ports = " ); - for( i = 0; i < Conf_ListenPorts_Count; i++ ) - { - if( i != 0 ) printf( ", " ); - printf( "%u", (unsigned int) Conf_ListenPorts[i] ); - } - puts( "" ); + fputs(" Ports = ", stdout); + + ports_puts(&Conf_ListenPorts); + printf( " Listen = %s\n", Conf_ListenAddress ); pwd = getpwuid( Conf_UID ); if( pwd ) printf( " ServerUID = %s\n", pwd->pw_name ); @@ -144,16 +201,11 @@ printf( " ConnectRetry = %d\n", Conf_ConnectRetry ); printf( " OperCanUseMode = %s\n", Conf_OperCanMode == true? "yes" : "no" ); printf( " OperServerMode = %s\n", Conf_OperServerMode == true? "yes" : "no" ); - if( Conf_MaxConnections > 0 ) printf( " MaxConnections = %ld\n", Conf_MaxConnections ); - else printf( " MaxConnections = -1\n" ); - if( Conf_MaxConnectionsIP > 0 ) printf( " MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP ); - else printf( " MaxConnectionsIP = -1\n" ); - if( Conf_MaxJoins > 0 ) printf( " MaxJoins = %d\n", Conf_MaxJoins ); - else printf( " MaxJoins = -1\n" ); - puts( "" ); + printf( " MaxConnections = %ld\n", Conf_MaxConnections>0 ? Conf_MaxConnections : -1); + printf( " MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP>0 ? Conf_MaxConnectionsIP : -1); + printf( " MaxJoins = %d\n\n", Conf_MaxJoins>0 ? Conf_MaxJoins : -1); - for( i = 0; i < Conf_Oper_Count; i++ ) - { + for( i = 0; i < Conf_Oper_Count; i++ ) { if( ! Conf_Oper[i].name[0] ) continue; /* Valid "Operator" section */ @@ -164,31 +216,29 @@ puts( "" ); } - for( i = 0; i < MAX_SERVERS; i++ ) - { + for( i = 0; i < MAX_SERVERS; i++ ) { if( ! Conf_Server[i].name[0] ) continue; /* Valid "Server" section */ puts( "[SERVER]" ); printf( " Name = %s\n", Conf_Server[i].name ); printf( " Host = %s\n", Conf_Server[i].host ); - printf( " Port = %d\n", Conf_Server[i].port ); + printf( " Port = %u\n", (unsigned int)Conf_Server[i].port ); printf( " MyPassword = %s\n", Conf_Server[i].pwd_in ); printf( " PeerPassword = %s\n", Conf_Server[i].pwd_out ); - printf( " Group = %d\n", Conf_Server[i].group ); - puts( "" ); + printf( " Group = %d\n\n", Conf_Server[i].group ); } - for( i = 0; i < Conf_Channel_Count; i++ ) - { + for( i = 0; i < Conf_Channel_Count; i++ ) { if( ! Conf_Channel[i].name[0] ) continue; /* Valid "Channel" section */ puts( "[CHANNEL]" ); printf( " Name = %s\n", Conf_Channel[i].name ); printf( " Modes = %s\n", Conf_Channel[i].modes ); - printf( " Topic = %s\n", Conf_Channel[i].topic ); - puts( "" ); + + topic = (char*)array_start(&Conf_Channel[i].topic); + printf( " Topic = %s\n\n", topic ? topic : ""); } return 0; @@ -207,29 +257,25 @@ time_t t; /* Check all our configured servers */ - for( i = 0; i < MAX_SERVERS; i++ ) - { + for( i = 0; i < MAX_SERVERS; i++ ) { if( Conf_Server[i].conn_id != Idx ) continue; /* Gotcha! Mark server configuration as "unused": */ Conf_Server[i].conn_id = NONE; - if( Conf_Server[i].flags & CONF_SFLAG_ONCE ) - { + if( Conf_Server[i].flags & CONF_SFLAG_ONCE ) { /* Delete configuration here */ Init_Server_Struct( &Conf_Server[i] ); - } - else - { + } else { /* Set time for next connect attempt */ - t = time(NULL); - if (Conf_Server[i].lasttry < t - Conf_ConnectRetry) { - /* The connection has been "long", so we don't - * require the next attempt to be delayed. */ - Conf_Server[i].lasttry = - t - Conf_ConnectRetry + RECONNECT_DELAY; - } else - Conf_Server[i].lasttry = t; + t = time(NULL); + if (Conf_Server[i].lasttry < t - Conf_ConnectRetry) { + /* The connection has been "long", so we don't + * require the next attempt to be delayed. */ + Conf_Server[i].lasttry = + t - Conf_ConnectRetry + RECONNECT_DELAY; + } else + Conf_Server[i].lasttry = t; } } } /* Conf_UnsetServer */ @@ -256,8 +302,7 @@ assert( Idx > NONE ); - for( i = 0; i < MAX_SERVERS; i++ ) - { + for( i = 0; i < MAX_SERVERS; i++ ) { if( Conf_Server[i].conn_id == Idx ) return i; } return NONE; @@ -273,10 +318,8 @@ assert( Name != NULL ); - for( i = 0; i < MAX_SERVERS; i++ ) - { - if( strcasecmp( Conf_Server[i].name, Name ) == 0 ) - { + for( i = 0; i < MAX_SERVERS; i++ ) { + if( strcasecmp( Conf_Server[i].name, Name ) == 0 ) { /* Gotcha! Set port and enable server: */ Conf_Server[i].port = Port; Conf_Server[i].flags &= ~CONF_SFLAG_DISABLED; @@ -296,10 +339,8 @@ assert( Name != NULL ); - for( i = 0; i < MAX_SERVERS; i++ ) - { - if( strcasecmp( Conf_Server[i].name, Name ) == 0 ) - { + for( i = 0; i < MAX_SERVERS; i++ ) { + if( strcasecmp( Conf_Server[i].name, Name ) == 0 ) { /* Gotcha! Disable and disconnect server: */ Conf_Server[i].flags |= CONF_SFLAG_DISABLED; if( Conf_Server[i].conn_id > NONE ) Conn_Close( Conf_Server[i].conn_id, NULL, "Server link terminated on operator request", true); @@ -323,8 +364,7 @@ assert( PeerPwd != NULL ); /* Search unused item in server configuration structure */ - for( i = 0; i < MAX_SERVERS; i++ ) - { + for( i = 0; i < MAX_SERVERS; i++ ) { /* Is this item used? */ if( ! Conf_Server[i].name[0] ) break; } @@ -342,7 +382,7 @@ } /* Conf_AddServer */ -LOCAL void +static void Set_Defaults( bool InitServers ) { /* Initialize configuration variables with default values. */ @@ -366,7 +406,6 @@ strlcpy( Conf_PidFile, PID_FILE, sizeof( Conf_PidFile )); - Conf_ListenPorts_Count = 0; strcpy( Conf_ListenAddress, "" ); Conf_UID = Conf_GID = 0; @@ -391,21 +430,22 @@ } /* Set_Defaults */ -LOCAL void +static void Read_Config( void ) { /* Read configuration file. */ char section[LINE_LEN], str[LINE_LEN], *var, *arg, *ptr; + const UINT16 defaultport = 6667; int line, i, n; FILE *fd; /* Open configuration file */ fd = fopen( NGIRCd_ConfFile, "r" ); - if( ! fd ) - { + if( ! fd ) { /* No configuration file found! */ - Config_Error( LOG_ALERT, "Can't read configuration \"%s\": %s", NGIRCd_ConfFile, strerror( errno )); + Config_Error( LOG_ALERT, "Can't read configuration \"%s\": %s", + NGIRCd_ConfFile, strerror( errno )); Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME ); exit( 1 ); } @@ -418,28 +458,24 @@ * And delete all servers which are "duplicates" of servers * that are already marked as "once" (such servers have been * created by the last rehash but are now useless). */ - for( i = 0; i < MAX_SERVERS; i++ ) - { + for( i = 0; i < MAX_SERVERS; i++ ) { if( Conf_Server[i].conn_id == NONE ) Init_Server_Struct( &Conf_Server[i] ); - else - { + else { /* This structure is in use ... */ - if( Conf_Server[i].flags & CONF_SFLAG_ONCE ) - { + if( Conf_Server[i].flags & CONF_SFLAG_ONCE ) { /* Check for duplicates */ - for( n = 0; n < MAX_SERVERS; n++ ) - { + for( n = 0; n < MAX_SERVERS; n++ ) { if( n == i ) continue; - if( Conf_Server[i].conn_id == Conf_Server[n].conn_id ) - { + if( Conf_Server[i].conn_id == Conf_Server[n].conn_id ) { Init_Server_Struct( &Conf_Server[n] ); - Log( LOG_DEBUG, "Deleted unused duplicate server %d (kept %d).", n, i ); +#ifdef DEBUG + Log(LOG_DEBUG,"Deleted unused duplicate server %d (kept %d).", + n, i ); +#endif } } - } - else - { + } else { /* Mark server as "once" */ Conf_Server[i].flags |= CONF_SFLAG_ONCE; Log( LOG_DEBUG, "Marked server %d as \"once\"", i ); @@ -454,8 +490,7 @@ New_Server_Idx = NONE; /* Read configuration file */ - while( true ) - { + while( true ) { if( ! fgets( str, LINE_LEN, fd )) break; ngt_TrimStr( str ); line++; @@ -464,15 +499,15 @@ if( str[0] == ';' || str[0] == '#' || str[0] == '\0' ) continue; /* Is this the beginning of a new section? */ - if(( str[0] == '[' ) && ( str[strlen( str ) - 1] == ']' )) - { + if(( str[0] == '[' ) && ( str[strlen( str ) - 1] == ']' )) { strlcpy( section, str, sizeof( section )); - if( strcasecmp( section, "[GLOBAL]" ) == 0 ) continue; - if( strcasecmp( section, "[OPERATOR]" ) == 0 ) - { - if( Conf_Oper_Count + 1 > MAX_OPERATORS ) Config_Error( LOG_ERR, "Too many operators configured." ); - else - { + if( strcasecmp( section, "[GLOBAL]" ) == 0 ) + continue; + + if( strcasecmp( section, "[OPERATOR]" ) == 0 ) { + if( Conf_Oper_Count + 1 > MAX_OPERATORS ) + Config_Error( LOG_ERR, "Too many operators configured."); + else { /* Initialize new operator structure */ Conf_Oper[Conf_Oper_Count].name[0] = '\0'; Conf_Oper[Conf_Oper_Count].pwd[0] = '\0'; @@ -484,11 +519,9 @@ } continue; } - if( strcasecmp( section, "[SERVER]" ) == 0 ) - { + if( strcasecmp( section, "[SERVER]" ) == 0 ) { /* Check if there is already a server to add */ - if( New_Server.name[0] ) - { + if( New_Server.name[0] ) { /* Copy data to "real" server structure */ assert( New_Server_Idx > NONE ); Conf_Server[New_Server_Idx] = New_Server; @@ -498,13 +531,11 @@ Init_Server_Struct( &New_Server ); /* Search unused item in server configuration structure */ - for( i = 0; i < MAX_SERVERS; i++ ) - { + for( i = 0; i < MAX_SERVERS; i++ ) { /* Is this item used? */ if( ! Conf_Server[i].name[0] ) break; } - if( i >= MAX_SERVERS ) - { + if( i >= MAX_SERVERS ) { /* Oops, no free item found! */ Config_Error( LOG_ERR, "Too many servers configured." ); New_Server_Idx = NONE; @@ -512,15 +543,14 @@ else New_Server_Idx = i; continue; } - if( strcasecmp( section, "[CHANNEL]" ) == 0 ) - { - if( Conf_Channel_Count + 1 > MAX_DEFCHANNELS ) Config_Error( LOG_ERR, "Too many pre-defined channels configured." ); - else - { + if( strcasecmp( section, "[CHANNEL]" ) == 0 ) { + if( Conf_Channel_Count + 1 > MAX_DEFCHANNELS ) { + Config_Error( LOG_ERR, "Too many pre-defined channels configured." ); + } else { /* Initialize new channel structure */ strcpy( Conf_Channel[Conf_Channel_Count].name, "" ); strcpy( Conf_Channel[Conf_Channel_Count].modes, "" ); - strcpy( Conf_Channel[Conf_Channel_Count].topic, "" ); + array_free(&Conf_Channel[Conf_Channel_Count].topic); Conf_Channel_Count++; } continue; @@ -532,8 +562,7 @@ /* Split line into variable name and parameters */ ptr = strchr( str, '=' ); - if( ! ptr ) - { + if( ! ptr ) { Config_Error( LOG_ERR, "%s, line %d: Syntax error!", NGIRCd_ConfFile, line ); continue; } @@ -552,23 +581,23 @@ fclose( fd ); /* Check if there is still a server to add */ - if( New_Server.name[0] ) - { + if( New_Server.name[0] ) { /* Copy data to "real" server structure */ assert( New_Server_Idx > NONE ); Conf_Server[New_Server_Idx] = New_Server; } - - /* If there are no ports configured use the default: 6667 */ - if( Conf_ListenPorts_Count < 1 ) - { - Conf_ListenPorts_Count = 1; - Conf_ListenPorts[0] = 6667; + + if (0 == array_length(&Conf_ListenPorts, sizeof(UINT16))) { + if (!array_copyb(&Conf_ListenPorts, (char*) &defaultport, sizeof defaultport)) { + Config_Error( LOG_ALERT, "Could not add default listening Port %u: %s", + (unsigned int) defaultport, strerror(errno)); + exit( 1 ); + } } } /* Read_Config */ -LOCAL bool +static bool Check_ArgIsTrue( const char *Arg ) { if( strcasecmp( Arg, "yes" ) == 0 ) return true; @@ -579,120 +608,97 @@ } /* Check_ArgIsTrue */ -LOCAL void +static void Handle_GLOBAL( int Line, char *Var, char *Arg ) { struct passwd *pwd; struct group *grp; - char *ptr; - long port; + size_t len; assert( Line > 0 ); assert( Var != NULL ); assert( Arg != NULL ); - if( strcasecmp( Var, "Name" ) == 0 ) - { + if( strcasecmp( Var, "Name" ) == 0 ) { /* Server name */ - if( strlcpy( Conf_ServerName, Arg, sizeof( Conf_ServerName )) >= sizeof( Conf_ServerName )) + len = strlcpy( Conf_ServerName, Arg, sizeof( Conf_ServerName )); + if (len >= sizeof( Conf_ServerName )) Config_Error_TooLong( Line, Var ); - return; } - if( strcasecmp( Var, "Info" ) == 0 ) - { + if( strcasecmp( Var, "Info" ) == 0 ) { /* Info text of server */ - if( strlcpy( Conf_ServerInfo, Arg, sizeof( Conf_ServerInfo )) >= sizeof( Conf_ServerInfo )) + len = strlcpy( Conf_ServerInfo, Arg, sizeof( Conf_ServerInfo )); + if (len >= sizeof( Conf_ServerInfo )) Config_Error_TooLong ( Line, Var ); - return; } - if( strcasecmp( Var, "Password" ) == 0 ) - { + if( strcasecmp( Var, "Password" ) == 0 ) { /* Global server password */ - if( strlcpy( Conf_ServerPwd, Arg, sizeof( Conf_ServerPwd )) >= sizeof( Conf_ServerPwd )) + len = strlcpy( Conf_ServerPwd, Arg, sizeof( Conf_ServerPwd )); + if (len >= sizeof( Conf_ServerPwd )) Config_Error_TooLong( Line, Var ); - return; } - if( strcasecmp( Var, "AdminInfo1" ) == 0 ) - { + if( strcasecmp( Var, "AdminInfo1" ) == 0 ) { /* Administrative info #1 */ - if( strlcpy( Conf_ServerAdmin1, Arg, sizeof( Conf_ServerAdmin1 )) >= sizeof( Conf_ServerAdmin1 )) Config_Error_TooLong ( Line, Var ); + len = strlcpy( Conf_ServerAdmin1, Arg, sizeof( Conf_ServerAdmin1 )); + if (len >= sizeof( Conf_ServerAdmin1 )) + Config_Error_TooLong ( Line, Var ); return; } - if( strcasecmp( Var, "AdminInfo2" ) == 0 ) - { + if( strcasecmp( Var, "AdminInfo2" ) == 0 ) { /* Administrative info #2 */ - if( strlcpy( Conf_ServerAdmin2, Arg, sizeof( Conf_ServerAdmin2 )) >= sizeof( Conf_ServerAdmin2 )) Config_Error_TooLong ( Line, Var ); + len = strlcpy( Conf_ServerAdmin2, Arg, sizeof( Conf_ServerAdmin2 )); + if (len >= sizeof( Conf_ServerAdmin2 )) + Config_Error_TooLong ( Line, Var ); return; } - if( strcasecmp( Var, "AdminEMail" ) == 0 ) - { + if( strcasecmp( Var, "AdminEMail" ) == 0 ) { /* Administrative email contact */ - if( strlcpy( Conf_ServerAdminMail, Arg, sizeof( Conf_ServerAdminMail )) >= sizeof( Conf_ServerAdminMail )) Config_Error_TooLong( Line, Var ); + len = strlcpy( Conf_ServerAdminMail, Arg, sizeof( Conf_ServerAdminMail )); + if (len >= sizeof( Conf_ServerAdminMail )) + Config_Error_TooLong( Line, Var ); return; } - if( strcasecmp( Var, "Ports" ) == 0 ) - { - /* Ports on that the server should listen. More port numbers - * must be separated by "," */ - ptr = strtok( Arg, "," ); - while( ptr ) - { - ngt_TrimStr( ptr ); - port = atol( ptr ); - if( Conf_ListenPorts_Count + 1 > MAX_LISTEN_PORTS ) Config_Error( LOG_ERR, "Too many listen ports configured. Port %ld ignored.", port ); - else - { - if( port > 0 && port < 0xFFFF ) Conf_ListenPorts[Conf_ListenPorts_Count++] = (UINT16)port; - else Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Illegal port number %ld!", NGIRCd_ConfFile, Line, port ); - } - ptr = strtok( NULL, "," ); - } + + if( strcasecmp( Var, "Ports" ) == 0 ) { + ports_parse(&Conf_ListenPorts, Line, Arg); return; } - if( strcasecmp( Var, "MotdFile" ) == 0 ) - { + if( strcasecmp( Var, "MotdFile" ) == 0 ) { /* "Message of the day" (MOTD) file */ - if( strlcpy( Conf_MotdFile, Arg, sizeof( Conf_MotdFile )) >= sizeof( Conf_MotdFile )) + len = strlcpy( Conf_MotdFile, Arg, sizeof( Conf_MotdFile )); + if (len >= sizeof( Conf_MotdFile )) Config_Error_TooLong( Line, Var ); - return; } - if( strcasecmp( Var, "MotdPhrase" ) == 0 ) - { + if( strcasecmp( Var, "MotdPhrase" ) == 0 ) { /* "Message of the day" phrase (instead of file) */ - if( strlcpy( Conf_MotdPhrase, Arg, sizeof( Conf_MotdPhrase )) >= sizeof( Conf_MotdPhrase )) + len = strlcpy( Conf_MotdPhrase, Arg, sizeof( Conf_MotdPhrase )); + if (len >= sizeof( Conf_MotdPhrase )) Config_Error_TooLong( Line, Var ); - return; } - if( strcasecmp( Var, "ChrootDir" ) == 0 ) - { + if( strcasecmp( Var, "ChrootDir" ) == 0 ) { /* directory for chroot() */ - if( strlcpy( Conf_Chroot, Arg, sizeof( Conf_Chroot )) >= sizeof( Conf_Chroot )) + len = strlcpy( Conf_Chroot, Arg, sizeof( Conf_Chroot )); + if (len >= sizeof( Conf_Chroot )) Config_Error_TooLong( Line, Var ); - return; } - - if ( strcasecmp( Var, "PidFile" ) == 0 ) - { + if ( strcasecmp( Var, "PidFile" ) == 0 ) { /* name of pidfile */ - if( strlcpy( Conf_PidFile, Arg, sizeof( Conf_PidFile )) >= sizeof( Conf_PidFile )) + len = strlcpy( Conf_PidFile, Arg, sizeof( Conf_PidFile )); + if (len >= sizeof( Conf_PidFile )) Config_Error_TooLong( Line, Var ); - return; } - - if( strcasecmp( Var, "ServerUID" ) == 0 ) - { + if( strcasecmp( Var, "ServerUID" ) == 0 ) { /* UID the daemon should switch to */ pwd = getpwnam( Arg ); if( pwd ) Conf_UID = pwd->pw_uid; - else - { + else { #ifdef HAVE_ISDIGIT if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var ); else @@ -701,13 +707,11 @@ } return; } - if( strcasecmp( Var, "ServerGID" ) == 0 ) - { + if( strcasecmp( Var, "ServerGID" ) == 0 ) { /* GID the daemon should use */ grp = getgrnam( Arg ); if( grp ) Conf_GID = grp->gr_gid; - else - { + else { #ifdef HAVE_ISDIGIT if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var ); else @@ -716,53 +720,47 @@ } return; } - if( strcasecmp( Var, "PingTimeout" ) == 0 ) - { + if( strcasecmp( Var, "PingTimeout" ) == 0 ) { /* PING timeout */ Conf_PingTimeout = atoi( Arg ); - if( Conf_PingTimeout < 5 ) - { - Config_Error( LOG_WARNING, "%s, line %d: Value of \"PingTimeout\" too low!", NGIRCd_ConfFile, Line ); + if( Conf_PingTimeout < 5 ) { + Config_Error( LOG_WARNING, "%s, line %d: Value of \"PingTimeout\" too low!", + NGIRCd_ConfFile, Line ); Conf_PingTimeout = 5; } return; } - if( strcasecmp( Var, "PongTimeout" ) == 0 ) - { + if( strcasecmp( Var, "PongTimeout" ) == 0 ) { /* PONG timeout */ Conf_PongTimeout = atoi( Arg ); - if( Conf_PongTimeout < 5 ) - { - Config_Error( LOG_WARNING, "%s, line %d: Value of \"PongTimeout\" too low!", NGIRCd_ConfFile, Line ); + if( Conf_PongTimeout < 5 ) { + Config_Error( LOG_WARNING, "%s, line %d: Value of \"PongTimeout\" too low!", + NGIRCd_ConfFile, Line ); Conf_PongTimeout = 5; } return; } - if( strcasecmp( Var, "ConnectRetry" ) == 0 ) - { + if( strcasecmp( Var, "ConnectRetry" ) == 0 ) { /* Seconds between connection attempts to other servers */ Conf_ConnectRetry = atoi( Arg ); - if( Conf_ConnectRetry < 5 ) - { - Config_Error( LOG_WARNING, "%s, line %d: Value of \"ConnectRetry\" too low!", NGIRCd_ConfFile, Line ); + if( Conf_ConnectRetry < 5 ) { + Config_Error( LOG_WARNING, "%s, line %d: Value of \"ConnectRetry\" too low!", + NGIRCd_ConfFile, Line ); Conf_ConnectRetry = 5; } return; } - if( strcasecmp( Var, "OperCanUseMode" ) == 0 ) - { + if( strcasecmp( Var, "OperCanUseMode" ) == 0 ) { /* Are IRC operators allowed to use MODE in channels they aren't Op in? */ Conf_OperCanMode = Check_ArgIsTrue( Arg ); return; } - if( strcasecmp( Var, "OperServerMode" ) == 0 ) - { + if( strcasecmp( Var, "OperServerMode" ) == 0 ) { /* Mask IRC operator as if coming from the server? (ircd-irc2 compat hack) */ Conf_OperServerMode = Check_ArgIsTrue( Arg ); return; } - if( strcasecmp( Var, "MaxConnections" ) == 0 ) - { + if( strcasecmp( Var, "MaxConnections" ) == 0 ) { /* Maximum number of connections. Values <= 0 are equal to "no limit". */ #ifdef HAVE_ISDIGIT if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var); @@ -771,9 +769,8 @@ Conf_MaxConnections = atol( Arg ); return; } - if( strcasecmp( Var, "MaxConnectionsIP" ) == 0 ) - { - /* Maximum number of simoultanous connections from one IP. Values <= 0 are equal to "no limit". */ + if( strcasecmp( Var, "MaxConnectionsIP" ) == 0 ) { + /* Maximum number of simultaneous connections from one IP. Values <= 0 -> "no limit" */ #ifdef HAVE_ISDIGIT if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var ); else @@ -781,8 +778,7 @@ Conf_MaxConnectionsIP = atoi( Arg ); return; } - if( strcasecmp( Var, "MaxJoins" ) == 0 ) - { + if( strcasecmp( Var, "MaxJoins" ) == 0 ) { /* Maximum number of channels a user can join. Values <= 0 are equal to "no limit". */ #ifdef HAVE_ISDIGIT if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var ); @@ -791,59 +787,64 @@ Conf_MaxJoins = atoi( Arg ); return; } - if( strcasecmp( Var, "Listen" ) == 0 ) - { + if( strcasecmp( Var, "Listen" ) == 0 ) { /* IP-Address to bind sockets */ - if( strlcpy( Conf_ListenAddress, Arg, sizeof( Conf_ListenAddress )) >= sizeof( Conf_ListenAddress )) - { + len = strlcpy( Conf_ListenAddress, Arg, sizeof( Conf_ListenAddress )); + if (len >= sizeof( Conf_ListenAddress )) Config_Error_TooLong( Line, Var ); - } return; } - Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var ); + Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", + NGIRCd_ConfFile, Line, Var ); } /* Handle_GLOBAL */ -LOCAL void +static void Handle_OPERATOR( int Line, char *Var, char *Arg ) { + unsigned int opercount; + size_t len; assert( Line > 0 ); assert( Var != NULL ); assert( Arg != NULL ); assert( Conf_Oper_Count > 0 ); - if( strcasecmp( Var, "Name" ) == 0 ) - { + if ( Conf_Oper_Count == 0 ) + return; + + opercount = Conf_Oper_Count - 1; + + if( strcasecmp( Var, "Name" ) == 0 ) { /* Name of IRC operator */ - if( strlcpy( Conf_Oper[Conf_Oper_Count - 1].name, Arg, sizeof( Conf_Oper[Conf_Oper_Count - 1].name )) >= sizeof( Conf_Oper[Conf_Oper_Count - 1].name )) Config_Error_TooLong( Line, Var ); + len = strlcpy( Conf_Oper[opercount].name, Arg, sizeof( Conf_Oper[opercount].name )); + if (len >= sizeof( Conf_Oper[opercount].name )) + Config_Error_TooLong( Line, Var ); return; } - if( strcasecmp( Var, "Password" ) == 0 ) - { + if( strcasecmp( Var, "Password" ) == 0 ) { /* Password of IRC operator */ - if( strlcpy( Conf_Oper[Conf_Oper_Count - 1].pwd, Arg, sizeof( Conf_Oper[Conf_Oper_Count - 1].pwd )) >= sizeof( Conf_Oper[Conf_Oper_Count - 1].pwd )) Config_Error_TooLong( Line, Var ); + len = strlcpy( Conf_Oper[opercount].pwd, Arg, sizeof( Conf_Oper[opercount].pwd )); + if (len >= sizeof( Conf_Oper[opercount].pwd )) + Config_Error_TooLong( Line, Var ); return; } - if( strcasecmp( Var, "Mask" ) == 0 ) - { - if (Conf_Oper[Conf_Oper_Count - 1].mask) return; /* Hostname already configured */ - Conf_Oper[Conf_Oper_Count - 1].mask = strdup( Arg ); - if (! Conf_Oper[Conf_Oper_Count - 1].mask) { - Config_Error( LOG_ERR, "%s, line %d: Cannot allocate memory for operator mask: %s", NGIRCd_ConfFile, Line, strerror(errno) ); - return; - } + if( strcasecmp( Var, "Mask" ) == 0 ) { + if (Conf_Oper[opercount].mask) return; /* Hostname already configured */ + Conf_Oper[opercount].mask = strdup_warn( Arg ); return; } - Config_Error( LOG_ERR, "%s, line %d (section \"Operator\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var ); + Config_Error( LOG_ERR, "%s, line %d (section \"Operator\"): Unknown variable \"%s\"!", + NGIRCd_ConfFile, Line, Var ); } /* Handle_OPERATOR */ -LOCAL void +static void Handle_SERVER( int Line, char *Var, char *Arg ) { long port; + size_t len; assert( Line > 0 ); assert( Var != NULL ); @@ -852,180 +853,210 @@ /* Ignore server block if no space is left in server configuration structure */ if( New_Server_Idx <= NONE ) return; - if( strcasecmp( Var, "Host" ) == 0 ) - { + if( strcasecmp( Var, "Host" ) == 0 ) { /* Hostname of the server */ - if( strlcpy( New_Server.host, Arg, sizeof( New_Server.host )) >= sizeof( New_Server.host )) + len = strlcpy( New_Server.host, Arg, sizeof( New_Server.host )); + if (len >= sizeof( New_Server.host )) Config_Error_TooLong ( Line, Var ); - return; } - if( strcasecmp( Var, "Name" ) == 0 ) - { + if( strcasecmp( Var, "Name" ) == 0 ) { /* Name of the server ("Nick"/"ID") */ - if( strlcpy( New_Server.name, Arg, sizeof( New_Server.name )) >= sizeof( New_Server.name )) + len = strlcpy( New_Server.name, Arg, sizeof( New_Server.name )); + if (len >= sizeof( New_Server.name )) Config_Error_TooLong( Line, Var ); return; } - if( strcasecmp( Var, "MyPassword" ) == 0 ) - { + if( strcasecmp( Var, "MyPassword" ) == 0 ) { /* Password of this server which is sent to the peer */ - if( strlcpy( New_Server.pwd_in, Arg, sizeof( New_Server.pwd_in )) >= sizeof( New_Server.pwd_in )) Config_Error_TooLong( Line, Var ); + if (*Arg == ':') { + Config_Error(LOG_ERR, + "%s, line %d (section \"Server\"): MyPassword must not start with ':'!", + NGIRCd_ConfFile, Line); + } + len = strlcpy( New_Server.pwd_in, Arg, sizeof( New_Server.pwd_in )); + if (len >= sizeof( New_Server.pwd_in )) + Config_Error_TooLong( Line, Var ); return; } - if( strcasecmp( Var, "PeerPassword" ) == 0 ) - { + if( strcasecmp( Var, "PeerPassword" ) == 0 ) { /* Passwort of the peer which must be received */ - if( strlcpy( New_Server.pwd_out, Arg, sizeof( New_Server.pwd_out )) >= sizeof( New_Server.pwd_out )) Config_Error_TooLong( Line, Var ); + len = strlcpy( New_Server.pwd_out, Arg, sizeof( New_Server.pwd_out )); + if (len >= sizeof( New_Server.pwd_out )) + Config_Error_TooLong( Line, Var ); return; } - if( strcasecmp( Var, "Port" ) == 0 ) - { + if( strcasecmp( Var, "Port" ) == 0 ) { /* Port to which this server should connect */ port = atol( Arg ); - if( port > 0 && port < 0xFFFF ) New_Server.port = (UINT16)port; - else Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Illegal port number %ld!", NGIRCd_ConfFile, Line, port ); + if( port > 0 && port < 0xFFFF ) + New_Server.port = (UINT16)port; + else + Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Illegal port number %ld!", + NGIRCd_ConfFile, Line, port ); return; } - if( strcasecmp( Var, "Group" ) == 0 ) - { + if( strcasecmp( Var, "Group" ) == 0 ) { /* Server group */ #ifdef HAVE_ISDIGIT - if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var ); + if( ! isdigit( (int)*Arg )) + Config_Error_NaN( Line, Var ); else #endif New_Server.group = atoi( Arg ); return; } - Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var ); + Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Unknown variable \"%s\"!", + NGIRCd_ConfFile, Line, Var ); } /* Handle_SERVER */ -LOCAL void +static void Handle_CHANNEL( int Line, char *Var, char *Arg ) { + size_t len; + size_t chancount = 0; + assert( Line > 0 ); assert( Var != NULL ); assert( Arg != NULL ); + if (Conf_Channel_Count > 0) + chancount = Conf_Channel_Count - 1; - if( strcasecmp( Var, "Name" ) == 0 ) - { + if( strcasecmp( Var, "Name" ) == 0 ) { /* Name of the channel */ - if( strlcpy( Conf_Channel[Conf_Channel_Count - 1].name, Arg, sizeof( Conf_Channel[Conf_Channel_Count - 1].name )) >= sizeof( Conf_Channel[Conf_Channel_Count - 1].name )) + len = strlcpy( Conf_Channel[chancount].name, Arg, sizeof( Conf_Channel[chancount].name )); + if (len >= sizeof( Conf_Channel[chancount].name )) Config_Error_TooLong( Line, Var ); return; } - if( strcasecmp( Var, "Modes" ) == 0 ) - { + if( strcasecmp( Var, "Modes" ) == 0 ) { /* Initial modes */ - if( strlcpy( Conf_Channel[Conf_Channel_Count - 1].modes, Arg, sizeof( Conf_Channel[Conf_Channel_Count - 1].modes )) >= sizeof( Conf_Channel[Conf_Channel_Count - 1].modes )) + len = strlcpy( Conf_Channel[chancount].modes, Arg, sizeof( Conf_Channel[chancount].modes )); + if (len >= sizeof( Conf_Channel[chancount].modes )) Config_Error_TooLong( Line, Var ); return; } - if( strcasecmp( Var, "Topic" ) == 0 ) - { + if( strcasecmp( Var, "Topic" ) == 0 ) { /* Initial topic */ - if( strlcpy( Conf_Channel[Conf_Channel_Count - 1].topic, Arg, sizeof( Conf_Channel[Conf_Channel_Count - 1].topic )) >= sizeof( Conf_Channel[Conf_Channel_Count - 1].topic )) + if (!array_copys( &Conf_Channel[chancount].topic, Arg)) Config_Error_TooLong( Line, Var ); - return; } - Config_Error( LOG_ERR, "%s, line %d (section \"Channel\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var ); + Config_Error( LOG_ERR, "%s, line %d (section \"Channel\"): Unknown variable \"%s\"!", + NGIRCd_ConfFile, Line, Var ); } /* Handle_CHANNEL */ -LOCAL void -Validate_Config( bool Configtest ) +static void +Validate_Config(bool Configtest, bool Rehash) { /* Validate configuration settings. */ #ifdef DEBUG int i, servers, servers_once; #endif + char *ptr; + + /* Validate configured server name, see RFC 2812 section 2.3.1 */ + ptr = Conf_ServerName; + do { + if (*ptr >= 'a' && *ptr <= 'z') continue; + if (*ptr >= 'A' && *ptr <= 'Z') continue; + if (*ptr >= '1' && *ptr <= '0') continue; + if (ptr > Conf_ServerName) { + if (*ptr == '.' || *ptr == '-') + continue; + } + Conf_ServerName[0] = '\0'; + break; + } while (*(++ptr)); - if( ! Conf_ServerName[0] ) - { + if (!Conf_ServerName[0]) { /* No server name configured! */ - Config_Error( LOG_ALERT, "No server name configured in \"%s\" (section 'Global': 'Name')!", NGIRCd_ConfFile ); - if( ! Configtest ) - { - Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME ); - exit( 1 ); + Config_Error(LOG_ALERT, + "No (valid) server name configured in \"%s\" (section 'Global': 'Name')!", + NGIRCd_ConfFile); + if (!Configtest && !Rehash) { + Config_Error(LOG_ALERT, + "%s exiting due to fatal errors!", + PACKAGE_NAME); + exit(1); } } - - if( Conf_ServerName[0] && ! strchr( Conf_ServerName, '.' )) - { + + if (Conf_ServerName[0] && !strchr(Conf_ServerName, '.')) { /* No dot in server name! */ - Config_Error( LOG_ALERT, "Invalid server name configured in \"%s\" (section 'Global': 'Name'): Dot missing!", NGIRCd_ConfFile ); - if( ! Configtest ) - { - Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME ); - exit( 1 ); + Config_Error(LOG_ALERT, + "Invalid server name configured in \"%s\" (section 'Global': 'Name'): Dot missing!", + NGIRCd_ConfFile); + if (!Configtest) { + Config_Error(LOG_ALERT, + "%s exiting due to fatal errors!", + PACKAGE_NAME); + exit(1); } } #ifdef STRICT_RFC - if( ! Conf_ServerAdminMail[0] ) - { + if (!Conf_ServerAdminMail[0]) { /* No administrative contact configured! */ - Config_Error( LOG_ALERT, "No administrator email address configured in \"%s\" ('AdminEMail')!", NGIRCd_ConfFile ); - if( ! Configtest ) - { - Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME ); - exit( 1 ); + Config_Error(LOG_ALERT, + "No administrator email address configured in \"%s\" ('AdminEMail')!", + NGIRCd_ConfFile); + if (!Configtest) { + Config_Error(LOG_ALERT, + "%s exiting due to fatal errors!", + PACKAGE_NAME); + exit(1); } } #endif - if( ! Conf_ServerAdmin1[0] && ! Conf_ServerAdmin2[0] && ! Conf_ServerAdminMail[0] ) - { + if (!Conf_ServerAdmin1[0] && !Conf_ServerAdmin2[0] + && !Conf_ServerAdminMail[0]) { /* No administrative information configured! */ - Config_Error( LOG_WARNING, "No administrative information configured but required by RFC!" ); + Config_Error(LOG_WARNING, + "No administrative information configured but required by RFC!"); } -#ifdef FD_SETSIZE - if(( Conf_MaxConnections > (long)FD_SETSIZE ) || ( Conf_MaxConnections < 1 )) - { - Conf_MaxConnections = (long)FD_SETSIZE; - Config_Error( LOG_ERR, "Setting MaxConnections to %ld, select() can't handle more file descriptors!", Conf_MaxConnections ); - } -#else - Config_Error( LOG_WARN, "Don't know how many file descriptors select() can handle on this system, don't set MaxConnections too high!" ); -#endif #ifdef DEBUG servers = servers_once = 0; - for( i = 0; i < MAX_SERVERS; i++ ) - { - if( Conf_Server[i].name[0] ) - { + for (i = 0; i < MAX_SERVERS; i++) { + if (Conf_Server[i].name[0]) { servers++; - if( Conf_Server[i].flags & CONF_SFLAG_ONCE ) servers_once++; + if (Conf_Server[i].flags & CONF_SFLAG_ONCE) + servers_once++; } } - Log( LOG_DEBUG, "Configuration: Operators=%d, Servers=%d[%d], Channels=%d", Conf_Oper_Count, servers, servers_once, Conf_Channel_Count ); + Log(LOG_DEBUG, + "Configuration: Operators=%d, Servers=%d[%d], Channels=%d", + Conf_Oper_Count, servers, servers_once, Conf_Channel_Count); #endif } /* Validate_Config */ -LOCAL void +static void Config_Error_TooLong ( const int Line, const char *Item ) { Config_Error( LOG_WARNING, "%s, line %d: Value of \"%s\" too long!", NGIRCd_ConfFile, Line, Item ); } -LOCAL void + +static void Config_Error_NaN( const int Line, const char *Item ) { - Config_Error( LOG_WARNING, "%s, line %d: Value of \"%s\" is not a number!", NGIRCd_ConfFile, Line, Item ); + Config_Error( LOG_WARNING, "%s, line %d: Value of \"%s\" is not a number!", + NGIRCd_ConfFile, Line, Item ); } + #ifdef PROTOTYPES -LOCAL void Config_Error( const int Level, const char *Format, ... ) +static void Config_Error( const int Level, const char *Format, ... ) #else -LOCAL void Config_Error( Level, Format, va_alist ) +static void Config_Error( Level, Format, va_alist ) const int Level; const char *Format; va_dcl @@ -1049,12 +1080,12 @@ /* During "normal operations" the log functions of the daemon should * be used, but during testing of the configuration file, all messages * should go directly to the console: */ - if( Use_Log ) Log( Level, "%s", msg ); + if (Use_Log) Log( Level, "%s", msg ); else puts( msg ); } /* Config_Error */ -LOCAL void +static void Init_Server_Struct( CONF_SERVER *Server ) { /* Initialize server configuration structur to default values */ @@ -1068,6 +1099,7 @@ if( NGIRCd_Passive ) Server->flags = CONF_SFLAG_DISABLED; + Resolve_Init(&Server->res_stat); Server->conn_id = NONE; } /* Init_Server_Struct */ Index: src/ngircd/conf.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/conf.h,v retrieving revision 1.34 retrieving revision 1.40 diff -u -r1.34 -r1.40 --- src/ngircd/conf.h 20 Mar 2005 13:54:06 -0000 1.34 +++ src/ngircd/conf.h 10 May 2006 21:24:01 -0000 1.40 @@ -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.34 2005/03/20 13:54:06 fw Exp $ + * $Id: conf.h,v 1.40 2006/05/10 21:24:01 alex Exp $ * * Configuration management (header) */ @@ -20,6 +20,7 @@ #include #include "defines.h" +#include "array.h" #include "portab.h" typedef struct _Conf_Oper @@ -39,7 +40,7 @@ UINT16 port; /* Server port */ int group; /* Group of server */ time_t lasttry; /* Last connect attempt */ - RES_STAT *res_stat; /* Status of the resolver */ + RES_STAT res_stat; /* Status of the resolver */ int flags; /* Flags */ CONN_ID conn_id; /* ID of server connection or NONE */ } CONF_SERVER; @@ -48,7 +49,7 @@ { char name[CHANNEL_NAME_LEN]; /* Name of the channel */ char modes[CHANNEL_MODE_LEN]; /* Initial channel modes */ - char topic[CHANNEL_TOPIC_LEN]; /* Initial topic */ + array topic; /* Initial topic */ } CONF_CHANNEL; @@ -77,15 +78,14 @@ GLOBAL char Conf_MotdPhrase[LINE_LEN]; /* Ports the server should listen on */ -GLOBAL UINT16 Conf_ListenPorts[MAX_LISTEN_PORTS]; -GLOBAL int Conf_ListenPorts_Count; +GLOBAL array Conf_ListenPorts; /* Address to which the socket should be bound or empty (=all) */ GLOBAL char Conf_ListenAddress[16]; /* User and group ID the server should run with */ -GLOBAL unsigned int Conf_UID; -GLOBAL unsigned int Conf_GID; +GLOBAL uid_t Conf_UID; +GLOBAL gid_t Conf_GID; /* A directory to chroot() in */ GLOBAL char Conf_Chroot[FNAME_LEN]; @@ -102,14 +102,14 @@ /* Operators */ GLOBAL CONF_OPER Conf_Oper[MAX_OPERATORS]; -GLOBAL int Conf_Oper_Count; +GLOBAL unsigned int Conf_Oper_Count; /* Servers */ GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS]; /* Pre-defined channels */ GLOBAL CONF_CHANNEL Conf_Channel[MAX_DEFCHANNELS]; -GLOBAL int Conf_Channel_Count; +GLOBAL unsigned int Conf_Channel_Count; /* Are IRC operators allowed to always use MODE? */ GLOBAL bool Conf_OperCanMode; @@ -129,9 +129,9 @@ GLOBAL int Conf_MaxConnectionsIP; -GLOBAL void Conf_Init PARAMS((void )); -GLOBAL void Conf_Rehash PARAMS((void )); -GLOBAL int Conf_Test PARAMS((void )); +GLOBAL void Conf_Init PARAMS((void)); +GLOBAL void Conf_Rehash PARAMS((void)); +GLOBAL int Conf_Test PARAMS((void)); GLOBAL void Conf_UnsetServer PARAMS(( CONN_ID Idx )); GLOBAL void Conf_SetServer PARAMS(( int ConfServer, CONN_ID Idx )); Index: src/ngircd/conn-func.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/conn-func.c,v retrieving revision 1.6 retrieving revision 1.10 diff -u -r1.6 -r1.10 --- src/ngircd/conn-func.c 12 Jun 2005 16:32:17 -0000 1.6 +++ src/ngircd/conn-func.c 10 May 2006 21:24:01 -0000 1.10 @@ -16,7 +16,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: conn-func.c,v 1.6 2005/06/12 16:32:17 alex Exp $"; +static char UNUSED id[] = "$Id: conn-func.c,v 1.10 2006/05/10 21:24:01 alex Exp $"; #include "imp.h" #include @@ -73,7 +73,13 @@ assert( Seconds >= 0 ); t = time( NULL ) + Seconds; - if( t > My_Connections[Idx].delaytime ) My_Connections[Idx].delaytime = t; + if (t > My_Connections[Idx].delaytime) + My_Connections[Idx].delaytime = t; + +#ifdef DEBUG + Log(LOG_DEBUG, "Add penalty time on connection %d: %ld second(s).", + Idx, (long)Seconds); +#endif } /* Conn_SetPenalty */ @@ -150,7 +156,7 @@ } /* Conn_Next */ -GLOBAL int +GLOBAL UINT16 Conn_Options( CONN_ID Idx ) { assert( Idx > NONE ); @@ -171,7 +177,7 @@ assert(Idx > NONE); /* Search client structure for this link ... */ - c = Client_GetFromConn(Idx); + c = Conn_GetClient(Idx); if(c != NULL) return Client_StartTime(c); @@ -179,17 +185,18 @@ } /* Conn_StartTime */ -GLOBAL int +GLOBAL size_t Conn_SendQ( CONN_ID Idx ) { /* Laenge der Daten im Schreibbuffer liefern */ assert( Idx > NONE ); #ifdef ZLIB - if( My_Connections[Idx].options & CONN_ZIP ) return My_Connections[Idx].zip.wdatalen; + if( My_Connections[Idx].options & CONN_ZIP ) + return array_bytes(&My_Connections[Idx].zip.wbuf); else #endif - return My_Connections[Idx].wdatalen; + return array_bytes(&My_Connections[Idx].wbuf); } /* Conn_SendQ */ @@ -213,17 +220,18 @@ } /* Conn_SendBytes */ -GLOBAL int +GLOBAL size_t Conn_RecvQ( CONN_ID Idx ) { /* Laenge der Daten im Lesebuffer liefern */ assert( Idx > NONE ); #ifdef ZLIB - if( My_Connections[Idx].options & CONN_ZIP ) return My_Connections[Idx].zip.rdatalen; + if( My_Connections[Idx].options & CONN_ZIP ) + return array_bytes(&My_Connections[Idx].zip.rbuf); else #endif - return My_Connections[Idx].rdatalen; + return array_bytes(&My_Connections[Idx].rbuf); } /* Conn_RecvQ */ Index: src/ngircd/conn-func.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/conn-func.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- src/ngircd/conn-func.h 25 Apr 2005 18:37:16 -0000 1.4 +++ src/ngircd/conn-func.h 10 May 2006 21:24:01 -0000 1.5 @@ -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.4 2005/04/25 18:37:16 fw Exp $ + * $Id: conn-func.h,v 1.5 2006/05/10 21:24:01 alex Exp $ * * Connection management: Global functions (header) */ @@ -30,8 +30,8 @@ GLOBAL time_t Conn_GetIdle PARAMS(( CONN_ID Idx )); GLOBAL time_t Conn_LastPing PARAMS(( CONN_ID Idx )); GLOBAL time_t Conn_StartTime PARAMS(( CONN_ID Idx )); -GLOBAL int Conn_SendQ PARAMS(( CONN_ID Idx )); -GLOBAL int Conn_RecvQ PARAMS(( CONN_ID Idx )); +GLOBAL size_t Conn_SendQ PARAMS(( CONN_ID Idx )); +GLOBAL size_t Conn_RecvQ PARAMS(( CONN_ID Idx )); GLOBAL long Conn_SendMsg PARAMS(( CONN_ID Idx )); GLOBAL long Conn_RecvMsg PARAMS(( CONN_ID Idx )); GLOBAL long Conn_SendBytes PARAMS(( CONN_ID Idx )); @@ -47,7 +47,7 @@ GLOBAL CONN_ID Conn_First PARAMS(( void )); GLOBAL CONN_ID Conn_Next PARAMS(( CONN_ID Idx )); -GLOBAL int Conn_Options PARAMS(( CONN_ID Idx )); +GLOBAL UINT16 Conn_Options PARAMS(( CONN_ID Idx )); GLOBAL void Conn_ResetWCounter PARAMS(( void )); GLOBAL long Conn_WCounter PARAMS(( void )); Index: src/ngircd/conn-zip.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/conn-zip.c,v retrieving revision 1.7 retrieving revision 1.11 diff -u -r1.7 -r1.11 --- src/ngircd/conn-zip.c 25 Apr 2005 18:37:16 -0000 1.7 +++ src/ngircd/conn-zip.c 23 Jul 2006 15:19:20 -0000 1.11 @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de) + * Copyright (c)2001-2006 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 @@ -19,7 +19,10 @@ #ifdef ZLIB -static char UNUSED id[] = "$Id: conn-zip.c,v 1.7 2005/04/25 18:37:16 fw Exp $"; +/* 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 $"; #include "imp.h" #include @@ -30,6 +33,7 @@ #include "conn-func.h" #include "log.h" +#include "array.h" #include "exp.h" #include "conn-zip.h" @@ -79,7 +83,7 @@ GLOBAL bool -Zip_Buffer( CONN_ID Idx, char *Data, int Len ) +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. */ @@ -87,19 +91,17 @@ assert( Idx > NONE ); assert( Data != NULL ); assert( Len > 0 ); + assert( Len <= ZWRITEBUFFER_LEN ); - /* Ist noch Platz im Kompressions-Puffer? */ - if( ZWRITEBUFFER_LEN - My_Connections[Idx].zip.wdatalen < Len + 50 ) - { - /* Nein! Puffer zunaechst leeren ...*/ + if (Len > ZWRITEBUFFER_LEN) + return false; + + if ( array_bytes( &My_Connections[Idx].zip.wbuf ) >= ZWRITEBUFFER_LEN ) { + /* compression buffer is full, flush */ if( ! Zip_Flush( Idx )) return false; } - /* Daten kopieren */ - memmove( My_Connections[Idx].zip.wbuf + My_Connections[Idx].zip.wdatalen, Data, Len ); - My_Connections[Idx].zip.wdatalen += Len; - - return true; + return array_catb(&My_Connections[Idx].zip.wbuf, Data, Len); } /* Zip_Buffer */ @@ -109,16 +111,26 @@ /* Daten komprimieren und in Schreibpuffer kopieren. * Es wird true bei Erfolg, sonst false geliefert. */ - int result, out_len; + int result; + unsigned char zipbuf[WRITEBUFFER_LEN]; + int zipbuf_used = 0; z_stream *out; out = &My_Connections[Idx].zip.out; - out->next_in = (void *)My_Connections[Idx].zip.wbuf; - out->avail_in = My_Connections[Idx].zip.wdatalen; - out->next_out = (void *)(My_Connections[Idx].wbuf + My_Connections[Idx].wdatalen); - out->avail_out = WRITEBUFFER_LEN - My_Connections[Idx].wdatalen; + 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); + out->next_out = zipbuf; + out->avail_out = (uInt)sizeof zipbuf; + +#ifdef DEBUG_ZIP + Log(LOG_DEBUG, "out->avail_in %d, out->avail_out %d", + out->avail_in, out->avail_out); +#endif result = deflate( out, Z_SYNC_FLUSH ); if(( result != Z_OK ) || ( out->avail_in > 0 )) { @@ -127,11 +139,18 @@ return false; } - out_len = WRITEBUFFER_LEN - My_Connections[Idx].wdatalen - out->avail_out; - My_Connections[Idx].wdatalen += out_len; - My_Connections[Idx].bytes_out += out_len; - My_Connections[Idx].zip.bytes_out += My_Connections[Idx].zip.wdatalen; - My_Connections[Idx].zip.wdatalen = 0; + assert(out->avail_out <= WRITEBUFFER_LEN); + zipbuf_used = WRITEBUFFER_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)) + return false; + + My_Connections[Idx].bytes_out += zipbuf_used; + My_Connections[Idx].zip.bytes_out += array_bytes(&My_Connections[Idx].zip.wbuf); + array_trunc(&My_Connections[Idx].zip.wbuf); return true; } /* Zip_Flush */ @@ -144,20 +163,34 @@ * wird false geliefert, ansonsten true. Der Fall, dass keine * Daten mehr zu entpacken sind, ist _kein_ Fehler! */ - int result, in_len, out_len; + int result; + unsigned char unzipbuf[READBUFFER_LEN]; + int unzipbuf_used = 0; + unsigned int z_rdatalen; + unsigned int in_len; + z_stream *in; assert( Idx > NONE ); - if( My_Connections[Idx].zip.rdatalen <= 0 ) return true; + z_rdatalen = (unsigned int)array_bytes(&My_Connections[Idx].zip.rbuf); + if (z_rdatalen == 0) + return true; in = &My_Connections[Idx].zip.in; + + in->next_in = array_start(&My_Connections[Idx].zip.rbuf); + if (!in->next_in) + return false; - in->next_in = (void *)My_Connections[Idx].zip.rbuf; - in->avail_in = My_Connections[Idx].zip.rdatalen; - in->next_out = (void *)(My_Connections[Idx].rbuf + My_Connections[Idx].rdatalen); - in->avail_out = READBUFFER_LEN - My_Connections[Idx].rdatalen - 1; - + in->avail_in = z_rdatalen; + in->next_out = unzipbuf; + in->avail_out = (uInt)sizeof unzipbuf; + +#ifdef DEBUG_ZIP + Log(LOG_DEBUG, "in->avail_in %d, in->avail_out %d", + in->avail_in, in->avail_out); +#endif result = inflate( in, Z_SYNC_FLUSH ); if( result != Z_OK ) { @@ -166,19 +199,24 @@ return false; } - in_len = My_Connections[Idx].zip.rdatalen - in->avail_in; - out_len = READBUFFER_LEN - My_Connections[Idx].rdatalen - 1 - in->avail_out; - My_Connections[Idx].rdatalen += out_len; + assert(z_rdatalen >= in->avail_in); + in_len = z_rdatalen - in->avail_in; + unzipbuf_used = READBUFFER_LEN - in->avail_out; +#ifdef DEBUG_ZIP + Log(LOG_DEBUG, "unzipbuf_used: %d - %d = %d", READBUFFER_LEN, + in->avail_out, unzipbuf_used); +#endif + assert(unzipbuf_used <= READBUFFER_LEN); + if (!array_catb(&My_Connections[Idx].rbuf, (char*) unzipbuf, + (size_t)unzipbuf_used)) + return false; - if( in->avail_in > 0 ) - { - /* es konnten nicht alle Daten entpackt werden, vermutlich war - * im Ziel-Puffer kein Platz mehr. Umkopieren ... */ - My_Connections[Idx].zip.rdatalen -= in_len; - memmove( My_Connections[Idx].zip.rbuf, My_Connections[Idx].zip.rbuf + in_len, My_Connections[Idx].zip.rdatalen ); + if( in->avail_in > 0 ) { + array_moveleft(&My_Connections[Idx].zip.rbuf, 1, in_len ); + } else { + array_trunc( &My_Connections[Idx].zip.rbuf ); + My_Connections[Idx].zip.bytes_in += unzipbuf_used; } - else My_Connections[Idx].zip.rdatalen = 0; - My_Connections[Idx].zip.bytes_in += out_len; return true; } /* Unzip_Buffer */ Index: src/ngircd/conn-zip.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/conn-zip.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- src/ngircd/conn-zip.h 19 Mar 2005 18:43:48 -0000 1.3 +++ src/ngircd/conn-zip.h 10 May 2006 21:24:01 -0000 1.4 @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: conn-zip.h,v 1.3 2005/03/19 18:43:48 fw Exp $ + * $Id: conn-zip.h,v 1.4 2006/05/10 21:24:01 alex Exp $ * * Connection compression using ZLIB (header) */ @@ -22,7 +22,7 @@ GLOBAL bool Zip_InitConn PARAMS(( CONN_ID Idx )); -GLOBAL bool Zip_Buffer PARAMS(( CONN_ID Idx, char *Data, int Len )); +GLOBAL bool Zip_Buffer PARAMS(( CONN_ID Idx, char *Data, size_t Len )); GLOBAL bool Zip_Flush PARAMS(( CONN_ID Idx )); GLOBAL bool Unzip_Buffer PARAMS(( CONN_ID Idx )); Index: src/ngircd/conn.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/conn.c,v retrieving revision 1.155.2.3 retrieving revision 1.198 diff -u -r1.155.2.3 -r1.198 --- src/ngircd/conn.c 11 Oct 2005 19:28:47 -0000 1.155.2.3 +++ src/ngircd/conn.c 23 Jul 2006 23:05:20 -0000 1.198 @@ -15,8 +15,9 @@ #define CONN_MODULE #include "portab.h" +#include "io.h" -static char UNUSED id[] = "$Id: conn.c,v 1.155.2.3 2005/10/11 19:28:47 alex Exp $"; +static char UNUSED id[] = "$Id: conn.c,v 1.198 2006/07/23 23:05:20 alex Exp $"; #include "imp.h" #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -55,6 +55,7 @@ # include /* for TCP Wrappers */ #endif +#include "array.h" #include "defines.h" #include "resolve.h" @@ -71,7 +72,7 @@ #include "parse.h" #include "tool.h" -#ifdef RENDEZVOUS +#ifdef ZEROCONF # include "rendezvous.h" #endif @@ -81,44 +82,122 @@ #define SERVER_WAIT (NONE - 1) -LOCAL void Handle_Read PARAMS(( int sock )); -LOCAL bool Handle_Write PARAMS(( CONN_ID Idx )); -LOCAL void New_Connection PARAMS(( int Sock )); -LOCAL CONN_ID Socket2Index PARAMS(( int Sock )); -LOCAL void Read_Request PARAMS(( CONN_ID Idx )); -LOCAL bool Handle_Buffer PARAMS(( CONN_ID Idx )); -LOCAL void Check_Connections PARAMS(( void )); -LOCAL void Check_Servers PARAMS(( void )); -LOCAL void Init_Conn_Struct PARAMS(( CONN_ID Idx )); -LOCAL bool Init_Socket PARAMS(( int Sock )); -LOCAL void New_Server PARAMS(( int Server, CONN_ID Idx )); -LOCAL void Read_Resolver_Result PARAMS(( int r_fd )); -LOCAL void Simple_Message PARAMS(( int Sock, char *Msg )); -LOCAL int Count_Connections PARAMS(( struct sockaddr_in addr )); +static bool Handle_Write PARAMS(( CONN_ID Idx )); +static int New_Connection PARAMS(( int Sock )); +static CONN_ID Socket2Index PARAMS(( int Sock )); +static void Read_Request PARAMS(( CONN_ID Idx )); +static bool Handle_Buffer PARAMS(( CONN_ID Idx )); +static void Check_Connections PARAMS(( void )); +static void Check_Servers PARAMS(( void )); +static void Init_Conn_Struct PARAMS(( CONN_ID Idx )); +static bool Init_Socket PARAMS(( int Sock )); +static void New_Server PARAMS(( int Server )); +static void Simple_Message PARAMS(( int Sock, const char *Msg )); +static int Count_Connections PARAMS(( struct sockaddr_in addr )); +static int NewListener PARAMS(( const UINT16 Port )); -LOCAL fd_set My_Listeners; -LOCAL fd_set My_Sockets; +static array My_Listeners; +static array My_ConnArray; #ifdef TCPWRAP int allow_severity = LOG_INFO; int deny_severity = LOG_ERR; #endif -LOCAL void -FreeRes_stat( CONNECTION *c ) +static void server_login PARAMS((CONN_ID idx)); + +static void cb_Read_Resolver_Result PARAMS(( int sock, UNUSED short what)); +static void cb_Connect_to_Server PARAMS(( int sock, UNUSED short what)); +static void cb_clientserver PARAMS((int sock, short what)); + +static void +cb_listen(int sock, short irrelevant) { - assert( c != NULL ); - assert( c->res_stat != NULL ); + (void) irrelevant; + New_Connection( sock ); +} + + +static void +cb_connserver(int sock, UNUSED short what) +{ + int res, err; + socklen_t sock_len; + CLIENT *c; + CONN_ID idx = Socket2Index( sock ); + if (idx <= NONE) { + LogDebug("cb_connserver wants to write on unknown socket?!"); + io_close(sock); + return; + } + + assert( what & IO_WANTWRITE); + + /* connect() finished, get result. */ + sock_len = sizeof( err ); + res = getsockopt( My_Connections[idx].sock, SOL_SOCKET, SO_ERROR, &err, &sock_len ); + assert( sock_len == sizeof( err )); + + /* Error while connecting? */ + if ((res != 0) || (err != 0)) { + if (res != 0) + Log(LOG_CRIT, "getsockopt (connection %d): %s!", + idx, strerror(errno)); + else + Log(LOG_CRIT, + "Can't connect socket to \"%s:%d\" (connection %d): %s!", + My_Connections[idx].host, + 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); + + return; + } + + Conn_OPTION_DEL( &My_Connections[idx], CONN_ISCONNECTING ); + server_login(idx); +} + + +static void +server_login(CONN_ID idx) +{ + Log( LOG_INFO, "Connection %d with \"%s:%d\" established. Now logging in ...", idx, + My_Connections[idx].host, Conf_Server[Conf_GetServer( idx )].port ); - if (!c->res_stat) return; + io_event_setcb( My_Connections[idx].sock, cb_clientserver); + io_event_add( My_Connections[idx].sock, IO_WANTREAD|IO_WANTWRITE); - FD_CLR( c->res_stat->pipe[0], &Resolver_FDs ); + /* Send PASS and SERVER command to peer */ + Conn_WriteStr( idx, "PASS %s %s", Conf_Server[Conf_GetServer( idx )].pwd_out, NGIRCd_ProtoID ); + Conn_WriteStr( idx, "SERVER %s :%s", Conf_ServerName, Conf_ServerInfo ); +} + + +static void +cb_clientserver(int sock, short what) +{ + CONN_ID idx = Socket2Index( sock ); + if (idx <= NONE) { +#ifdef DEBUG + Log(LOG_WARNING, "WTF: cb_clientserver wants to write on unknown socket?!"); +#endif + io_close(sock); + return; + } - close( c->res_stat->pipe[0] ); - close( c->res_stat->pipe[1] ); + if (what & IO_WANTREAD) + Read_Request( idx ); - free( c->res_stat ); - c->res_stat = NULL; + if (what & IO_WANTWRITE) + Handle_Write( idx ); } @@ -136,23 +215,22 @@ /* konfiguriertes Limit beachten */ if( Pool_Size > Conf_MaxConnections ) Pool_Size = Conf_MaxConnections; } - My_Connections = (CONNECTION *) calloc( Pool_Size, sizeof( CONNECTION ) ); - if( ! My_Connections ) - { - /* Speicher konnte nicht alloziert werden! */ + + if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)Pool_Size)) { Log( LOG_EMERG, "Can't allocate memory! [Conn_Init]" ); exit( 1 ); } -#ifdef DEBUG - Log( LOG_DEBUG, "Allocated connection pool for %d items (%ld bytes).", Pool_Size, sizeof( CONNECTION ) * Pool_Size ); -#endif - /* zu Beginn haben wir keine Verbindungen */ - FD_ZERO( &My_Listeners ); - FD_ZERO( &My_Sockets ); + /* FIXME: My_Connetions/Pool_Size is needed by other parts of the + * code; remove them! */ + My_Connections = (CONNECTION*) array_start(&My_ConnArray); - /* Groesster File-Descriptor fuer select() */ - Conn_MaxFD = 0; + LogDebug("Allocated connection pool for %d items (%ld bytes).", + array_length(&My_ConnArray, sizeof( CONNECTION )), array_bytes(&My_ConnArray)); + + assert( array_length(&My_ConnArray, sizeof( CONNECTION )) >= (size_t) Pool_Size); + + array_free( &My_Listeners ); /* Connection-Struktur initialisieren */ for( i = 0; i < Pool_Size; i++ ) Init_Conn_Struct( i ); @@ -169,64 +247,71 @@ * schliessen und freigeben. */ CONN_ID idx; - int i; -#ifdef DEBUG - Log( LOG_DEBUG, "Shutting down all connections ..." ); -#endif + LogDebug("Shutting down all connections ..." ); -#ifdef RENDEZVOUS - Rendezvous_UnregisterListeners( ); -#endif + Conn_ExitListeners(); /* Sockets schliessen */ - for( i = 0; i < Conn_MaxFD + 1; i++ ) - { - if( FD_ISSET( i, &My_Sockets )) - { - for( idx = 0; idx < Pool_Size; idx++ ) - { - if( My_Connections[idx].sock == i ) break; - } - if( FD_ISSET( i, &My_Listeners )) - { - close( i ); -#ifdef DEBUG - Log( LOG_DEBUG, "Listening socket %d closed.", i ); -#endif - } - else if( idx < Pool_Size ) - { - if( NGIRCd_SignalRestart ) Conn_Close( idx, NULL, "Server going down (restarting)", true ); - else Conn_Close( idx, NULL, "Server going down", true ); - } - else - { - Log( LOG_WARNING, "Closing unknown connection %d ...", i ); - close( i ); - } + for( idx = 0; idx < Pool_Size; idx++ ) { + if( My_Connections[idx].sock > NONE ) { + Conn_Close( idx, NULL, NGIRCd_SignalRestart ? + "Server going down (restarting)":"Server going down", true ); } } - free( My_Connections ); + array_free(&My_ConnArray); My_Connections = NULL; Pool_Size = 0; + io_library_shutdown(); } /* Conn_Exit */ +static int +ports_initlisteners(array *a, void (*func)(int,short)) +{ + int created = 0; + size_t len; + int fd; + UINT16 *port; + + len = array_length(a, sizeof (UINT16)); + port = array_start(a); + while(len--) { + fd = NewListener( *port ); + if (fd < 0) { + port++; + continue; + } + if (!io_event_create( fd, IO_WANTREAD, func )) { + Log( LOG_ERR, "io_event_create(): Could not add listening fd %d (port %u): %s!", + fd, (unsigned int) *port, strerror(errno)); + close(fd); + port++; + continue; + } + created++; + port++; + } + + return created; +} + + GLOBAL int Conn_InitListeners( void ) { /* Initialize ports on which the server should accept connections */ - int created, i; + int created; - created = 0; - for( i = 0; i < Conf_ListenPorts_Count; i++ ) - { - if( Conn_NewListener( Conf_ListenPorts[i] )) created++; - else Log( LOG_ERR, "Can't listen on port %u!", (unsigned int) Conf_ListenPorts[i] ); + if (!io_library_init(CONNECTION_POOL)) { + Log(LOG_EMERG, "Cannot initialize IO routines: %s", strerror(errno)); + return -1; } + + created = ports_initlisteners(&Conf_ListenPorts, cb_listen); + return created; } /* Conn_InitListeners */ @@ -235,43 +320,43 @@ Conn_ExitListeners( void ) { /* Close down all listening sockets */ - - int i; - -#ifdef RENDEZVOUS + int *fd; + size_t arraylen; +#ifdef ZEROCONF Rendezvous_UnregisterListeners( ); #endif - Log( LOG_INFO, "Shutting down all listening sockets ..." ); - for( i = 0; i < Conn_MaxFD + 1; i++ ) - { - if( FD_ISSET( i, &My_Sockets ) && FD_ISSET( i, &My_Listeners )) - { - close( i ); -#ifdef DEBUG - Log( LOG_DEBUG, "Listening socket %d closed.", i ); -#endif - } + arraylen = array_length(&My_Listeners, sizeof (int)); + Log( LOG_INFO, "Shutting down all listening sockets (%d total)...", arraylen ); + fd = array_start(&My_Listeners); + while(arraylen--) { + assert(fd != NULL); + assert(*fd >= 0); + io_close(*fd); + LogDebug("Listening socket %d closed.", *fd ); + fd++; } + array_free(&My_Listeners); } /* Conn_ExitListeners */ -GLOBAL bool -Conn_NewListener( const UINT16 Port ) +/* return new listening port file descriptor or -1 on failure */ +static int +NewListener( const UINT16 Port ) { /* Create new listening socket on specified port */ struct sockaddr_in addr; struct in_addr inaddr; int sock; -#ifdef RENDEZVOUS +#ifdef ZEROCONF char name[CLIENT_ID_LEN], *info; #endif /* Server-"Listen"-Socket initialisieren */ memset( &addr, 0, sizeof( addr )); memset( &inaddr, 0, sizeof( inaddr )); - addr.sin_family = AF_INET; + addr.sin_family = (sa_family_t)AF_INET; addr.sin_port = htons( Port ); if( Conf_ListenAddress[0] ) { @@ -282,49 +367,45 @@ if( inaddr.s_addr == (unsigned)-1 ) #endif { - Log( LOG_CRIT, "Can't listen on %s:%u: can't convert ip address %s!", Conf_ListenAddress, Port, Conf_ListenAddress ); - return false; + Log( LOG_CRIT, "Can't listen on %s:%u: can't convert ip address %s!", + Conf_ListenAddress, Port, Conf_ListenAddress ); + return -1; } } else inaddr.s_addr = htonl( INADDR_ANY ); addr.sin_addr = inaddr; - /* Socket erzeugen */ sock = socket( PF_INET, SOCK_STREAM, 0); - if( sock < 0 ) - { + if( sock < 0 ) { Log( LOG_CRIT, "Can't create socket: %s!", strerror( errno )); - return false; + return -1; } - if( ! Init_Socket( sock )) return false; + if( ! Init_Socket( sock )) return -1; - /* an Port binden */ - if( bind( sock, (struct sockaddr *)&addr, (socklen_t)sizeof( addr )) != 0 ) - { + if (bind(sock, (struct sockaddr *)&addr, (socklen_t)sizeof(addr)) != 0) { Log( LOG_CRIT, "Can't bind socket: %s!", strerror( errno )); close( sock ); - return false; + return -1; } - /* in "listen mode" gehen :-) */ - if( listen( sock, 10 ) != 0 ) - { - Log( LOG_CRIT, "Can't listen on soecket: %s!", strerror( errno )); + if( listen( sock, 10 ) != 0 ) { + Log( LOG_CRIT, "Can't listen on socket: %s!", strerror( errno )); close( sock ); - return false; + return -1; } - /* Neuen Listener in Strukturen einfuegen */ - FD_SET( sock, &My_Listeners ); - FD_SET( sock, &My_Sockets ); - - if( sock > Conn_MaxFD ) Conn_MaxFD = sock; + /* keep fd in list so we can close it when ngircd restarts/shuts down */ + if (!array_catb( &My_Listeners,(char*) &sock, sizeof(int) )) { + Log( LOG_CRIT, "Can't add socket to My_Listeners array: %s!", strerror( errno )); + close( sock ); + return -1; + } if( Conf_ListenAddress[0]) Log( LOG_INFO, "Now listening on %s:%d (socket %d).", Conf_ListenAddress, Port, sock ); else Log( LOG_INFO, "Now listening on 0.0.0.0:%d (socket %d).", Port, sock ); -#ifdef RENDEZVOUS +#ifdef ZEROCONF /* Get best server description text */ if( ! Conf_ServerInfo[0] ) info = Conf_ServerName; else @@ -345,49 +426,45 @@ } /* Add port number to description if non-standard */ - if( Port != 6667 ) snprintf( name, sizeof( name ), "%s (port %u)", info, Port ); - else strlcpy( name, info, sizeof( name )); + if (Port != 6667) + snprintf(name, sizeof name, "%s (port %u)", info, + (unsigned int)Port); + else + strlcpy(name, info, sizeof name); /* Register service */ - Rendezvous_Register( name, RENDEZVOUS_TYPE, Port ); + Rendezvous_Register( name, MDNS_TYPE, Port ); #endif - - return true; -} /* Conn_NewListener */ + return sock; +} /* NewListener */ GLOBAL void Conn_Handler( void ) { - /* "Hauptschleife": Aktive Verbindungen ueberwachen. Folgende Aktionen - * werden dabei durchgefuehrt, bis der Server terminieren oder neu - * starten soll: - * - * - neue Verbindungen annehmen, - * - Server-Verbindungen aufbauen, - * - geschlossene Verbindungen loeschen, - * - volle Schreibpuffer versuchen zu schreiben, - * - volle Lesepuffer versuchen zu verarbeiten, - * - Antworten von Resolver Sub-Prozessen annehmen. + /* "Main Loop.": Loop until a signal (for shutdown or restart) arrives. + * Call io_dispatch() to check for read/writeable sockets every second + * Wait for status change on pending connections (e.g: when the hostname has been resolved) + * check for penalty/timeouts + * handle input buffers */ - - fd_set read_sockets, write_sockets; + int i; + unsigned int wdatalen; struct timeval tv; - time_t start, t; - CONN_ID i, idx; + time_t t; bool timeout; - start = time( NULL ); - while(( ! NGIRCd_SignalQuit ) && ( ! NGIRCd_SignalRestart )) - { + while(( ! NGIRCd_SignalQuit ) && ( ! NGIRCd_SignalRestart )) { timeout = true; -#ifdef RENDEZVOUS +#ifdef ZEROCONF Rendezvous_Handler( ); #endif /* Should the configuration be reloaded? */ - if( NGIRCd_SignalRehash ) NGIRCd_Rehash( ); + if (NGIRCd_SignalRehash) { + NGIRCd_Rehash( ); + } /* Check configured servers and established links */ Check_Servers( ); @@ -396,119 +473,65 @@ t = time( NULL ); /* noch volle Lese-Buffer suchen */ - for( i = 0; i < Pool_Size; i++ ) - { - if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].rdatalen > 0 ) && + for( i = 0; i < Pool_Size; i++ ) { + if(( My_Connections[i].sock > NONE ) && ( array_bytes(&My_Connections[i].rbuf) > 0 ) && ( My_Connections[i].delaytime < t )) { /* Kann aus dem Buffer noch ein Befehl extrahiert werden? */ - if( Handle_Buffer( i )) timeout = false; + if (Handle_Buffer( i )) timeout = false; } } /* noch volle Schreib-Puffer suchen */ - FD_ZERO( &write_sockets ); - for( i = 0; i < Pool_Size; i++ ) - { + for( i = 0; i < Pool_Size; i++ ) { + if ( My_Connections[i].sock <= NONE ) + continue; + + wdatalen = (unsigned int)array_bytes(&My_Connections[i].wbuf); + #ifdef ZLIB - if(( My_Connections[i].sock > NONE ) && (( My_Connections[i].wdatalen > 0 ) || ( My_Connections[i].zip.wdatalen > 0 ))) + if (( wdatalen > 0 ) || ( array_bytes(&My_Connections[i].zip.wbuf)> 0 )) #else - if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].wdatalen > 0 )) + if ( wdatalen > 0 ) #endif { /* Socket der Verbindung in Set aufnehmen */ - FD_SET( My_Connections[i].sock, &write_sockets ); + io_event_add( My_Connections[i].sock, IO_WANTWRITE ); } } - /* Sockets mit im Aufbau befindlichen ausgehenden Verbindungen suchen */ - for( i = 0; i < Pool_Size; i++ ) - { - if ( My_Connections[i].sock > NONE ) { - if ( Conn_OPTION_ISSET( &My_Connections[i], CONN_ISCONNECTING )) { - FD_SET( My_Connections[i].sock, &write_sockets ); - } - } - - } - /* von welchen Sockets koennte gelesen werden? */ - read_sockets = My_Sockets; - for( i = 0; i < Pool_Size; i++ ) - { - if ( My_Connections[i].sock > NONE ) { - if ( My_Connections[i].res_stat ) { - /* wait for completion of Resolver Sub-Process */ - FD_CLR( My_Connections[i].sock, &read_sockets ); - continue; - } + for (i = 0; i < Pool_Size; i++ ) { + if ( My_Connections[i].sock <= NONE ) + continue; - if ( Conn_OPTION_ISSET( &My_Connections[i], CONN_ISCONNECTING )) { - /* wait for completion of connect() */ - FD_CLR( My_Connections[i].sock, &read_sockets ); - continue; - } - } - if( My_Connections[i].delaytime > t ) - { - /* Fuer die Verbindung ist eine "Penalty-Zeit" gesetzt */ - FD_CLR( My_Connections[i].sock, &read_sockets ); + if (Resolve_INPROGRESS(&My_Connections[i].res_stat)) { + /* wait for completion of Resolver Sub-Process */ + io_event_del( My_Connections[i].sock, IO_WANTREAD ); + continue; } - } - for( i = 0; i < Conn_MaxFD + 1; i++ ) - { - /* Pipes von Resolver Sub-Prozessen aufnehmen */ - if( FD_ISSET( i, &Resolver_FDs )) - { - FD_SET( i, &read_sockets ); - } - } - /* Timeout initialisieren */ - tv.tv_usec = 0; - if( timeout ) tv.tv_sec = 1; - else tv.tv_sec = 0; + if ( Conn_OPTION_ISSET( &My_Connections[i], CONN_ISCONNECTING )) + continue; /* wait for completion of connect() */ - /* Auf Aktivitaet warten */ - i = select( Conn_MaxFD + 1, &read_sockets, &write_sockets, NULL, &tv ); - if( i == 0 ) - { - /* keine Veraenderung an den Sockets */ - continue; - } - if( i == -1 ) - { - /* Fehler (z.B. Interrupt) */ - if( errno != EINTR ) - { - Log( LOG_EMERG, "Conn_Handler(): select(): %s!", strerror( errno )); - Log( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME ); - exit( 1 ); + if( My_Connections[i].delaytime > t ) { + /* Fuer die Verbindung ist eine "Penalty-Zeit" gesetzt */ + io_event_del( My_Connections[i].sock, IO_WANTREAD ); + continue; } - continue; + io_event_add( My_Connections[i].sock, IO_WANTREAD ); } - /* Koennen Daten geschrieben werden? */ - for( i = 0; i < Conn_MaxFD + 1; i++ ) - { - if( ! FD_ISSET( i, &write_sockets )) continue; - - /* Es kann geschrieben werden ... */ - idx = Socket2Index( i ); - if( idx == NONE ) continue; - - if( ! Handle_Write( idx )) - { - /* Fehler beim Schreiben! Diesen Socket nun - * auch aus dem Read-Set entfernen: */ - FD_CLR( i, &read_sockets ); - } - } + /* (re-)set timeout - tv_sec/usec are undefined after io_dispatch() returns */ + tv.tv_usec = 0; + tv.tv_sec = timeout ? 1 : 0; - /* Daten zum Lesen vorhanden? */ - for( i = 0; i < Conn_MaxFD + 1; i++ ) - { - if( FD_ISSET( i, &read_sockets )) Handle_Read( i ); + /* wait for activity */ + i = io_dispatch( &tv ); + if (i == -1 && errno != EINTR ) { + Log(LOG_EMERG, "Conn_Handler(): io_dispatch(): %s!", strerror(errno)); + Log(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME); + exit( 1 ); } } @@ -538,6 +561,7 @@ #endif { char buffer[COMMAND_LEN]; + size_t len; bool ok; va_list ap; @@ -549,8 +573,7 @@ #else va_start( ap ); #endif - - if (vsnprintf(buffer, COMMAND_LEN - 2, Format, ap) >= COMMAND_LEN - 2) { + if (vsnprintf( buffer, COMMAND_LEN - 2, Format, ap ) >= COMMAND_LEN - 2 ) { /* * The string that should be written to the socket is longer * than the allowed size of COMMAND_LEN bytes (including both @@ -583,8 +606,8 @@ Log(LOG_DEBUG, " -> connection %d: '%s'.", Idx, buffer); #endif - strlcat( buffer, "\r\n", sizeof( buffer )); - ok = Conn_Write( Idx, buffer, strlen( buffer )); + len = strlcat( buffer, "\r\n", sizeof( buffer )); + ok = Conn_Write(Idx, buffer, len); My_Connections[Idx].msg_out++; va_end( ap ); @@ -593,7 +616,7 @@ GLOBAL bool -Conn_Write( CONN_ID Idx, char *Data, int Len ) +Conn_Write( CONN_ID Idx, char *Data, size_t Len ) { /* Daten in Socket schreiben. Bei "fatalen" Fehlern wird * der Client disconnectiert und false geliefert. */ @@ -606,26 +629,21 @@ * "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. */ - if( My_Connections[Idx].sock <= NONE ) - { -#ifdef DEBUG - Log( LOG_DEBUG, "Skipped write on closed socket (connection %d).", Idx ); -#endif + if( My_Connections[Idx].sock <= NONE ) { + 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( WRITEBUFFER_LEN - My_Connections[Idx].wdatalen - Len <= 0 ) - { + 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; - /* nun neu pruefen: */ - if( WRITEBUFFER_LEN - My_Connections[Idx].wdatalen - Len <= 0 ) - { + /* 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; @@ -641,8 +659,9 @@ #endif { /* Daten in Puffer kopieren */ - memcpy( My_Connections[Idx].wbuf + My_Connections[Idx].wdatalen, Data, Len ); - My_Connections[Idx].wdatalen += Len; + if (!array_catb( &My_Connections[Idx].wbuf, Data, Len )) + return false; + My_Connections[Idx].bytes_out += Len; } @@ -673,9 +692,7 @@ if( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ISCLOSING )) { /* Conn_Close() has been called recursively for this link; * probabe reason: Handle_Write() failed -- see below. */ -#ifdef DEBUG - Log( LOG_DEBUG, "Recursive request to close connection: %d", Idx ); -#endif + LogDebug("Recursive request to close connection: %d", Idx ); return; } @@ -684,14 +701,19 @@ /* Mark link as "closing" */ Conn_OPTION_ADD( &My_Connections[Idx], CONN_ISCLOSING ); - if( LogMsg ) txt = LogMsg; - else txt = FwdMsg; - if( ! txt ) txt = "Reason unknown"; - - Log( LOG_INFO, "Shutting down connection %d (%s) with %s:%d ...", Idx, LogMsg ? LogMsg : FwdMsg, My_Connections[Idx].host, ntohs( My_Connections[Idx].addr.sin_port )); + if (LogMsg) + txt = LogMsg; + else + txt = FwdMsg; + if (! txt) + txt = "Reason unknown"; + + Log(LOG_INFO, "Shutting down connection %d (%s) with %s:%d ...", Idx, + LogMsg ? LogMsg : FwdMsg, My_Connections[Idx].host, + ntohs(My_Connections[Idx].addr.sin_port)); /* Search client, if any */ - c = Client_GetFromConn( Idx ); + c = Conn_GetClient( Idx ); /* Should the client be informed? */ if (InformClient) { @@ -699,8 +721,9 @@ /* Send statistics to client if registered as user: */ if ((c != NULL) && (Client_Type(c) == CLIENT_USER)) { Conn_WriteStr( Idx, - "NOTICE %s :%sConnection statistics: client %.1f kb, server %.1f kb.", - Client_ID(Client_ThisServer()), NOTICE_TXTPREFIX, + ":%s NOTICE %s :%sConnection statistics: client %.1f kb, server %.1f kb.", + Client_ID(Client_ThisServer()), Client_ID(c), + NOTICE_TXTPREFIX, (double)My_Connections[Idx].bytes_in / 1024, (double)My_Connections[Idx].bytes_out / 1024); } @@ -720,42 +743,60 @@ (void)Handle_Write( Idx ); /* Search client, if any (re-check!) */ - c = Client_GetFromConn( Idx ); + c = Conn_GetClient( Idx ); /* Shut down socket */ - if( close( My_Connections[Idx].sock ) != 0 ) - { + if (! io_close(My_Connections[Idx].sock)) { /* Oops, we can't close the socket!? This is ... ugly! */ - Log( LOG_CRIT, "Error closing connection %d (socket %d) with %s:%d - %s! (ignored)", Idx, My_Connections[Idx].sock, My_Connections[Idx].host, ntohs( My_Connections[Idx].addr.sin_port), strerror( errno )); + Log(LOG_CRIT, + "Error closing connection %d (socket %d) with %s:%d - %s! (ignored)", + Idx, My_Connections[Idx].sock, My_Connections[Idx].host, + ntohs(My_Connections[Idx].addr.sin_port), strerror(errno)); } /* Mark socket as invalid: */ - FD_CLR( My_Connections[Idx].sock, &My_Sockets ); My_Connections[Idx].sock = NONE; /* If there is still a client, unregister it now */ - if( c ) Client_Destroy( c, LogMsg, FwdMsg, true ); + if (c) + Client_Destroy(c, LogMsg, FwdMsg, true); /* Calculate statistics and log information */ in_k = (double)My_Connections[Idx].bytes_in / 1024; out_k = (double)My_Connections[Idx].bytes_out / 1024; #ifdef ZLIB - if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) { + if (Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP)) { in_z_k = (double)My_Connections[Idx].zip.bytes_in / 1024; out_z_k = (double)My_Connections[Idx].zip.bytes_out / 1024; + /* Make sure that no division by zero can occur during + * the calculation of in_p and out_p: in_z_k and out_z_k + * are non-zero, that's guaranteed by the protocol until + * compression can be enabled. */ + if (! in_z_k) + in_z_k = in_k; + if (! out_z_k) + out_z_k = out_k; in_p = (int)(( in_k * 100 ) / in_z_k ); out_p = (int)(( out_k * 100 ) / out_z_k ); - Log( LOG_INFO, "Connection %d with %s:%d closed (in: %.1fk/%.1fk/%d%%, out: %.1fk/%.1fk/%d%%).", Idx, My_Connections[Idx].host, ntohs( My_Connections[Idx].addr.sin_port ), in_k, in_z_k, in_p, out_k, out_z_k, out_p ); + Log(LOG_INFO, + "Connection %d with %s:%d closed (in: %.1fk/%.1fk/%d%%, out: %.1fk/%.1fk/%d%%).", + Idx, My_Connections[Idx].host, + ntohs(My_Connections[Idx].addr.sin_port), + in_k, in_z_k, in_p, out_k, out_z_k, out_p); } else #endif { - Log( LOG_INFO, "Connection %d with %s:%d closed (in: %.1fk, out: %.1fk).", Idx, My_Connections[Idx].host, ntohs( My_Connections[Idx].addr.sin_port ), in_k, out_k ); + Log(LOG_INFO, + "Connection %d with %s:%d closed (in: %.1fk, out: %.1fk).", + Idx, My_Connections[Idx].host, + ntohs(My_Connections[Idx].addr.sin_port), + in_k, out_k); } - /* Is there a resolver sub-process running? */ - if( My_Connections[Idx].res_stat ) - FreeRes_stat( &My_Connections[Idx] ); + /* cancel running resolver */ + if (Resolve_INPROGRESS(&My_Connections[Idx].res_stat)) + Resolve_Shutdown(&My_Connections[Idx].res_stat); /* Servers: Modify time of next connect attempt? */ Conf_UnsetServer( Idx ); @@ -765,15 +806,18 @@ if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) { inflateEnd( &My_Connections[Idx].zip.in ); deflateEnd( &My_Connections[Idx].zip.out ); + array_free(&My_Connections[Idx].zip.rbuf); + array_free(&My_Connections[Idx].zip.wbuf); } #endif + array_free(&My_Connections[Idx].rbuf); + array_free(&My_Connections[Idx].wbuf); + /* Clean up connection structure (=free it) */ Init_Conn_Struct( Idx ); -#ifdef DEBUG - Log( LOG_DEBUG, "Shutdown of connection %d completed.", Idx ); -#endif + LogDebug("Shutdown of connection %d completed.", Idx ); } /* Conn_Close */ @@ -787,13 +831,13 @@ CONN_ID i; int c; - for( i = 0; i < Pool_Size; i++ ) - { + for( i = 0; i < Pool_Size; i++ ) { /* Established connection? */ - if( My_Connections[i].sock <= NONE ) continue; + if (My_Connections[i].sock < 0) + continue; /* Server connection? */ - client = Client_GetFromConn( i ); + client = Conn_GetClient( i ); if(( ! client ) || ( Client_Type( client ) != CLIENT_SERVER )) continue; for( c = 0; c < MAX_SERVERS; c++ ) @@ -802,132 +846,75 @@ if( ! Conf_Server[c].host[0] ) continue; /* Duplicate? */ - if( strcmp( Conf_Server[c].name, Client_ID( client )) == 0 ) Conf_Server[c].conn_id = i; + if( strcmp( Conf_Server[c].name, Client_ID( client )) == 0 ) + Conf_Server[c].conn_id = i; } } } /* SyncServerStruct */ -LOCAL void -Handle_Read( int Sock ) -{ - /* Aktivitaet auf einem Socket verarbeiten: - * - neue Clients annehmen, - * - Daten von Clients verarbeiten, - * - Resolver-Rueckmeldungen annehmen. */ - - CONN_ID idx; - - assert( Sock > NONE ); - - if( FD_ISSET( Sock, &My_Listeners )) - { - /* es ist einer unserer Listener-Sockets: es soll - * also eine neue Verbindung aufgebaut werden. */ - - New_Connection( Sock ); - } - else if( FD_ISSET( Sock, &Resolver_FDs )) - { - /* Rueckmeldung von einem Resolver Sub-Prozess */ - - Read_Resolver_Result( Sock ); - } - else - { - /* Ein Client Socket: entweder ein User oder Server */ - - idx = Socket2Index( Sock ); - if( idx > NONE ) Read_Request( idx ); - } -} /* Handle_Read */ - - -LOCAL bool +/** + * Send out data of write buffer; connect new sockets. + */ +static bool Handle_Write( CONN_ID Idx ) { - /* Daten aus Schreibpuffer versenden bzw. Connection aufbauen */ - - int len, res, err; - socklen_t sock_len; - CLIENT *c; + ssize_t len; + size_t wdatalen; assert( Idx > NONE ); + if ( My_Connections[Idx].sock < 0 ) { + LogDebug("Handle_Write() on closed socket, connection %d", Idx); + return false; + } assert( My_Connections[Idx].sock > NONE ); - if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ISCONNECTING )) { - /* connect() has finished, check result */ - - Conn_OPTION_DEL( &My_Connections[Idx], CONN_ISCONNECTING ); - - /* Ergebnis des connect() ermitteln */ - sock_len = sizeof( err ); - res = getsockopt( My_Connections[Idx].sock, SOL_SOCKET, SO_ERROR, &err, &sock_len ); - assert( sock_len == sizeof( err )); - - /* Error while connecting? */ - if ((res != 0) || (err != 0)) { - if (res != 0) - Log(LOG_CRIT, "getsockopt (connection %d): %s!", - Idx, strerror(errno)); - else - Log(LOG_CRIT, - "Can't connect socket to \"%s:%d\" (connection %d): %s!", - My_Connections[Idx].host, - 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 = Client_GetFromConn(Idx); - if (c) - Client_DestroyNow(c); - - Conn_Close(Idx, "Can't connect!", NULL, false); - - /* Set the timestamp of the last connect attempt */ - Conf_UnsetServer(Idx); - - return false; - } - Log( LOG_INFO, "Connection %d with \"%s:%d\" established. Now logging in ...", Idx, My_Connections[Idx].host, Conf_Server[Conf_GetServer( Idx )].port ); - - /* Send PASS and SERVER command to peer */ - Conn_WriteStr( Idx, "PASS %s %s", Conf_Server[Conf_GetServer( Idx )].pwd_out, NGIRCd_ProtoID ); - return Conn_WriteStr( Idx, "SERVER %s :%s", Conf_ServerName, Conf_ServerInfo ); - } + wdatalen = array_bytes(&My_Connections[Idx].wbuf ); #ifdef ZLIB - if(( My_Connections[Idx].wdatalen <= 0 ) && ( ! My_Connections[Idx].zip.wdatalen )) + if (wdatalen == 0 && !array_bytes(&My_Connections[Idx].zip.wbuf)) { + io_event_del(My_Connections[Idx].sock, IO_WANTWRITE ); return true; + } - /* write buffer empty, but not compression buf? -> flush compression buf. */ - if( My_Connections[Idx].wdatalen == 0 ) Zip_Flush( Idx ); + /* write buffer empty, but not compression buffer? + * -> flush compression buffer! */ + if (wdatalen == 0) + Zip_Flush(Idx); #else - if( My_Connections[Idx].wdatalen <= 0 ) + if (wdatalen == 0) { + io_event_del(My_Connections[Idx].sock, IO_WANTWRITE ); return true; + } #endif - len = write( My_Connections[Idx].sock, My_Connections[Idx].wbuf, My_Connections[Idx].wdatalen ); + /* 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); + + len = write(My_Connections[Idx].sock, + array_start(&My_Connections[Idx].wbuf), wdatalen ); + if( len < 0 ) { - if( errno == EAGAIN || errno == EINTR) + if (errno == EAGAIN || errno == EINTR) return true; - Log( LOG_ERR, "Write error on connection %d (socket %d): %s!", Idx, - My_Connections[Idx].sock, strerror( errno )); - Conn_Close( Idx, "Write error!", NULL, false ); + Log(LOG_ERR, "Write error on connection %d (socket %d): %s!", + Idx, My_Connections[Idx].sock, strerror(errno)); + Conn_Close(Idx, "Write error!", NULL, false); return false; } - /* Update buffer len and move any data not yet written to beginning of buf */ - My_Connections[Idx].wdatalen -= len; - memmove( My_Connections[Idx].wbuf, My_Connections[Idx].wbuf + len, My_Connections[Idx].wdatalen ); + /* move any data not yet written to beginning */ + array_moveleft(&My_Connections[Idx].wbuf, 1, (size_t)len); return true; } /* Handle_Write */ -LOCAL void +static int New_Connection( int Sock ) { /* Neue Client-Verbindung von Listen-Socket annehmen und @@ -937,22 +924,18 @@ struct request_info req; #endif struct sockaddr_in new_addr; - int new_sock, new_sock_len; - RES_STAT *s; - CONN_ID idx; + int new_sock, new_sock_len, new_Pool_Size; CLIENT *c; - POINTER *ptr; - long new_size, cnt; + long cnt; assert( Sock > NONE ); - /* Connection auf Listen-Socket annehmen */ - new_sock_len = sizeof( new_addr ); - new_sock = accept( Sock, (struct sockaddr *)&new_addr, (socklen_t *)&new_sock_len ); - if( new_sock < 0 ) - { - Log( LOG_CRIT, "Can't accept connection: %s!", strerror( errno )); - return; + new_sock_len = (int)sizeof new_addr; + new_sock = accept(Sock, (struct sockaddr *)&new_addr, + (socklen_t *)&new_sock_len); + if (new_sock < 0) { + Log(LOG_CRIT, "Can't accept connection: %s!", strerror(errno)); + return -1; } #ifdef TCPWRAP @@ -965,12 +948,13 @@ Log( deny_severity, "Refused connection from %s (by TCP Wrappers)!", inet_ntoa( new_addr.sin_addr )); Simple_Message( new_sock, "ERROR :Connection refused" ); close( new_sock ); - return; + return -1; } #endif /* Socket initialisieren */ - Init_Socket( new_sock ); + if (!Init_Socket( new_sock )) + return -1; /* Check IP-based connection limit */ cnt = Count_Connections( new_addr ); @@ -980,243 +964,220 @@ Log( LOG_ERR, "Refused connection from %s: too may connections (%ld) from this IP address!", inet_ntoa( new_addr.sin_addr ), cnt); Simple_Message( new_sock, "ERROR :Connection refused, too many connections from your IP address!" ); close( new_sock ); - return; + return -1; } - /* Freie Connection-Struktur suchen */ - for( idx = 0; idx < Pool_Size; idx++ ) if( My_Connections[idx].sock == NONE ) break; - if( idx >= Pool_Size ) - { - new_size = Pool_Size + CONNECTION_POOL; - - /* Im bisherigen Pool wurde keine freie Connection-Struktur mehr gefunden. - * Wenn erlaubt und moeglich muss nun der Pool vergroessert werden: */ - - if( Conf_MaxConnections > 0 ) - { - /* Es ist ein Limit konfiguriert */ - if( Pool_Size >= Conf_MaxConnections ) - { - /* Mehr Verbindungen duerfen wir leider nicht mehr annehmen ... */ - Log( LOG_ALERT, "Can't accept connection: limit (%d) reached!", Pool_Size ); - Simple_Message( new_sock, "ERROR :Connection limit reached" ); - close( new_sock ); - return; - } - if( new_size > Conf_MaxConnections ) new_size = Conf_MaxConnections; - } - if( new_size < Pool_Size ) + if( new_sock >= Pool_Size ) { + new_Pool_Size = new_sock + 1; + /* No free Connection Structures, check if we may accept further connections */ + if ((( Conf_MaxConnections > 0) && Pool_Size >= Conf_MaxConnections) || + (new_Pool_Size < Pool_Size)) { - Log( LOG_ALERT, "Can't accept connection: limit (%d) reached -- overflow!", Pool_Size ); + Log( LOG_ALERT, "Can't accept connection: limit (%d) reached!", Pool_Size ); Simple_Message( new_sock, "ERROR :Connection limit reached" ); close( new_sock ); - return; + return -1; } - ptr = (POINTER *)realloc( My_Connections, sizeof( CONNECTION ) * new_size ); - if( ! ptr ) - { + if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), + (size_t)new_sock)) { Log( LOG_EMERG, "Can't allocate memory! [New_Connection]" ); Simple_Message( new_sock, "ERROR: Internal error" ); close( new_sock ); - return; + return -1; } - -#ifdef DEBUG - Log( LOG_DEBUG, "Allocated new connection pool for %ld items (%ld bytes). [realloc()]", new_size, sizeof( CONNECTION ) * new_size ); -#endif + LogDebug("Bumped connection pool to %ld items (internal: %ld items, %ld bytes)", + new_sock, array_length(&My_ConnArray, sizeof(CONNECTION)), array_bytes(&My_ConnArray)); /* Adjust pointer to new block */ - My_Connections = (CONNECTION *)ptr; - - /* Initialize new items */ - for( idx = Pool_Size; idx < new_size; idx++ ) Init_Conn_Struct( idx ); - idx = Pool_Size; - - /* Adjust new pool size */ - Pool_Size = new_size; + My_Connections = array_start(&My_ConnArray); + while (Pool_Size < new_Pool_Size) + Init_Conn_Struct(Pool_Size++); } - /* Client-Struktur initialisieren */ - c = Client_NewLocal( idx, inet_ntoa( new_addr.sin_addr ), CLIENT_UNKNOWN, false ); - if( ! c ) - { + 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 ); - return; + return -1; } - /* Verbindung registrieren */ - Init_Conn_Struct( idx ); - My_Connections[idx].sock = new_sock; - My_Connections[idx].addr = new_addr; - - /* Neuen Socket registrieren */ - FD_SET( new_sock, &My_Sockets ); - if( new_sock > Conn_MaxFD ) Conn_MaxFD = new_sock; + Init_Conn_Struct( new_sock ); + My_Connections[new_sock].sock = new_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.", idx, inet_ntoa( new_addr.sin_addr ), ntohs( new_addr.sin_port), Sock ); + 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 ); /* Hostnamen ermitteln */ - strlcpy( My_Connections[idx].host, inet_ntoa( new_addr.sin_addr ), sizeof( My_Connections[idx].host )); - Client_SetHostname( c, My_Connections[idx].host ); -#ifdef IDENTAUTH - s = Resolve_Addr( &new_addr, My_Connections[idx].sock ); -#else - s = Resolve_Addr( &new_addr ); -#endif - /* resolver process has been started */ - if( s ) My_Connections[idx].res_stat = s; + strlcpy( My_Connections[new_sock].host, inet_ntoa( new_addr.sin_addr ), + sizeof( My_Connections[new_sock].host )); + + Client_SetHostname( c, My_Connections[new_sock].host ); + + Resolve_Addr(&My_Connections[new_sock].res_stat, &new_addr, + My_Connections[new_sock].sock, cb_Read_Resolver_Result); /* Penalty-Zeit setzen */ - Conn_SetPenalty( idx, 4 ); + Conn_SetPenalty( new_sock, 4 ); + return new_sock; } /* New_Connection */ -LOCAL CONN_ID +static CONN_ID Socket2Index( int Sock ) { /* zum Socket passende Connection suchen */ - CONN_ID idx; - - assert( Sock > NONE ); - - for( idx = 0; idx < Pool_Size; idx++ ) if( My_Connections[idx].sock == Sock ) break; + assert( Sock >= 0 ); - if( idx >= Pool_Size ) - { + if( Sock >= Pool_Size || My_Connections[Sock].sock != Sock ) { /* die Connection wurde vermutlich (wegen eines * Fehlers) bereits wieder abgebaut ... */ -#ifdef DEBUG - Log( LOG_DEBUG, "Socket2Index: can't get connection for socket %d!", Sock ); -#endif + LogDebug("Socket2Index: can't get connection for socket %d!", Sock); return NONE; } - else return idx; + return Sock; } /* Socket2Index */ -LOCAL void +static void Read_Request( CONN_ID Idx ) { /* Daten von Socket einlesen und entsprechend behandeln. * Tritt ein Fehler auf, so wird der Socket geschlossen. */ - int len, bsize; -#ifdef ZLIB + ssize_t len; + char readbuf[1024]; CLIENT *c; -#endif assert( Idx > NONE ); assert( My_Connections[Idx].sock > NONE ); - /* wenn noch nicht registriert: maximal mit ZREADBUFFER_LEN arbeiten, - * ansonsten koennen Daten ggf. nicht umkopiert werden. */ - bsize = READBUFFER_LEN; #ifdef ZLIB - c = Client_GetFromConn( Idx ); - if(( Client_Type( c ) != CLIENT_USER ) && ( Client_Type( c ) != CLIENT_SERVER ) && ( Client_Type( c ) != CLIENT_SERVICE ) && ( bsize > ZREADBUFFER_LEN )) bsize = ZREADBUFFER_LEN; -#endif - -#ifdef ZLIB - if(( bsize - My_Connections[Idx].rdatalen - 1 < 1 ) || ( ZREADBUFFER_LEN - My_Connections[Idx].zip.rdatalen < 1 )) + if (( array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN ) || + ( array_bytes(&My_Connections[Idx].zip.rbuf) >= ZREADBUFFER_LEN )) #else - if( bsize - My_Connections[Idx].rdatalen - 1 < 1 ) + 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, My_Connections[Idx].rdatalen ); + 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; } -#ifdef ZLIB - if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) { - len = recv( My_Connections[Idx].sock, My_Connections[Idx].zip.rbuf + My_Connections[Idx].zip.rdatalen, ( ZREADBUFFER_LEN - My_Connections[Idx].zip.rdatalen ), 0 ); - if( len > 0 ) My_Connections[Idx].zip.rdatalen += len; - } - else -#endif - { - len = recv( My_Connections[Idx].sock, My_Connections[Idx].rbuf + My_Connections[Idx].rdatalen, bsize - My_Connections[Idx].rdatalen - 1, 0 ); - if( len > 0 ) My_Connections[Idx].rdatalen += len; - } - - if( len == 0 ) - { - /* Socket wurde geschlossen */ - 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 )); + 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 ); return; } - if( len < 0 ) - { - /* Operation haette Socket "nur" blockiert ... */ + if( len < 0 ) { if( errno == EAGAIN ) return; - - /* Fehler beim Lesen */ - Log( LOG_ERR, "Read error on connection %d (socket %d): %s!", Idx, My_Connections[Idx].sock, strerror( errno )); + 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 + if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_ZIP)) { + if (!array_catb(&My_Connections[Idx].zip.rbuf, readbuf, + (size_t) len)) { + Log(LOG_ERR, + "Could not append recieved data to zip input buffer (connn %d): %d bytes!", + Idx, len); + Conn_Close(Idx, "Receive buffer overflow!", NULL, + false); + return; + } + } else +#endif + { + readbuf[len] = 0; + if (!array_cats( &My_Connections[Idx].rbuf, readbuf )) { + 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 ); + } + } - /* Connection-Statistik aktualisieren */ + /* Update connection statistics */ My_Connections[Idx].bytes_in += len; - /* Timestamp aktualisieren */ - My_Connections[Idx].lastdata = time( NULL ); + /* Update timestamp of last data received if this connection is + * registered as a user, server or service connection. Don't update + * otherwise, so users have at least Conf_PongTimeout seconds time to + * register with the IRC server -- see Check_Connections(). + * Set "lastping", too, so we can handle time shifts backwards ... */ + c = Conn_GetClient(Idx); + if (c && (Client_Type(c) == CLIENT_USER + || Client_Type(c) == CLIENT_SERVER + || Client_Type(c) == CLIENT_SERVICE)) { + My_Connections[Idx].lastdata = time(NULL); + My_Connections[Idx].lastping = My_Connections[Idx].lastdata; + } - Handle_Buffer( Idx ); + /* Look at the data in the (read-) buffer of this connection */ + Handle_Buffer(Idx); } /* Read_Request */ -LOCAL bool +static bool Handle_Buffer( CONN_ID Idx ) { - /* Daten im Lese-Puffer einer Verbindung verarbeiten. - * Wurde ein Request verarbeitet, so wird true geliefert, - * ansonsten false (auch bei Fehlern). */ - + /* Handle Data in Connections Read-Buffer. + * Return true if a reuqest was handled, false otherwise (also returned on errors). */ #ifndef STRICT_RFC char *ptr1, *ptr2; #endif char *ptr; - int len, delta; - bool action, result; + size_t len, delta; + bool result; + time_t starttime; #ifdef ZLIB bool old_z; #endif + starttime = time(NULL); result = false; - do - { + for (;;) { /* Check penalty */ - if( My_Connections[Idx].delaytime > time( NULL )) return result; - + if( My_Connections[Idx].delaytime > starttime) return result; #ifdef ZLIB - /* ggf. noch unkomprimiete Daten weiter entpacken */ + /* unpack compressed data */ if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) if( ! Unzip_Buffer( Idx )) return false; #endif - if( My_Connections[Idx].rdatalen < 1 ) break; + if (0 == array_bytes(&My_Connections[Idx].rbuf)) + break; - /* Eine komplette Anfrage muss mit CR+LF enden, vgl. - * RFC 2812. Haben wir eine? */ - My_Connections[Idx].rbuf[My_Connections[Idx].rdatalen] = '\0'; - ptr = strstr( My_Connections[Idx].rbuf, "\r\n" ); + if (!array_cat0_temporary(&My_Connections[Idx].rbuf)) /* make sure buf is NULL terminated */ + return false; + + /* A Complete Request end with CR+LF, see RFC 2812. */ + ptr = strstr( array_start(&My_Connections[Idx].rbuf), "\r\n" ); - if( ptr ) delta = 2; + if( ptr ) delta = 2; /* complete request */ #ifndef STRICT_RFC - else - { - /* Nicht RFC-konforme Anfrage mit nur CR oder LF? Leider - * machen soetwas viele Clients, u.a. "mIRC" :-( */ - ptr1 = strchr( My_Connections[Idx].rbuf, '\r' ); - ptr2 = strchr( My_Connections[Idx].rbuf, '\n' ); + else { + /* Check for non-RFC-compliant request (only CR or LF)? Unfortunately, + * there are quite a few clients that do this (incl. "mIRC" :-( */ + ptr1 = strchr( array_start(&My_Connections[Idx].rbuf), '\r' ); + ptr2 = strchr( array_start(&My_Connections[Idx].rbuf), '\n' ); delta = 1; if( ptr1 && ptr2 ) ptr = ptr1 > ptr2 ? ptr2 : ptr1; else if( ptr1 ) ptr = ptr1; @@ -1224,194 +1185,162 @@ } #endif - action = false; - if( ptr ) - { - /* Ende der Anfrage wurde gefunden */ - *ptr = '\0'; - len = ( ptr - My_Connections[Idx].rbuf ) + delta; - if( len > ( COMMAND_LEN - 1 )) - { - /* Eine Anfrage darf(!) nicht laenger als 512 Zeichen - * (incl. CR+LF!) werden; vgl. RFC 2812. Wenn soetwas - * empfangen wird, wird der Client disconnectiert. */ - Log( LOG_ERR, "Request too long (connection %d): %d bytes (max. %d expected)!", Idx, My_Connections[Idx].rdatalen, COMMAND_LEN - 1 ); - Conn_Close( Idx, NULL, "Request too long", true ); - return false; - } + if( ! ptr ) + break; + /* End of request found */ + *ptr = '\0'; + + len = ( ptr - (char*) array_start(&My_Connections[Idx].rbuf)) + delta; + + if( len > ( COMMAND_LEN - 1 )) { + /* Request must not exceed 512 chars (incl. CR+LF!), see + * RFC 2812. Disconnect Client if this happens. */ + Log( LOG_ERR, "Request too long (connection %d): %d bytes (max. %d expected)!", + Idx, array_bytes(&My_Connections[Idx].rbuf), COMMAND_LEN - 1 ); + Conn_Close( Idx, NULL, "Request too long", true ); + return false; + } + + if (len <= 2) { /* request was empty (only '\r\n') */ + array_moveleft(&My_Connections[Idx].rbuf, 1, delta); /* delta is either 1 or 2 */ + break; + } #ifdef ZLIB - /* merken, ob Stream bereits komprimiert wird */ - old_z = My_Connections[Idx].options & CONN_ZIP; + /* remember if stream is already compressed */ + old_z = My_Connections[Idx].options & CONN_ZIP; #endif - if( len > delta ) - { - /* Es wurde ein Request gelesen */ - My_Connections[Idx].msg_in++; - if( ! Parse_Request( Idx, My_Connections[Idx].rbuf )) return false; - else action = true; - } + My_Connections[Idx].msg_in++; + if (!Parse_Request(Idx, (char*)array_start(&My_Connections[Idx].rbuf) )) + return false; - /* Puffer anpassen */ - My_Connections[Idx].rdatalen -= len; - memmove( My_Connections[Idx].rbuf, My_Connections[Idx].rbuf + len, My_Connections[Idx].rdatalen ); + result = true; + array_moveleft(&My_Connections[Idx].rbuf, 1, len); + LogDebug("Connection %d: %d bytes left in read buffer.", + Idx, array_bytes(&My_Connections[Idx].rbuf)); #ifdef ZLIB - if(( ! old_z ) && ( My_Connections[Idx].options & CONN_ZIP ) && ( My_Connections[Idx].rdatalen > 0 )) - { - /* Mit dem letzten Befehl wurde Socket-Kompression aktiviert. - * Evtl. schon vom Socket gelesene Daten in den Unzip-Puffer - * umkopieren, damit diese nun zunaechst entkomprimiert werden */ - if( My_Connections[Idx].rdatalen > ZREADBUFFER_LEN ) - { - /* Hupsa! Soviel Platz haben wir aber gar nicht! */ - Log( LOG_ALERT, "Can't move receive buffer: No space left in unzip buffer (need %d bytes)!", My_Connections[Idx].rdatalen ); - return false; - } - memcpy( My_Connections[Idx].zip.rbuf, My_Connections[Idx].rbuf, My_Connections[Idx].rdatalen ); - My_Connections[Idx].zip.rdatalen = My_Connections[Idx].rdatalen; - My_Connections[Idx].rdatalen = 0; -#ifdef DEBUG - Log( LOG_DEBUG, "Moved already received data (%d bytes) to uncompression buffer.", My_Connections[Idx].zip.rdatalen ); -#endif /* DEBUG */ + if(( ! old_z ) && ( My_Connections[Idx].options & CONN_ZIP ) && + ( array_bytes(&My_Connections[Idx].rbuf) > 0 )) + { + /* 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; } -#endif /* ZLIB */ - } - - if( action ) result = true; - } while( action ); + if (!array_copy( &My_Connections[Idx].zip.rbuf, &My_Connections[Idx].rbuf )) + return false; + array_trunc(&My_Connections[Idx].rbuf); + LogDebug("Moved already received data (%u bytes) to uncompression buffer.", + array_bytes(&My_Connections[Idx].zip.rbuf)); + } +#endif /* ZLIB */ + } return result; } /* Handle_Buffer */ -LOCAL void -Check_Connections( void ) +static void +Check_Connections(void) { - /* Pruefen, ob Verbindungen noch "alive" sind. Ist dies - * nicht der Fall, zunaechst PING-PONG spielen und, wenn - * auch das nicht "hilft", Client disconnectieren. */ - + /* check if connections are alive. if not, play PING-PONG first. + * if this doesn't help either, disconnect client. */ CLIENT *c; CONN_ID i; - for( i = 0; i < Pool_Size; i++ ) - { - if( My_Connections[i].sock == NONE ) continue; + for (i = 0; i < Pool_Size; i++) { + if (My_Connections[i].sock < 0) + continue; - c = Client_GetFromConn( i ); - if( c && (( Client_Type( c ) == CLIENT_USER ) || ( Client_Type( c ) == CLIENT_SERVER ) || ( Client_Type( c ) == CLIENT_SERVICE ))) - { - /* verbundener User, Server oder Service */ - if( My_Connections[i].lastping > My_Connections[i].lastdata ) - { - /* es wurde bereits ein PING gesendet */ - if( My_Connections[i].lastping < time( NULL ) - Conf_PongTimeout ) - { + c = Conn_GetClient(i); + if (c && ((Client_Type(c) == CLIENT_USER) + || (Client_Type(c) == CLIENT_SERVER) + || (Client_Type(c) == CLIENT_SERVICE))) { + /* connected User, Server or Service */ + if (My_Connections[i].lastping > + My_Connections[i].lastdata) { + /* We already sent a ping */ + if (My_Connections[i].lastping < + time(NULL) - Conf_PongTimeout) { /* Timeout */ -#ifdef DEBUG - Log( LOG_DEBUG, "Connection %d: Ping timeout: %d seconds.", i, Conf_PongTimeout ); -#endif - Conn_Close( i, NULL, "Ping timeout", true ); + LogDebug + ("Connection %d: Ping timeout: %d seconds.", + i, Conf_PongTimeout); + Conn_Close(i, NULL, "Ping timeout", + true); } - } - else if( My_Connections[i].lastdata < time( NULL ) - Conf_PingTimeout ) - { - /* es muss ein PING gesendet werden */ -#ifdef DEBUG - Log( LOG_DEBUG, "Connection %d: sending PING ...", i ); -#endif - My_Connections[i].lastping = time( NULL ); - Conn_WriteStr( i, "PING :%s", Client_ID( Client_ThisServer( ))); - } - } - else - { - /* noch nicht vollstaendig aufgebaute Verbindung */ - if( My_Connections[i].lastdata < time( NULL ) - Conf_PingTimeout ) - { - /* Timeout */ -#ifdef DEBUG - Log( LOG_DEBUG, "Connection %d timed out ...", i ); -#endif - Conn_Close( i, NULL, "Timeout", false ); + } else if (My_Connections[i].lastdata < + time(NULL) - Conf_PingTimeout) { + /* We need to send a PING ... */ + LogDebug("Connection %d: sending PING ...", i); + My_Connections[i].lastping = time(NULL); + Conn_WriteStr(i, "PING :%s", + Client_ID(Client_ThisServer())); + } + } else { + /* The connection is not fully established yet, so + * we don't do the PING-PONG game here but instead + * disconnect the client after "a short time" if it's + * still not registered. */ + + if (My_Connections[i].lastdata < + time(NULL) - Conf_PongTimeout) { + LogDebug + ("Unregistered connection %d timed out ...", + i); + Conn_Close(i, NULL, "Timeout", false); } } } } /* Check_Connections */ -LOCAL void +static void Check_Servers( void ) { /* Check if we can establish further server links */ - RES_STAT *s; - CONN_ID idx; int i, n; - - /* Serach all connections, are there results from the resolver? */ - for( idx = 0; idx < Pool_Size; idx++ ) - { - if( My_Connections[idx].sock != SERVER_WAIT ) continue; - - /* IP resolved? */ - if( My_Connections[idx].res_stat == NULL ) New_Server( Conf_GetServer( idx ), idx ); - } + time_t time_now; /* Check all configured servers */ - for( i = 0; i < MAX_SERVERS; i++ ) - { + for( i = 0; i < MAX_SERVERS; i++ ) { /* Valid outgoing server which isn't already connected or disabled? */ - if(( ! Conf_Server[i].host[0] ) || ( ! Conf_Server[i].port > 0 ) || ( Conf_Server[i].conn_id > NONE ) || ( Conf_Server[i].flags & CONF_SFLAG_DISABLED )) continue; + if(( ! Conf_Server[i].host[0] ) || ( ! Conf_Server[i].port > 0 ) || + ( Conf_Server[i].conn_id > NONE ) || ( Conf_Server[i].flags & CONF_SFLAG_DISABLED )) + continue; /* Is there already a connection in this group? */ - if( Conf_Server[i].group > NONE ) - { - for( n = 0; n < MAX_SERVERS; n++ ) - { - if( n == i ) continue; - if(( Conf_Server[n].conn_id > NONE ) && ( Conf_Server[n].group == Conf_Server[i].group )) break; + if( Conf_Server[i].group > NONE ) { + for (n = 0; n < MAX_SERVERS; n++) { + if (n == i) continue; + if ((Conf_Server[n].conn_id > NONE) && + (Conf_Server[n].group == Conf_Server[i].group)) + break; } - if( n < MAX_SERVERS ) continue; + if (n < MAX_SERVERS) continue; } /* Check last connect attempt? */ - if( Conf_Server[i].lasttry > time( NULL ) - Conf_ConnectRetry ) continue; + time_now = time(NULL); + if( Conf_Server[i].lasttry > (time_now - Conf_ConnectRetry)) + continue; /* Okay, try to connect now */ - Conf_Server[i].lasttry = time( NULL ); - - /* Search free connection structure */ - for( idx = 0; idx < Pool_Size; idx++ ) if( My_Connections[idx].sock == NONE ) break; - if( idx >= Pool_Size ) - { - Log( LOG_ALERT, "Can't establist server connection: connection limit reached (%d)!", Pool_Size ); - return; - } -#ifdef DEBUG - Log( LOG_DEBUG, "Preparing connection %d for \"%s\" ...", idx, Conf_Server[i].host ); -#endif - - /* Verbindungs-Struktur initialisieren */ - Init_Conn_Struct( idx ); - My_Connections[idx].sock = SERVER_WAIT; - Conf_Server[i].conn_id = idx; - - /* Resolve Hostname. If this fails, try to use it as an IP address */ - strlcpy( Conf_Server[i].ip, Conf_Server[i].host, sizeof( Conf_Server[i].ip )); - strlcpy( My_Connections[idx].host, Conf_Server[i].host, sizeof( My_Connections[idx].host )); - s = Resolve_Name( Conf_Server[i].host ); - - /* resolver process running? */ - if( s ) My_Connections[idx].res_stat = s; + Conf_Server[i].lasttry = time_now; + assert(Resolve_Getfd(&Conf_Server[i].res_stat) < 0); + Resolve_Name(&Conf_Server[i].res_stat, Conf_Server[i].host, cb_Connect_to_Server); } } /* Check_Servers */ -LOCAL void -New_Server( int Server, CONN_ID Idx ) +static void +New_Server( int Server ) { /* Establish new server link */ @@ -1421,19 +1350,9 @@ CLIENT *c; assert( Server > NONE ); - assert( Idx > NONE ); - - /* Did we get a valid IP address? */ - if( ! Conf_Server[Server].ip[0] ) - { - /* No. Free connection structure and abort: */ - Init_Conn_Struct( Idx ); - Conf_Server[Server].conn_id = NONE; - Log( LOG_ERR, "Can't connect to \"%s\" (connection %d): ip address unknown!", Conf_Server[Server].host, Idx ); - return; - } - Log( LOG_INFO, "Establishing connection to \"%s\", %s, port %d (connection %d) ... ", Conf_Server[Server].host, Conf_Server[Server].ip, Conf_Server[Server].port, Idx ); + Log( LOG_INFO, "Establishing connection to \"%s\", %s, port %d ... ", Conf_Server[Server].host, + Conf_Server[Server].ip, Conf_Server[Server].port ); #ifdef HAVE_INET_ATON if( inet_aton( Conf_Server[Server].ip, &inaddr ) == 0 ) @@ -1443,100 +1362,104 @@ if( inaddr.s_addr == (unsigned)-1 ) #endif { - /* Can't convert IP address */ - Init_Conn_Struct( Idx ); - Conf_Server[Server].conn_id = NONE; - Log( LOG_ERR, "Can't connect to \"%s\" (connection %d): can't convert ip address %s!", Conf_Server[Server].host, Idx, Conf_Server[Server].ip ); + Log( LOG_ERR, "Can't connect to \"%s\": can't convert ip address %s!", + Conf_Server[Server].host, Conf_Server[Server].ip ); return; } memset( &new_addr, 0, sizeof( new_addr )); - new_addr.sin_family = AF_INET; + new_addr.sin_family = (sa_family_t)AF_INET; new_addr.sin_addr = inaddr; new_addr.sin_port = htons( Conf_Server[Server].port ); new_sock = socket( PF_INET, SOCK_STREAM, 0 ); - if ( new_sock < 0 ) - { - /* Can't create socket */ - Init_Conn_Struct( Idx ); - Conf_Server[Server].conn_id = NONE; + if ( new_sock < 0 ) { Log( LOG_CRIT, "Can't create socket: %s!", strerror( errno )); return; } if( ! Init_Socket( new_sock )) return; - res = connect( new_sock, (struct sockaddr *)&new_addr, sizeof( new_addr )); - if(( res != 0 ) && ( errno != EINPROGRESS )) - { - /* Can't connect socket */ + res = connect(new_sock, (struct sockaddr *)&new_addr, + (socklen_t)sizeof(new_addr)); + if(( res != 0 ) && ( errno != EINPROGRESS )) { Log( LOG_CRIT, "Can't connect socket: %s!", strerror( errno )); close( new_sock ); - Init_Conn_Struct( Idx ); - Conf_Server[Server].conn_id = NONE; return; } - - /* Client-Struktur initialisieren */ - c = Client_NewLocal( Idx, inet_ntoa( new_addr.sin_addr ), CLIENT_UNKNOWNSERVER, false ); - if( ! c ) - { - /* Can't create new client structure */ + + if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)new_sock)) { + Log(LOG_ALERT, + "Cannot allocate memory for server connection (socket %d)", + new_sock); close( new_sock ); - Init_Conn_Struct( Idx ); - Conf_Server[Server].conn_id = NONE; + return; + } + + My_Connections = array_start(&My_ConnArray); + + assert(My_Connections[new_sock].sock <= 0); + + Init_Conn_Struct(new_sock); + + c = Client_NewLocal( new_sock, inet_ntoa( new_addr.sin_addr ), CLIENT_UNKNOWNSERVER, false ); + if( ! c ) { Log( LOG_ALERT, "Can't establish connection: can't create client structure!" ); + close( new_sock ); return; } + Client_SetIntroducer( c, c ); Client_SetToken( c, TOKEN_OUTBOUND ); /* Register connection */ - My_Connections[Idx].sock = new_sock; - My_Connections[Idx].addr = new_addr; - strlcpy( My_Connections[Idx].host, Conf_Server[Server].host, sizeof( My_Connections[Idx].host )); + Conf_Server[Server].conn_id = new_sock; + My_Connections[new_sock].sock = new_sock; + My_Connections[new_sock].addr = new_addr; + My_Connections[new_sock].client = c; + strlcpy( My_Connections[new_sock].host, Conf_Server[Server].host, + sizeof(My_Connections[new_sock].host )); /* Register new socket */ - FD_SET( new_sock, &My_Sockets ); - Conn_OPTION_ADD( &My_Connections[Idx], CONN_ISCONNECTING ); - - if( new_sock > Conn_MaxFD ) Conn_MaxFD = new_sock; + if (!io_event_create( new_sock, IO_WANTWRITE, cb_connserver)) { + Log( LOG_ALERT, "io_event_create(): could not add fd %d", strerror(errno)); + Conn_Close( new_sock, "io_event_create() failed", NULL, false ); + Init_Conn_Struct( new_sock ); + Conf_Server[Server].conn_id = NONE; + } -#ifdef DEBUG - Log( LOG_DEBUG, "Registered new connection %d on socket %d.", Idx, My_Connections[Idx].sock ); -#endif + LogDebug("Registered new connection %d on socket %d.", + new_sock, My_Connections[new_sock].sock ); + Conn_OPTION_ADD( &My_Connections[new_sock], CONN_ISCONNECTING ); } /* New_Server */ -LOCAL void +static void Init_Conn_Struct( CONN_ID Idx ) { time_t now = time( NULL ); /* Connection-Struktur initialisieren */ memset( &My_Connections[Idx], 0, sizeof ( CONNECTION )); - My_Connections[Idx].sock = NONE; + My_Connections[Idx].sock = -1; My_Connections[Idx].lastdata = now; My_Connections[Idx].lastprivmsg = now; + Resolve_Init(&My_Connections[Idx].res_stat); } /* Init_Conn_Struct */ -LOCAL bool +static bool Init_Socket( int Sock ) { /* Initialize socket (set options) */ int value; -#ifdef O_NONBLOCK /* unknown on A/UX */ - if( fcntl( Sock, F_SETFL, O_NONBLOCK ) != 0 ) - { + if (!io_setnonblock(Sock)) { Log( LOG_CRIT, "Can't enable non-blocking mode for socket: %s!", strerror( errno )); close( Sock ); return false; } -#endif /* Don't block this port after socket shutdown */ value = 1; @@ -1549,9 +1472,7 @@ /* Set type of service (TOS) */ #if defined(IP_TOS) && defined(IPTOS_LOWDELAY) value = IPTOS_LOWDELAY; -#ifdef DEBUG - Log( LOG_DEBUG, "Setting option IP_TOS on socket %d to IPTOS_LOWDELAY (%d).", Sock, value ); -#endif + LogDebug("Setting option IP_TOS on socket %d to IPTOS_LOWDELAY (%d).", Sock, value ); if( setsockopt( Sock, SOL_IP, IP_TOS, &value, (socklen_t)sizeof( value )) != 0 ) { Log( LOG_ERR, "Can't set socket option IP_TOS: %s!", strerror( errno )); @@ -1563,137 +1484,126 @@ } /* Init_Socket */ -LOCAL void -Read_Resolver_Result( int r_fd ) + +static void +cb_Connect_to_Server(int fd, UNUSED short events) +{ + /* Read result of resolver sub-process from pipe and start connection */ + int i; + size_t len; + char readbuf[HOST_LEN + 1]; + + LogDebug("Resolver: Got forward lookup callback on fd %d, events %d", fd, events); + + for (i=0; i < MAX_SERVERS; i++) { + if (Resolve_Getfd(&Conf_Server[i].res_stat) == fd ) + break; + } + + if( i >= MAX_SERVERS) { + /* Ops, no matching server found?! */ + io_close( fd ); + LogDebug("Resolver: Got Forward Lookup callback for unknown server!?"); + return; + } + + /* Read result from pipe */ + len = Resolve_Read(&Conf_Server[i].res_stat, readbuf, sizeof readbuf -1); + if (len == 0) + return; + + readbuf[len] = '\0'; + LogDebug("Got result from resolver: \"%s\" (%u bytes read).", readbuf, len); + strlcpy( Conf_Server[i].ip, readbuf, sizeof( Conf_Server[i].ip )); + + /* connect() */ + New_Server(i); +} /* cb_Read_Forward_Lookup */ + + +static void +cb_Read_Resolver_Result( int r_fd, UNUSED short events ) { /* Read result of resolver sub-process from pipe and update the * apropriate connection/client structure(s): hostname and/or * IDENT user name.*/ CLIENT *c; - int len, i, n; - RES_STAT *s; - char *ptr; + int i; + size_t len; + char *identptr; +#ifdef IDENTAUTH + char readbuf[HOST_LEN + 2 + CLIENT_USER_LEN]; +#else + char readbuf[HOST_LEN + 1]; +#endif + + LogDebug("Resolver: Got callback on fd %d, events %d", r_fd, events ); /* Search associated connection ... */ - for( i = 0; i < Pool_Size; i++ ) - { + for( i = 0; i < Pool_Size; i++ ) { if(( My_Connections[i].sock != NONE ) - && ( My_Connections[i].res_stat != NULL ) - && ( My_Connections[i].res_stat->pipe[0] == r_fd )) + && ( Resolve_Getfd(&My_Connections[i].res_stat) == r_fd )) break; } - if( i >= Pool_Size ) - { + if( i >= Pool_Size ) { /* Ops, none found? Probably the connection has already * been closed!? We'll ignore that ... */ - FD_CLR( r_fd, &Resolver_FDs ); - close( r_fd ); -#ifdef DEBUG - Log( LOG_DEBUG, "Resolver: Got result for unknown connection!?" ); -#endif + io_close( r_fd ); + LogDebug("Resolver: Got callback for unknown connection!?"); return; } - /* Get resolver structure */ - s = My_Connections[i].res_stat; - assert( s != NULL ); - /* Read result from pipe */ - len = read( r_fd, s->buffer + s->bufpos, sizeof( s->buffer ) - s->bufpos - 1 ); - if( len < 0 ) - { - /* Error! */ - Log( LOG_CRIT, "Resolver: Can't read result: %s!", strerror( errno )); - FreeRes_stat( &My_Connections[i] ); + len = Resolve_Read(&My_Connections[i].res_stat, readbuf, sizeof readbuf -1); + if (len == 0) return; - } - s->bufpos += len; - s->buffer[s->bufpos] = '\0'; - /* If the result string is incomplete, return to main loop and - * wait until we can read in more bytes. */ -#ifdef IDENTAUTH -try_resolve: -#endif - ptr = strchr( s->buffer, '\n' ); - if( ! ptr ) return; - *ptr = '\0'; - -#ifdef DEBUG - Log( LOG_DEBUG, "Got result from resolver: \"%s\" (%d bytes), stage %d.", s->buffer, len, s->stage ); -#endif + readbuf[len] = '\0'; + identptr = strchr(readbuf, '\n'); + assert(identptr != NULL); + if (!identptr) { + Log( LOG_CRIT, "Resolver: Got malformed result!"); + return; + } + *identptr = '\0'; + LogDebug("Got result from resolver: \"%s\" (%u bytes read).", readbuf, len); /* Okay, we got a complete result: this is a host name for outgoing - * connections and a host name or IDENT user name (if enabled) for + * connections and a host name and IDENT user name (if enabled) for * incoming connections.*/ - if( My_Connections[i].sock > NONE ) - { - /* Incoming connection. Search client ... */ - c = Client_GetFromConn( i ); - assert( c != NULL ); + assert ( My_Connections[i].sock >= 0 ); + /* Incoming connection. Search client ... */ + c = Conn_GetClient( i ); + assert( c != NULL ); - /* Only update client information of unregistered clients */ - if( Client_Type( c ) == CLIENT_UNKNOWN ) - { - switch(s->stage) { - case 0: /* host name */ - strlcpy( My_Connections[i].host, s->buffer, sizeof( My_Connections[i].host )); - Client_SetHostname( c, s->buffer ); + /* Only update client information of unregistered clients */ + if( Client_Type( c ) == CLIENT_UNKNOWN ) { + strlcpy(My_Connections[i].host, readbuf, sizeof( My_Connections[i].host)); + Client_SetHostname( c, readbuf); #ifdef IDENTAUTH - /* clean up buffer for IDENT result */ - len = strlen( s->buffer ) + 1; - assert((size_t)len <= sizeof( s->buffer )); - memmove( s->buffer, s->buffer + len, sizeof( s->buffer ) - len ); - assert(len <= s->bufpos ); - s->bufpos -= len; - - /* Don't close pipe and clean up, but - * instead wait for IDENT result */ - s->stage = 1; - goto try_resolve; - - case 1: /* IDENT user name */ - if( s->buffer[0] ) - { - Log( LOG_INFO, "IDENT lookup for connection %ld: \"%s\".", i, s->buffer ); - Client_SetUser( c, s->buffer, true ); - } - else Log( LOG_INFO, "IDENT lookup for connection %ld: no result.", i ); -#endif - break; - default: - Log( LOG_ERR, "Resolver: got result for unknown stage %d!?", s->stage ); - } + ++identptr; + if (*identptr) { + Log( LOG_INFO, "IDENT lookup for connection %ld: \"%s\".", i, identptr); + Client_SetUser( c, identptr, true ); + } else { + Log( LOG_INFO, "IDENT lookup for connection %ld: no result.", i ); } +#endif + } #ifdef DEBUG else Log( LOG_DEBUG, "Resolver: discarding result for already registered connection %d.", i ); #endif - } - else - { - /* Outgoing connection (server link): set the IP address - * so that we can connect to it in the main loop. */ - - /* Search server ... */ - n = Conf_GetServer( i ); - assert( n > NONE ); - - strlcpy( Conf_Server[n].ip, s->buffer, sizeof( Conf_Server[n].ip )); - } - - /* Clean up ... */ - FreeRes_stat( &My_Connections[i] ); - /* Reset penalty time */ Conn_ResetPenalty( i ); -} /* Read_Resolver_Result */ +} /* cb_Read_Resolver_Result */ -LOCAL void -Simple_Message( int Sock, char *Msg ) +static void +Simple_Message( int Sock, const char *Msg ) { char buf[COMMAND_LEN]; + size_t len; /* Write "simple" message to socket, without using compression * or even the connection write buffers. Used e.g. for error * messages by New_Connection(). */ @@ -1701,23 +1611,38 @@ assert( Msg != NULL ); strlcpy( buf, Msg, sizeof buf - 2); - strlcat( buf, "\r\n", sizeof buf); - (void)write( Sock, buf, strlen( buf ) ); + len = strlcat( buf, "\r\n", sizeof buf); + (void)write(Sock, buf, len); } /* Simple_Error */ -LOCAL int +static int Count_Connections( struct sockaddr_in addr_in ) { int i, cnt; cnt = 0; - for( i = 0; i < Pool_Size; i++ ) - { + for( i = 0; i < Pool_Size; i++ ) { if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].addr.sin_addr.s_addr == addr_in.sin_addr.s_addr )) cnt++; } return cnt; } /* Count_Connections */ +GLOBAL CLIENT * +Conn_GetClient( CONN_ID Idx ) +{ + /* return Client-Structure that belongs to the local Connection Idx. + * If none is found, return NULL. + */ + CONNECTION *c; + assert( Idx >= 0 ); + + c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx); + + assert(c != NULL); + + return c ? c->client : NULL; +} + /* -eof- */ Index: src/ngircd/conn.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/conn.h,v retrieving revision 1.35.2.1 retrieving revision 1.42 diff -u -r1.35.2.1 -r1.42 --- src/ngircd/conn.h 30 Jul 2005 23:24:50 -0000 1.35.2.1 +++ src/ngircd/conn.h 10 May 2006 21:24:01 -0000 1.42 @@ -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.35.2.1 2005/07/30 23:24:50 alex Exp $ + * $Id: conn.h,v 1.42 2006/05/10 21:24:01 alex Exp $ * * Connection management (header) */ @@ -31,11 +31,13 @@ typedef int CONN_ID; +#include "client.h" #ifdef CONN_MODULE #include "defines.h" #include "resolve.h" +#include "array.h" #ifdef ZLIB #include @@ -43,10 +45,8 @@ { z_stream in; /* "Handle" for input stream */ z_stream out; /* "Handle" for output stream */ - char rbuf[READBUFFER_LEN]; /* Read buffer */ - int rdatalen; /* Length of data in read buffer (compressed) */ - char wbuf[WRITEBUFFER_LEN]; /* Write buffer */ - int wdatalen; /* Length of data in write buffer (uncompressed) */ + array rbuf; /* Read buffer (compressed) */ + array wbuf; /* Write buffer (uncompressed) */ long bytes_in, bytes_out; /* Counter for statistics (uncompressed!) */ } ZIPDATA; #endif /* ZLIB */ @@ -55,12 +55,10 @@ { int sock; /* Socket handle */ struct sockaddr_in addr; /* Client address */ - RES_STAT *res_stat; /* Status of resolver process, if any */ + RES_STAT res_stat; /* Status of resolver process */ char host[HOST_LEN]; /* Hostname */ - char rbuf[READBUFFER_LEN]; /* Read buffer */ - int rdatalen; /* Length of data in read buffer */ - char wbuf[WRITEBUFFER_LEN]; /* Write buffer */ - int wdatalen; /* Length of data in write buffer */ + array rbuf; /* Read buffer */ + array wbuf; /* Write buffer */ time_t lastdata; /* Last activity */ time_t lastping; /* Last PING */ time_t lastprivmsg; /* Last PRIVMSG */ @@ -69,6 +67,7 @@ long msg_in, msg_out; /* Received and sent IRC messages */ int flag; /* Flag (see "irc-write" module) */ UINT16 options; /* Link options / connection state */ + CLIENT *client; /* pointer to client structure */ #ifdef ZLIB ZIPDATA zip; /* Compression information */ #endif /* ZLIB */ @@ -87,21 +86,16 @@ GLOBAL int Conn_InitListeners PARAMS(( void )); GLOBAL void Conn_ExitListeners PARAMS(( void )); -GLOBAL bool Conn_NewListener PARAMS(( const UINT16 Port )); - GLOBAL void Conn_Handler PARAMS(( void )); -GLOBAL bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, int Len )); +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 )); GLOBAL void Conn_SyncServerStruct PARAMS(( void )); -GLOBAL int Conn_MaxFD; - - +GLOBAL CLIENT* Conn_GetClient PARAMS((CONN_ID i)); #endif - /* -eof- */ Index: src/ngircd/defines.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/defines.h,v retrieving revision 1.52.2.2 retrieving revision 1.58 diff -u -r1.52.2.2 -r1.58 --- src/ngircd/defines.h 5 Jul 2005 22:58:25 -0000 1.52.2.2 +++ src/ngircd/defines.h 15 Jun 2006 20:28:15 -0000 1.58 @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2003 by Alexander Barton (alex@barton.de) + * Copyright (c)2001-2005 Alexander Barton (alex@barton.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -8,101 +8,123 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: defines.h,v 1.52.2.2 2005/07/05 22:58:25 alex Exp $ - * - * Global defines of ngIRCd. + * $Id: defines.h,v 1.58 2006/06/15 20:28:15 alex Exp $ */ + #ifndef __defines_h__ #define __defines_h__ +/** + * @file + * Global constants ("#defines") used by the ngIRCd. + */ #define NONE -1 -#define FNAME_LEN 256 /* max. length of file name */ +#define FNAME_LEN 256 /* Max. length of file name */ -#define LINE_LEN 256 /* max. length of a line in the configuration file */ +#define LINE_LEN 256 /* Max. length of a line in the + configuration file */ -#define HOST_LEN 256 /* max. lenght of fully qualified host names */ +#define HOST_LEN 256 /* Max. lenght of fully qualified host + names (e. g. "abc.domain.tld") */ -#define MAX_LISTEN_PORTS 16 /* max. count of listening ports */ +#define MAX_LISTEN_PORTS 16 /* Max. count of listening ports */ -#define MAX_OPERATORS 16 /* max. count of configurable operators */ +#define MAX_OPERATORS 16 /* Max. count of configurable IRC Ops */ -#define MAX_SERVERS 16 /* max. count of configurable servers ("peers") */ +#define MAX_SERVERS 16 /* Max. count of configurable servers */ -#define MAX_DEFCHANNELS 16 /* max. count of preconfigurable channels */ +#define MAX_DEFCHANNELS 16 /* Max. count of predefined channels */ -#define MAX_SERVICES 8 /* max. number of configurable services */ +#define MAX_SERVICES 8 /* Max. count of services */ -#define MAX_WHOWAS 64 /* max. number of WHOWAS items */ +#define MAX_WHOWAS 64 /* Max. number of WHOWAS items */ #define DEFAULT_WHOWAS 5 /* default count for WHOWAS command */ -#define CONNECTION_POOL 100 /* size of default connection pool */ +#define CONNECTION_POOL 100 /* Size of default connection pool */ -#define CLIENT_ID_LEN 64 /* max. length of an IRC ID; see RFC 2812, 1.1 and 1.2.1 */ -#define CLIENT_NICK_LEN 10 /* max. nick length; see. RFC 2812, 1.2.1 */ -#define CLIENT_PASS_LEN 21 /* max. password length */ +#define CLIENT_ID_LEN 64 /* Max. length of an IRC ID; see RFC + RFC 2812 section 1.1 and 1.2.1 */ +#define CLIENT_NICK_LEN 10 /* Max. nick length, see. RFC 2812 + section 1.2.1 */ +#define CLIENT_PASS_LEN 21 /* Max. password length */ #define CLIENT_USER_LEN 10 /* Max. length of user name ("login") - see RFC 2812, section 1.2.1 */ -#define CLIENT_NAME_LEN 32 /* max. length of "real names" */ -#define CLIENT_HOST_LEN 64 /* max. host name length */ -#define CLIENT_MODE_LEN 8 /* max. lenth of all client modes */ -#define CLIENT_INFO_LEN 64 /* max. length of server info texts */ -#define CLIENT_AWAY_LEN 128 /* max. length of away messages */ -#define CLIENT_FLAGS_LEN 100 /* max. length of client flags */ - -#define CHANNEL_NAME_LEN 51 /* max. length of a channel name, see. RFC 2812, 1.3 */ -#define CHANNEL_MODE_LEN 9 /* max. length of channel modes */ -#define CHANNEL_TOPIC_LEN 128 /* max. length of a channel topic */ - -#define COMMAND_LEN 513 /* max. IRC command length, see. RFC 2812, 3.2 */ - -#define READBUFFER_LEN 2048 /* size of the read buffer of a connection (bytes) */ -#define WRITEBUFFER_LEN 4096 /* size of the write buffer of a connection (bytes) */ + see RFC 2812, section 1.2.1 */ +#define CLIENT_NAME_LEN 32 /* Max. length of "real names" */ +#define CLIENT_HOST_LEN 64 /* Max. host name length */ +#define CLIENT_MODE_LEN 8 /* Max. lenth of all client modes */ +#define CLIENT_INFO_LEN 64 /* Max. length of server info texts */ +#define CLIENT_AWAY_LEN 128 /* Max. length of away messages */ +#define CLIENT_FLAGS_LEN 100 /* Max. length of client flags */ + +#define CHANNEL_NAME_LEN 51 /* Max. length of a channel name, see + RFC 2812 section 1.3 */ +#define CHANNEL_MODE_LEN 9 /* Max. length of channel modes */ + +#define COMMAND_LEN 513 /* Max. IRC command length, see. RFC + 2812 section 3.2 */ + +#define READBUFFER_LEN 2048 /* Size of the read buffer of a + connection in bytes. */ +#define WRITEBUFFER_LEN 4096 /* Size of the write buffer of a + connection in bytes. */ #ifdef ZLIB -#define ZREADBUFFER_LEN 1024 /* compressed read buffer of a connection (bytes) */ -#define ZWRITEBUFFER_LEN 4096 /* compressed write buffer of a connection (bytes) */ +#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 PROTOVER "0210" /* implemented IRC protocol version (see RFC 2813, 4.1.1) */ -#define PROTOIRC "-IRC" /* protocol suffix (see RFC 2813, 4.1.1) */ -#define PROTOIRCPLUS "-IRC+" /* protokol suffix for IRC+ protocol (see doc/Protocol.txt) */ +#define PROTOVER "0210" /* Implemented IRC protocol version, + see RFC 2813 section 4.1.1. */ +#define PROTOIRC "-IRC" /* Protocol suffix, see RFC 2813 + section 4.1.1 */ +#define PROTOIRCPLUS "-IRC+" /* Protocol suffix used by the IRC+ + protocol, see doc/Protocol.txt */ #ifdef IRCPLUS -# define IRCPLUSFLAGS "CL" /* standard IRC+ flags */ +# define IRCPLUSFLAGS "CL" /* Standard IRC+ flags */ #endif -#define STARTUP_DELAY 1 /* delay outgoing connections n seconds after startup */ -#define RECONNECT_DELAY 3 /* time to delay re-connect attempts (seconds) */ +#define STARTUP_DELAY 1 /* Delay outgoing connections n seconds + after startup. */ +#define RECONNECT_DELAY 3 /* Time to delay re-connect attempts + in seconds. */ -#define USERMODES "aios" /* supported user modes */ -#define CHANMODES "biklImnoPstv" /* supported channel modes */ +#define USERMODES "aios" /* Supported user modes. */ +#define CHANMODES "biIklmnoPstv" /* Supported channel modes. */ -#define CONNECTED true /* internal status codes */ +#define CONNECTED true /* Internal status codes. */ #define DISCONNECTED false -#define DEFAULT_AWAY_MSG "Away" /* away message for users connected to linked servers */ +#define DEFAULT_AWAY_MSG "Away" /* Away message for users connected to + linked servers. */ + +#define DEFAULT_TOPIC_ID "-Server-" /* Default ID for "topic owner". */ -#define CONFIG_FILE "/ngircd.conf" -#define MOTD_FILE "/ngircd.motd" -#define MOTD_PHRASE "" -#define CHROOT_DIR "" -#define PID_FILE "" +#define CONFIG_FILE "/ngircd.conf" /* Configuration file name. */ +#define MOTD_FILE "/ngircd.motd" /* Name of the MOTD file. */ +#define MOTD_PHRASE "" /* Default MOTD phrase string. */ +#define CHROOT_DIR "" /* Default chroot() directory. */ +#define PID_FILE "" /* Default file for the process ID. */ -#define ERROR_DIR "/tmp" +#define ERROR_DIR "/tmp" /* Error directory used in debug mode */ -#define MAX_LOG_MSG_LEN 256 /* max. length of a log message */ +#define MAX_LOG_MSG_LEN 256 /* Max. length of a log message. */ -#define TOKEN_OUTBOUND -2 /* tag for outbound server links */ +#define TOKEN_OUTBOUND -2 /* Tag for outbound server links. */ -#define NOTICE_TXTPREFIX "" /* prefix for NOTICEs from the server to users */ +#define NOTICE_TXTPREFIX "" /* Prefix for NOTICEs from the server + to users. Some servers use '*'. */ #define CUT_TXTSUFFIX "[CUT]" /* Suffix for oversized messages that have been shortened and cut off. */ -#ifdef RENDEZVOUS -#define RENDEZVOUS_TYPE "_ircu._tcp." /* service type to register with Rendezvous */ + +#ifdef ZEROCONF +#define MDNS_TYPE "_ircu._tcp." /* Service type to register with mDNS */ #endif Index: src/ngircd/hash.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/hash.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- src/ngircd/hash.c 19 Mar 2005 18:43:48 -0000 1.11 +++ src/ngircd/hash.c 31 Jul 2005 20:13:08 -0000 1.12 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: hash.c,v 1.11 2005/03/19 18:43:48 fw Exp $"; +static char UNUSED id[] = "$Id: hash.c,v 1.12 2005/07/31 20:13:08 alex Exp $"; #include "imp.h" #include @@ -27,7 +27,7 @@ #include "hash.h" -LOCAL UINT32 jenkins_hash PARAMS(( register UINT8 *k, register UINT32 length, register UINT32 initval )); +static UINT32 jenkins_hash PARAMS(( register UINT8 *k, register UINT32 length, register UINT32 initval )); GLOBAL UINT32 @@ -72,7 +72,7 @@ } /* mix */ -LOCAL UINT32 +static UINT32 jenkins_hash( register UINT8 *k, register UINT32 length, register UINT32 initval ) { /* k: the key Index: src/ngircd/io.c =================================================================== RCS file: src/ngircd/io.c diff -N src/ngircd/io.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/ngircd/io.c 23 Jul 2006 23:11:44 -0000 1.16 @@ -0,0 +1,605 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * Please read the file COPYING, README and AUTHORS for more information. + * + * I/O abstraction interface. + * Copyright (c) 2005 Florian Westphal (westphal@foo.fh-furtwangen.de) + * + */ + +#include "portab.h" + +static char UNUSED id[] = "$Id: io.c,v 1.16 2006/07/23 23:11:44 alex Exp $"; + +#include +#include +#include +#include +#include +#include +#include + +#include "array.h" +#include "io.h" +#include "log.h" + +/* Enables extra debug messages in event add/delete/callback code. */ +/* #define DEBUG_IO */ + +typedef struct { + void (*callback)(int, short); + short what; +} io_event; + +#define INIT_IOEVENT { NULL, -1, 0, NULL } +#define IO_ERROR 4 + +#ifdef HAVE_EPOLL_CREATE +#define IO_USE_EPOLL 1 +#else +# ifdef HAVE_KQUEUE +#define IO_USE_KQUEUE 1 +# else +#define IO_USE_SELECT 1 +#endif +#endif + +static bool library_initialized; + +#ifdef IO_USE_EPOLL +#include + +static int io_masterfd; +static bool io_event_change_epoll(int fd, short what, const int action); +static int io_dispatch_epoll(struct timeval *tv); +#endif + +#ifdef IO_USE_KQUEUE +#include +#include +static array io_evcache; +static int io_masterfd; + +static int io_dispatch_kqueue(struct timeval *tv); +static bool io_event_change_kqueue(int, short, const int action); +#endif + +#ifdef IO_USE_SELECT +#include "defines.h" /* for conn.h */ +#include "conn.h" /* for CONN_IDX (needed by resolve.h) */ +#include "resolve.h" /* for RES_STAT (needed by conf.h) */ +#include "conf.h" /* for Conf_MaxConnections */ + +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); +#endif + +static array io_events; + +static void io_docallback PARAMS((int fd, short what)); + +static io_event * +io_event_get(int fd) +{ + io_event *i; + + assert(fd >= 0); + + i = (io_event *) array_get(&io_events, sizeof(io_event), (size_t) fd); + + assert(i != NULL); + + return i; +} + + +bool +io_library_init(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; +#endif + if (library_initialized) + return true; + +#ifdef IO_USE_SELECT +#ifdef FD_SETSIZE + if (eventsize >= FD_SETSIZE) + eventsize = FD_SETSIZE - 1; +#endif +#endif + if ((eventsize > 0) && !array_alloc(&io_events, sizeof(io_event), (size_t)eventsize)) + eventsize = 0; + +#ifdef IO_USE_EPOLL + io_masterfd = epoll_create(ecreate_hint); + Log(LOG_INFO, + "IO subsystem: epoll (hint size %d, initial maxfd %u, masterfd %d).", + ecreate_hint, eventsize, io_masterfd); + ret = io_masterfd >= 0; + if (ret) library_initialized = true; + + return ret; +#endif +#ifdef IO_USE_SELECT + Log(LOG_INFO, "IO subsystem: select (initial maxfd %u).", + eventsize); + FD_ZERO(&readers); + FD_ZERO(&writers); +#ifdef FD_SETSIZE + if (Conf_MaxConnections >= (int)FD_SETSIZE) { + Log(LOG_WARNING, + "MaxConnections (%d) exceeds limit (%u), changed MaxConnections to %u.", + Conf_MaxConnections, FD_SETSIZE, FD_SETSIZE - 1); + + 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_KQUEUE + io_masterfd = kqueue(); + + Log(LOG_INFO, + "IO subsystem: kqueue (initial maxfd %u, masterfd %d)", + eventsize, io_masterfd); + ret = io_masterfd >= 0; + if (ret) library_initialized = true; + + return ret; +#endif +} + + +void +io_library_shutdown(void) +{ +#ifdef IO_USE_SELECT + FD_ZERO(&readers); + FD_ZERO(&writers); +#else + close(io_masterfd); /* kqueue, epoll */ + io_masterfd = -1; +#endif +#ifdef IO_USE_KQUEUE + array_free(&io_evcache); +#endif + library_initialized = false; +} + + +bool +io_event_setcb(int fd, void (*cbfunc) (int, short)) +{ + io_event *i = io_event_get(fd); + if (!i) + return false; + + i->callback = cbfunc; + return true; +} + + +bool +io_event_create(int fd, short what, void (*cbfunc) (int, short)) +{ + bool ret; + io_event *i; + + assert(fd >= 0); + +#ifdef IO_USE_SELECT +#ifdef 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 */ + + i = (io_event *) array_alloc(&io_events, sizeof(io_event), (size_t) fd); + if (!i) { + Log(LOG_WARNING, + "array_alloc failed: could not allocate space for %d io_event structures", + fd); + return false; + } + + i->callback = cbfunc; + i->what = 0; +#ifdef IO_USE_EPOLL + ret = io_event_change_epoll(fd, what, EPOLL_CTL_ADD); +#endif +#ifdef IO_USE_KQUEUE + ret = io_event_change_kqueue(fd, what, EV_ADD|EV_ENABLE); +#endif +#ifdef IO_USE_SELECT + ret = io_event_add(fd, what); +#endif + if (ret) i->what = what; + return ret; +} + + +#ifdef IO_USE_EPOLL +static bool +io_event_change_epoll(int fd, short what, const int action) +{ + struct epoll_event ev = { 0, {0} }; + ev.data.fd = fd; + + if (what & IO_WANTREAD) + ev.events = EPOLLIN | EPOLLPRI; + if (what & IO_WANTWRITE) + ev.events |= EPOLLOUT; + + return epoll_ctl(io_masterfd, action, fd, &ev) == 0; +} +#endif + +#ifdef IO_USE_KQUEUE +static bool +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; + + assert(len>0); + + if (len < 0) { + array_free(&io_evcache); + return false; + } + + events = array_start(&io_evcache); + + assert(events != NULL); + + ret = kevent(io_masterfd, events, len, NULL, 0, NULL) == 0; + if (ret) + array_trunc(&io_evcache); + return ret; +} + + +static bool +io_event_change_kqueue(int fd, short what, const int action) +{ + struct kevent kev; + bool ret = true; + + if (what & IO_WANTREAD) { + EV_SET(&kev, fd, EVFILT_READ, action, 0, 0, 0); + 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); + ret = array_catb(&io_evcache, (char*) &kev, sizeof (kev)); + if (!ret) + ret = kevent(io_masterfd, &kev, 1, NULL, 0, NULL) == 0; + } + + if (array_length(&io_evcache, sizeof kev) >= 100) + io_event_kqueue_commit_cache(); + return ret; +} +#endif + + +bool +io_event_add(int fd, short what) +{ + io_event *i = io_event_get(fd); + + if (!i) return false; + if (i->what == what) return true; +#ifdef DEBUG_IO + Log(LOG_DEBUG, "io_event_add(): fd %d (arg: %d), what %d.", i->fd, fd, what); +#endif + i->what |= what; +#ifdef IO_USE_EPOLL + 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_SELECT + if (fd > select_maxfd) + select_maxfd = fd; + + if (what & IO_WANTREAD) + FD_SET(fd, &readers); + if (what & IO_WANTWRITE) + FD_SET(fd, &writers); + + return true; +#endif +} + + +bool +io_setnonblock(int fd) +{ + int flags = fcntl(fd, F_GETFL); + if (flags == -1) + return false; + +#ifndef O_NONBLOCK +#define O_NONBLOCK O_NDELAY +#endif + flags |= O_NONBLOCK; + + return fcntl(fd, F_SETFL, flags) == 0; +} + + +bool +io_close(int fd) +{ + io_event *i; +#ifdef IO_USE_SELECT + FD_CLR(fd, &writers); + FD_CLR(fd, &readers); + + if (fd == select_maxfd) { + while (select_maxfd>0) { + --select_maxfd; /* find largest fd */ + i = io_event_get(select_maxfd); + if (i && i->callback) break; + } + } +#endif + i = io_event_get(fd); +#ifdef IO_USE_KQUEUE + if (array_length(&io_evcache, sizeof (struct kevent))) /* pending data in cache? */ + io_event_kqueue_commit_cache(); + + /* both kqueue and epoll remove fd from all sets automatically on the last close + * of the descriptor. since we don't know if this is the last close we'll have + * to remove the set explicitly. */ + if (i) { + io_event_change_kqueue(fd, i->what, EV_DELETE); + io_event_kqueue_commit_cache(); + } +#endif +#ifdef IO_USE_EPOLL + io_event_change_epoll(fd, 0, EPOLL_CTL_DEL); +#endif + if (i) { + i->callback = NULL; + i->what = 0; + } + return close(fd) == 0; +} + + +bool +io_event_del(int fd, short what) +{ + io_event *i = io_event_get(fd); +#ifdef DEBUG_IO + Log(LOG_DEBUG, "io_event_del(): trying to delete eventtype %d on fd %d", what, fd); +#endif + if (!i) return false; + + i->what &= ~what; + +#ifdef IO_USE_EPOLL + return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD); +#endif + +#ifdef IO_USE_KQUEUE + return io_event_change_kqueue(fd, what, EV_DISABLE); +#endif +#ifdef IO_USE_SELECT + if (what & IO_WANTWRITE) + FD_CLR(fd, &writers); + + if (what & IO_WANTREAD) + FD_CLR(fd, &readers); + + return true; +#endif +} + + +#ifdef IO_USE_SELECT +static int +io_dispatch_select(struct timeval *tv) +{ + fd_set readers_tmp = readers; + fd_set writers_tmp = writers; + short what; + int ret, i; + int fds_ready; + ret = select(select_maxfd + 1, &readers_tmp, &writers_tmp, NULL, tv); + if (ret <= 0) + return ret; + + fds_ready = ret; + + for (i = 0; i <= select_maxfd; i++) { + what = 0; + if (FD_ISSET(i, &readers_tmp)) { + what = IO_WANTREAD; + fds_ready--; + } + + if (FD_ISSET(i, &writers_tmp)) { + what |= IO_WANTWRITE; + fds_ready--; + } + if (what) + io_docallback(i, what); + if (fds_ready <= 0) + break; + } + + return ret; +} +#endif + + +#ifdef IO_USE_EPOLL +static int +io_dispatch_epoll(struct timeval *tv) +{ + time_t sec = tv->tv_sec * 1000; + int i, total = 0, ret, timeout = tv->tv_usec + sec; + struct epoll_event epoll_ev[100]; + short type; + + if (timeout < 0) + timeout = 1000; + + do { + ret = epoll_wait(io_masterfd, epoll_ev, 100, timeout); + total += ret; + if (ret <= 0) + return total; + + for (i = 0; i < ret; i++) { + type = 0; + if (epoll_ev[i].events & (EPOLLERR | EPOLLHUP)) + type = IO_ERROR; + + if (epoll_ev[i].events & (EPOLLIN | EPOLLPRI)) + type |= IO_WANTREAD; + + if (epoll_ev[i].events & EPOLLOUT) + type |= IO_WANTWRITE; + + io_docallback(epoll_ev[i].data.fd, type); + } + + timeout = 0; + } while (ret == 100); + + return total; +} +#endif + + +#ifdef IO_USE_KQUEUE +static int +io_dispatch_kqueue(struct timeval *tv) +{ + int i, total = 0, ret; + struct kevent kev[100]; + struct kevent *newevents; + struct timespec ts; + 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; + assert(newevents_len >= 0); + if (newevents_len < 0) + newevents_len = 0; +#ifdef DEBUG + if (newevents_len) + assert(newevents != NULL); +#endif + ret = kevent(io_masterfd, newevents, newevents_len, kev, + 100, &ts); + if ((newevents_len>0) && ret != -1) + array_trunc(&io_evcache); + + total += ret; + if (ret <= 0) + return total; + + for (i = 0; i < ret; i++) { + if (kev[i].flags & EV_EOF) { +#ifdef DEBUG + LogDebug("kev.flag has EV_EOF set, setting IO_ERROR", + kev[i].filter, kev[i].ident); +#endif + io_docallback((int)kev[i].ident, IO_ERROR); + continue; + } + + switch (kev[i].filter) { + case EVFILT_READ: + io_docallback((int)kev[i].ident, IO_WANTREAD); + break; + case EVFILT_WRITE: + io_docallback((int)kev[i].ident, IO_WANTWRITE); + break; + default: +#ifdef DEBUG + LogDebug("Unknown kev.filter number %d for fd %d", + kev[i].filter, kev[i].ident); /* Fall through */ +#endif + case EV_ERROR: + io_docallback((int)kev[i].ident, IO_ERROR); + break; + } + } + ts.tv_sec = 0; + ts.tv_nsec = 0; + } while (ret == 100); + + return total; +} +#endif + + +int +io_dispatch(struct timeval *tv) +{ +#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); +#endif +} + + +/* call the callback function inside the struct matching fd */ +static void +io_docallback(int fd, short what) +{ + io_event *i; +#ifdef DEBUG_IO + Log(LOG_DEBUG, "doing callback for fd %d, what %d", fd, what); +#endif + i = io_event_get(fd); + + 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: src/ngircd/io.h diff -N src/ngircd/io.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/ngircd/io.h 14 Jul 2005 09:15:58 -0000 1.3 @@ -0,0 +1,51 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * Please read the file COPYING, README and AUTHORS for more information. + * + * I/O abstraction interface header + * + * $Id: io.h,v 1.3 2005/07/14 09:15:58 alex Exp $ + */ + +#ifndef io_H_inclucded +#define io_H_included + +#include "portab.h" +#include + +#define IO_WANTREAD 1 +#define IO_WANTWRITE 2 + +/* init library. + sets up epoll/kqueue descriptors and tries to allocate space for ioevlen + file descriptors. ioevlen is just the _initial_ size, not a limit. */ +bool io_library_init PARAMS((unsigned int ioevlen)); + +/* shutdown and free all internal data structures */ +void io_library_shutdown PARAMS((void)); + +/* add fd to internal set, enable readability check, set callback */ +bool io_event_create PARAMS((int fd, short what, void (*cbfunc)(int, short))); + +/* change callback function associated with fd */ +bool io_event_setcb PARAMS((int fd, void (*cbfunc)(int, short))); + +/* watch fd for event of type what */ +bool io_event_add PARAMS((int fd, short what)); + +/* do not watch fd for event of type what */ +bool io_event_del PARAMS((int fd, short what)); + +/* remove fd from watchlist, close() fd. */ +bool io_close PARAMS((int fd)); + +/* set O_NONBLOCK */ +bool io_setnonblock PARAMS((int fd)); + +/* watch fds for activity */ +int io_dispatch PARAMS((struct timeval *tv)); + +#endif /* io_H_included */ Index: src/ngircd/irc-channel.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/irc-channel.c,v retrieving revision 1.30 retrieving revision 1.35 diff -u -r1.30 -r1.35 --- src/ngircd/irc-channel.c 12 Jun 2005 18:23:59 -0000 1.30 +++ src/ngircd/irc-channel.c 16 Mar 2006 20:14:16 -0000 1.35 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-channel.c,v 1.30 2005/06/12 18:23:59 alex Exp $"; +static char UNUSED id[] = "$Id: irc-channel.c,v 1.35 2006/03/16 20:14:16 fw Exp $"; #include "imp.h" #include @@ -43,11 +43,11 @@ GLOBAL bool IRC_JOIN( CLIENT *Client, REQUEST *Req ) { - char *channame, *key, *flags, *topic, modes[8]; + char *channame, *channame_ptr, *key, *key_ptr, *flags, *topic, modes[8]; bool is_new_chan, is_invited, is_banned; CLIENT *target; CHANNEL *chan; - + assert( Client != NULL ); assert( Req != NULL ); @@ -60,13 +60,20 @@ if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix ); /* Are channel keys given? */ - if( Req->argc > 1 ) key = Req->argv[1]; - else key = NULL; + if (Req->argc > 1) { + key = Req->argv[1]; + key_ptr = strchr(key, ','); + if (key_ptr) *key_ptr = '\0'; + } + else + key = key_ptr = NULL; + + channame = Req->argv[0]; + channame_ptr = strchr(channame, ','); + if (channame_ptr) *channame_ptr = '\0'; /* Channel-Namen durchgehen */ - chan = NULL; - channame = strtok( Req->argv[0], "," ); - while( channame ) + while (channame) { chan = NULL; flags = NULL; @@ -90,14 +97,9 @@ if( Client_Type( Client ) == CLIENT_USER ) { /* Test if the user has reached his maximum channel count */ - if( Client_Type( Client ) == CLIENT_USER ) - { - if(( Conf_MaxJoins > 0 ) && ( Channel_CountForUser( Client ) >= Conf_MaxJoins )) - { - IRC_WriteStrClient( Client, ERR_TOOMANYCHANNELS_MSG, Client_ID( Client ), channame ); - return CONNECTED; - } - } + if(( Conf_MaxJoins > 0 ) && ( Channel_CountForUser( Client ) >= Conf_MaxJoins )) + return IRC_WriteStrClient( Client, ERR_TOOMANYCHANNELS_MSG, + Client_ID( Client ), channame ); /* Existiert der Channel bereits, oder wird er im Moment neu erzeugt? */ if( is_new_chan ) @@ -211,17 +213,37 @@ /* an Client bestaetigen */ IRC_WriteStrClientPrefix( Client, target, "JOIN :%s", channame ); - /* Topic an Client schicken */ - topic = Channel_Topic( chan ); - if( *topic ) IRC_WriteStrClient( Client, RPL_TOPIC_MSG, Client_ID( Client ), channame, topic ); + /* Send topic to client, if any */ + topic = Channel_Topic(chan); + if (*topic) { + IRC_WriteStrClient(Client, RPL_TOPIC_MSG, + Client_ID(Client), channame, topic); +#ifndef STRICT_RFC + IRC_WriteStrClient(Client, RPL_TOPICSETBY_MSG, + Client_ID(Client), channame, + Channel_TopicWho(chan), + Channel_TopicTime(chan)); +#endif + } /* Mitglieder an Client Melden */ IRC_Send_NAMES( Client, chan ); IRC_WriteStrClient( Client, RPL_ENDOFNAMES_MSG, Client_ID( Client ), Channel_Name( chan )); } - /* naechsten Namen ermitteln */ - channame = strtok( NULL, "," ); + /* next channel? */ + channame = channame_ptr; + if (channame) { + channame++; + channame_ptr = strchr(channame, ','); + if (channame_ptr) *channame_ptr = '\0'; + + if (key_ptr) { + key = ++key_ptr; + key_ptr = strchr(key, ','); + if (key_ptr) *key_ptr = '\0'; + } + } } return CONNECTED; } /* IRC_JOIN */ @@ -268,6 +290,7 @@ CHANNEL *chan; CLIENT *from; char *topic; + bool r; assert( Client != NULL ); assert( Req != NULL ); @@ -288,10 +311,22 @@ if( Req->argc == 1 ) { - /* Topic erfragen */ - topic = Channel_Topic( chan ); - if( *topic ) return IRC_WriteStrClient( from, RPL_TOPIC_MSG, Client_ID( from ), Channel_Name( chan ), topic ); - else return IRC_WriteStrClient( from, RPL_NOTOPIC_MSG, Client_ID( from ), Channel_Name( chan )); + /* Request actual topic */ + topic = Channel_Topic(chan); + if (*topic) { + r = IRC_WriteStrClient(from, RPL_TOPIC_MSG, + Client_ID(Client), Channel_Name(chan), topic); +#ifndef STRICT_RFC + r = IRC_WriteStrClient(from, RPL_TOPICSETBY_MSG, + Client_ID(Client), Channel_Name(chan), + Channel_TopicWho(chan), + Channel_TopicTime(chan)); +#endif + return r; + } + else + return IRC_WriteStrClient(from, RPL_NOTOPIC_MSG, + Client_ID(from), Channel_Name(chan)); } if( strchr( Channel_Modes( chan ), 't' )) @@ -300,9 +335,11 @@ if( ! strchr( Channel_UserModes( chan, from ), 'o' )) return IRC_WriteStrClient( from, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( from ), Channel_Name( chan )); } - /* Topic setzen */ - Channel_SetTopic( chan, Req->argv[1] ); - Log( LOG_DEBUG, "User \"%s\" set topic on \"%s\": %s", Client_Mask( from ), Channel_Name( chan ), Req->argv[1][0] ? Req->argv[1] : "" ); + /* Set new topic */ + Channel_SetTopic(chan, from, Req->argv[1]); + Log(LOG_DEBUG, "User \"%s\" set topic on \"%s\": %s", + Client_Mask(from), Channel_Name(chan), + Req->argv[1][0] ? Req->argv[1] : ""); /* im Channel bekannt machen und an Server weiterleiten */ IRC_WriteStrServersPrefix( Client, from, "TOPIC %s :%s", Req->argv[0], Req->argv[1] ); @@ -478,8 +515,9 @@ if(( ! *ptr ) && ( Req->argv[arg_topic][0] )) { /* OK, there is no topic jet */ - Channel_SetTopic( chan, Req->argv[arg_topic] ); - IRC_WriteStrChannelPrefix( Client, chan, from, false, "TOPIC %s :%s", Req->argv[0], Channel_Topic( chan )); + Channel_SetTopic(chan, Client, Req->argv[arg_topic]); + IRC_WriteStrChannelPrefix(Client, chan, from, false, + "TOPIC %s :%s", Req->argv[0], Channel_Topic(chan)); } } Index: src/ngircd/irc-info.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/irc-info.c,v retrieving revision 1.30 retrieving revision 1.33 diff -u -r1.30 -r1.33 --- src/ngircd/irc-info.c 17 Jun 2005 19:15:43 -0000 1.30 +++ src/ngircd/irc-info.c 10 May 2006 21:24:01 -0000 1.33 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-info.c,v 1.30 2005/06/17 19:15:43 fw Exp $"; +static char UNUSED id[] = "$Id: irc-info.c,v 1.33 2006/05/10 21:24:01 alex Exp $"; #include "imp.h" #include @@ -377,7 +377,7 @@ con = Conn_First( ); while( con != NONE ) { - cl = Client_GetFromConn( con ); + cl = Conn_GetClient( con ); if( cl && (( Client_Type( cl ) == CLIENT_SERVER ) || ( cl == Client ))) { /* Server link or our own connection */ @@ -870,47 +870,59 @@ } /* IRC_Send_LUSERS */ +static bool Show_MOTD_Start(CLIENT *Client) +{ + return IRC_WriteStrClient(Client, RPL_MOTDSTART_MSG, + Client_ID( Client ), Client_ID( Client_ThisServer( ))); +} + +static bool Show_MOTD_Sendline(CLIENT *Client, const char *msg) +{ + return IRC_WriteStrClient(Client, RPL_MOTD_MSG, Client_ID( Client ), msg); +} + +static bool Show_MOTD_End(CLIENT *Client) +{ + return IRC_WriteStrClient( Client, RPL_ENDOFMOTD_MSG, Client_ID( Client )); +} + + GLOBAL bool IRC_Show_MOTD( CLIENT *Client ) { - bool ok; char line[127]; FILE *fd; assert( Client != NULL ); - if( Conf_MotdPhrase[0] ) - { - if( ! IRC_WriteStrClient( Client, RPL_MOTDSTART_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )))) return DISCONNECTED; - if( ! IRC_WriteStrClient( Client, RPL_MOTD_MSG, Client_ID( Client ), Conf_MotdPhrase )) return DISCONNECTED; - return IRC_WriteStrClient( Client, RPL_ENDOFMOTD_MSG, Client_ID( Client )); + if (Conf_MotdPhrase[0]) { + if (!Show_MOTD_Start(Client)) + return DISCONNECTED; + if (!Show_MOTD_Sendline(Client, Conf_MotdPhrase)) + return DISCONNECTED; + + return Show_MOTD_End(Client); } fd = fopen( Conf_MotdFile, "r" ); - if( ! fd ) - { + if( ! fd ) { Log( LOG_WARNING, "Can't read MOTD file \"%s\": %s", Conf_MotdFile, strerror( errno )); return IRC_WriteStrClient( Client, ERR_NOMOTD_MSG, Client_ID( Client ) ); } - if( ! IRC_WriteStrClient( Client, RPL_MOTDSTART_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )))) return DISCONNECTED; - while( true ) - { - if( ! fgets( line, sizeof( line ), fd )) break; + if (!Show_MOTD_Start( Client )) + return DISCONNECTED; + while (fgets( line, (int)sizeof line, fd )) { ngt_TrimLastChr( line, '\n'); - if( ! IRC_WriteStrClient( Client, RPL_MOTD_MSG, Client_ID( Client ), line )) - { + if( ! Show_MOTD_Sendline( Client, line)) { fclose( fd ); return false; } } - ok = IRC_WriteStrClient( Client, RPL_ENDOFMOTD_MSG, Client_ID( Client ) ); - - fclose( fd ); - - return ok; + fclose(fd); + return Show_MOTD_End(Client); } /* IRC_Show_MOTD */ Index: src/ngircd/irc-login.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/irc-login.c,v retrieving revision 1.44 retrieving revision 1.49 diff -u -r1.44 -r1.49 --- src/ngircd/irc-login.c 4 Jun 2005 12:32:09 -0000 1.44 +++ src/ngircd/irc-login.c 1 Sep 2005 10:51:24 -0000 1.49 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-login.c,v 1.44 2005/06/04 12:32:09 fw Exp $"; +static char UNUSED id[] = "$Id: irc-login.c,v 1.49 2005/09/01 10:51:24 alex Exp $"; #include "imp.h" #include @@ -41,8 +41,8 @@ #include "irc-login.h" -LOCAL bool Hello_User PARAMS(( CLIENT *Client )); -LOCAL void Kill_Nick PARAMS(( char *Nick, char *Reason )); +static bool Hello_User PARAMS(( CLIENT *Client )); +static void Kill_Nick PARAMS(( char *Nick, char *Reason )); GLOBAL bool @@ -427,77 +427,134 @@ GLOBAL bool -IRC_PING( CLIENT *Client, REQUEST *Req ) +IRC_PING(CLIENT *Client, REQUEST *Req) { CLIENT *target, *from; - assert( Client != NULL ); - assert( Req != NULL ); + assert(Client != NULL); + assert(Req != NULL); - /* Falsche Anzahl Parameter? */ - if( Req->argc < 1 ) return IRC_WriteStrClient( Client, ERR_NOORIGIN_MSG, Client_ID( Client )); + /* Wrong number of arguments? */ + if (Req->argc < 1) + return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG, + Client_ID(Client)); #ifdef STRICT_RFC - if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + /* Don't ignore additional arguments when in "strict" mode */ + if (Req->argc > 2) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); #endif - if( Req->argc > 1 ) - { - /* es wurde ein Ziel-Client angegeben */ - target = Client_Search( Req->argv[1] ); - if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[1] ); - if( target != Client_ThisServer( )) - { - /* ok, forwarden */ - if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix ); - else from = Client; - if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->prefix ); - return IRC_WriteStrClientPrefix( target, from, "PING %s :%s", Client_ID( from ), Req->argv[1] ); + if (Req->argc > 1) { + /* A target has been specified ... */ + target = Client_Search(Req->argv[1]); + + if (!target || Client_Type(target) != CLIENT_SERVER) + return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG, + Client_ID(Client), Req->argv[1]); + + if (target != Client_ThisServer()) { + /* Ok, we have to forward the PING */ + if (Client_Type(Client) == CLIENT_SERVER) + from = Client_Search(Req->prefix); + else + from = Client; + if (!from) + return IRC_WriteStrClient(Client, + ERR_NOSUCHSERVER_MSG, + Client_ID(Client), Req->prefix); + + return IRC_WriteStrClientPrefix(target, from, + "PING %s :%s", Req->argv[0], + Req->argv[1] ); } } - Log( LOG_DEBUG, "Connection %d: got PING, sending PONG ...", Client_Conn( Client )); - return IRC_WriteStrClient( Client, "PONG %s :%s", Client_ID( Client_ThisServer( )), Client_ID( Client )); + if (Client_Type(Client) == CLIENT_SERVER) { + if (Req->prefix) + from = Client_Search(Req->prefix); + else + from = Client; + } else + from = Client_ThisServer(); + if (!from) + return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG, + Client_ID(Client), Req->prefix); + + Log(LOG_DEBUG, "Connection %d: got PING, sending PONG ...", + Client_Conn(Client)); + +#ifdef STRICT_RFC + return IRC_WriteStrClient(Client, "PONG %s :%s", + Client_ID(from), Client_ID(Client)); +#else + /* Some clients depend on the argument being returned in the PONG + * reply (not mentioned in any RFC, though) */ + return IRC_WriteStrClient(Client, "PONG %s :%s", + Client_ID(from), Req->argv[0]); +#endif } /* IRC_PING */ GLOBAL bool -IRC_PONG( CLIENT *Client, REQUEST *Req ) +IRC_PONG(CLIENT *Client, REQUEST *Req) { CLIENT *target, *from; + char *s; - assert( Client != NULL ); - assert( Req != NULL ); + assert(Client != NULL); + assert(Req != NULL); - /* Falsche Anzahl Parameter? */ - if( Req->argc < 1 ) return IRC_WriteStrClient( Client, ERR_NOORIGIN_MSG, Client_ID( Client )); - if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + /* Wrong number of arguments? */ + if (Req->argc < 1) + return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG, + Client_ID(Client)); + if (Req->argc > 2) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); + + /* Forward? */ + if (Req->argc == 2 && Client_Type(Client) == CLIENT_SERVER) { + target = Client_Search(Req->argv[0]); + if (!target) + return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG, + Client_ID(Client), Req->argv[0]); + + from = Client_Search(Req->prefix); + + if (target != Client_ThisServer() && target != from) { + /* Ok, we have to forward the message. */ + if (!from) + return IRC_WriteStrClient(Client, + ERR_NOSUCHSERVER_MSG, + Client_ID(Client), Req->prefix); - /* forwarden? */ - if( Req->argc == 2 ) - { - target = Client_Search( Req->argv[1] ); - if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[1] ); - if( target != Client_ThisServer( )) - { - /* ok, forwarden */ - if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix ); - else from = Client; - if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->prefix ); - return IRC_WriteStrClientPrefix( target, from, "PONG %s :%s", Client_ID( from ), Req->argv[1] ); + if (Client_Type(Client_NextHop(target)) != CLIENT_SERVER) + s = Client_ID(from); + else + s = Req->argv[0]; + return IRC_WriteStrClientPrefix(target, from, + "PONG %s :%s", s, Req->argv[1]); } } - /* Der Connection-Timestamp wurde schon beim Lesen aus dem Socket - * aktualisiert, daher muss das hier nicht mehr gemacht werden. */ + /* The connection timestamp has already been updated when the data has + * been read from so socket, so we don't need to update it here. */ - if( Client_Conn( Client ) > NONE ) Log( LOG_DEBUG, "Connection %d: received PONG. Lag: %ld seconds.", Client_Conn( Client ), time( NULL ) - Conn_LastPing( Client_Conn( Client ))); - else Log( LOG_DEBUG, "Connection %d: received PONG.", Client_Conn( Client )); + if (Client_Conn(Client) > NONE) + Log(LOG_DEBUG, + "Connection %d: received PONG. Lag: %ld seconds.", + Client_Conn(Client), + time(NULL) - Conn_LastPing(Client_Conn(Client))); + else + Log(LOG_DEBUG, + "Connection %d: received PONG.", Client_Conn(Client)); return CONNECTED; } /* IRC_PONG */ -LOCAL bool +static bool Hello_User( CLIENT *Client ) { #ifdef CVSDATE @@ -542,7 +599,8 @@ #endif /* Features */ - if( ! IRC_WriteStrClient( Client, RPL_ISUPPORT_MSG, Client_ID( Client ), CLIENT_NICK_LEN - 1, CHANNEL_TOPIC_LEN - 1, CLIENT_AWAY_LEN - 1, Conf_MaxJoins )) return DISCONNECTED; + if( ! IRC_WriteStrClient( Client, RPL_ISUPPORT_MSG, Client_ID( Client ), CLIENT_NICK_LEN - 1, + COMMAND_LEN - 23, CLIENT_AWAY_LEN - 1, Conf_MaxJoins )) return DISCONNECTED; Client_SetType( Client, CLIENT_USER ); @@ -556,7 +614,7 @@ } /* Hello_User */ -LOCAL void +static void Kill_Nick( char *Nick, char *Reason ) { REQUEST r; Index: src/ngircd/irc-mode.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/irc-mode.c,v retrieving revision 1.43 retrieving revision 1.45 diff -u -r1.43 -r1.45 --- src/ngircd/irc-mode.c 17 Jun 2005 19:14:58 -0000 1.43 +++ src/ngircd/irc-mode.c 10 May 2006 21:24:01 -0000 1.45 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-mode.c,v 1.43 2005/06/17 19:14:58 fw Exp $"; +static char UNUSED id[] = "$Id: irc-mode.c,v 1.45 2006/05/10 21:24:01 alex Exp $"; #include "imp.h" #include @@ -38,16 +38,16 @@ #include "irc-mode.h" -LOCAL bool Client_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )); -LOCAL bool Channel_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )); +static bool Client_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )); +static bool Channel_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )); -LOCAL bool Add_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )); -LOCAL bool Add_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )); +static bool Add_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )); +static bool Add_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )); -LOCAL bool Del_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )); -LOCAL bool Del_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )); +static bool Del_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )); +static bool Del_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )); -LOCAL bool Send_ListChange PARAMS(( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Mask )); +static bool Send_ListChange PARAMS(( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Mask )); GLOBAL bool @@ -71,19 +71,24 @@ else origin = Client; /* Channel or user mode? */ - cl = chan = NULL; - if( Client_IsValidNick( Req->argv[0] )) cl = Client_Search( Req->argv[0] ); - if( Channel_IsValidName( Req->argv[0] )) chan = Channel_Search( Req->argv[0] ); - - if( cl ) return Client_Mode( Client, Req, origin, cl ); - if( chan ) return Channel_Mode( Client, Req, origin, chan ); + cl = NULL; chan = NULL; + if (Client_IsValidNick(Req->argv[0])) + cl = Client_Search(Req->argv[0]); + if (Channel_IsValidName(Req->argv[0])) + chan = Channel_Search(Req->argv[0]); + + if (cl) + return Client_Mode(Client, Req, origin, cl); + if (chan) + return Channel_Mode(Client, Req, origin, chan); /* No target found! */ - return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] ); + return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + Client_ID(Client), Req->argv[0]); } /* IRC_MODE */ -LOCAL bool +static bool Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ) { /* Handle client mode requests */ @@ -236,7 +241,7 @@ } /* Client_Mode */ -LOCAL bool +static bool Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ) { /* Handle channel and channel-user modes */ @@ -627,7 +632,7 @@ } /* IRC_AWAY */ -LOCAL bool +static bool Add_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ) { char *mask; @@ -649,7 +654,7 @@ } /* Add_Invite */ -LOCAL bool +static bool Add_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ) { char *mask; @@ -671,7 +676,7 @@ } /* Add_Ban */ -LOCAL bool +static bool Del_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ) { char *mask; @@ -686,7 +691,7 @@ } /* Del_Invite */ -LOCAL bool +static bool Del_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ) { char *mask; @@ -701,7 +706,7 @@ } /* Del_Ban */ -LOCAL bool +static bool Send_ListChange( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Mask ) { /* Bestaetigung an Client schicken & andere Server sowie Channel-User informieren */ Index: src/ngircd/irc-oper.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/irc-oper.c,v retrieving revision 1.22 retrieving revision 1.27 diff -u -r1.22 -r1.27 --- src/ngircd/irc-oper.c 12 Jun 2005 18:02:09 -0000 1.22 +++ src/ngircd/irc-oper.c 23 Jul 2006 15:43:18 -0000 1.27 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-oper.c,v 1.22 2005/06/12 18:02:09 fw Exp $"; +static char UNUSED id[] = "$Id: irc-oper.c,v 1.27 2006/07/23 15:43:18 alex Exp $"; #include "imp.h" #include @@ -23,7 +23,7 @@ #include "ngircd.h" #include "resolve.h" -#include "conn.h" +#include "conn-func.h" #include "conf.h" #include "client.h" #include "channel.h" @@ -37,7 +37,7 @@ #include "irc-oper.h" -LOCAL bool +static bool Bad_OperPass(CLIENT *Client, char *errtoken, char *errmsg) { Log( LOG_WARNING, "Got invalid OPER from \"%s\": \"%s\" -- %s", Client_Mask( Client ), @@ -50,7 +50,7 @@ GLOBAL bool IRC_OPER( CLIENT *Client, REQUEST *Req ) { - int i; + unsigned int i; assert( Client != NULL ); assert( Req != NULL ); @@ -90,21 +90,46 @@ GLOBAL bool -IRC_DIE( CLIENT *Client, REQUEST *Req ) +IRC_DIE(CLIENT * Client, REQUEST * Req) { /* Shut down server */ - assert( Client != NULL ); - assert( Req != NULL ); + CONN_ID c; + CLIENT *cl; + + assert(Client != NULL); + assert(Req != NULL); /* Not a local IRC operator? */ - if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client )); - + if ((!Client_HasMode(Client, 'o')) || (!Client_OperByMe(Client))) + return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG, + Client_ID(Client)); + /* Bad number of parameters? */ - if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); +#ifdef STRICT_RFC + if (Req->argc != 0) +#else + if (Req->argc > 1) +#endif + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); + + /* Is a message given? */ + if (Req->argc > 0) { + c = Conn_First(); + while (c != NONE) { + cl = Conn_GetClient(c); + if (Client_Type(cl) == CLIENT_USER) + IRC_WriteStrClient(cl, "NOTICE %s :%s", + Client_ID(cl), Req->argv[0]); + c = Conn_Next(c); + } + } - Log( LOG_NOTICE|LOG_snotice, "Got DIE command from \"%s\" ...", Client_Mask( Client )); + Log(LOG_NOTICE | LOG_snotice, "Got DIE command from \"%s\" ...", + Client_Mask(Client)); NGIRCd_SignalQuit = true; + return CONNECTED; } /* IRC_DIE */ @@ -150,35 +175,52 @@ } /* IRC_RESTART */ +/** + * Connect configured or new server. + */ GLOBAL bool -IRC_CONNECT(CLIENT *Client, REQUEST *Req ) +IRC_CONNECT(CLIENT * Client, REQUEST * Req) { - /* Connect configured or new server */ - assert( Client != NULL ); - assert( Req != NULL ); + assert(Client != NULL); + assert(Req != NULL); /* Not a local IRC operator? */ - if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client )); + if ((!Client_HasMode(Client, 'o')) || (!Client_OperByMe(Client))) + return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG, + Client_ID(Client)); /* Bad number of parameters? */ - if(( Req->argc != 2 ) && ( Req->argc != 5 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); + if ((Req->argc != 2) && (Req->argc != 5)) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); /* Invalid port number? */ - if( atoi( Req->argv[1] ) < 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); - - Log( LOG_NOTICE|LOG_snotice, "Got CONNECT command from \"%s\" for \"%s\".", Client_Mask( Client ), Req->argv[0]); + if (atoi(Req->argv[1]) < 1) + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); + + Log(LOG_NOTICE | LOG_snotice, + "Got CONNECT command from \"%s\" for \"%s\".", Client_Mask(Client), + Req->argv[0]); - if( Req->argc == 2 ) - { + if (Req->argc == 2) { /* Connect configured server */ - if( ! Conf_EnableServer( Req->argv[0], atoi( Req->argv[1] ))) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] ); - } - else - { + if (!Conf_EnableServer + (Req->argv[0], (UINT16) atoi(Req->argv[1]))) + return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG, + Client_ID(Client), + Req->argv[0]); + } else { /* Add server */ - if( ! Conf_AddServer( Req->argv[0], atoi( Req->argv[1] ), Req->argv[2], Req->argv[3], Req->argv[4] )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] ); + if (!Conf_AddServer + (Req->argv[0], (UINT16) atoi(Req->argv[1]), Req->argv[2], + Req->argv[3], Req->argv[4])) + return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG, + Client_ID(Client), + Req->argv[0]); } + return CONNECTED; } /* IRC_CONNECT */ @@ -208,7 +250,7 @@ if( ! Conf_DisableServer( Req->argv[0] )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] ); /* Are we still connected or were we killed, too? */ - if( Client_GetFromConn( my_conn )) return CONNECTED; + if( Conn_GetClient( my_conn )) return CONNECTED; else return DISCONNECTED; } /* IRC_CONNECT */ Index: src/ngircd/irc-server.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/irc-server.c,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- src/ngircd/irc-server.c 19 Mar 2005 18:43:49 -0000 1.38 +++ src/ngircd/irc-server.c 30 Apr 2006 21:31:43 -0000 1.39 @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de) + * Copyright (c)2001-2006 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 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-server.c,v 1.38 2005/03/19 18:43:49 fw Exp $"; +static char UNUSED id[] = "$Id: irc-server.c,v 1.39 2006/04/30 21:31:43 alex Exp $"; #include "imp.h" #include @@ -244,22 +244,24 @@ if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED; } + /* Get next channel ... */ + chan = Channel_Next(chan); + } + #ifdef IRCPLUS - if( strchr( Client_Flags( Client ), 'L' )) - { + if (strchr(Client_Flags(Client), 'L')) { #ifdef DEBUG - Log( LOG_DEBUG, "Synchronizing INVITE- and BAN-lists ..." ); + Log(LOG_DEBUG, + "Synchronizing INVITE- and BAN-lists ..."); #endif - /* Synchronize INVITE- and BAN-lists */ - if( ! Lists_SendInvites( Client )) return DISCONNECTED; - if( ! Lists_SendBans( Client )) return DISCONNECTED; - } + /* Synchronize INVITE- and BAN-lists */ + if (! Lists_SendInvites(Client)) + return DISCONNECTED; + if (! Lists_SendBans(Client)) + return DISCONNECTED; + } #endif - /* naechsten Channel suchen */ - chan = Channel_Next( chan ); - } - return CONNECTED; } else if( Client_Type( Client ) == CLIENT_SERVER ) Index: src/ngircd/irc-write.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/irc-write.c,v retrieving revision 1.18 retrieving revision 1.20 diff -u -r1.18 -r1.20 --- src/ngircd/irc-write.c 27 Apr 2005 07:39:18 -0000 1.18 +++ src/ngircd/irc-write.c 10 May 2006 21:24:01 -0000 1.20 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-write.c,v 1.18 2005/04/27 07:39:18 alex Exp $"; +static char UNUSED id[] = "$Id: irc-write.c,v 1.20 2006/05/10 21:24:01 alex Exp $"; #include "imp.h" #include @@ -39,7 +39,7 @@ #define SEND_TO_SERVER 2 -LOCAL char *Get_Prefix PARAMS(( CLIENT *Target, CLIENT *Client )); +static char *Get_Prefix PARAMS(( CLIENT *Target, CLIENT *Client )); #ifdef PROTOTYPES @@ -400,7 +400,7 @@ GLOBAL void -IRC_SetPenalty( CLIENT *Client, int Seconds ) +IRC_SetPenalty( CLIENT *Client, time_t Seconds ) { CONN_ID c; @@ -410,11 +410,12 @@ if( Client_Type( Client ) == CLIENT_SERVER ) return; c = Client_Conn( Client ); - if( c > NONE ) Conn_SetPenalty( c, Seconds ); + if (c > NONE) + Conn_SetPenalty(c, Seconds); } /* IRC_SetPenalty */ -LOCAL char * +static char * Get_Prefix( CLIENT *Target, CLIENT *Client ) { assert( Target != NULL ); Index: src/ngircd/irc-write.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/irc-write.h,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- src/ngircd/irc-write.h 19 Mar 2005 18:43:49 -0000 1.7 +++ src/ngircd/irc-write.h 10 May 2006 21:24:01 -0000 1.8 @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: irc-write.h,v 1.7 2005/03/19 18:43:49 fw Exp $ + * $Id: irc-write.h,v 1.8 2006/05/10 21:24:01 alex Exp $ * * Sending IRC commands over the network (header) */ @@ -30,7 +30,7 @@ GLOBAL bool IRC_WriteStrRelatedPrefix PARAMS(( CLIENT *Client, CLIENT *Prefix, bool Remote, char *Format, ... )); -GLOBAL void IRC_SetPenalty PARAMS(( CLIENT *Client, int Seconds )); +GLOBAL void IRC_SetPenalty PARAMS(( CLIENT *Client, time_t Seconds )); #endif Index: src/ngircd/irc.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/irc.c,v retrieving revision 1.126.2.1 retrieving revision 1.131 diff -u -r1.126.2.1 -r1.131 --- src/ngircd/irc.c 2 Aug 2005 23:08:27 -0000 1.126.2.1 +++ src/ngircd/irc.c 23 Jul 2006 14:55:40 -0000 1.131 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc.c,v 1.126.2.1 2005/08/02 23:08:27 alex Exp $"; +static char UNUSED id[] = "$Id: irc.c,v 1.131 2006/07/23 14:55:40 alex Exp $"; #include "imp.h" #include @@ -22,10 +22,9 @@ #include #include "ngircd.h" -#include "conn.h" #include "resolve.h" -#include "conf.h" #include "conn-func.h" +#include "conf.h" #include "client.h" #include "channel.h" #include "defines.h" @@ -38,7 +37,7 @@ #include "irc.h" -LOCAL char *Option_String PARAMS(( CONN_ID Idx )); +static char *Option_String PARAMS(( CONN_ID Idx )); GLOBAL bool @@ -160,7 +159,7 @@ Log( LOG_NOTICE, "Client with nick \"%s\" is unknown here.", Req->argv[0] ); /* Are we still connected or were we killed, too? */ - if(( my_conn > NONE ) && ( Client_GetFromConn( my_conn ))) + if(( my_conn > NONE ) && ( Conn_GetClient( my_conn ))) return CONNECTED; else return DISCONNECTED; @@ -325,17 +324,19 @@ } /* IRC_HELP */ -LOCAL char * +static char * Option_String( CONN_ID Idx ) { static char option_txt[8]; - int options; + UINT16 options; - options = Conn_Options( Idx ); + options = Conn_Options(Idx); - strcpy( option_txt, "F" ); /* No idea what this means but the original ircd sends it ... */ + strcpy(option_txt, "F"); /* No idea what this means, but the + * original ircd sends it ... */ #ifdef ZLIB - if( options & CONN_ZIP ) strcat( option_txt, "z" ); + if(options & CONN_ZIP) /* zlib compression supported. */ + strcat(option_txt, "z"); #endif return option_txt; Index: src/ngircd/lists.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/lists.c,v retrieving revision 1.17 retrieving revision 1.18 diff -u -r1.17 -r1.18 --- src/ngircd/lists.c 19 Mar 2005 18:43:49 -0000 1.17 +++ src/ngircd/lists.c 31 Jul 2005 20:13:08 -0000 1.18 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: lists.c,v 1.17 2005/03/19 18:43:49 fw Exp $"; +static char UNUSED id[] = "$Id: lists.c,v 1.18 2005/07/31 20:13:08 alex Exp $"; #include "imp.h" #include @@ -48,13 +48,13 @@ } C2C; -LOCAL C2C *My_Invites, *My_Bans; +static C2C *My_Invites, *My_Bans; -LOCAL C2C *New_C2C PARAMS(( char *Mask, CHANNEL *Chan, bool OnlyOnce )); +static C2C *New_C2C PARAMS(( char *Mask, CHANNEL *Chan, bool OnlyOnce )); -LOCAL bool Check_List PARAMS(( C2C **Cl2Chan, CLIENT *Client, CHANNEL *Chan )); -LOCAL bool Already_Registered PARAMS(( C2C *Cl2Chan, char *Mask, CHANNEL *Chan )); +static bool Check_List PARAMS(( C2C **Cl2Chan, CLIENT *Client, CHANNEL *Chan )); +static bool Already_Registered PARAMS(( C2C *Cl2Chan, char *Mask, CHANNEL *Chan )); @@ -407,7 +407,7 @@ } /* Lists_MakeMask */ -LOCAL C2C * +static C2C * New_C2C( char *Mask, CHANNEL *Chan, bool OnlyOnce ) { C2C *c2c; @@ -431,7 +431,7 @@ } /* New_C2C */ -LOCAL bool +static bool Check_List( C2C **Cl2Chan, CLIENT *Client, CHANNEL *Chan ) { C2C *c2c, *last; @@ -470,7 +470,7 @@ } /* Check_List */ -LOCAL bool +static bool Already_Registered( C2C *List, char *Mask, CHANNEL *Chan ) { C2C *c2c; Index: src/ngircd/log.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/log.c,v retrieving revision 1.57.2.1 retrieving revision 1.61 diff -u -r1.57.2.1 -r1.61 --- src/ngircd/log.c 29 Aug 2005 11:19:48 -0000 1.57.2.1 +++ src/ngircd/log.c 23 Jul 2006 23:23:45 -0000 1.61 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: log.c,v 1.57.2.1 2005/08/29 11:19:48 alex Exp $"; +static char UNUSED id[] = "$Id: log.c,v 1.61 2006/07/23 23:23:45 alex Exp $"; #include "imp.h" #include @@ -44,15 +44,15 @@ #include "log.h" -LOCAL char Init_Txt[127]; -LOCAL bool Is_Daemon; +static char Init_Txt[127]; +static bool Is_Daemon; #ifdef DEBUG -LOCAL char Error_File[FNAME_LEN]; +static char Error_File[FNAME_LEN]; #endif -LOCAL void Wall_ServerNotice PARAMS(( char *Msg )); +static void Wall_ServerNotice PARAMS(( char *Msg )); GLOBAL void @@ -162,6 +162,60 @@ } /* Log_Exit */ +/** + * Log function for debug messages. + * This function is only functional when the program is compiled with debug + * code enabled; otherwise it is an empty function which the compiler will + * hopefully mangle down to "nothing". Therefore you should use LogDebug(...) + * in favor to Log(LOG_DEBUG, ...). + * @param Format Format string like printf(). + * @param ... Further arguments. + */ +# ifdef PROTOTYPES +GLOBAL void +#ifdef DEBUG +LogDebug( const char *Format, ... ) +#else +LogDebug( UNUSED const char *Format, ... ) +#endif /* DEBUG */ +# else +GLOBAL void +LogDebug( Format, va_alist ) +const char *Format; +va_dcl +# endif /* PROTOTYPES */ +#ifdef DEBUG +{ + char msg[MAX_LOG_MSG_LEN]; + va_list ap; + + if (!NGIRCd_Debug) return; +#ifdef PROTOTYPES + va_start( ap, Format ); +#else + va_start( ap ); +#endif + vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap ); + va_end( ap ); + Log(LOG_DEBUG, "%s", msg); +} +#else +{ + /* Do nothing. + * The compiler should optimize this out, please ;-) */ +} +#endif /* DEBUG */ + + +/** + * Logging function of ngIRCd. + * This function logs messages to the console and/or syslog, whichever is + * suitable for the mode ngIRCd is running in (daemon vs. non-daemon). + * Please note: you sould use LogDebug(...) for debug messages! + * @param Level syslog level (LOG_xxx) + * @param Format Format string like printf(). + * @param ... Further arguments. + */ #ifdef PROTOTYPES GLOBAL void Log( int Level, const char *Format, ... ) @@ -174,7 +228,6 @@ #endif { /* Eintrag in Logfile(s) schreiben */ - char msg[MAX_LOG_MSG_LEN]; bool snotice; va_list ap; @@ -306,7 +359,7 @@ * Send log messages to users flagged with the "s" mode. * @param Msg The message to send. */ -LOCAL void +static void Wall_ServerNotice( char *Msg ) { CLIENT *c; Index: src/ngircd/log.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/log.h,v retrieving revision 1.18 retrieving revision 1.19 diff -u -r1.18 -r1.19 --- src/ngircd/log.h 24 Jun 2005 19:55:10 -0000 1.18 +++ src/ngircd/log.h 8 Feb 2006 17:33:28 -0000 1.19 @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: log.h,v 1.18 2005/06/24 19:55:10 alex Exp $ + * $Id: log.h,v 1.19 2006/02/08 17:33:28 fw Exp $ * * Logging functions (header) */ @@ -39,6 +39,7 @@ GLOBAL void Log_Exit PARAMS(( void )); GLOBAL void Log PARAMS(( int Level, const char *Format, ... )); +GLOBAL void LogDebug PARAMS(( const char *Format, ... )); GLOBAL void Log_Init_Resolver PARAMS(( void )); GLOBAL void Log_Exit_Resolver PARAMS(( void )); Index: src/ngircd/match.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/match.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- src/ngircd/match.c 19 Mar 2005 18:43:49 -0000 1.3 +++ src/ngircd/match.c 31 Jul 2005 20:13:08 -0000 1.4 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: match.c,v 1.3 2005/03/19 18:43:49 fw Exp $"; +static char UNUSED id[] = "$Id: match.c,v 1.4 2005/07/31 20:13:08 alex Exp $"; #include "imp.h" #include @@ -32,8 +32,8 @@ */ -LOCAL int Matche PARAMS(( char *p, char *t )); -LOCAL int Matche_After_Star PARAMS(( char *p, char *t )); +static int Matche PARAMS(( char *p, char *t )); +static int Matche_After_Star PARAMS(( char *p, char *t )); #define MATCH_PATTERN 6 /* bad pattern */ @@ -53,7 +53,7 @@ } /* Match */ -LOCAL int +static int Matche( char *p, char *t ) { register char range_start, range_end; @@ -200,7 +200,7 @@ } /* Matche */ -LOCAL int +static int Matche_After_Star( char *p, char *t ) { register int nextp, match = 0; Index: src/ngircd/messages.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/messages.h,v retrieving revision 1.66 retrieving revision 1.67 diff -u -r1.66 -r1.67 --- src/ngircd/messages.h 28 Feb 2004 02:18:16 -0000 1.66 +++ src/ngircd/messages.h 2 Sep 2005 12:50:25 -0000 1.67 @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: messages.h,v 1.66 2004/02/28 02:18:16 alex Exp $ + * $Id: messages.h,v 1.67 2005/09/02 12:50:25 alex Exp $ * * IRC numerics (Header) */ @@ -62,6 +62,7 @@ #define RPL_CHANNELMODEIS_MSG "324 %s %s +%s" #define RPL_NOTOPIC_MSG "331 %s %s :No topic is set" #define RPL_TOPIC_MSG "332 %s %s :%s" +#define RPL_TOPICSETBY_MSG "333 %s %s %s %u" #define RPL_INVITING_MSG "341 %s %s %s" #define RPL_INVITELIST_MSG "346 %s %s %s" #define RPL_ENDOFINVITELIST_MSG "347 %s %s :End of channel invite list" Index: src/ngircd/ngircd.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/ngircd.c,v retrieving revision 1.102.2.2 retrieving revision 1.113 diff -u -r1.102.2.2 -r1.113 --- src/ngircd/ngircd.c 8 Jul 2005 23:20:04 -0000 1.102.2.2 +++ src/ngircd/ngircd.c 23 Jul 2006 12:07:33 -0000 1.113 @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2005 by Alexander Barton (alex@barton.de) + * Copyright (c)2001-2006 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.102.2.2 2005/07/08 23:20:04 alex Exp $"; +static char UNUSED id[] = "$Id: ngircd.c,v 1.113 2006/07/23 12:07:33 alex Exp $"; /** * @file @@ -48,7 +48,7 @@ #include "parse.h" #include "irc.h" -#ifdef RENDEZVOUS +#ifdef ZEROCONF #include "rendezvous.h" #endif @@ -56,20 +56,20 @@ #include "ngircd.h" -LOCAL void Initialize_Signal_Handler PARAMS(( void )); -LOCAL void Signal_Handler PARAMS(( int Signal )); +static void Initialize_Signal_Handler PARAMS(( void )); +static void Signal_Handler PARAMS(( int Signal )); -LOCAL void Show_Version PARAMS(( void )); -LOCAL void Show_Help PARAMS(( void )); +static void Show_Version PARAMS(( void )); +static void Show_Help PARAMS(( void )); -LOCAL void Pidfile_Create PARAMS(( long )); -LOCAL void Pidfile_Delete PARAMS(( void )); +static void Pidfile_Create PARAMS(( pid_t pid )); +static void Pidfile_Delete PARAMS(( void )); -LOCAL void Fill_Version PARAMS(( void )); +static void Fill_Version PARAMS(( void )); -LOCAL void Setup_FDStreams PARAMS(( void )); +static void Setup_FDStreams PARAMS(( void )); -LOCAL bool NGIRCd_Init PARAMS(( bool )); +static bool NGIRCd_Init PARAMS(( bool )); /** * The main() function of ngIRCd. @@ -262,18 +262,19 @@ Log_Init( ! NGIRCd_NoDaemon ); Conf_Init( ); - if (!NGIRCd_Init( NGIRCd_NoDaemon )) { - Log(LOG_WARNING, "Fatal: Initialization failed"); + /* Initialize the "main program": chroot environment, user and + * group ID, ... */ + if (!NGIRCd_Init(NGIRCd_NoDaemon)) { + Log(LOG_ALERT, "Fatal: Initialization failed"); exit(1); } /* Initialize modules, part II: these functions are eventually * called with already dropped privileges ... */ - Resolve_Init( ); Lists_Init( ); Channel_Init( ); Client_Init( ); -#ifdef RENDEZVOUS +#ifdef ZEROCONF Rendezvous_Init( ); #endif Conn_Init( ); @@ -322,7 +323,7 @@ /* Alles abmelden */ Conn_Exit( ); -#ifdef RENDEZVOUS +#ifdef ZEROCONF Rendezvous_Exit( ); #endif Client_Exit( ); @@ -342,7 +343,7 @@ * further usage, for example by the IRC command VERSION and the --version * command line switch. */ -LOCAL void +static void Fill_Version( void ) { NGIRCd_VersionAddition[0] = '\0'; @@ -362,11 +363,11 @@ strlcat( NGIRCd_VersionAddition, "TCPWRAP", sizeof NGIRCd_VersionAddition ); #endif -#ifdef RENDEZVOUS +#ifdef ZEROCONF if( NGIRCd_VersionAddition[0] ) strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition ); - strlcat( NGIRCd_VersionAddition, "RENDEZVOUS", sizeof NGIRCd_VersionAddition ); + strlcat( NGIRCd_VersionAddition, "ZEROCONF", sizeof NGIRCd_VersionAddition ); #endif #ifdef IDENTAUTH if( NGIRCd_VersionAddition[0] ) @@ -439,7 +440,7 @@ /* Recover old server name: it can't be changed during run-time */ if( strcmp( old_name, Conf_ServerName ) != 0 ) { - strcpy( Conf_ServerName, old_name ); + strlcpy( Conf_ServerName, old_name, sizeof Conf_ServerName ); Log( LOG_ERR, "Can't change \"ServerName\" on runtime! Ignored new name." ); } @@ -459,7 +460,7 @@ /** * Initialize the signal handler. */ -LOCAL void +static void Initialize_Signal_Handler( void ) { /* Signal-Handler initialisieren: einige Signale @@ -481,27 +482,27 @@ #endif /* Signal-Handler einhaengen */ - sigaction( SIGINT, &saction, NULL ); - sigaction( SIGQUIT, &saction, NULL ); - sigaction( SIGTERM, &saction, NULL); - sigaction( SIGHUP, &saction, NULL); - sigaction( SIGCHLD, &saction, NULL); + sigaction(SIGINT, &saction, NULL); + sigaction(SIGQUIT, &saction, NULL); + sigaction(SIGTERM, &saction, NULL); + sigaction(SIGHUP, &saction, NULL); + sigaction(SIGCHLD, &saction, NULL); /* einige Signale ignorieren */ saction.sa_handler = SIG_IGN; - sigaction( SIGPIPE, &saction, NULL ); + sigaction(SIGPIPE, &saction, NULL); #else /* kein sigaction() vorhanden */ /* Signal-Handler einhaengen */ - signal( SIGINT, Signal_Handler ); - signal( SIGQUIT, Signal_Handler ); - signal( SIGTERM, Signal_Handler ); - signal( SIGHUP, Signal_Handler ); - signal( SIGCHLD, Signal_Handler ); + signal(SIGINT, Signal_Handler); + signal(SIGQUIT, Signal_Handler); + signal(SIGTERM, Signal_Handler); + signal(SIGHUP, Signal_Handler); + signal(SIGCHLD, Signal_Handler); /* einige Signale ignorieren */ - signal( SIGPIPE, SIG_IGN ); + signal(SIGPIPE, SIG_IGN); #endif } /* Initialize_Signal_Handler */ @@ -512,7 +513,7 @@ * user and/or the system to it. For example SIGTERM and SIGHUP. * @param Signal Number of the signal to handle. */ -LOCAL void +static void Signal_Handler( int Signal ) { switch( Signal ) @@ -543,12 +544,12 @@ /** * Display copyright and version information of ngIRCd on the console. */ -LOCAL void +static void Show_Version( void ) { puts( NGIRCd_Version ); - puts( "Copyright (c)2001-2005 by Alexander Barton ()." ); - puts( "Homepage: \n" ); + puts( "Copyright (c)2001-2006 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." ); } /* Show_Version */ @@ -559,7 +560,7 @@ * This help depends on the configuration of the executable and only shows * options that are actually enabled. */ -LOCAL void +static void Show_Help( void ) { #ifdef DEBUG @@ -580,7 +581,7 @@ /** * Delete the file containing the process ID (PID). */ -LOCAL void +static void Pidfile_Delete( void ) { /* Pidfile configured? */ @@ -599,8 +600,8 @@ * Create the file containing the process ID of ngIRCd ("PID file"). * @param pid The process ID to be stored in this file. */ -LOCAL void -Pidfile_Create( long pid ) +static void +Pidfile_Create(pid_t pid) { int pidfd; char pidbuf[64]; @@ -619,13 +620,13 @@ return; } - len = snprintf( pidbuf, sizeof pidbuf, "%ld\n", pid ); - if (len < 0|| len < (int)sizeof pid) { + len = snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid); + if (len < 0 || len >= (int)sizeof pidbuf) { Log( LOG_ERR, "Error converting pid"); return; } - if( write( pidfd, pidbuf, len) != len) + if (write(pidfd, pidbuf, (size_t)len) != (ssize_t)len) Log( LOG_ERR, "Can't write PID file (%s): %s", Conf_PidFile, strerror( errno )); if( close(pidfd) != 0 ) @@ -636,7 +637,7 @@ /** * Redirect stdin, stdout and stderr to apropriate file handles. */ -LOCAL void +static void Setup_FDStreams( void ) { int fd; @@ -661,8 +662,8 @@ } /* Setup_FDStreams */ -LOCAL bool -NGIRCd_getNobodyID(unsigned int *uid, unsigned int *gid ) +static bool +NGIRCd_getNobodyID(uid_t *uid, gid_t *gid ) { struct passwd *pwd; @@ -680,7 +681,7 @@ } -LOCAL bool +static bool NGIRCd_Init( bool NGIRCd_NoDaemon ) { static bool initialized; @@ -688,7 +689,7 @@ struct passwd *pwd; struct group *grp; int real_errno; - long pid; + pid_t pid; if (initialized) return true; @@ -748,7 +749,7 @@ * connected to ther controlling terminal. Use "--nodaemon" * to disable this "daemon mode" (useful for debugging). */ if ( ! NGIRCd_NoDaemon ) { - pid = (long)fork( ); + pid = fork( ); if( pid > 0 ) { /* "Old" process: exit. */ exit( 0 ); Index: src/ngircd/parse.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/parse.c,v retrieving revision 1.63.2.1 retrieving revision 1.67 diff -u -r1.63.2.1 -r1.67 --- src/ngircd/parse.c 24 Jul 2005 21:06:51 -0000 1.63.2.1 +++ src/ngircd/parse.c 23 Apr 2006 10:37:27 -0000 1.67 @@ -12,7 +12,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: parse.c,v 1.63.2.1 2005/07/24 21:06:51 alex Exp $"; +static char UNUSED id[] = "$Id: parse.c,v 1.67 2006/04/23 10:37:27 fw Exp $"; /** * @file @@ -103,13 +103,13 @@ }; -LOCAL void Init_Request PARAMS(( REQUEST *Req )); +static void Init_Request PARAMS(( REQUEST *Req )); -LOCAL bool Validate_Prefix PARAMS(( CONN_ID Idx, REQUEST *Req, bool *Closed )); -LOCAL bool Validate_Command PARAMS(( CONN_ID Idx, REQUEST *Req, bool *Closed )); -LOCAL bool Validate_Args PARAMS(( CONN_ID Idx, REQUEST *Req, bool *Closed )); +static bool Validate_Prefix PARAMS(( CONN_ID Idx, REQUEST *Req, bool *Closed )); +static bool Validate_Command PARAMS(( CONN_ID Idx, REQUEST *Req, bool *Closed )); +static bool Validate_Args PARAMS(( CONN_ID Idx, REQUEST *Req, bool *Closed )); -LOCAL bool Handle_Request PARAMS(( CONN_ID Idx, REQUEST *Req )); +static bool Handle_Request PARAMS(( CONN_ID Idx, REQUEST *Req )); /** @@ -247,7 +247,7 @@ * Initialize request structure. * @param Req Request structure to be initialized. */ -LOCAL void +static void Init_Request( REQUEST *Req ) { /* Neue Request-Struktur initialisieren */ @@ -263,7 +263,7 @@ } /* Init_Request */ -LOCAL bool +static bool Validate_Prefix( CONN_ID Idx, REQUEST *Req, bool *Closed ) { CLIENT *client, *c; @@ -277,7 +277,7 @@ if( ! Req->prefix ) return true; /* Client-Struktur der Connection ermitteln */ - client = Client_GetFromConn( Idx ); + client = Conn_GetClient( Idx ); assert( client != NULL ); /* nur validieren, wenn bereits registrierte Verbindung */ @@ -306,7 +306,7 @@ { /* das angegebene Prefix ist aus dieser Richtung, also * aus der gegebenen Connection, ungueltig! */ - Log( LOG_ERR, "Spoofed prefix \"%s\" from \"%s\" (connection %d, command %s)!", Req->prefix, Client_Mask( Client_GetFromConn( Idx )), Idx, Req->command ); + Log( LOG_ERR, "Spoofed prefix \"%s\" from \"%s\" (connection %d, command %s)!", Req->prefix, Client_Mask( Conn_GetClient( Idx )), Idx, Req->command ); Conn_Close( Idx, NULL, "Spoofed prefix", true); *Closed = true; return false; @@ -316,7 +316,7 @@ } /* Validate_Prefix */ -LOCAL bool +static bool Validate_Command( UNUSED CONN_ID Idx, UNUSED REQUEST *Req, bool *Closed ) { assert( Idx >= 0 ); @@ -327,7 +327,7 @@ } /* Validate_Comman */ -LOCAL bool +static bool Validate_Args( UNUSED CONN_ID Idx, UNUSED REQUEST *Req, bool *Closed ) { assert( Idx >= 0 ); @@ -338,7 +338,7 @@ } /* Validate_Args */ -LOCAL bool +static bool Handle_Request( CONN_ID Idx, REQUEST *Req ) { /* Client-Request verarbeiten. Bei einem schwerwiegenden Fehler @@ -354,7 +354,7 @@ assert( Req != NULL ); assert( Req->command != NULL ); - client = Client_GetFromConn( Idx ); + client = Conn_GetClient( Idx ); assert( client != NULL ); /* Statuscode? */ @@ -445,9 +445,12 @@ Req->argc == 1 ? "parameter" : "parameters", Req->prefix ? "" : " no" ); - if( Client_Type( client ) != CLIENT_SERVER ) - return IRC_WriteStrClient( client, ERR_UNKNOWNCOMMAND_MSG, - Client_ID( client ), Req->command ); + if (Client_Type(client) != CLIENT_SERVER) { + result = IRC_WriteStrClient(client, ERR_UNKNOWNCOMMAND_MSG, + Client_ID(client), Req->command); + Conn_SetPenalty(Idx, 1); + return result; + } return true; } /* Handle_Request */ Index: src/ngircd/rendezvous.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/rendezvous.c,v retrieving revision 1.5 retrieving revision 1.8 diff -u -r1.5 -r1.8 --- src/ngircd/rendezvous.c 19 Mar 2005 18:43:49 -0000 1.5 +++ src/ngircd/rendezvous.c 10 May 2006 21:24:01 -0000 1.8 @@ -18,10 +18,10 @@ #include "portab.h" -#ifdef RENDEZVOUS +#ifdef ZEROCONF -static char UNUSED id[] = "$Id: rendezvous.c,v 1.5 2005/03/19 18:43:49 fw Exp $"; +static char UNUSED id[] = "$Id: rendezvous.c,v 1.8 2006/05/10 21:24:01 alex Exp $"; #include "imp.h" #include @@ -72,10 +72,10 @@ #endif } SERVICE; -LOCAL SERVICE My_Rendezvous[MAX_RENDEZVOUS]; +static SERVICE My_Rendezvous[MAX_RENDEZVOUS]; -LOCAL void Unregister( int Idx ); +static void Unregister( int Idx ); /* -- Apple API -- */ @@ -84,7 +84,7 @@ #define MAX_MACH_MSG_SIZE 512 -LOCAL void Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrCode, void *Context ); +static void Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrCode, void *Context ); #endif /* Apple */ @@ -93,10 +93,10 @@ #ifdef HOWL -LOCAL sw_discovery My_Discovery_Session = NULL; -LOCAL sw_salt My_Salt; +static sw_discovery My_Discovery_Session = NULL; +static sw_salt My_Salt; -LOCAL sw_result HOWL_API Registration_Reply_Handler( sw_discovery Session, sw_discovery_publish_status Status, sw_discovery_oid Id, sw_opaque Extra ); +static sw_result HOWL_API Registration_Reply_Handler( sw_discovery Session, sw_discovery_publish_status Status, sw_discovery_oid Id, sw_opaque Extra ); #endif /* Howl */ @@ -144,7 +144,7 @@ } /* Rendezvous_Exit */ -GLOBAL bool Rendezvous_Register( char *Name, char *Type, unsigned int Port ) +GLOBAL bool Rendezvous_Register( char *Name, char *Type, UINT16 Port ) { /* Register new service */ @@ -263,7 +263,7 @@ } /* Rendezvous_Handler */ -LOCAL void Unregister( int Idx ) +static void Unregister( int Idx ) { /* Unregister service */ @@ -289,7 +289,7 @@ #ifdef APPLE -LOCAL void Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrCode, void *Context ) +static void Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrCode, void *Context ) { SERVICE *s = (SERVICE *)Context; char txt[50]; @@ -310,7 +310,8 @@ strcpy( txt, "name conflict!" ); break; default: - sprintf( txt, "error code %ld!", (long)ErrCode ); + snprintf(txt, sizeof txt, "error code %ld!", + (long)ErrCode); } Log( LOG_INFO, "Can't register \"%s\" with Rendezvous: %s", s->Desc, txt ); @@ -326,7 +327,7 @@ #ifdef HOWL -LOCAL sw_result HOWL_API Registration_Reply_Handler( sw_discovery Session, sw_discovery_publish_status Status, UNUSED sw_discovery_oid Id, sw_opaque Extra ) +static sw_result HOWL_API Registration_Reply_Handler( sw_discovery Session, sw_discovery_publish_status Status, UNUSED sw_discovery_oid Id, sw_opaque Extra ) { SERVICE *s = (SERVICE *)Extra; char txt[50]; @@ -347,7 +348,8 @@ strcpy( txt, "name conflict!" ); break; default: - sprintf( txt, "error code %ld!", (long)Status ); + snprintf(txt, sizeof txt, "error code %ld!", + (long)Status); } Log( LOG_INFO, "Can't register \"%s\" with Rendezvous: %s", s->Desc, txt ); @@ -360,7 +362,7 @@ #endif /* Howl */ -#endif /* RENDEZVOUS */ +#endif /* ZEROCONF */ /* -eof- */ Index: src/ngircd/rendezvous.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/rendezvous.h,v retrieving revision 1.2 retrieving revision 1.4 diff -u -r1.2 -r1.4 --- src/ngircd/rendezvous.h 19 Mar 2005 18:43:49 -0000 1.2 +++ src/ngircd/rendezvous.h 10 May 2006 21:24:01 -0000 1.4 @@ -8,13 +8,13 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: rendezvous.h,v 1.2 2005/03/19 18:43:49 fw Exp $ + * $Id: rendezvous.h,v 1.4 2006/05/10 21:24:01 alex Exp $ * * "Rendezvous" functions (Header) */ -#ifdef RENDEZVOUS +#ifdef ZEROCONF #ifndef __rdezvous_h__ #define __rdezvous_h__ @@ -23,7 +23,7 @@ GLOBAL void Rendezvous_Init( void ); GLOBAL void Rendezvous_Exit( void ); -GLOBAL bool Rendezvous_Register( char *Name, char *Type, unsigned int Port ); +GLOBAL bool Rendezvous_Register( char *Name, char *Type, UINT16 Port ); GLOBAL bool Rendezvous_Unregister( char *Name ); GLOBAL void Rendezvous_UnregisterListeners( void ); @@ -33,7 +33,7 @@ #endif /* __rdezvous_h__ */ -#endif /* RENDEZVOUS */ +#endif /* ZEROCONF */ /* -eof- */ Index: src/ngircd/resolve.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/resolve.c,v retrieving revision 1.12.2.1 retrieving revision 1.24 diff -u -r1.12.2.1 -r1.24 --- src/ngircd/resolve.c 2 Sep 2005 22:07:38 -0000 1.12.2.1 +++ src/ngircd/resolve.c 10 May 2006 21:24:01 -0000 1.24 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: resolve.c,v 1.12.2.1 2005/09/02 22:07:38 fw Exp $"; +static char UNUSED id[] = "$Id: resolve.c,v 1.24 2006/05/10 21:24:01 alex Exp $"; #include "imp.h" #include @@ -39,195 +39,206 @@ #include "exp.h" #include "resolve.h" +#include "io.h" -#ifdef IDENTAUTH -LOCAL void Do_ResolveAddr PARAMS(( struct sockaddr_in *Addr, int Sock, int w_fd )); -#else -LOCAL void Do_ResolveAddr PARAMS(( struct sockaddr_in *Addr, int w_fd )); -#endif - -LOCAL void Do_ResolveName PARAMS(( char *Host, int w_fd )); +static void Do_ResolveAddr PARAMS(( struct sockaddr_in *Addr, int Sock, int w_fd )); +static void Do_ResolveName PARAMS(( const char *Host, int w_fd )); +static bool register_callback PARAMS((RES_STAT *s, void (*cbfunc)(int, short))); #ifdef h_errno -LOCAL char *Get_Error PARAMS(( int H_Error )); +static char *Get_Error PARAMS(( int H_Error )); #endif -LOCAL RES_STAT *New_Res_Stat PARAMS(( void )); - - -GLOBAL void -Resolve_Init( void ) +static pid_t +Resolver_fork(int *pipefds) { - /* Initialize module */ - - FD_ZERO( &Resolver_FDs ); -} /* Resolve_Init */ - + pid_t pid; -#ifdef IDENTAUTH -GLOBAL RES_STAT * -Resolve_Addr( struct sockaddr_in *Addr, int Sock ) -#else -GLOBAL RES_STAT * -Resolve_Addr( struct sockaddr_in *Addr ) -#endif + if (pipe(pipefds) != 0) { + Log( LOG_ALERT, "Resolver: Can't create output pipe: %s!", strerror( errno )); + return -1; + } + + pid = fork(); + switch(pid) { + case -1: + Log( LOG_CRIT, "Resolver: Can't fork: %s!", strerror( errno )); + close(pipefds[0]); + close(pipefds[1]); + return -1; + case 0: /* child */ + close(pipefds[0]); + Log_Init_Resolver( ); + return 0; + } + /* parent */ + close(pipefds[1]); + return pid; +} + + +/** + * Resolve IP (asynchronous!). + */ +GLOBAL bool +Resolve_Addr(RES_STAT * s, struct sockaddr_in *Addr, int identsock, + void (*cbfunc) (int, short)) { - /* Resolve IP (asynchronous!). On errors, e.g. if the child process - * can't be forked, this functions returns NULL. */ - - RES_STAT *s; - int pid; + int pipefd[2]; + pid_t pid; - s = New_Res_Stat( ); - if( ! s ) return NULL; + assert(s != NULL); - /* For sub-process */ - pid = fork( ); - if( pid > 0 ) - { - /* Main process */ + pid = Resolver_fork(pipefd); + if (pid > 0) { +#ifdef DEBUG Log( LOG_DEBUG, "Resolver for %s created (PID %d).", inet_ntoa( Addr->sin_addr ), pid ); - FD_SET( s->pipe[0], &Resolver_FDs ); - if( s->pipe[0] > Conn_MaxFD ) Conn_MaxFD = s->pipe[0]; +#endif s->pid = pid; - return s; - } - else if( pid == 0 ) - { + s->resolver_fd = pipefd[0]; + return register_callback(s, cbfunc); + } else if( pid == 0 ) { /* Sub process */ - Log_Init_Resolver( ); -#ifdef IDENTAUTH - Do_ResolveAddr( Addr, Sock, s->pipe[1] ); -#else - Do_ResolveAddr( Addr, s->pipe[1] ); -#endif + Do_ResolveAddr( Addr, identsock, pipefd[1]); Log_Exit_Resolver( ); - exit( 0 ); - } - else - { - /* Error! */ - close(s->pipe[0]); - close(s->pipe[1]); - free( s ); - Log( LOG_CRIT, "Resolver: Can't fork: %s!", strerror( errno )); - return NULL; + exit(0); } + return false; } /* Resolve_Addr */ -GLOBAL RES_STAT * -Resolve_Name( char *Host ) +/** + * Resolve hostname (asynchronous!). + */ +GLOBAL bool +Resolve_Name( RES_STAT *s, const char *Host, void (*cbfunc)(int, short)) { - /* Resolve hostname (asynchronous!). On errors, e.g. if the child - * process can't be forked, this functions returns NULL. */ - - RES_STAT *s; - int pid; + int pipefd[2]; + pid_t pid; - s = New_Res_Stat( ); - if( ! s ) return NULL; + assert(s != NULL); - /* Fork sub-process */ - pid = fork( ); - if( pid > 0 ) - { + pid = Resolver_fork(pipefd); + if (pid > 0) { /* Main process */ +#ifdef DEBUG Log( LOG_DEBUG, "Resolver for \"%s\" created (PID %d).", Host, pid ); - FD_SET( s->pipe[0], &Resolver_FDs ); - if( s->pipe[0] > Conn_MaxFD ) Conn_MaxFD = s->pipe[0]; +#endif s->pid = pid; - return s; - } - else if( pid == 0 ) - { + s->resolver_fd = pipefd[0]; + return register_callback(s, cbfunc); + } else if( pid == 0 ) { /* Sub process */ - Log_Init_Resolver( ); - Do_ResolveName( Host, s->pipe[1] ); + Do_ResolveName(Host, pipefd[1]); Log_Exit_Resolver( ); - exit( 0 ); - } - else - { - /* Error! */ - close(s->pipe[0]); - close(s->pipe[1]); - free( s ); - Log( LOG_CRIT, "Resolver: Can't fork: %s!", strerror( errno )); - return NULL; + exit(0); } + return false; } /* Resolve_Name */ -#ifdef IDENTAUTH -LOCAL void -Do_ResolveAddr( struct sockaddr_in *Addr, int Sock, int w_fd ) -#else -LOCAL void -Do_ResolveAddr( struct sockaddr_in *Addr, int w_fd ) -#endif +GLOBAL void +Resolve_Init(RES_STAT *s) +{ + assert(s != NULL); + s->resolver_fd = -1; + s->pid = 0; +} + + +static void +Do_ResolveAddr( struct sockaddr_in *Addr, int identsock, int w_fd ) { /* Resolver sub-process: resolve IP address and write result into * pipe to parent. */ char hostname[HOST_LEN]; + char ipstr[HOST_LEN]; struct hostent *h; size_t len; + struct in_addr *addr; + char *ntoaptr; + array resolved_addr; #ifdef IDENTAUTH char *res; #endif - + array_init(&resolved_addr); /* Resolve IP address */ +#ifdef DEBUG Log_Resolver( LOG_DEBUG, "Now resolving %s ...", inet_ntoa( Addr->sin_addr )); +#endif h = gethostbyaddr( (char *)&Addr->sin_addr, sizeof( Addr->sin_addr ), AF_INET ); - if( h ) strlcpy( hostname, h->h_name, sizeof( hostname )); - else - { + if (!h) { #ifdef h_errno Log_Resolver( LOG_WARNING, "Can't resolve address \"%s\": %s!", inet_ntoa( Addr->sin_addr ), Get_Error( h_errno )); #else Log_Resolver( LOG_WARNING, "Can't resolve address \"%s\"!", inet_ntoa( Addr->sin_addr )); #endif strlcpy( hostname, inet_ntoa( Addr->sin_addr ), sizeof( hostname )); + } else { + strlcpy( hostname, h->h_name, sizeof( hostname )); + + h = gethostbyname( hostname ); + if ( h ) { + if (memcmp(h->h_addr, &Addr->sin_addr, sizeof (struct in_addr))) { + addr = (struct in_addr*) h->h_addr; + strlcpy(ipstr, inet_ntoa(*addr), sizeof ipstr); + ntoaptr = inet_ntoa( Addr->sin_addr ); + Log(LOG_WARNING,"Possible forgery: %s resolved to %s (which is at ip %s!)", + ntoaptr, hostname, ipstr); + strlcpy( hostname, ntoaptr, sizeof hostname); + } + } else { + ntoaptr = inet_ntoa( Addr->sin_addr ); + Log(LOG_WARNING, "Possible forgery: %s resolved to %s (which has no ip address)", + ntoaptr, hostname); + strlcpy( hostname, ntoaptr, sizeof hostname); + } } Log_Resolver( LOG_DEBUG, "Ok, translated %s to \"%s\".", inet_ntoa( Addr->sin_addr ), hostname ); - /* Write resolver result into pipe to parent */ len = strlen( hostname ); hostname[len] = '\n'; len++; - if( (size_t)write( w_fd, hostname, len ) != (size_t)len ) - { - Log_Resolver( LOG_CRIT, "Resolver: Can't write to parent: %s!", strerror( errno )); + if (!array_copyb(&resolved_addr, hostname, len )) { + Log_Resolver( LOG_CRIT, "Resolver: Can't copy resolved name: %s!", strerror( errno )); close( w_fd ); return; } #ifdef IDENTAUTH - /* Do "IDENT" (aka "AUTH") lookup and write result to parent */ - Log_Resolver( LOG_DEBUG, "Doing IDENT lookup on socket %d ...", Sock ); - res = ident_id( Sock, 10 ); - Log_Resolver( LOG_DEBUG, "Ok, IDENT lookup on socket %d done: \"%s\"", Sock, res ? res : "" ); - - /* Write IDENT result into pipe to parent */ - if (res) { - len = strlen(res); - res[len] = '\n'; - len++; - } else len = 1; + assert(identsock >= 0); + if (identsock >= 0) { + /* Do "IDENT" (aka "AUTH") lookup and append result to resolved_addr array */ +#ifdef DEBUG + Log_Resolver( LOG_DEBUG, "Doing IDENT lookup on socket %d ...", identsock ); +#endif + res = ident_id( identsock, 10 ); +#ifdef DEBUG + Log_Resolver(LOG_DEBUG, "Ok, IDENT lookup on socket %d done: \"%s\"", + identsock, res ? res : "(NULL)" ); +#endif + if (res && !array_cats(&resolved_addr, res)) { + Log_Resolver(LOG_WARNING, "Resolver: Cannot copy IDENT result: %s!", strerror(errno)); + /* omit ident and return hostname only */ + } - if( (size_t)write( w_fd, res ? res : "\n", len ) != (size_t)len ) - { - Log_Resolver( LOG_CRIT, "Resolver: Can't write to parent (IDENT): %s!", strerror( errno )); - close( w_fd ); + if (res) free(res); } - free( res ); +#else + (void)identsock; #endif + len = array_bytes(&resolved_addr); + if( (size_t)write( w_fd, array_start(&resolved_addr), len) != len ) + Log_Resolver( LOG_CRIT, "Resolver: Can't write result to parent: %s!", strerror( errno )); + + close(w_fd); + array_free(&resolved_addr); } /* Do_ResolveAddr */ -LOCAL void -Do_ResolveName( char *Host, int w_fd ) +static void +Do_ResolveName( const char *Host, int w_fd ) { /* Resolver sub-process: resolve name and write result into pipe * to parent. */ @@ -235,33 +246,30 @@ char ip[16]; struct hostent *h; struct in_addr *addr; - int len; + size_t len; Log_Resolver( LOG_DEBUG, "Now resolving \"%s\" ...", Host ); /* Resolve hostname */ h = gethostbyname( Host ); - if( h ) - { + if( h ) { addr = (struct in_addr *)h->h_addr; strlcpy( ip, inet_ntoa( *addr ), sizeof( ip )); - } - else - { + } else { #ifdef h_errno Log_Resolver( LOG_WARNING, "Can't resolve \"%s\": %s!", Host, Get_Error( h_errno )); #else Log_Resolver( LOG_WARNING, "Can't resolve \"%s\"!", Host ); #endif - ip[0] = '\0'; + close(w_fd); + return; } - if( ip[0] ) Log_Resolver( LOG_DEBUG, "Ok, translated \"%s\" to %s.", Host, ip ); - +#ifdef DEBUG + Log_Resolver( LOG_DEBUG, "Ok, translated \"%s\" to %s.", Host, ip ); +#endif /* Write result into pipe to parent */ len = strlen( ip ); - ip[len] = '\n'; len++; - if( (size_t)write( w_fd, ip, len ) != (size_t)len ) - { + if ((size_t)write( w_fd, ip, len ) != len) { Log_Resolver( LOG_CRIT, "Resolver: Can't write to parent: %s!", strerror( errno )); close( w_fd ); } @@ -270,7 +278,7 @@ #ifdef h_errno -LOCAL char * +static char * Get_Error( int H_Error ) { /* Get error message for H_Error */ @@ -293,33 +301,73 @@ #endif -LOCAL RES_STAT * -New_Res_Stat( void ) +static bool +register_callback( RES_STAT *s, void (*cbfunc)(int, short)) { - RES_STAT *s; + assert(cbfunc != NULL); + assert(s != NULL); + assert(s->resolver_fd >= 0); + + if (io_setnonblock(s->resolver_fd) && + io_event_create(s->resolver_fd, IO_WANTREAD, cbfunc)) + return true; + + Log( LOG_CRIT, "Resolver: Could not register callback function: %s!", strerror(errno)); + Resolve_Shutdown(s); + return false; +} - /* Allocate memory */ - s = (RES_STAT *)malloc( sizeof( RES_STAT )); - if( ! s ) - { - Log( LOG_EMERG, "Resolver: Can't allocate memory! [Resolve_Addr]" ); - return NULL; - } - /* Initialize pipe for result */ - if( pipe( s->pipe ) != 0 ) - { - free( s ); - Log( LOG_ALERT, "Resolver: Can't create output pipe: %s!", strerror( errno )); - return NULL; - } +GLOBAL bool +Resolve_Shutdown( RES_STAT *s) +{ + bool ret = false; + + assert(s != NULL); + assert(s->resolver_fd >= 0); + + if (s->resolver_fd >= 0) + ret = io_close(s->resolver_fd); - s->stage = 0; - s->bufpos = 0; - s->pid = -1; + Resolve_Init(s); + return ret; +} + + +/** + * Read result of resolver sub-process from pipe + */ +GLOBAL size_t +Resolve_Read( RES_STAT *s, void* readbuf, size_t buflen) +{ + int err; + ssize_t bytes_read; - return s; -} /* New_Res_Stat */ + assert(buflen > 0); + /* Read result from pipe */ + errno = 0; + bytes_read = read(s->resolver_fd, readbuf, buflen); + if (bytes_read < 0) { + if (errno != EAGAIN) { + err = errno; + Log( LOG_CRIT, "Resolver: Can't read result: %s!", strerror(err)); + Resolve_Shutdown(s); + errno = err; + return 0; + } + return 0; + } + + Resolve_Shutdown(s); + if (bytes_read == 0) { /* EOF: lookup failed */ +#ifdef DEBUG + Log( LOG_DEBUG, "Resolver: Can't read result: EOF"); +#endif + return 0; + } + return (size_t)bytes_read; +} /* -eof- */ + Index: src/ngircd/resolve.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/ngircd/resolve.h,v retrieving revision 1.8 retrieving revision 1.13 diff -u -r1.8 -r1.13 --- src/ngircd/resolve.h 19 Mar 2005 18:43:49 -0000 1.8 +++ src/ngircd/resolve.h 10 May 2006 21:24:02 -0000 1.13 @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: resolve.h,v 1.8 2005/03/19 18:43:49 fw Exp $ + * $Id: resolve.h,v 1.13 2006/05/10 21:24:02 alex Exp $ * * Asynchronous resolver (header) */ @@ -17,39 +17,24 @@ #ifndef __resolve_h__ #define __resolve_h__ - -#ifdef HAVE_SYS_SELECT_H -# include -#endif -#include +#include "array.h" #include - -typedef struct _Res_Stat -{ - int pid; /* PID des Child-Prozess */ - int pipe[2]; /* Pipe fuer IPC */ - int stage; /* Hostname/IP(0) or IDENT(1)? */ - int bufpos; /* Position in buffer */ - char buffer[HOST_LEN]; /* Buffer */ +/* This struct must not be accessed directly */ +typedef struct _Res_Stat { + pid_t pid; /* PID of resolver process */ + int resolver_fd; /* pipe fd for lookup result. */ } RES_STAT; -GLOBAL fd_set Resolver_FDs; - - -GLOBAL void Resolve_Init PARAMS(( void )); - -#ifdef IDENTAUTH -GLOBAL RES_STAT *Resolve_Addr PARAMS(( struct sockaddr_in *Addr, int Sock )); -#else -GLOBAL RES_STAT *Resolve_Addr PARAMS(( struct sockaddr_in *Addr )); -#endif - -GLOBAL RES_STAT *Resolve_Name PARAMS(( char *Host )); +#define Resolve_Getfd(x) ((x)->resolver_fd) +#define Resolve_INPROGRESS(x) ((x)->resolver_fd >= 0) +GLOBAL bool Resolve_Addr PARAMS(( RES_STAT *s, struct sockaddr_in *Addr, int identsock, void (*cbfunc)(int, short))); +GLOBAL bool Resolve_Name PARAMS(( RES_STAT *s, const char *Host, void (*cbfunc)(int, short) )); +GLOBAL size_t Resolve_Read PARAMS(( RES_STAT *s, void *buf, size_t buflen)); +GLOBAL void Resolve_Init PARAMS(( RES_STAT *s)); +GLOBAL bool Resolve_Shutdown PARAMS(( RES_STAT *s)); #endif - - /* -eof- */ Index: src/portab/portab.h =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/portab/portab.h,v retrieving revision 1.21 retrieving revision 1.22 diff -u -r1.21 -r1.22 --- src/portab/portab.h 16 Apr 2005 09:23:01 -0000 1.21 +++ src/portab/portab.h 31 Jul 2005 20:13:11 -0000 1.22 @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: portab.h,v 1.21 2005/04/16 09:23:01 fw Exp $ + * $Id: portab.h,v 1.22 2005/07/31 20:13:11 alex Exp $ * * Portability functions and declarations (header for libngbportab). */ @@ -65,9 +65,6 @@ #endif -/* keywords */ -#define LOCAL static - /* datatypes */ #ifndef PROTOTYPES Index: src/portab/portabtest.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/portab/portabtest.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- src/portab/portabtest.c 19 Mar 2005 18:43:50 -0000 1.12 +++ src/portab/portabtest.c 31 Jul 2005 20:13:11 -0000 1.13 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: portabtest.c,v 1.12 2005/03/19 18:43:50 fw Exp $"; +static char UNUSED id[] = "$Id: portabtest.c,v 1.13 2005/07/31 20:13:11 alex Exp $"; #include "imp.h" #include @@ -25,7 +25,7 @@ #include "exp.h" -LOCAL void Panic PARAMS (( char *Reason, int Code )); +static void Panic PARAMS (( char *Reason, int Code )); GLOBAL int @@ -51,7 +51,7 @@ } /* portab_check_types */ -LOCAL void +static void Panic( char *Reason, int Code ) { /* Oops, something failed!? */ Index: src/testsuite/stress-A.e =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/testsuite/stress-A.e,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- src/testsuite/stress-A.e 9 Sep 2002 22:56:07 -0000 1.1 +++ src/testsuite/stress-A.e 12 Aug 2005 21:35:12 -0000 1.2 @@ -1,4 +1,6 @@ -# $Id: stress-A.e,v 1.1 2002/09/09 22:56:07 alex Exp $ +# $Id: stress-A.e,v 1.2 2005/08/12 21:35:12 alex Exp $ + +set timeout 30 spawn telnet localhost 6789 expect { Index: src/testsuite/stress-B.e =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/testsuite/stress-B.e,v retrieving revision 1.1 retrieving revision 1.3 diff -u -r1.1 -r1.3 --- src/testsuite/stress-B.e 9 Sep 2002 22:56:07 -0000 1.1 +++ src/testsuite/stress-B.e 30 Dec 2005 22:12:28 -0000 1.3 @@ -1,11 +1,13 @@ -# $Id: stress-B.e,v 1.1 2002/09/09 22:56:07 alex Exp $ +# $Id: stress-B.e,v 1.3 2005/12/30 22:12:28 alex Exp $ send "user user . . :User\r" expect { timeout { exit 1 } - "376" + " 376" } +sleep 2 + send "oper TestOp 123\r" expect { timeout { exit 1 } @@ -13,53 +15,59 @@ } expect { timeout { exit 1 } - "381 test*" + " 381 test" } +sleep 2 + send "join #channel\r" expect { timeout { exit 1 } - ":test*!~user@* JOIN :#channel" + " 353 * = #channel " } expect { timeout { exit 1 } - "366" + " 366 * #channel :" } send "mode #channel\r" expect { timeout { exit 1 } - "324 test* #channel" + " 324 test* #channel" } send "join #channel2\r" expect { timeout { exit 1 } - ":test*!~user@* JOIN :#channel2" + " 353 * = #channel2 " } expect { timeout { exit 1 } - "366" + " 366 * #channel2 :" } send "names\r" expect { timeout { exit 1 } - "366" + " 366 " } +sleep 3 + send "part #channel2\r" expect { timeout { exit 1 } - ":test*!~user@* PART #channel2" + " PART #channel2 " } send "part #channel\r" expect { timeout { exit 1 } - ":test*!~user@* PART #channel" + " PART #channel " } +sleep 1 + send "quit\r" expect { timeout { exit 1 } Index: src/testsuite/stress-server.sh =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/testsuite/stress-server.sh,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- src/testsuite/stress-server.sh 6 Sep 2004 22:04:06 -0000 1.15 +++ src/testsuite/stress-server.sh 30 Dec 2005 22:13:21 -0000 1.16 @@ -9,7 +9,7 @@ # (at your option) any later version. # Please read the file COPYING, README and AUTHORS for more information. # -# $Id: stress-server.sh,v 1.15 2004/09/06 22:04:06 alex Exp $ +# $Id: stress-server.sh,v 1.16 2005/12/30 22:13:21 alex Exp $ # # detect source directory @@ -50,6 +50,16 @@ no=`expr ${no} + 1` done +# run first script and check if it succeeds +echo_n " checking stress script ..." +expect tests/0.e > logs/stress-0.log 2> /dev/null +if [ $? -ne 0 ]; then + echo " failure!" + exit 1 +else + echo " ok." +fi + no=0 while [ ${no} -lt $CLIENTS ]; do expect tests/${no}.e > logs/stress-${no}.log 2> /dev/null & Index: src/testsuite/wait-tests.sh =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/testsuite/wait-tests.sh,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- src/testsuite/wait-tests.sh 6 Sep 2004 22:04:06 -0000 1.4 +++ src/testsuite/wait-tests.sh 12 Aug 2005 21:34:19 -0000 1.5 @@ -9,11 +9,14 @@ # (at your option) any later version. # Please read the file COPYING, README and AUTHORS for more information. # -# $Id: wait-tests.sh,v 1.4 2004/09/06 22:04:06 alex Exp $ +# $Id: wait-tests.sh,v 1.5 2005/08/12 21:34:19 alex Exp $ # [ "$1" -gt 0 ] 2> /dev/null && MAX="$1" || MAX=5 +# detect source directory +[ -z "$srcdir" ] && srcdir=`dirname $0` + PS_FLAGS="-f" ps $PS_FLAGS >/dev/null 2>&1 [ $? -ne 0 ] && PS_FLAGS="a" Index: src/tool/tool.c =================================================================== RCS file: /srv/cvs/ngircd/ngircd/src/tool/tool.c,v retrieving revision 1.3 retrieving revision 1.6 diff -u -r1.3 -r1.6 --- src/tool/tool.c 19 Mar 2005 18:43:52 -0000 1.3 +++ src/tool/tool.c 9 Apr 2006 12:53:07 -0000 1.6 @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: tool.c,v 1.3 2005/03/19 18:43:52 fw Exp $"; +static char UNUSED id[] = "$Id: tool.c,v 1.6 2006/04/09 12:53:07 alex Exp $"; #include "imp.h" #include @@ -26,28 +26,40 @@ #include "tool.h" +/** + * Removes all leading and trailing whitespaces of a string. + * @param String The string to remove whitespaces from. + */ GLOBAL void -ngt_TrimStr( char *String ) +ngt_TrimStr(char *String) { - /* Mit ngt_TrimStr() werden fuehrende und folgende Leerzeichen, - * Tabulatoren und Zeilenumbrueche (ASCII 10 und ASCII 13) aus - * dem String entfernt. */ - - char *start, *ptr; + char *start, *end; - assert( String != NULL ); + assert(String != NULL); start = String; - - /* Zeichen am Anfang pruefen ... */ - while(( *start == ' ' ) || ( *start == 9 )) start++; - - /* Zeichen am Ende pruefen ... */ - ptr = strchr( start, '\0' ) - 1; - while((( *ptr == ' ' ) || ( *ptr == 9 ) || ( *ptr == 10 ) || ( *ptr == 13 )) && ptr >= start ) ptr--; - *(++ptr) = '\0'; - memmove( String, start, strlen( start ) + 1 ); + /* Remove whitespaces at the beginning of the string ... */ + while (*start == ' ' || *start == '\t' || + *start == '\n' || *start == '\r') + start++; + + if (!*start) { + *String = '\0'; + return; + } + + /* ... and at the end: */ + end = strchr(start, '\0'); + end--; + while ((*end == ' ' || *end == '\t' || *end == '\n' || *end == '\r') + && end >= start) + end--; + + /* New trailing NULL byte */ + *(++end) = '\0'; + + memmove(String, start, (size_t)(end - start)+1); } /* ngt_TrimStr */