1
0
mirror of https://github.com/osmarks/ngircd.git synced 2025-09-22 12:14:03 +00:00

Compare commits

...

59 Commits

Author SHA1 Message Date
Florian Westphal
bc3d1f1761 [Parser]: Don't use Client_Type after command has been processed.
This caused a read from already free'd memory, if the processed
command (IRC_QUIT) calls Client_Destroy. (from HEAD)
2008-02-05 13:15:05 +00:00
Alexander Barton
10cc60d1c2 Updated Debian changelog for 0.10.4. 2008-01-07 21:05:37 +00:00
Alexander Barton
928404860b ngIRCd 0.10.4 2008-01-07 20:57:39 +00:00
Florian Westphal
26c65a11cf IRC_PART could reference invalid memory. 2008-01-07 11:41:43 +00:00
Alexander Barton
d64ab2a36d Fixed a compile problem with elder gcc (detected with 2.95.2). [from HEAD] 2007-07-31 20:48:15 +00:00
Alexander Barton
058316059f Ooops, wrong date ... "great". Next try ... 2007-07-31 19:33:51 +00:00
Alexander Barton
c74aa136af New release, fixing a security bug: 0.10.3 2007-07-31 19:07:59 +00:00
Alexander Barton
079e0cf9a4 SECURITY: Fixed a severe bug in handling JOIN commands, which could
cause the server to crash. Thanks to Sebastian Vesper, <net@veoson.net>.
2007-07-31 18:54:26 +00:00
Alexander Barton
1e1cc6d47f Release 0.10.2. 2007-06-08 09:05:23 +00:00
Alexander Barton
c61de8bc0c Updated config.sub and config.guess [from HEAD]. 2007-05-26 10:44:51 +00:00
Alexander Barton
794603bb59 ngIRCd 0.10.2-rc2 2007-05-19 14:22:40 +00:00
Alexander Barton
302bd8ddaf Server links are allowed to use larger write buffers now (up to 50 KB);
removed Z{READ|WRITE}BUFFER_LEN. -- Both from HEAD.
2007-05-18 22:11:18 +00:00
Florian Westphal
cddc7e719d make needlesly global function Conn_Write static. (from HEAD) 2007-05-09 13:21:38 +00:00
Alexander Barton
001c3bb1b4 Version 0.10.2-pre1 2007-05-05 20:43:11 +00:00
Alexander Barton
5cb18415da Updated year of copyright notice. 2007-05-05 20:25:47 +00:00
Alexander Barton
69b595e8d4 Updated documentation. 2007-05-05 20:25:19 +00:00
Florian Westphal
090b596752 fix compressed server links (broken since 0.10.0) 2007-05-02 12:22:43 +00:00
Florian Westphal
f67ad15a36 sync with HEAD. 2007-04-03 22:08:50 +00:00
Florian Westphal
5c3e02393b re-arranged invite and ban list-handling (from HEAD) 2007-04-03 20:23:30 +00:00
Florian Westphal
3f7191db0f revert to last good revision 2006-12-17 23:06:29 +00:00
Florian Westphal
1e29560bac do not call Conn_Close when io_event_create fails [from HEAD] 2006-12-17 23:00:47 +00:00
Florian Westphal
880d4a88b1 fix possibe buffer-off-by one [from HEAD] 2006-12-17 23:00:17 +00:00
Florian Westphal
a915559086 don't call Resolve_Shutdown() when io_event_create fails [from HEAD] 2006-12-17 22:59:56 +00:00
Alexander Barton
52512462a2 ngIRCd 0.10.1. 2006-12-17 14:06:19 +00:00
Alexander Barton
d9323ada46 Updated documentation for release 0.10.1. 2006-12-17 13:55:29 +00:00
Alexander Barton
ec1847f018 Added support for Solaris 11. [from HEAD] 2006-12-17 13:49:49 +00:00
Florian Westphal
0af8fafdfb add PredefChannelsOnly to manpage [from HEAD] 2006-12-11 22:08:14 +00:00
Florian Westphal
c9e26562ce Changed Numerics 265 and 266 to follow ircd 2.11.x "standards". [from HEAD]
Allow PASS syntax defined in RFC 1459 for server links, too. [from HEAD]
Enhanced ISUPPORT message (005 numeric). [from HEAD]
2006-12-02 14:26:52 +00:00
Florian Westphal
a64e33b317 cleanups [from HEAD] 2006-12-02 14:21:26 +00:00
Florian Westphal
7e2e23d12f make several counters unsigned, char *s -> const char *s [from HEAD] 2006-12-02 14:00:00 +00:00
Florian Westphal
ab7bb74581 cleanups [from HEAD] 2006-12-02 13:54:10 +00:00
Florian Westphal
254bf129dc merge Conf_PredefChannelsOnly [from HEAD] 2006-12-02 13:33:52 +00:00
Florian Westphal
14cdb7fdd0 char* -> const char* [from HEAD] 2006-12-02 13:18:22 +00:00
Florian Westphal
740d876c44 backport checks for inline keyword and strcspn() [from HEAD] 2006-12-02 13:13:53 +00:00
Florian Westphal
de9a130bd9 merge Conf_PredefChannelsOnly Config Option [from HEAD] 2006-12-02 13:10:43 +00:00
Florian Westphal
a0e0da74f8 make several counters unsigned [from HEAD] 2006-12-02 13:08:02 +00:00
Florian Westphal
83c14a6383 - whitespace damage [from HEAD] 2006-12-02 13:06:50 +00:00
Florian Westphal
6c12659bcf #define MASK_LEN should use parentheses [from HEAD] 2006-12-02 13:05:38 +00:00
Florian Westphal
83d4d66818 make LogDebug() 'static inline' if DEBUG is not defined [from HEAD] 2006-12-02 13:02:07 +00:00
Florian Westphal
2434e86e14 char *foo -> const char *foo [from HEAD] 2006-12-02 13:01:11 +00:00
Florian Westphal
2b4b416d2f cleanups [from HEAD] 2006-12-02 13:00:25 +00:00
Alexander Barton
62f74db6f6 Fixed validation of server names containing digits. [from HEAD] 2006-11-10 10:06:14 +00:00
Florian Westphal
cf4ae77991 fix Channel_Join() [from HEAD] 2006-10-05 18:30:47 +00:00
Alexander Barton
1f652554dd Update info text of local server after re-reading configuration. [from HEAD] 2006-10-03 11:01:05 +00:00
Alexander Barton
032bf78ed4 ngIRCd 0.10.0 2006-10-01 16:21:55 +00:00
Alexander Barton
ce66aa1028 Removed "~sid" postfix; ooopsa. 2006-10-01 16:13:21 +00:00
Alexander Barton
9296c27cac Added "Provides: ircd" and bumped standards version. 2006-10-01 16:10:47 +00:00
Alexander Barton
921a5434af Updated ChangeLog. 2006-09-16 13:51:35 +00:00
Alexander Barton
7c7d417fd2 Fix file handle leak [from HEAD]. 2006-09-16 13:49:15 +00:00
Alexander Barton
ed71217b31 ngIRCd 0.10.0-pre2 2006-09-09 19:00:06 +00:00
Alexander Barton
57fb95eb1d ngircd 0.10.0-pre2 release. 2006-09-09 18:50:47 +00:00
Alexander Barton
6f2f2ecd3b only test for stack smashing protector if we are using gcc;
use -fstack-protector-all for the test to make sure the guard variable is added.
[from HEAD.]
2006-09-09 18:34:00 +00:00
Alexander Barton
cf824dd8e7 Updated list of supported/tested platforms. [from HEAD] 2006-09-09 18:10:56 +00:00
Alexander Barton
01ba196d7d fix gcc 4.1 -fstack-protector detection. [from HEAD] 2006-08-13 18:21:31 +00:00
Alexander Barton
af6c532007 New release: 0.10.0-pre1 2006-08-02 10:29:11 +00:00
Alexander Barton
1ca10ff590 Updated debian changelog (from HEAD). 2006-08-02 09:54:19 +00:00
Alexander Barton
cd7862cec4 Updated documentation. 2006-08-02 09:04:20 +00:00
Alexander Barton
f9a928451d Updated documentation. 2006-08-02 08:19:38 +00:00
Alexander Barton
2a22629e74 Increased version number to 0.10.x :-) 2006-07-31 20:32:20 +00:00
51 changed files with 1701 additions and 1137 deletions

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server ngIRCd - Next Generation IRC Server
(c)2001-2005 Alexander Barton, (c)2001-2008 Alexander Barton,
alex@barton.de, http://www.barton.de/ alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the ngIRCd is free software and published under the
@@ -9,9 +9,53 @@
-- ChangeLog -- -- ChangeLog --
ngIRCd 0.10.4 (2008-01-07)
ngIRCd CVSHEAD - SECURITY: IRC_PART could reference invalid memory, causing
ngircd to crash.
ngIRCd 0.10.3 (2007-07-31)
- SECURITY: Fixed a severe bug in handling JOIN commands, which could
cause the server to crash. Thanks to Sebastian Vesper, <net@veoson.net>.
ngIRCd 0.10.2 (2007-06-08)
ngIRCd 0.10.2-pre2 (2007-05-19)
- Server links are allowed to use larger write buffers now (up to 50 KB).
ngIRCd 0.10.2-pre1 (2007-05-05)
- Fix compressed server links (broken since 0.10.0).
- Predefined Channel configuration now allows specification of channel key
(mode k) and maximum user count (mode l).
- When using epoll() IO interface, compile in the select() interface as
well and fall back to it when epoll() isn't available on runtime.
- New configure option "--without-select" to disable select() IO API
(even when using epoll(), see above).
- Added support for IO APIs "poll()" and "/dev/poll".
- Reorganized internal handling of invite and ban lists.
ngIRCd 0.10.1 (2006-12-17)
- Fixed validation of server names containing digits.
- Update the "info text" of the local server after re-reading configuration.
- Changed Numerics 265 and 266 to follow ircd 2.11.x "standards".
- Allow PASS syntax defined in RFC 1459 for server links, too.
- Enhanced ISUPPORT message (005 numeric).
- New configuration option "PredefChannelsOnly": if set, clients can only
join predefined channels.
- Code cleanups: use "LogDebug(...)" instead of "Log(LOG_DEBUG, ...)", use
"strcspn()", unsigned vs. signed, use "const", fix whitespaces, ...
ngIRCd 0.10.0 (2006-10-01)
- Fixed file handle leak when daemon is not able to send MOTD to a client.
ngIRCd 0.10.0-pre2 (2006-09-09)
- Fixed build problems with GCC option -fstack-protector.
- Minor documentation updates.
ngIRCd 0.10.0-pre1 (2006-08-02)
- Validate "ServerName" (see RFC 2812, section 2.3.1). - Validate "ServerName" (see RFC 2812, section 2.3.1).
- Enhanced DIE to accept a single parameter ("comment text") which is sent - Enhanced DIE to accept a single parameter ("comment text") which is sent
to all locally connected clients before the server goes down. to all locally connected clients before the server goes down.
@@ -654,4 +698,4 @@ ngIRCd 0.0.1, 31.12.2001
-- --
$Id: ChangeLog,v 1.302 2006/07/23 16:42:45 alex Exp $ $Id: ChangeLog,v 1.302.2.21 2008/01/07 20:57:39 alex Exp $

16
INSTALL
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server ngIRCd - Next Generation IRC Server
(c)2001-2004 by Alexander Barton, (c)2001-2006 by Alexander Barton,
alex@barton.de, http://www.barton.de/ alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the ngIRCd is free software and published under the
@@ -149,14 +149,20 @@ standard locations.
The Z compression library ("libz") is required for this option. The Z compression library ("libz") is required for this option.
* IO Backend (autodetected by default): * IO Backend (autodetected by default):
--with-select[=<path>] / --without-select
--with-poll[=<path>] / --without-poll
--with-devpoll[=<path>] / --without-devpoll
--with-epoll[=<path>] / --without-epoll --with-epoll[=<path>] / --without-epoll
--with-kqueue[=<path>] / --without-kqueue --with-kqueue[=<path>] / --without-kqueue
ngIRCd can use three different IO "backends": the "old school" select() ngIRCd can use different IO "backends": the "old school" select() and poll()
API which should be supported by most UNIX-like operating systems, or the API which should be supported by most UNIX-like operating systems, or the
more efficient and flexible epoll() (Linux 2.6) or kqueue() (BSD) APIs. more efficient and flexible epoll() (Linux >=2.6), kqueue() (BSD) and
/dev/poll APIs.
By default the IO backend is autodetected, but you can use "--without-xxx" By default the IO backend is autodetected, but you can use "--without-xxx"
to disable a more enhanced API and force the daemon to use select(). to disable a more enhanced API.
When using the epoll() API, support for select() is compiled in as well by
default to enable the binary to run on older Linux kernels (<2.6), too.
* IDENT-Support: * IDENT-Support:
--with-ident[=<path>] --with-ident[=<path>]
@@ -241,4 +247,4 @@ number. In both cases the server exits after the output.
-- --
$Id: INSTALL,v 1.23 2005/12/30 22:43:23 alex Exp $ $Id: INSTALL,v 1.23.2.2 2007/04/03 22:08:50 fw Exp $

33
NEWS
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server ngIRCd - Next Generation IRC Server
(c)2001-2005 Alexander Barton, (c)2001-2007 Alexander Barton,
alex@barton.de, http://www.barton.de/ alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the ngIRCd is free software and published under the
@@ -10,6 +10,35 @@
-- NEWS -- -- NEWS --
ngIRCd 0.10.2 (2007-06-08)
- Predefined channel configuration now allows specification of channel key
(mode k) and maximum user count (mode l): variables "Key" and "MaxUsers".
- When using the epoll() IO interface, compile in the select() interface as
well and fall back to it when epoll() isn't available on runtime.
- Added support for IO APIs "poll()" and "/dev/poll".
ngIRCd 0.10.1 (2006-12-17)
- Allow PASS syntax defined in RFC 1459 for server links, too.
- New configuration option "PredefChannelsOnly": if set, clients can only
join predefined channels.
ngIRCd 0.10.0 (2006-10-01)
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) ngIRCd 0.9.0 (2005-07-24)
- Never run with root privileges but always switch the user ID. - Never run with root privileges but always switch the user ID.
@@ -208,4 +237,4 @@ ngIRCd 0.0.1, 31.12.2001
-- --
$Id: NEWS,v 1.75 2005/07/26 19:41:49 alex Exp $ $Id: NEWS,v 1.75.2.7 2007/06/08 09:05:23 alex Exp $

6
README
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server ngIRCd - Next Generation IRC Server
(c)2001-2005 Alexander Barton, (c)2001-2007 Alexander Barton,
alex@barton.de, http://www.barton.de/ alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the ngIRCd is free software and published under the
@@ -19,6 +19,8 @@ Licence (URL: http://www.gnu.org/licenses/gpl.html). ngIRCd means "next
generation IRC daemon", it's written from scratch and not deduced from the generation IRC daemon", it's written from scratch and not deduced from the
"grandfather of IRC daemons", the daemon of the IRCNet. "grandfather of IRC daemons", the daemon of the IRCNet.
Please see the INSTALL document for installation and upgrade information!
II. Status II. Status
~~~~~~~~~~~ ~~~~~~~~~~~
@@ -84,4 +86,4 @@ mail to <alex@barton.de>.
-- --
$Id: README,v 1.21 2005/07/09 14:39:42 alex Exp $ $Id: README,v 1.21.2.2 2007/05/05 20:25:20 alex Exp $

47
config.guess vendored
View File

@@ -1,9 +1,10 @@
#! /bin/sh #! /bin/sh
# Attempt to guess a canonical system name. # Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
# Inc.
timestamp='2006-02-23' timestamp='2007-03-06'
# This file is free software; you can redistribute it and/or modify it # 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 # under the terms of the GNU General Public License as published by
@@ -160,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*) machine=arm-unknown ;; arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;; sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;; sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac esac
# The Operating System including object format, if it has switched # The Operating System including object format, if it has switched
@@ -210,7 +212,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
exit ;; exit ;;
macppc:MirBSD:*:*) macppc:MirBSD:*:*)
echo powerppc-unknown-mirbsd${UNAME_RELEASE} echo powerpc-unknown-mirbsd${UNAME_RELEASE}
exit ;; exit ;;
*:MirBSD:*:*) *:MirBSD:*:*)
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
@@ -770,6 +772,8 @@ EOF
case ${UNAME_MACHINE} in case ${UNAME_MACHINE} in
pc98) pc98)
echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*) *)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac esac
@@ -777,10 +781,7 @@ EOF
i*:CYGWIN*:*) i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin echo ${UNAME_MACHINE}-pc-cygwin
exit ;; exit ;;
i*:MINGW*:*) *:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:MSYS_NT-*:*:*)
echo ${UNAME_MACHINE}-pc-mingw32 echo ${UNAME_MACHINE}-pc-mingw32
exit ;; exit ;;
i*:windows32*:*) i*:windows32*:*)
@@ -790,12 +791,15 @@ EOF
i*:PW*:*) i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32 echo ${UNAME_MACHINE}-pc-pw32
exit ;; exit ;;
x86:Interix*:[345]*) *:Interix*:[3456]*)
echo i586-pc-interix${UNAME_RELEASE} case ${UNAME_MACHINE} in
exit ;; x86)
EM64T:Interix*:[345]*) echo i586-pc-interix${UNAME_RELEASE}
echo x86_64-unknown-interix${UNAME_RELEASE} exit ;;
exit ;; EM64T | authenticamd)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks echo i${UNAME_MACHINE}-pc-mks
exit ;; exit ;;
@@ -831,6 +835,9 @@ EOF
arm*:Linux:*:*) arm*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;; exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
cris:Linux:*:*) cris:Linux:*:*)
echo cris-axis-linux-gnu echo cris-axis-linux-gnu
exit ;; exit ;;
@@ -947,6 +954,9 @@ EOF
x86_64:Linux:*:*) x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu echo x86_64-unknown-linux-gnu
exit ;; exit ;;
xtensa:Linux:*:*)
echo xtensa-unknown-linux-gnu
exit ;;
i*86:Linux:*:*) i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so # The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent # first see if it will tell us. cd to the root directory to prevent
@@ -989,7 +999,7 @@ EOF
LIBC=gnulibc1 LIBC=gnulibc1
# endif # endif
#else #else
#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun) #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
LIBC=gnu LIBC=gnu
#else #else
LIBC=gnuaout LIBC=gnuaout
@@ -1205,6 +1215,15 @@ EOF
SX-6:SUPER-UX:*:*) SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE} echo sx6-nec-superux${UNAME_RELEASE}
exit ;; exit ;;
SX-7:SUPER-UX:*:*)
echo sx7-nec-superux${UNAME_RELEASE}
exit ;;
SX-8:SUPER-UX:*:*)
echo sx8-nec-superux${UNAME_RELEASE}
exit ;;
SX-8R:SUPER-UX:*:*)
echo sx8r-nec-superux${UNAME_RELEASE}
exit ;;
Power*:Rhapsody:*:*) Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE} echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;; exit ;;

68
config.sub vendored
View File

@@ -1,9 +1,10 @@
#! /bin/sh #! /bin/sh
# Configuration validation subroutine script. # Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
# Inc.
timestamp='2006-02-23' timestamp='2007-01-18'
# This file is (in principle) common to ALL GNU software. # This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software # The presence of a machine in this file suggests that SOME GNU software
@@ -240,15 +241,16 @@ case $basic_machine in
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \ | am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| bfin \ | bfin \
| c4x | clipper \ | c4x | clipper \
| d10v | d30v | dlx | dsp16xx \ | d10v | d30v | dlx | dsp16xx \
| fr30 | frv \ | fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \ | i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \ | ip2k | iq2000 \
| m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \ | m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep \
| mips | mipsbe | mipseb | mipsel | mipsle \ | mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \ | mips16 \
| mips64 | mips64el \ | mips64 | mips64el \
@@ -274,21 +276,19 @@ case $basic_machine in
| pdp10 | pdp11 | pj | pjl \ | pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \ | pyramid \
| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ | score \
| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \ | sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| strongarm \ | spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \ | tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \ | v850 | v850e \
| we32k \ | we32k \
| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
| z8k) | z8k)
basic_machine=$basic_machine-unknown basic_machine=$basic_machine-unknown
;; ;;
m32c)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12) m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12. # Motorola 68HC11/12.
basic_machine=$basic_machine-unknown basic_machine=$basic_machine-unknown
@@ -318,18 +318,18 @@ case $basic_machine in
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* \ | avr-* | avr32-* \
| bfin-* | bs2000-* \ | bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | craynv-* | cydra-* \ | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \ | d10v-* | d30v-* | dlx-* \
| elxsi-* \ | elxsi-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \ | h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \ | i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \ | ip2k-* | iq2000-* \
| m32r-* | m32rle-* \ | m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* \ | m88110-* | m88k-* | maxq-* | mcore-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
@@ -358,23 +358,21 @@ case $basic_machine in
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \ | pyramid-* \
| romp-* | rs6000-* \ | romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \ | sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \ | tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tron-* \ | tron-* \
| v850-* | v850e-* | vax-* \ | v850-* | v850e-* | vax-* \
| we32k-* \ | we32k-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
| xstormy16-* | xtensa-* \ | xstormy16-* | xtensa-* \
| ymp-* \ | ymp-* \
| z8k-*) | z8k-*)
;; ;;
m32c-*)
;;
# Recognize the various machine names and aliases which stand # Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS. # for a CPU type and a company and sometimes even an OS.
386bsd) 386bsd)
@@ -912,6 +910,10 @@ case $basic_machine in
sb1el) sb1el)
basic_machine=mipsisa64sb1el-unknown basic_machine=mipsisa64sb1el-unknown
;; ;;
sde)
basic_machine=mipsisa32-sde
os=-elf
;;
sei) sei)
basic_machine=mips-sei basic_machine=mips-sei
os=-seiux os=-seiux
@@ -923,6 +925,9 @@ case $basic_machine in
basic_machine=sh-hitachi basic_machine=sh-hitachi
os=-hms os=-hms
;; ;;
sh5el)
basic_machine=sh5le-unknown
;;
sh64) sh64)
basic_machine=sh64-unknown basic_machine=sh64-unknown
;; ;;
@@ -1128,7 +1133,7 @@ case $basic_machine in
sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown basic_machine=sh-unknown
;; ;;
sparc | sparcv8 | sparcv9 | sparcv9b) sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
basic_machine=sparc-sun basic_machine=sparc-sun
;; ;;
cydra) cydra)
@@ -1217,7 +1222,7 @@ case $os in
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos*) | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
# Remember, each alternative MUST END IN *, to match a version number. # Remember, each alternative MUST END IN *, to match a version number.
;; ;;
-qnx*) -qnx*)
@@ -1369,6 +1374,12 @@ else
# system, and we'll never get to this point. # system, and we'll never get to this point.
case $basic_machine in case $basic_machine in
score-*)
os=-elf
;;
spu-*)
os=-elf
;;
*-acorn) *-acorn)
os=-riscix1.2 os=-riscix1.2
;; ;;
@@ -1378,9 +1389,9 @@ case $basic_machine in
arm*-semi) arm*-semi)
os=-aout os=-aout
;; ;;
c4x-* | tic4x-*) c4x-* | tic4x-*)
os=-coff os=-coff
;; ;;
# This must come before the *-dec entry. # This must come before the *-dec entry.
pdp10-*) pdp10-*)
os=-tops20 os=-tops20
@@ -1406,6 +1417,9 @@ case $basic_machine in
m68*-cisco) m68*-cisco)
os=-aout os=-aout
;; ;;
mep-*)
os=-elf
;;
mips*-cisco) mips*-cisco)
os=-elf os=-elf
;; ;;

View File

@@ -1,6 +1,6 @@
# #
# ngIRCd -- The Next Generation IRC Daemon # ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2005 Alexander Barton <alex@barton.de> # Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@@ -8,13 +8,13 @@
# (at your option) any later version. # (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information. # Please read the file COPYING, README and AUTHORS for more information.
# #
# $Id: configure.in,v 1.118 2006/05/17 16:44:14 alex Exp $ # $Id: configure.in,v 1.118.2.14 2008/01/07 20:57:39 alex Exp $
# #
# -- Initialisation -- # -- Initialisation --
AC_PREREQ(2.50) AC_PREREQ(2.50)
AC_INIT(ngircd, CVSHEAD) AC_INIT(ngircd, 0.10.4)
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c) AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
AC_CANONICAL_TARGET AC_CANONICAL_TARGET
AM_INIT_AUTOMAKE(1.6) AM_INIT_AUTOMAKE(1.6)
@@ -53,33 +53,33 @@ AC_PROG_RANLIB
AM_C_PROTOTYPES AM_C_PROTOTYPES
AC_C_CONST AC_C_CONST
AC_C_INLINE
# -- Hard coded system and compiler dependencies/features/options ... -- # -- Hard coded system and compiler dependencies/features/options ... --
AC_DEFUN([GCC_STACK_PROTECT_CC],[
ssp_cc=yes
# we use -fstack-protector-all for the test to enfoce the use of the guard variable
AC_MSG_CHECKING([whether ${CC} accepts -fstack-protector])
ssp_old_cflags="$CFLAGS"
CFLAGS="$CFLAGS -fstack-protector-all"
AC_TRY_LINK(,,, ssp_cc=no)
echo $ssp_cc
CFLAGS="$ssp_old_cflags"
if test "X$ssp_cc" = "Xyes"; then
CFLAGS="$CFLAGS -fstack-protector"
AC_DEFINE([ENABLE_SSP_CC], 1, [Define if SSP C support is enabled.])
fi
])
if test "$GCC" = "yes"; then if test "$GCC" = "yes"; then
# We are using the GNU C compiler. Good! # We are using the GNU C compiler. Good!
CFLAGS="$CFLAGS -pipe -W -Wall -Wpointer-arith -Wstrict-prototypes" CFLAGS="$CFLAGS -pipe -W -Wall -Wpointer-arith -Wstrict-prototypes"
GCC_STACK_PROTECT_CC
fi 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 case "$target_os" in
hpux*) hpux*)
# This is HP/UX, we need to define _XOPEN_SOURCE_EXTENDED # This is HP/UX, we need to define _XOPEN_SOURCE_EXTENDED
@@ -138,17 +138,15 @@ AC_FUNC_STRFTIME
AC_CHECK_FUNCS([ \ AC_CHECK_FUNCS([ \
bind gethostbyaddr gethostbyname gethostname inet_ntoa malloc memmove \ bind gethostbyaddr gethostbyname gethostname inet_ntoa malloc memmove \
memset realloc setsid setsockopt socket strcasecmp strchr strerror \ memset realloc setsid setsockopt socket strcasecmp strchr strcspn strerror \
strstr waitpid],,AC_MSG_ERROR([required function missing!])) strstr waitpid],,AC_MSG_ERROR([required function missing!]))
AC_CHECK_FUNCS(inet_aton isdigit sigaction snprintf vsnprintf strdup strlcpy strlcat) AC_CHECK_FUNCS(inet_aton isdigit sigaction snprintf vsnprintf strdup strlcpy strlcat)
AC_CHECK_FUNCS(select,[AC_CHECK_HEADERS(sys/select.h)],
AC_MSG_ERROR([required function select() is missing!])
)
# -- Configuration options -- # -- Configuration options --
# use syslog?
x_syslog_on=no x_syslog_on=no
AC_ARG_WITH(syslog, AC_ARG_WITH(syslog,
[ --without-syslog disable syslog (autodetected by default)], [ --without-syslog disable syslog (autodetected by default)],
@@ -174,6 +172,8 @@ if test "$x_syslog_on" = "yes"; then
AC_CHECK_HEADERS(syslog.h,,AC_MSG_ERROR([required C header missing!])) AC_CHECK_HEADERS(syslog.h,,AC_MSG_ERROR([required C header missing!]))
fi fi
# use zlib compression?
x_zlib_on=no x_zlib_on=no
AC_ARG_WITH(zlib, AC_ARG_WITH(zlib,
[ --without-zlib disable zlib compression (autodetected by default)], [ --without-zlib disable zlib compression (autodetected by default)],
@@ -198,44 +198,120 @@ if test "$x_zlib_on" = "yes"; then
AC_CHECK_HEADERS(zlib.h,,AC_MSG_ERROR([required C header missing!])) AC_CHECK_HEADERS(zlib.h,,AC_MSG_ERROR([required C header missing!]))
fi fi
# detect which IO API to use:
x_io_backend=select x_io_backend=none
AC_ARG_WITH(epoll,
[ --without-epoll disable epoll support (autodetected by default)], AC_ARG_WITH(select,
[ --without-select disable select IO support (autodetected by default)],
[ if test "$withval" != "no"; then [ if test "$withval" != "no"; then
if test "$withval" != "yes"; then if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS" CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS" CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS" LDFLAGS="-L$withval/lib $LDFLAGS"
fi fi
AC_CHECK_FUNCS(epoll_create, x_io_backend=epoll, AC_CHECK_FUNCS(select, x_io_select=yes,
AC_MSG_ERROR([Can't enable epoll support!]) AC_MSG_ERROR([Can't enable select IO support!])
) )
fi fi
], ],
[ [
AC_CHECK_FUNCS(epoll_create, x_io_backend=epoll) AC_CHECK_FUNCS(select, x_io_select=yes)
]
)
AC_ARG_WITH(poll,
[ --without-poll disable poll support (autodetected by default)],
[ if test "$withval" != "no"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS"
fi
AC_CHECK_FUNCS(poll, x_io_backend=poll\(\),
AC_MSG_ERROR([Can't enable poll IO support!])
)
fi
],
[
AC_CHECK_FUNCS(poll, x_io_backend=poll\(\))
]
)
AC_ARG_WITH(devpoll,
[ --without-devpoll disable /dev/poll IO support (autodetected by default)],
[ if test "$withval" != "no"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS"
fi
AC_CHECK_HEADERS(sys/devpoll.h,,AC_MSG_ERROR([required C header missing!]))
fi
],
[
AC_CHECK_HEADERS(sys/devpoll.h, x_io_backend=/dev/poll)
]
)
AC_ARG_WITH(epoll,
[ --without-epoll disable epoll IO support (autodetected by default)],
[ if test "$withval" != "no"; then
if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS"
fi
AC_CHECK_FUNCS(epoll_create, x_io_epoll=yes,
AC_MSG_ERROR([Can't enable epoll IO support!])
)
fi
],
[
AC_CHECK_FUNCS(epoll_create, x_io_epoll=yes)
] ]
) )
AC_ARG_WITH(kqueue, AC_ARG_WITH(kqueue,
[ --without-kqueue disable kqueue support (autodetected by default)], [ --without-kqueue disable kqueue IO support (autodetected by default)],
[ if test "$withval" != "no"; then [ if test "$withval" != "no"; then
if test "$withval" != "yes"; then if test "$withval" != "yes"; then
CFLAGS="-I$withval/include $CFLAGS" CFLAGS="-I$withval/include $CFLAGS"
CPPFLAGS="-I$withval/include $CPPFLAGS" CPPFLAGS="-I$withval/include $CPPFLAGS"
LDFLAGS="-L$withval/lib $LDFLAGS" LDFLAGS="-L$withval/lib $LDFLAGS"
fi fi
AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue, AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue\(\),
AC_MSG_ERROR([Can't enable kqueue support!]) AC_MSG_ERROR([Can't enable kqueue IO support!])
) )
fi fi
], ],
[ [
AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue) AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue\(\))
] ]
) )
if test "$x_io_epoll" = "yes" -a "$x_io_select" = "yes"; then
# when epoll() and select() are available, we'll use both!
x_io_backend="epoll(), select()"
else
if test "$x_io_epoll" = "yes"; then
# we prefere epoll() if it is available
x_io_backend="epoll()"
else
if test "$x_io_select" = "yes" -a "$x_io_backend" = "none"; then
# we'll use select, when available and no "better"
# interface has been detected ...
x_io_backend="select()"
fi
fi
fi
if test "$x_io_backend" = "none"; then
AC_MSG_ERROR([No useabe IO API activated/found!?])
fi
# use TCP wrappers?
x_tcpwrap_on=no x_tcpwrap_on=no
AC_ARG_WITH(tcp-wrappers, AC_ARG_WITH(tcp-wrappers,
@@ -266,6 +342,8 @@ int deny_severity = 0;
] ]
) )
# include support for "zeroconf"?
x_zeroconf_on=no x_zeroconf_on=no
AC_ARG_WITH(zeroconf, AC_ARG_WITH(zeroconf,
[ --with-zeroconf enable support for "Zeroconf"], [ --with-zeroconf enable support for "Zeroconf"],
@@ -314,6 +392,8 @@ if test "$x_zeroconf_on" = "howl"; then
AC_DEFINE(ZEROCONF, 1) AC_DEFINE(ZEROCONF, 1)
fi fi
# do IDENT requests using libident?
x_identauth_on=no x_identauth_on=no
AC_ARG_WITH(ident, AC_ARG_WITH(ident,
[ --with-ident enable "IDENT" ("AUTH") protocol support], [ --with-ident enable "IDENT" ("AUTH") protocol support],
@@ -335,6 +415,8 @@ if test "$x_identauth_on" = "yes"; then
AC_CHECK_HEADERS(ident.h,,AC_MSG_ERROR([required C header missing!])) AC_CHECK_HEADERS(ident.h,,AC_MSG_ERROR([required C header missing!]))
fi fi
# compile in IRC+ protocol support?
x_ircplus_on=yes x_ircplus_on=yes
AC_ARG_ENABLE(ircplus, AC_ARG_ENABLE(ircplus,
[ --disable-ircplus disable IRC+ protocol], [ --disable-ircplus disable IRC+ protocol],
@@ -344,6 +426,8 @@ if test "$x_ircplus_on" = "yes"; then
AC_DEFINE(IRCPLUS, 1) AC_DEFINE(IRCPLUS, 1)
fi fi
# compile in IRC "sniffer"?
x_sniffer_on=no; x_debug_on=no x_sniffer_on=no; x_debug_on=no
AC_ARG_ENABLE(sniffer, AC_ARG_ENABLE(sniffer,
[ --enable-sniffer enable IRC traffic sniffer (enables debug mode)], [ --enable-sniffer enable IRC traffic sniffer (enables debug mode)],
@@ -353,6 +437,8 @@ AC_ARG_ENABLE(sniffer,
fi fi
) )
# enable additional debugging code?
AC_ARG_ENABLE(debug, AC_ARG_ENABLE(debug,
[ --enable-debug show additional debug output], [ --enable-debug show additional debug output],
if test "$enableval" = "yes"; then x_debug_on=yes; fi if test "$enableval" = "yes"; then x_debug_on=yes; fi
@@ -362,6 +448,8 @@ if test "$x_debug_on" = "yes"; then
test "$GCC" = "yes" && CFLAGS="-pedantic $CFLAGS" test "$GCC" = "yes" && CFLAGS="-pedantic $CFLAGS"
fi fi
# enable "strict RFC rules"?
x_strict_rfc_on=no x_strict_rfc_on=no
AC_ARG_ENABLE(strict-rfc, AC_ARG_ENABLE(strict-rfc,
[ --enable-strict-rfc strict RFC conformance -- may break clients!], [ --enable-strict-rfc strict RFC conformance -- may break clients!],
@@ -482,7 +570,7 @@ test "$x_identauth_on" = "yes" \
&& echo $ECHO_N "yes $ECHO_C" \ && echo $ECHO_N "yes $ECHO_C" \
|| echo $ECHO_N "no $ECHO_C" || echo $ECHO_N "no $ECHO_C"
echo $ECHO_N " I/O backend: $ECHO_C" echo $ECHO_N " I/O backend: $ECHO_C"
echo "\"$x_io_backend()\"" echo "\"$x_io_backend\""
echo echo

View File

@@ -1,3 +1,64 @@
ngircd (0.10.4-0ab1) unstable; urgency=high
* New "upstream" release: 0.10.4 - fixing a security bug.
-- Alexander Barton <alex@barton.de> Mon, 7 Jan 2008 22:04:44 +0100
ngircd (0.10.3-0ab1) unstable; urgency=high
* New "upstream" release: 0.10.3 - fixing a security bug.
-- Alexander Barton <alex@barton.de> Tue, 31 Jul 2007 21:02:52 +0200
ngircd (0.10.2-0ab1) unstable; urgency=low
* New "upstream" release: 0.10.2
-- Alexander Barton <alex@barton.de> Fri, 8 Jun 2007 10:49:36 +0200
ngircd (0.10.1-0ab1) unstable; urgency=low
* New "upstream" release: 0.10.1
-- Alexander Barton <alex@barton.de> Sun, 17 Dec 2006 14:52:06 +0100
ngircd (0.10.0-0ab1) unstable; urgency=low
* New "upstream" release: 0.10.0
-- Alexander Barton <alex@barton.de> Sun, 1 Oct 2006 18:14:21 +0200
ngircd (0.10.0-0ab0-pre2-1) unstable; urgency=low
* Bumped standards version to 3.7.2.1.
* Added "Provides: ircd" to Debian control file.
-- Alexander Barton <alex@barton.de> Sun, 1 Oct 2006 16:25:33 +0200
ngircd (0.10.0-0ab0-pre2) unstable; urgency=low
* Second "upstream" prerelease of upcoming 0.10.0 release.
-- Alexander Barton <alex@barton.de> Sat, 9 Sep 2006 20:57:52 +0200
ngircd (0.10.0-0ab0-pre1) unstable; urgency=low
* Prerelease of upcoming new "upstream release".
-- Alexander Barton <alex@barton.de> 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.
-- Alexander Barton <alex@barton.de> Sat, 15 Oct 2005 14:10:34 +0200
ngircd (0.9.1-0ab1) unstable; urgency=medium
* New "upstream release" addressing two problems in ngIRCd 0.9.0.
-- Alexander Barton <alex@barton.de> Wed, 3 Aug 2005 15:10:41 +0200
ngircd (0.9.0-0ab2) unstable; urgency=medium ngircd (0.9.0-0ab2) unstable; urgency=medium
* Init script: fixed a problem with symbolic links in runlevel directories * Init script: fixed a problem with symbolic links in runlevel directories

View File

@@ -3,11 +3,12 @@ Section: net
Priority: optional Priority: optional
Maintainer: Alexander Barton <alex@barton.de> Maintainer: Alexander Barton <alex@barton.de>
Build-Depends: debhelper (>> 4.0.0), libz-dev, libwrap-dev, libident-dev Build-Depends: debhelper (>> 4.0.0), libz-dev, libwrap-dev, libident-dev
Standards-Version: 3.5.8 Standards-Version: 3.7.2.1
Package: ngircd Package: ngircd
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends} Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: ircd
Description: A lightweight daemon for the Internet Relay Chat (IRC) Description: A lightweight daemon for the Internet Relay Chat (IRC)
ngIRCd is a free open source daemon for the Internet Relay Chat (IRC) ngIRCd is a free open source daemon for the Internet Relay Chat (IRC)
network. It is written from scratch and is not based upon the original network. It is written from scratch and is not based upon the original
@@ -28,6 +29,7 @@ Description: A lightweight daemon for the Internet Relay Chat (IRC)
Package: ngircd-full Package: ngircd-full
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends} Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: ircd
Conflicts: ngircd Conflicts: ngircd
Description: A lightweight daemon for the Internet Relay Chat (IRC) Description: A lightweight daemon for the Internet Relay Chat (IRC)
ngIRCd is a free open source daemon for the Internet Relay Chat (IRC) ngIRCd is a free open source daemon for the Internet Relay Chat (IRC)

View File

@@ -2,9 +2,20 @@
# #
# ngIRCd start and stop script for Debian-based systems # ngIRCd start and stop script for Debian-based systems
# #
# $Id: ngircd.init,v 1.6 2005/07/26 19:37:18 alex Exp $ # $Id: ngircd.init,v 1.6.2.1 2007/04/03 22:08:50 fw Exp $
# #
### BEGIN INIT INFO
# Provides: ircd
# Required-Start: $local_fs
# Required-Stop: $local_fs
# Should-Start: $syslog $network
# Should-Stop: $syslog $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Next Generation IRC Server
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/ngircd DAEMON=/usr/sbin/ngircd
NAME=ngIRCd NAME=ngIRCd

View File

@@ -1,5 +1,5 @@
%define name ngircd %define name ngircd
%define version CVSHEAD %define version 0.10.4
%define release 1 %define release 1
%define prefix %{_prefix} %define prefix %{_prefix}

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server ngIRCd - Next Generation IRC Server
(c)2001-2003 by Alexander Barton, (c)2001-2006 Alexander Barton,
alex@barton.de, http://www.barton.de/ alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the ngIRCd is free software and published under the
@@ -47,11 +47,11 @@ Updating the CVS tree:
You can update a single file or the complete source tree. 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 If you want to contribute a couple of patches and write access to the CVS
repository would be handy, please contact Alex Barton, <alex@barton.de>. repository would be handy, please contact Alex Barton, <alex@barton.de>.
-- --
$Id: CVS.txt,v 1.8 2006/07/23 12:43:15 alex Exp $ $Id: CVS.txt,v 1.8.2.1 2006/08/02 09:04:20 alex Exp $

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server ngIRCd - Next Generation IRC Server
(c)2001-2004 Alexander Barton (c)2001-2006 Alexander Barton
alex@barton.de, http://www.barton.de/ alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the ngIRCd is free software and published under the
@@ -26,24 +26,32 @@ list can be updated. Thanks for your help!
| | | | | | | |
Platform Compiler ngIRCd Date Tester C M T R See 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) 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 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 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/pc/solaris2.9 gcc 3.2.2 CVSHEAD 04-02-24 alex Y Y Y Y
i386/pc/solaris2.11 gcc 3.4.3 CVSHEAD 06-08-04 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/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/freebsd6.0 gcc 3.4.4 0.10.0-p1 06-08-04 alex Y Y Y Y (3)
i386/unknown/freebsd6.1 gcc 3.4.4 CVSHEAD 06-05-07 fw Y Y Y Y (3)
i386/unknown/gnu0.3 gcc 3.3.3 0.8.0 04-05-30 alex Y Y n Y 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 i386/unknown/netbsdelf1.6.1 gcc 2.95.3 CVSHEAD 04-02-24 alex Y Y Y Y
i386/unknown/netbsdelf3.0.1 gcc 3.3.3 0.10.0-p1 06-08-30 alex Y Y Y Y (3)
i386/unknown/openbsd3.9 gcc 3.3.5 0.10.0-p1 06-08-30 alex Y Y Y Y (3)
i686/pc/cygwin gcc 3.3.1 0.8.0 04-05-30 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 2.95.4 0.8.0 04-05-30 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) i686/pc/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y (1)
i386/pc/linux-gnu gcc 4.1.2 0.10.0-p1 06-08-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/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 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 ? ? 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/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/darwin7.4.0 gcc 3.3 0.8.0 04-05-30 alex Y Y Y Y
powerpc/apple/darwin7.9.0 gcc 3.3 CVSHEAD 06-05-07 fw Y Y Y Y (3) powerpc/apple/darwin7.9.0 gcc 3.3 CVSHEAD 06-05-07 fw Y Y Y Y (3)
powerpc/apple/darwin8.1.0 gcc 4.0 0.9.x-CVS 05-06-27 alex Y Y Y Y
powerpc/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y powerpc/unknown/linux-gnu gcc 3.3.3 0.8.0 04-05-30 alex Y Y Y Y
powerpc/unknown/openbsd3.6 gcc 2.95.3 0.10.0 06-10-08 alex Y Y n Y
sparc/sun/solaris2.6 gcc 2.95.3 0.7.x-CVS 03-04-22 alex Y Y Y Y sparc/sun/solaris2.6 gcc 2.95.3 0.7.x-CVS 03-04-22 alex Y Y Y Y
sparc/sun/solaris2.7 gcc 3.3 0.8.0 04-05-30 alex Y Y Y Y sparc/sun/solaris2.7 gcc 3.3 0.8.0 04-05-30 alex Y Y Y Y
sparc/unkn./netbsdelf1.6.1 gcc 2.95.3 0.8.0 04-05-30 alex Y Y Y Y sparc/unkn./netbsdelf1.6.1 gcc 2.95.3 0.8.0 04-05-30 alex Y Y Y Y
@@ -51,16 +59,19 @@ sparc/unkn./netbsdelf1.6.1 gcc 2.95.3 0.8.0 04-05-30 alex Y Y Y Y
Notes Notes
~~~~~ ~~~~~
(1) i686/pc/linux-gnu: (1) i686/pc/linux-gnu:
ngIRCd has been tested with various Linux distributions, such as SuSE, ngIRCd has been tested with various Linux distributions, such as SuSE,
RedHat, Debian, and Gentoo using Kernels 2.2.x, 2.4.x and 2.6.x with RedHat, Debian, and Gentoo using Kernels 2.2.x, 2.4.x and 2.6.x with
various versions of the GNU C compiler (2.95.3, 3.0, 3.2, and 3.3). The various versions of the GNU C compiler (starting with 2.95.x and up to
eldest glibc used was glibc-2.0.7. ngIRCd compiled and run on all these version 4.1.x). The eldest glibc used was glibc-2.0.7. ngIRCd compiled
systems without problems. and run on all these systems without problems.
Actual Linux kernels (2.6.x) and glic's support the epoll() IO interface.
(2) This compiler is an pre-ANSI C compiler, therefore the source code is (2) This compiler is an pre-ANSI C compiler, therefore the source code is
automatically converted using the included ansi2knr tool while building. automatically converted using the included ansi2knr tool while building.
(3) kqueue io backend
(4) 6.1-PRERELEASE (3) Using the kqueue() IO interface.
-- --
$Id: Platforms.txt,v 1.14 2006/05/07 11:07:13 fw Exp $ $Id: Platforms.txt,v 1.14.2.2 2007/04/03 22:08:51 fw Exp $

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server ngIRCd - Next Generation IRC Server
(c)2001-2005 Alexander Barton (c)2001-2006 Alexander Barton
alex@barton.de, http://www.barton.de/ alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the ngIRCd is free software and published under the
@@ -16,7 +16,8 @@ with DNS Service Discovery (DNS-SD[3]).
To use this features you can use one of two APIs: To use this features you can use one of two APIs:
a) Apple "Bonjour" API as used by Mac OS X, a) Apple "Bonjour" API as used by Mac OS X,
b) the Howl[4] Zeroconf library. 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 When calling the configure script using the "--with-zeroconf" switch the
avalable API will be autodetected and the required additional libraries will avalable API will be autodetected and the required additional libraries will
@@ -32,7 +33,8 @@ Links:
[2] http://www.multicastdns.org/ [2] http://www.multicastdns.org/
[3] http://www.dns-sd.org/ [3] http://www.dns-sd.org/
[4] http://www.porchdogsoft.com/products/howl/ [4] http://www.porchdogsoft.com/products/howl/
[5] http://avahi.org/
-- --
$Id: Zeroconf.txt,v 1.1 2005/07/08 16:19:03 alex Exp $ $Id: Zeroconf.txt,v 1.1.2.1 2006/08/02 09:04:20 alex Exp $

View File

@@ -1,4 +1,4 @@
# $Id: sample-ngircd.conf,v 1.37 2006/04/09 12:27:23 alex Exp $ # $Id: sample-ngircd.conf,v 1.37.2.2 2007/04/03 22:08:51 fw Exp $
# #
# This is a sample configuration file for the ngIRCd, which must be adepted # This is a sample configuration file for the ngIRCd, which must be adepted
@@ -93,6 +93,9 @@
# server? (This is a compatibility hack for ircd-irc2 servers) # server? (This is a compatibility hack for ircd-irc2 servers)
;OperServerMode = no ;OperServerMode = no
# Allow Pre-Defined Channels only (see Section [Channels])
;PredefChannelsOnly = no
# Maximum number of simultaneous connection the server is allowed # Maximum number of simultaneous connection the server is allowed
# to accept (<=0: unlimited): # to accept (<=0: unlimited):
;MaxConnections = -1 ;MaxConnections = -1
@@ -175,7 +178,13 @@
;Topic = a great topic ;Topic = a great topic
# Initial channel modes # Initial channel modes
;Modes = tn ;Modes = tnk
# initial channel password (mode k)
;Key = Secret
# maximum users per channel (mode l)
;MaxUsers = 23
[Channel] [Channel]
# More [Channel] sections, if you like ... # More [Channel] sections, if you like ...

View File

@@ -8,14 +8,14 @@
# (at your option) any later version. # (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information. # Please read the file COPYING, README and AUTHORS for more information.
# #
# $Id: Makefile.am,v 1.2 2006/04/08 16:35:03 alex Exp $ # $Id: Makefile.am,v 1.2.2.1 2007/04/03 22:08:52 fw Exp $
# #
maintainer-clean-local: maintainer-clean-local:
rm -f Makefile Makefile.in rm -f Makefile Makefile.in
distclean-local: distclean-local:
rm -f html rm -rf html
srcdoc: srcdoc:
@doxygen --version >/dev/null 2>&1 \ @doxygen --version >/dev/null 2>&1 \

View File

@@ -1,5 +1,5 @@
.\" .\"
.\" $Id: ngircd.conf.5,v 1.20 2005/09/02 14:39:00 fw Exp $ .\" $Id: ngircd.conf.5,v 1.20.2.1 2006/12/11 22:08:14 fw Exp $
.\" .\"
.TH ngircd.conf 5 "August 2005" ngircd "ngIRCd Manual" .TH ngircd.conf 5 "August 2005" ngircd "ngIRCd Manual"
.SH NAME .SH NAME
@@ -146,6 +146,11 @@ If OperCanUseMode is enabled, this may lead the compatibility problems with
Servers that run the ircd-irc2 Software. This Option "masks" mode requests Servers that run the ircd-irc2 Software. This Option "masks" mode requests
by non-chanops as if they were coming from the server. Default: no. by non-chanops as if they were coming from the server. Default: no.
.TP .TP
\fBPredefChannelsOnly\fR
If enabled, no new channels can be created. Useful if
you do not want to have channels other than those defined in
the config file.
.TP
\fBMaxConnections\fR \fBMaxConnections\fR
Maximum number of simultaneous connection the server is allowed to accept Maximum number of simultaneous connection the server is allowed to accept
(<=0: unlimited). Default: -1. (<=0: unlimited). Default: -1.

View File

@@ -12,7 +12,7 @@
#include "array.h" #include "array.h"
static char UNUSED id[] = "$Id: array.c,v 1.11 2006/07/01 22:11:48 fw Exp $"; static char UNUSED id[] = "$Id: array.c,v 1.11.2.3 2007/04/03 22:08:52 fw Exp $";
#include <assert.h> #include <assert.h>
@@ -66,10 +66,7 @@ array_alloc(array * a, size_t size, size_t pos)
assert(size > 0); assert(size > 0);
if (pos_plus1 < pos) if (pos_plus1 == 0 || !safemult_sizet(size, pos_plus1, &alloc))
return NULL;
if (!safemult_sizet(size, pos_plus1, &alloc))
return NULL; return NULL;
if (a->allocated < alloc) { if (a->allocated < alloc) {
@@ -250,20 +247,22 @@ void *
array_get(array * a, size_t membersize, size_t pos) array_get(array * a, size_t membersize, size_t pos)
{ {
size_t totalsize; size_t totalsize;
size_t posplus1 = pos + 1;
assert(membersize > 0); assert(membersize > 0);
assert(a != NULL); assert(a != NULL);
if (array_UNUSABLE(a)) if (!posplus1 || array_UNUSABLE(a))
return NULL; return NULL;
if (!safemult_sizet(pos, membersize, &totalsize)) if (!safemult_sizet(posplus1, membersize, &totalsize))
return NULL; return NULL;
if (a->allocated < totalsize) if (a->allocated < totalsize)
return NULL; return NULL;
return a->mem + pos * membersize; totalsize = pos * membersize;
return a->mem + totalsize;
} }
@@ -271,7 +270,7 @@ void
array_free(array * a) array_free(array * a)
{ {
assert(a != NULL); assert(a != NULL);
#ifdef DEBUG #ifdef DEBUG_ARRAY
Log(LOG_DEBUG, Log(LOG_DEBUG,
"array_free(): %u bytes free'd (%u bytes still used at time of free()).", "array_free(): %u bytes free'd (%u bytes still used at time of free()).",
a->allocated, a->used); a->allocated, a->used);
@@ -283,16 +282,6 @@ array_free(array * a)
} }
void
array_free_wipe(array * a)
{
if (!array_UNUSABLE(a))
memset(a->mem, 0, a->allocated);
array_free(a);
}
void * void *
array_start(const array * const a) array_start(const array * const a)
{ {
@@ -331,9 +320,6 @@ array_moveleft(array * a, size_t membersize, size_t pos)
assert(a != NULL); assert(a != NULL);
assert(membersize > 0); assert(membersize > 0);
if (!pos)
return;
if (!safemult_sizet(membersize, pos, &bytepos)) { if (!safemult_sizet(membersize, pos, &bytepos)) {
a->used = 0; a->used = 0;
return; return;

View File

@@ -17,7 +17,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: channel.c,v 1.56 2006/07/24 22:54:09 alex Exp $"; static char UNUSED id[] = "$Id: channel.c,v 1.56.2.4 2007/07/31 20:48:15 alex Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -70,6 +70,22 @@ Channel_Init( void )
} /* Channel_Init */ } /* Channel_Init */
GLOBAL struct list_head *
Channel_GetListBans(CHANNEL *c)
{
assert(c != NULL);
return &c->list_bans;
}
GLOBAL struct list_head *
Channel_GetListInvites(CHANNEL *c)
{
assert(c != NULL);
return &c->list_invites;
}
GLOBAL void GLOBAL void
Channel_InitPredefined( void ) Channel_InitPredefined( void )
{ {
@@ -114,7 +130,10 @@ Channel_InitPredefined( void )
c = Conf_Channel[i].modes; c = Conf_Channel[i].modes;
while (*c) while (*c)
Channel_ModeAdd(chan, *c++); Channel_ModeAdd(chan, *c++);
Channel_SetKey(chan, Conf_Channel[i].key);
Channel_SetMaxUsers(chan, Conf_Channel[i].maxusers);
Log(LOG_INFO, "Created pre-defined channel \"%s\".", Log(LOG_INFO, "Created pre-defined channel \"%s\".",
Conf_Channel[i].name ); Conf_Channel[i].name );
} }
@@ -129,7 +148,7 @@ Channel_Exit( void )
{ {
CHANNEL *c, *c_next; CHANNEL *c, *c_next;
CL2CHAN *cl2chan, *cl2chan_next; CL2CHAN *cl2chan, *cl2chan_next;
/* Channel-Strukturen freigeben */ /* Channel-Strukturen freigeben */
c = My_Channels; c = My_Channels;
while( c ) while( c )
@@ -173,7 +192,7 @@ Channel_Join( CLIENT *Client, char *Name )
{ {
/* Gibt es noch nicht? Dann neu anlegen: */ /* Gibt es noch nicht? Dann neu anlegen: */
chan = Channel_Create( Name ); chan = Channel_Create( Name );
if( ! chan ) return false; if (!chan) return false;
} }
/* User dem Channel hinzufuegen */ /* User dem Channel hinzufuegen */
@@ -214,7 +233,6 @@ Channel_Kick( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason )
assert( Name != NULL ); assert( Name != NULL );
assert( Reason != NULL ); assert( Reason != NULL );
/* Channel suchen */
chan = Channel_Search( Name ); chan = Channel_Search( Name );
if( ! chan ) if( ! chan )
{ {
@@ -266,11 +284,11 @@ Channel_Quit( CLIENT *Client, char *Reason )
} /* Channel_Quit */ } /* Channel_Quit */
GLOBAL long GLOBAL unsigned long
Channel_Count( void ) Channel_Count( void )
{ {
CHANNEL *c; CHANNEL *c;
long count = 0; unsigned long count = 0;
c = My_Channels; c = My_Channels;
while( c ) while( c )
@@ -282,11 +300,11 @@ Channel_Count( void )
} /* Channel_Count */ } /* Channel_Count */
GLOBAL long GLOBAL unsigned long
Channel_MemberCount( CHANNEL *Chan ) Channel_MemberCount( CHANNEL *Chan )
{ {
CL2CHAN *cl2chan; CL2CHAN *cl2chan;
long count = 0; unsigned long count = 0;
assert( Chan != NULL ); assert( Chan != NULL );
@@ -321,27 +339,9 @@ Channel_CountForUser( CLIENT *Client )
} /* Channel_CountForUser */ } /* Channel_CountForUser */
GLOBAL int
Channel_PCount( void )
{
/* Count the number of persistent (mode 'P') channels */
CHANNEL *chan; GLOBAL const char *
int count = 0; Channel_Name( const CHANNEL *Chan )
chan = My_Channels;
while( chan )
{
if( strchr( chan->modes, 'P' )) count++;
chan = chan->next;
}
return count;
} /* Channel_PCount */
GLOBAL char *
Channel_Name( CHANNEL *Chan )
{ {
assert( Chan != NULL ); assert( Chan != NULL );
return Chan->name; return Chan->name;
@@ -364,7 +364,7 @@ Channel_Key( CHANNEL *Chan )
} /* Channel_Key */ } /* Channel_Key */
GLOBAL long GLOBAL unsigned long
Channel_MaxUsers( CHANNEL *Chan ) Channel_MaxUsers( CHANNEL *Chan )
{ {
assert( Chan != NULL ); assert( Chan != NULL );
@@ -463,25 +463,13 @@ Channel_GetChannel( CL2CHAN *Cl2Chan )
GLOBAL bool GLOBAL bool
Channel_IsValidName( char *Name ) Channel_IsValidName( const char *Name )
{ {
/* Pruefen, ob Name als Channelname gueltig */
char *ptr, badchars[10];
assert( Name != NULL ); assert( Name != NULL );
if(( Name[0] != '#' ) || ( strlen( Name ) >= CHANNEL_NAME_LEN )) return false; if(( Name[0] != '#' ) || ( strlen( Name ) >= CHANNEL_NAME_LEN )) return false;
ptr = Name; return Name[strcspn(Name, " ,:\007")] == 0;
strcpy( badchars, " ,:\007" );
while( *ptr )
{
if( strchr( badchars, *ptr )) return false;
ptr++;
}
return true;
} /* Channel_IsValidName */ } /* Channel_IsValidName */
@@ -548,7 +536,7 @@ Channel_UserModeAdd( CHANNEL *Chan, CLIENT *Client, char Mode )
cl2chan = Get_Cl2Chan( Chan, Client ); cl2chan = Get_Cl2Chan( Chan, Client );
assert( cl2chan != NULL ); assert( cl2chan != NULL );
x[0] = Mode; x[1] = '\0'; x[0] = Mode; x[1] = '\0';
if( ! strchr( cl2chan->modes, x[0] )) if( ! strchr( cl2chan->modes, x[0] ))
{ {
@@ -594,7 +582,7 @@ GLOBAL char *
Channel_UserModes( CHANNEL *Chan, CLIENT *Client ) Channel_UserModes( CHANNEL *Chan, CLIENT *Client )
{ {
/* return Users' Channel-Modes */ /* return Users' Channel-Modes */
CL2CHAN *cl2chan; CL2CHAN *cl2chan;
assert( Chan != NULL ); assert( Chan != NULL );
@@ -614,9 +602,7 @@ Channel_IsMemberOf( CHANNEL *Chan, CLIENT *Client )
assert( Chan != NULL ); assert( Chan != NULL );
assert( Client != NULL ); assert( Client != NULL );
return Get_Cl2Chan(Chan, Client) != NULL;
if( Get_Cl2Chan( Chan, Client )) return true;
else return false;
} /* Channel_IsMemberOf */ } /* Channel_IsMemberOf */
@@ -661,12 +647,9 @@ Channel_SetTopic(CHANNEL *Chan, CLIENT *Client, char *Topic)
if (len < array_bytes(&Chan->topic)) if (len < array_bytes(&Chan->topic))
array_free(&Chan->topic); array_free(&Chan->topic);
if (!array_copyb(&Chan->topic, Topic, len)) if (len >= COMMAND_LEN || !array_copyb(&Chan->topic, Topic, len+1))
Log(LOG_WARNING, "could not set new Topic \"%s\" on %s: %s", Log(LOG_WARNING, "could not set new Topic \"%s\" on %s: %s",
Topic, Chan->name, strerror(errno)); Topic, Chan->name, strerror(errno));
array_cat0(&Chan->topic);
#ifndef STRICT_RFC #ifndef STRICT_RFC
Chan->topic_time = time(NULL); Chan->topic_time = time(NULL);
if (Client != NULL && Client_Type(Client) != CLIENT_SERVER) if (Client != NULL && Client_Type(Client) != CLIENT_SERVER)
@@ -698,17 +681,17 @@ Channel_SetKey( CHANNEL *Chan, char *Key )
assert( Key != NULL ); assert( Key != NULL );
strlcpy( Chan->key, Key, sizeof( Chan->key )); strlcpy( Chan->key, Key, sizeof( Chan->key ));
Log( LOG_DEBUG, "Channel %s: Key is now \"%s\".", Chan->name, Chan->key ); LogDebug("Channel %s: Key is now \"%s\".", Chan->name, Chan->key );
} /* Channel_SetKey */ } /* Channel_SetKey */
GLOBAL void GLOBAL void
Channel_SetMaxUsers( CHANNEL *Chan, long Count ) Channel_SetMaxUsers(CHANNEL *Chan, unsigned long Count)
{ {
assert( Chan != NULL ); assert( Chan != NULL );
Chan->maxusers = Count; Chan->maxusers = Count;
Log( LOG_DEBUG, "Channel %s: Member limit is now %ld.", Chan->name, Chan->maxusers ); LogDebug("Channel %s: Member limit is now %lu.", Chan->name, Chan->maxusers );
} /* Channel_SetMaxUsers */ } /* Channel_SetMaxUsers */
@@ -730,9 +713,9 @@ Channel_Write( CHANNEL *Chan, CLIENT *From, CLIENT *Client, char *Text )
ok = true; ok = true;
if( strchr( Channel_Modes( Chan ), 'n' ) && ( ! is_member )) ok = false; if( strchr( Channel_Modes( Chan ), 'n' ) && ( ! is_member )) ok = false;
if( strchr( Channel_Modes( Chan ), 'm' ) && ( ! is_op ) && ( ! has_voice )) ok = false; if( strchr( Channel_Modes( Chan ), 'm' ) && ( ! is_op ) && ( ! has_voice )) ok = false;
/* Is the client banned? */ /* Is the client banned? */
if( Lists_CheckBanned( From, Chan )) if( Lists_Check(&Chan->list_bans, From))
{ {
/* Client is banned, but is he channel operator or has voice? */ /* Client is banned, but is he channel operator or has voice? */
if(( ! has_voice ) && ( ! is_op )) ok = false; if(( ! has_voice ) && ( ! is_op )) ok = false;
@@ -753,7 +736,7 @@ Channel_Create( char *Name )
CHANNEL *c; CHANNEL *c;
assert( Name != NULL ); assert( Name != NULL );
c = (CHANNEL *)malloc( sizeof( CHANNEL )); c = (CHANNEL *)malloc( sizeof( CHANNEL ));
if( ! c ) if( ! c )
{ {
@@ -765,9 +748,7 @@ Channel_Create( char *Name )
c->hash = Hash( c->name ); c->hash = Hash( c->name );
c->next = My_Channels; c->next = My_Channels;
My_Channels = c; My_Channels = c;
#ifdef DEBUG LogDebug("Created new channel structure for \"%s\".", Name);
Log( LOG_DEBUG, "Created new channel structure for \"%s\".", Name );
#endif
return c; return c;
} /* Channel_Create */ } /* Channel_Create */
@@ -851,25 +832,42 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, char *Re
switch( Type ) switch( Type )
{ {
case REMOVE_QUIT: case REMOVE_QUIT:
/* QUIT: andere Server wurden bereits informiert, vgl. Client_Destroy(); /* QUIT: other servers have already been notified, see Client_Destroy();
* hier also "nur" noch alle User in betroffenen Channeln infomieren */ * so only inform other clients in same channel. */
assert( InformServer == false ); assert( InformServer == false );
Log( LOG_DEBUG, "User \"%s\" left channel \"%s\" (%s).", Client_Mask( Client ), c->name, Reason ); LogDebug("User \"%s\" left channel \"%s\" (%s).",
Client_Mask( Client ), c->name, Reason );
break; break;
case REMOVE_KICK: case REMOVE_KICK:
/* User wurde geKICKed: ggf. andere Server sowie alle betroffenen User /* User was KICKed: inform other servers and all users in channel */
* im entsprechenden Channel informieren */ if( InformServer )
if( InformServer ) IRC_WriteStrServersPrefix( Client_NextHop( Origin ), Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason ); IRC_WriteStrServersPrefix( Client_NextHop( Origin ),
IRC_WriteStrChannelPrefix( Client, c, Origin, false, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason ); Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason);
if(( Client_Conn( Client ) > NONE ) && ( Client_Type( Client ) == CLIENT_USER )) IRC_WriteStrClientPrefix( Client, Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason ); IRC_WriteStrChannelPrefix(Client, c, Origin, false, "KICK %s %s :%s",
Log( LOG_DEBUG, "User \"%s\" has been kicked of \"%s\" by \"%s\": %s.", Client_Mask( Client ), c->name, Client_ID( Origin ), Reason ); c->name, Client_ID( Client ), Reason );
if ((Client_Conn(Client) > NONE) &&
(Client_Type(Client) == CLIENT_USER))
{
IRC_WriteStrClientPrefix(Client, Origin, "KICK %s %s :%s",
c->name, Client_ID( Client ), Reason);
}
LogDebug("User \"%s\" has been kicked of \"%s\" by \"%s\": %s.",
Client_Mask( Client ), c->name, Client_ID(Origin), Reason);
break; break;
default: default: /* PART */
/* PART */ if (InformServer)
if( InformServer ) IRC_WriteStrServersPrefix( Origin, Client, "PART %s :%s", c->name, Reason ); IRC_WriteStrServersPrefix(Origin, Client, "PART %s :%s", c->name, Reason);
IRC_WriteStrChannelPrefix( Origin, c, Client, false, "PART %s :%s", c->name, Reason );
if(( Client_Conn( Origin ) > NONE ) && ( Client_Type( Origin ) == CLIENT_USER )) IRC_WriteStrClientPrefix( Origin, Client, "PART %s :%s", c->name, Reason ); IRC_WriteStrChannelPrefix(Origin, c, Client, false, "PART %s :%s",
Log( LOG_DEBUG, "User \"%s\" left channel \"%s\" (%s).", Client_Mask( Client ), c->name, Reason ); c->name, Reason);
if ((Client_Conn(Origin) > NONE) &&
(Client_Type(Origin) == CLIENT_USER))
{
IRC_WriteStrClientPrefix( Origin, Client, "PART %s :%s", c->name, Reason);
LogDebug("User \"%s\" left channel \"%s\" (%s).",
Client_Mask(Client), c->name, Reason);
}
} }
/* Wenn Channel nun leer und nicht pre-defined: loeschen */ /* Wenn Channel nun leer und nicht pre-defined: loeschen */
@@ -882,6 +880,68 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, char *Re
} /* Remove_Client */ } /* Remove_Client */
GLOBAL bool
Channel_AddBan(CHANNEL *c, const char *mask )
{
struct list_head *h = Channel_GetListBans(c);
return Lists_Add(h, mask, false);
}
GLOBAL bool
Channel_AddInvite(CHANNEL *c, const char *mask, bool onlyonce)
{
struct list_head *h = Channel_GetListInvites(c);
return Lists_Add(h, mask, onlyonce);
}
static bool
ShowInvitesBans(struct list_head *head, CLIENT *Client, CHANNEL *Channel, bool invite)
{
struct list_elem *e;
char *msg = invite ? RPL_INVITELIST_MSG : RPL_BANLIST_MSG;
char *msg_end;
assert( Client != NULL );
assert( Channel != NULL );
e = Lists_GetFirst(head);
while (e) {
if( ! IRC_WriteStrClient( Client, msg, Client_ID( Client ),
Channel_Name( Channel ), Lists_GetMask(e) )) return DISCONNECTED;
e = Lists_GetNext(e);
}
msg_end = invite ? RPL_ENDOFINVITELIST_MSG : RPL_ENDOFBANLIST_MSG;
return IRC_WriteStrClient( Client, msg_end, Client_ID( Client ), Channel_Name( Channel ));
}
GLOBAL bool
Channel_ShowBans( CLIENT *Client, CHANNEL *Channel )
{
struct list_head *h;
assert( Channel != NULL );
h = Channel_GetListBans(Channel);
return ShowInvitesBans(h, Client, Channel, false);
}
GLOBAL bool
Channel_ShowInvites( CLIENT *Client, CHANNEL *Channel )
{
struct list_head *h;
assert( Channel != NULL );
h = Channel_GetListInvites(Channel);
return ShowInvitesBans(h, Client, Channel, true);
}
static CL2CHAN * static CL2CHAN *
Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan ) Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan )
{ {
@@ -911,7 +971,7 @@ static bool
Delete_Channel( CHANNEL *Chan ) Delete_Channel( CHANNEL *Chan )
{ {
/* Channel-Struktur loeschen */ /* Channel-Struktur loeschen */
CHANNEL *chan, *last_chan; CHANNEL *chan, *last_chan;
last_chan = NULL; last_chan = NULL;
@@ -927,13 +987,14 @@ Delete_Channel( CHANNEL *Chan )
Log( LOG_DEBUG, "Freed channel structure for \"%s\".", Chan->name ); Log( LOG_DEBUG, "Freed channel structure for \"%s\".", Chan->name );
/* Invite- und Ban-Lists aufraeumen */ /* Invite- und Ban-Lists aufraeumen */
Lists_DeleteChannel( chan ); Lists_Free( &chan->list_bans );
Lists_Free( &chan->list_invites );
/* Neu verketten und freigeben */ /* Neu verketten und freigeben */
if( last_chan ) last_chan->next = chan->next; if( last_chan ) last_chan->next = chan->next;
else My_Channels = chan->next; else My_Channels = chan->next;
free( chan ); free( chan );
return true; return true;
} /* Delete_Channel */ } /* Delete_Channel */

View File

@@ -8,7 +8,7 @@
* (at your option) any later version. * (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information. * Please read the file COPYING, README and AUTHORS for more information.
* *
* $Id: channel.h,v 1.29 2005/09/02 12:50:25 alex Exp $ * $Id: channel.h,v 1.29.2.2 2007/04/03 20:23:31 fw Exp $
* *
* Channel management (header) * Channel management (header)
*/ */
@@ -20,6 +20,7 @@
#if defined(__channel_c__) | defined(S_SPLINT_S) #if defined(__channel_c__) | defined(S_SPLINT_S)
#include "lists.h"
#include "defines.h" #include "defines.h"
#include "array.h" #include "array.h"
@@ -35,7 +36,9 @@ typedef struct _CHANNEL
char topic_who[CLIENT_NICK_LEN];/* Nickname of user that set topic */ char topic_who[CLIENT_NICK_LEN];/* Nickname of user that set topic */
#endif #endif
char key[CLIENT_PASS_LEN]; /* Channel key ("password", mode "k" ) */ char key[CLIENT_PASS_LEN]; /* Channel key ("password", mode "k" ) */
long maxusers; /* Maximum number of members (mode "l") */ unsigned long maxusers; /* Maximum number of members (mode "l") */
struct list_head list_bans; /* list head of banned users */
struct list_head list_invites; /* list head of invited users */
} CHANNEL; } CHANNEL;
typedef struct _CLIENT2CHAN typedef struct _CLIENT2CHAN
@@ -53,6 +56,8 @@ typedef POINTER CL2CHAN;
#endif #endif
GLOBAL struct list_head *Channel_GetListBans PARAMS((CHANNEL *c));
GLOBAL struct list_head *Channel_GetListInvites PARAMS((CHANNEL *c));
GLOBAL void Channel_Init PARAMS(( void )); GLOBAL void Channel_Init PARAMS(( void ));
GLOBAL void Channel_InitPredefined PARAMS(( void )); GLOBAL void Channel_InitPredefined PARAMS(( void ));
@@ -65,21 +70,20 @@ GLOBAL void Channel_Quit PARAMS(( CLIENT *Client, char *Reason ));
GLOBAL void Channel_Kick PARAMS(( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason )); GLOBAL void Channel_Kick PARAMS(( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason ));
GLOBAL long Channel_Count PARAMS(( void )); GLOBAL unsigned long Channel_Count PARAMS(( void ));
GLOBAL long Channel_MemberCount PARAMS(( CHANNEL *Chan )); GLOBAL unsigned long Channel_MemberCount PARAMS(( CHANNEL *Chan ));
GLOBAL int Channel_CountForUser PARAMS(( CLIENT *Client )); GLOBAL int Channel_CountForUser PARAMS(( CLIENT *Client ));
GLOBAL int Channel_PCount PARAMS(( void ));
GLOBAL char *Channel_Name PARAMS(( CHANNEL *Chan )); GLOBAL const char *Channel_Name PARAMS(( const CHANNEL *Chan ));
GLOBAL char *Channel_Modes PARAMS(( CHANNEL *Chan )); GLOBAL char *Channel_Modes PARAMS(( CHANNEL *Chan ));
GLOBAL char *Channel_Topic PARAMS(( CHANNEL *Chan )); GLOBAL char *Channel_Topic PARAMS(( CHANNEL *Chan ));
GLOBAL char *Channel_Key PARAMS(( CHANNEL *Chan )); GLOBAL char *Channel_Key PARAMS(( CHANNEL *Chan ));
GLOBAL long Channel_MaxUsers PARAMS(( CHANNEL *Chan )); GLOBAL unsigned long Channel_MaxUsers PARAMS(( CHANNEL *Chan ));
GLOBAL void Channel_SetTopic PARAMS(( CHANNEL *Chan, CLIENT *Client, 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_SetModes PARAMS(( CHANNEL *Chan, char *Modes ));
GLOBAL void Channel_SetKey PARAMS(( CHANNEL *Chan, char *Key )); GLOBAL void Channel_SetKey PARAMS(( CHANNEL *Chan, char *Key ));
GLOBAL void Channel_SetMaxUsers PARAMS(( CHANNEL *Chan, long Count )); GLOBAL void Channel_SetMaxUsers PARAMS(( CHANNEL *Chan, unsigned long Count ));
GLOBAL CHANNEL *Channel_Search PARAMS(( char *Name )); GLOBAL CHANNEL *Channel_Search PARAMS(( char *Name ));
@@ -94,7 +98,7 @@ GLOBAL CL2CHAN *Channel_NextChannelOf PARAMS(( CLIENT *Client, CL2CHAN *Cl2Chan
GLOBAL CLIENT *Channel_GetClient PARAMS(( CL2CHAN *Cl2Chan )); GLOBAL CLIENT *Channel_GetClient PARAMS(( CL2CHAN *Cl2Chan ));
GLOBAL CHANNEL *Channel_GetChannel PARAMS(( CL2CHAN *Cl2Chan )); GLOBAL CHANNEL *Channel_GetChannel PARAMS(( CL2CHAN *Cl2Chan ));
GLOBAL bool Channel_IsValidName PARAMS(( char *Name )); GLOBAL bool Channel_IsValidName PARAMS(( const char *Name ));
GLOBAL bool Channel_ModeAdd PARAMS(( CHANNEL *Chan, char Mode )); GLOBAL bool Channel_ModeAdd PARAMS(( CHANNEL *Chan, char Mode ));
GLOBAL bool Channel_ModeDel PARAMS(( CHANNEL *Chan, char Mode )); GLOBAL bool Channel_ModeDel PARAMS(( CHANNEL *Chan, char Mode ));
@@ -114,8 +118,10 @@ GLOBAL unsigned int Channel_TopicTime PARAMS(( CHANNEL *Chan ));
GLOBAL char *Channel_TopicWho PARAMS(( CHANNEL *Chan )); GLOBAL char *Channel_TopicWho PARAMS(( CHANNEL *Chan ));
#endif #endif
GLOBAL bool Channel_AddInvite PARAMS((CHANNEL *c, const char *Mask, bool OnlyOnce ));
GLOBAL bool Channel_AddBan PARAMS((CHANNEL *c, const char *Mask ));
GLOBAL bool Channel_ShowBans PARAMS((CLIENT *client, CHANNEL *c));
GLOBAL bool Channel_ShowInvites PARAMS((CLIENT *client, CHANNEL *c));
#endif #endif
/* -eof- */ /* -eof- */

View File

@@ -17,7 +17,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: client.c,v 1.91 2006/04/23 10:37:27 fw Exp $"; static char UNUSED id[] = "$Id: client.c,v 1.91.2.2 2007/04/03 22:08:52 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -57,8 +57,8 @@ static WHOWAS My_Whowas[MAX_WHOWAS];
static int Last_Whowas = -1; static int Last_Whowas = -1;
static long Count PARAMS(( CLIENT_TYPE Type )); static unsigned long Count PARAMS(( CLIENT_TYPE Type ));
static long MyCount PARAMS(( CLIENT_TYPE Type )); static unsigned long MyCount PARAMS(( CLIENT_TYPE Type ));
static CLIENT *New_Client_Struct PARAMS(( void )); static CLIENT *New_Client_Struct PARAMS(( void ));
static void Generate_MyToken PARAMS(( CLIENT *Client )); static void Generate_MyToken PARAMS(( CLIENT *Client ));
@@ -68,10 +68,6 @@ static CLIENT *Init_New_Client PARAMS((CONN_ID Idx, CLIENT *Introducer,
CLIENT *TopServer, int Type, char *ID, char *User, char *Hostname, CLIENT *TopServer, int Type, char *ID, char *User, char *Hostname,
char *Info, int Hops, int Token, char *Modes, bool Idented)); char *Info, int Hops, int Token, char *Modes, bool Idented));
#ifndef Client_DestroyNow
GLOBAL void Client_DestroyNow PARAMS((CLIENT *Client ));
#endif
long Max_Users = 0, My_Max_Users = 0; long Max_Users = 0, My_Max_Users = 0;
@@ -211,8 +207,8 @@ Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer,
if( Modes ) Client_SetModes( client, Modes ); if( Modes ) Client_SetModes( client, Modes );
if( Type == CLIENT_SERVER ) Generate_MyToken( client ); if( Type == CLIENT_SERVER ) Generate_MyToken( client );
/* ist der User away? */ if( strchr( client->modes, 'a' ))
if( strchr( client->modes, 'a' )) strlcpy( client->away, DEFAULT_AWAY_MSG, sizeof( client->away )); strlcpy( client->away, DEFAULT_AWAY_MSG, sizeof( client->away ));
/* Verketten */ /* Verketten */
client->next = (POINTER *)My_Clients; client->next = (POINTER *)My_Clients;
@@ -336,43 +332,14 @@ Client_Destroy( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit )
} /* Client_Destroy */ } /* Client_Destroy */
GLOBAL void
Client_DestroyNow( CLIENT *Client )
{
/* Destroy client structure immediately. This function is only
* intended for the connection layer to remove client structures
* of connections that can't be established! */
CLIENT *last, *c;
assert( Client != NULL );
last = NULL;
c = My_Clients;
while( c )
{
if( c == Client )
{
/* Wir haben den Client gefunden: entfernen */
if( last ) last->next = c->next;
else My_Clients = (CLIENT *)c->next;
free( c );
break;
}
last = c;
c = (CLIENT *)c->next;
}
} /* Client_DestroyNow */
GLOBAL void GLOBAL void
Client_SetHostname( CLIENT *Client, char *Hostname ) Client_SetHostname( CLIENT *Client, char *Hostname )
{ {
/* Hostname eines Clients setzen */ /* Hostname eines Clients setzen */
assert( Client != NULL ); assert( Client != NULL );
assert( Hostname != NULL ); assert( Hostname != NULL );
strlcpy( Client->host, Hostname, sizeof( Client->host )); strlcpy( Client->host, Hostname, sizeof( Client->host ));
} /* Client_SetHostname */ } /* Client_SetHostname */
@@ -399,7 +366,7 @@ Client_SetUser( CLIENT *Client, char *User, bool Idented )
assert( Client != NULL ); assert( Client != NULL );
assert( User != NULL ); assert( User != NULL );
if( Idented ) strlcpy( Client->user, User, sizeof( Client->user )); if( Idented ) strlcpy( Client->user, User, sizeof( Client->user ));
else else
{ {
@@ -416,7 +383,7 @@ Client_SetInfo( CLIENT *Client, char *Info )
assert( Client != NULL ); assert( Client != NULL );
assert( Info != NULL ); assert( Info != NULL );
strlcpy( Client->info, Info, sizeof( Client->info )); strlcpy( Client->info, Info, sizeof( Client->info ));
} /* Client_SetInfo */ } /* Client_SetInfo */
@@ -452,7 +419,7 @@ Client_SetPassword( CLIENT *Client, char *Pwd )
assert( Client != NULL ); assert( Client != NULL );
assert( Pwd != NULL ); assert( Pwd != NULL );
strlcpy( Client->pwd, Pwd, sizeof( Client->pwd )); strlcpy( Client->pwd, Pwd, sizeof( Client->pwd ));
} /* Client_SetPassword */ } /* Client_SetPassword */
@@ -522,7 +489,7 @@ Client_ModeAdd( CLIENT *Client, char Mode )
*/ */
char x[2]; char x[2];
assert( Client != NULL ); assert( Client != NULL );
x[0] = Mode; x[1] = '\0'; x[0] = Mode; x[1] = '\0';
@@ -661,8 +628,7 @@ GLOBAL char *
Client_User( CLIENT *Client ) Client_User( CLIENT *Client )
{ {
assert( Client != NULL ); assert( Client != NULL );
if( Client->user[0] ) return Client->user; return Client->user[0] ? Client->user : "~";
else return "~";
} /* Client_User */ } /* Client_User */
@@ -734,11 +700,13 @@ GLOBAL CLIENT *
Client_NextHop( CLIENT *Client ) Client_NextHop( CLIENT *Client )
{ {
CLIENT *c; CLIENT *c;
assert( Client != NULL ); assert( Client != NULL );
c = Client; c = Client;
while( c->introducer && ( c->introducer != c ) && ( c->introducer != This_Server )) c = c->introducer; while( c->introducer && ( c->introducer != c ) && ( c->introducer != This_Server ))
c = c->introducer;
return c; return c;
} /* Client_NextHop */ } /* Client_NextHop */
@@ -750,7 +718,7 @@ Client_Mask( CLIENT *Client )
* Prefixe benoetigt wird. */ * Prefixe benoetigt wird. */
assert( Client != NULL ); assert( Client != NULL );
if( Client->type == CLIENT_SERVER ) return Client->id; if( Client->type == CLIENT_SERVER ) return Client->id;
snprintf( GetID_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user, Client->host ); snprintf( GetID_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user, Client->host );
@@ -795,12 +763,9 @@ Client_Away( CLIENT *Client )
GLOBAL bool GLOBAL bool
Client_CheckNick( CLIENT *Client, char *Nick ) Client_CheckNick( CLIENT *Client, char *Nick )
{ {
/* Nick ueberpruefen */
assert( Client != NULL ); assert( Client != NULL );
assert( Nick != NULL ); assert( Nick != NULL );
/* Nick ungueltig? */
if( ! Client_IsValidNick( Nick )) if( ! Client_IsValidNick( Nick ))
{ {
IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), Nick ); IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), Nick );
@@ -913,13 +878,12 @@ Client_MyServiceCount( void )
} /* Client_MyServiceCount */ } /* Client_MyServiceCount */
GLOBAL long GLOBAL unsigned long
Client_MyServerCount( void ) Client_MyServerCount( void )
{ {
CLIENT *c; CLIENT *c;
long cnt; unsigned long cnt = 0;
cnt = 0;
c = My_Clients; c = My_Clients;
while( c ) while( c )
{ {
@@ -930,13 +894,12 @@ Client_MyServerCount( void )
} /* Client_MyServerCount */ } /* Client_MyServerCount */
GLOBAL long GLOBAL unsigned long
Client_OperCount( void ) Client_OperCount( void )
{ {
CLIENT *c; CLIENT *c;
long cnt; unsigned long cnt = 0;
cnt = 0;
c = My_Clients; c = My_Clients;
while( c ) while( c )
{ {
@@ -947,19 +910,19 @@ Client_OperCount( void )
} /* Client_OperCount */ } /* Client_OperCount */
GLOBAL long GLOBAL unsigned long
Client_UnknownCount( void ) Client_UnknownCount( void )
{ {
CLIENT *c; CLIENT *c;
long cnt; unsigned long cnt = 0;
cnt = 0;
c = My_Clients; c = My_Clients;
while( c ) while( c )
{ {
if( c && ( c->type != CLIENT_USER ) && ( c->type != CLIENT_SERVICE ) && ( c->type != CLIENT_SERVER )) cnt++; if( c && ( c->type != CLIENT_USER ) && ( c->type != CLIENT_SERVICE ) && ( c->type != CLIENT_SERVER )) cnt++;
c = (CLIENT *)c->next; c = (CLIENT *)c->next;
} }
return cnt; return cnt;
} /* Client_UnknownCount */ } /* Client_UnknownCount */
@@ -979,16 +942,13 @@ Client_MyMaxUserCount( void )
GLOBAL bool GLOBAL bool
Client_IsValidNick( char *Nick ) Client_IsValidNick( const char *Nick )
{ {
/* Ist der Nick gueltig? */ const char *ptr;
static const char goodchars[] = ";0123456789-";
char *ptr, goodchars[20];
assert( Nick != NULL ); assert( Nick != NULL );
strcpy( goodchars, ";0123456789-" );
if( Nick[0] == '#' ) return false; if( Nick[0] == '#' ) return false;
if( strchr( goodchars, Nick[0] )) return false; if( strchr( goodchars, Nick[0] )) return false;
if( strlen( Nick ) >= CLIENT_NICK_LEN ) return false; if( strlen( Nick ) >= CLIENT_NICK_LEN ) return false;
@@ -996,11 +956,11 @@ Client_IsValidNick( char *Nick )
ptr = Nick; ptr = Nick;
while( *ptr ) while( *ptr )
{ {
if(( *ptr < 'A' ) && ( ! strchr( goodchars, *ptr ))) return false; if (( *ptr < 'A' ) && ( ! strchr( goodchars, *ptr ))) return false;
if(( *ptr > '}' ) && ( ! strchr( goodchars, *ptr ))) return false; if ( *ptr > '}' ) return false;
ptr++; ptr++;
} }
return true; return true;
} /* Client_IsValidNick */ } /* Client_IsValidNick */
@@ -1037,13 +997,12 @@ Client_StartTime(CLIENT *Client)
} /* Client_Uptime */ } /* Client_Uptime */
static long static unsigned long
Count( CLIENT_TYPE Type ) Count( CLIENT_TYPE Type )
{ {
CLIENT *c; CLIENT *c;
long cnt; unsigned long cnt = 0;
cnt = 0;
c = My_Clients; c = My_Clients;
while( c ) while( c )
{ {
@@ -1054,13 +1013,12 @@ Count( CLIENT_TYPE Type )
} /* Count */ } /* Count */
static long static unsigned long
MyCount( CLIENT_TYPE Type ) MyCount( CLIENT_TYPE Type )
{ {
CLIENT *c; CLIENT *c;
long cnt; unsigned long cnt = 0;
cnt = 0;
c = My_Clients; c = My_Clients;
while( c ) while( c )
{ {
@@ -1075,9 +1033,9 @@ static CLIENT *
New_Client_Struct( void ) New_Client_Struct( void )
{ {
/* Neue CLIENT-Struktur pre-initialisieren */ /* Neue CLIENT-Struktur pre-initialisieren */
CLIENT *c; CLIENT *c;
c = (CLIENT *)malloc( sizeof( CLIENT )); c = (CLIENT *)malloc( sizeof( CLIENT ));
if( ! c ) if( ! c )
{ {
@@ -1130,7 +1088,7 @@ Adjust_Counters( CLIENT *Client )
assert( Client != NULL ); assert( Client != NULL );
if( Client->type != CLIENT_USER ) return; if( Client->type != CLIENT_USER ) return;
if( Client->conn_id != NONE ) if( Client->conn_id != NONE )
{ {
/* Local connection */ /* Local connection */
@@ -1153,7 +1111,7 @@ Client_RegisterWhowas( CLIENT *Client )
{ {
int slot; int slot;
time_t now; time_t now;
assert( Client != NULL ); assert( Client != NULL );
now = time(NULL); now = time(NULL);
@@ -1167,7 +1125,7 @@ Client_RegisterWhowas( CLIENT *Client )
#ifdef DEBUG #ifdef DEBUG
Log( LOG_DEBUG, "Saving WHOWAS information to slot %d ...", slot ); Log( LOG_DEBUG, "Saving WHOWAS information to slot %d ...", slot );
#endif #endif
My_Whowas[slot].time = now; My_Whowas[slot].time = now;
strlcpy( My_Whowas[slot].id, Client_ID( Client ), strlcpy( My_Whowas[slot].id, Client_ID( Client ),
sizeof( My_Whowas[slot].id )); sizeof( My_Whowas[slot].id ));
@@ -1179,7 +1137,7 @@ Client_RegisterWhowas( CLIENT *Client )
sizeof( My_Whowas[slot].info )); sizeof( My_Whowas[slot].info ));
strlcpy( My_Whowas[slot].server, Client_ID( Client_Introducer( Client )), strlcpy( My_Whowas[slot].server, Client_ID( Client_Introducer( Client )),
sizeof( My_Whowas[slot].server )); sizeof( My_Whowas[slot].server ));
Last_Whowas = slot; Last_Whowas = slot;
} /* Client_RegisterWhowas */ } /* Client_RegisterWhowas */

View File

@@ -8,7 +8,7 @@
* (at your option) any later version. * (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information. * Please read the file COPYING, README and AUTHORS for more information.
* *
* $Id: client.h,v 1.42 2006/04/23 10:37:27 fw Exp $ * $Id: client.h,v 1.42.2.3 2007/04/03 22:08:52 fw Exp $
* *
* Client management (header) * Client management (header)
*/ */
@@ -23,10 +23,9 @@
#define CLIENT_GOTNICK 4 /* client did send NICK */ #define CLIENT_GOTNICK 4 /* client did send NICK */
#define CLIENT_GOTUSER 8 /* client did send USER */ #define CLIENT_GOTUSER 8 /* client did send USER */
#define CLIENT_USER 16 /* client is an IRC user */ #define CLIENT_USER 16 /* client is an IRC user */
#define CLIENT_UNKNOWNSERVER 32 /* unregistered server connection */ #define CLIENT_SERVER 32 /* client is a server */
#define CLIENT_GOTPASSSERVER 64 /* client did send PASS in "server style" */ #define CLIENT_SERVICE 64 /* client is a service */
#define CLIENT_SERVER 128 /* client is a server */ #define CLIENT_UNKNOWNSERVER 128 /* unregistered server connection */
#define CLIENT_SERVICE 256 /* client is a service */
#define CLIENT_TYPE int #define CLIENT_TYPE int
@@ -81,9 +80,6 @@ GLOBAL CLIENT *Client_NewRemoteServer PARAMS(( CLIENT *Introducer, char *Hostnam
GLOBAL CLIENT *Client_NewRemoteUser PARAMS(( CLIENT *Introducer, char *Nick, int Hops, char *User, char *Hostname, int Token, char *Modes, char *Info, bool Idented )); GLOBAL CLIENT *Client_NewRemoteUser PARAMS(( CLIENT *Introducer, char *Nick, int Hops, char *User, char *Hostname, int Token, char *Modes, char *Info, bool Idented ));
GLOBAL void Client_Destroy PARAMS(( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit )); GLOBAL void Client_Destroy PARAMS(( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit ));
#ifdef CONN_MODULE
GLOBAL void Client_DestroyNow PARAMS(( CLIENT *Client ));
#endif
GLOBAL CLIENT *Client_ThisServer PARAMS(( void )); GLOBAL CLIENT *Client_ThisServer PARAMS(( void ));
@@ -138,15 +134,15 @@ GLOBAL bool Client_CheckID PARAMS(( CLIENT *Client, char *ID ));
GLOBAL long Client_UserCount PARAMS(( void )); GLOBAL long Client_UserCount PARAMS(( void ));
GLOBAL long Client_ServiceCount PARAMS(( void )); GLOBAL long Client_ServiceCount PARAMS(( void ));
GLOBAL long Client_ServerCount PARAMS(( void )); GLOBAL long Client_ServerCount PARAMS(( void ));
GLOBAL long Client_OperCount PARAMS(( void )); GLOBAL unsigned long Client_OperCount PARAMS(( void ));
GLOBAL long Client_UnknownCount PARAMS(( void )); GLOBAL unsigned long Client_UnknownCount PARAMS(( void ));
GLOBAL long Client_MyUserCount PARAMS(( void )); GLOBAL long Client_MyUserCount PARAMS(( void ));
GLOBAL long Client_MyServiceCount PARAMS(( void )); GLOBAL long Client_MyServiceCount PARAMS(( void ));
GLOBAL long Client_MyServerCount PARAMS(( void )); GLOBAL unsigned long Client_MyServerCount PARAMS(( void ));
GLOBAL long Client_MaxUserCount PARAMS(( void )); GLOBAL long Client_MaxUserCount PARAMS(( void ));
GLOBAL long Client_MyMaxUserCount PARAMS(( void )); GLOBAL long Client_MyMaxUserCount PARAMS(( void ));
GLOBAL bool Client_IsValidNick PARAMS(( char *Nick )); GLOBAL bool Client_IsValidNick PARAMS(( const char *Nick ));
GLOBAL WHOWAS *Client_GetWhowas PARAMS(( void )); GLOBAL WHOWAS *Client_GetWhowas PARAMS(( void ));
GLOBAL int Client_GetLastWhowasIndex PARAMS(( void )); GLOBAL int Client_GetLastWhowasIndex PARAMS(( void ));

View File

@@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: conf.c,v 1.92 2006/07/23 16:42:45 alex Exp $"; static char UNUSED id[] = "$Id: conf.c,v 1.92.2.4 2007/04/03 22:08:52 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -146,6 +146,9 @@ Conf_Rehash( void )
Set_Defaults( false ); Set_Defaults( false );
Read_Config( ); Read_Config( );
Validate_Config(false, true); Validate_Config(false, true);
/* Update CLIENT structure of local server */
Client_SetInfo(Client_ThisServer(), Conf_ServerInfo);
} /* Config_Rehash */ } /* Config_Rehash */
@@ -199,15 +202,16 @@ Conf_Test( void )
printf( " PingTimeout = %d\n", Conf_PingTimeout ); printf( " PingTimeout = %d\n", Conf_PingTimeout );
printf( " PongTimeout = %d\n", Conf_PongTimeout ); printf( " PongTimeout = %d\n", Conf_PongTimeout );
printf( " ConnectRetry = %d\n", Conf_ConnectRetry ); printf( " ConnectRetry = %d\n", Conf_ConnectRetry );
printf( " OperCanUseMode = %s\n", Conf_OperCanMode == true? "yes" : "no" ); printf( " OperCanUseMode = %s\n", Conf_OperCanMode == true ? "yes" : "no" );
printf( " OperServerMode = %s\n", Conf_OperServerMode == true? "yes" : "no" ); printf( " OperServerMode = %s\n", Conf_OperServerMode == true? "yes" : "no" );
printf( " PredefChannelsOnly = %s\n", Conf_PredefChannelsOnly == true ? "yes" : "no" );
printf( " MaxConnections = %ld\n", Conf_MaxConnections>0 ? Conf_MaxConnections : -1); printf( " MaxConnections = %ld\n", Conf_MaxConnections>0 ? Conf_MaxConnections : -1);
printf( " MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP>0 ? Conf_MaxConnectionsIP : -1); printf( " MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP>0 ? Conf_MaxConnectionsIP : -1);
printf( " MaxJoins = %d\n\n", Conf_MaxJoins>0 ? Conf_MaxJoins : -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; if( ! Conf_Oper[i].name[0] ) continue;
/* Valid "Operator" section */ /* Valid "Operator" section */
puts( "[OPERATOR]" ); puts( "[OPERATOR]" );
printf( " Name = %s\n", Conf_Oper[i].name ); printf( " Name = %s\n", Conf_Oper[i].name );
@@ -218,7 +222,7 @@ Conf_Test( void )
for( i = 0; i < MAX_SERVERS; i++ ) { for( i = 0; i < MAX_SERVERS; i++ ) {
if( ! Conf_Server[i].name[0] ) continue; if( ! Conf_Server[i].name[0] ) continue;
/* Valid "Server" section */ /* Valid "Server" section */
puts( "[SERVER]" ); puts( "[SERVER]" );
printf( " Name = %s\n", Conf_Server[i].name ); printf( " Name = %s\n", Conf_Server[i].name );
@@ -231,16 +235,18 @@ Conf_Test( void )
for( i = 0; i < Conf_Channel_Count; i++ ) { for( i = 0; i < Conf_Channel_Count; i++ ) {
if( ! Conf_Channel[i].name[0] ) continue; if( ! Conf_Channel[i].name[0] ) continue;
/* Valid "Channel" section */ /* Valid "Channel" section */
puts( "[CHANNEL]" ); puts( "[CHANNEL]" );
printf( " Name = %s\n", Conf_Channel[i].name ); printf( " Name = %s\n", Conf_Channel[i].name );
printf( " Modes = %s\n", Conf_Channel[i].modes ); printf( " Modes = %s\n", Conf_Channel[i].modes );
printf( " Key = %s\n", Conf_Channel[i].key );
printf( " MaxUsers = %lu\n", Conf_Channel[i].maxusers );
topic = (char*)array_start(&Conf_Channel[i].topic); topic = (char*)array_start(&Conf_Channel[i].topic);
printf( " Topic = %s\n\n", topic ? topic : ""); printf( " Topic = %s\n\n", topic ? topic : "");
} }
return 0; return 0;
} /* Conf_Test */ } /* Conf_Test */
@@ -268,14 +274,14 @@ Conf_UnsetServer( CONN_ID Idx )
Init_Server_Struct( &Conf_Server[i] ); Init_Server_Struct( &Conf_Server[i] );
} else { } else {
/* Set time for next connect attempt */ /* Set time for next connect attempt */
t = time(NULL); t = time(NULL);
if (Conf_Server[i].lasttry < t - Conf_ConnectRetry) { if (Conf_Server[i].lasttry < t - Conf_ConnectRetry) {
/* The connection has been "long", so we don't /* The connection has been "long", so we don't
* require the next attempt to be delayed. */ * require the next attempt to be delayed. */
Conf_Server[i].lasttry = Conf_Server[i].lasttry =
t - Conf_ConnectRetry + RECONNECT_DELAY; t - Conf_ConnectRetry + RECONNECT_DELAY;
} else } else
Conf_Server[i].lasttry = t; Conf_Server[i].lasttry = t;
} }
} }
} /* Conf_UnsetServer */ } /* Conf_UnsetServer */
@@ -297,9 +303,9 @@ GLOBAL int
Conf_GetServer( CONN_ID Idx ) Conf_GetServer( CONN_ID Idx )
{ {
/* Get index of server in configuration structure */ /* Get index of server in configuration structure */
int i = 0; int i = 0;
assert( Idx > NONE ); assert( Idx > NONE );
for( i = 0; i < MAX_SERVERS; i++ ) { for( i = 0; i < MAX_SERVERS; i++ ) {
@@ -377,7 +383,7 @@ Conf_AddServer( char *Name, UINT16 Port, char *Host, char *MyPwd, char *PeerPwd
strlcpy( Conf_Server[i].pwd_in, PeerPwd, sizeof( Conf_Server[i].pwd_in )); strlcpy( Conf_Server[i].pwd_in, PeerPwd, sizeof( Conf_Server[i].pwd_in ));
Conf_Server[i].port = Port; Conf_Server[i].port = Port;
Conf_Server[i].flags = CONF_SFLAG_ONCE; Conf_Server[i].flags = CONF_SFLAG_ONCE;
return true; return true;
} /* Conf_AddServer */ } /* Conf_AddServer */
@@ -409,7 +415,7 @@ Set_Defaults( bool InitServers )
strcpy( Conf_ListenAddress, "" ); strcpy( Conf_ListenAddress, "" );
Conf_UID = Conf_GID = 0; Conf_UID = Conf_GID = 0;
Conf_PingTimeout = 120; Conf_PingTimeout = 120;
Conf_PongTimeout = 20; Conf_PongTimeout = 20;
@@ -419,8 +425,9 @@ Set_Defaults( bool InitServers )
Conf_Channel_Count = 0; Conf_Channel_Count = 0;
Conf_OperCanMode = false; Conf_OperCanMode = false;
Conf_PredefChannelsOnly = false;
Conf_OperServerMode = false; Conf_OperServerMode = false;
Conf_MaxConnections = -1; Conf_MaxConnections = -1;
Conf_MaxConnectionsIP = 5; Conf_MaxConnectionsIP = 5;
Conf_MaxJoins = 10; Conf_MaxJoins = 10;
@@ -550,6 +557,8 @@ Read_Config( void )
/* Initialize new channel structure */ /* Initialize new channel structure */
strcpy( Conf_Channel[Conf_Channel_Count].name, "" ); strcpy( Conf_Channel[Conf_Channel_Count].name, "" );
strcpy( Conf_Channel[Conf_Channel_Count].modes, "" ); strcpy( Conf_Channel[Conf_Channel_Count].modes, "" );
strcpy( Conf_Channel[Conf_Channel_Count].key, "" );
Conf_Channel[Conf_Channel_Count].maxusers = 0;
array_free(&Conf_Channel[Conf_Channel_Count].topic); array_free(&Conf_Channel[Conf_Channel_Count].topic);
Conf_Channel_Count++; Conf_Channel_Count++;
} }
@@ -750,6 +759,11 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
} }
return; return;
} }
if( strcasecmp( Var, "PredefChannelsOnly" ) == 0 ) {
/* Should we only allow pre-defined-channels? (i.e. users cannot create their own channels) */
Conf_PredefChannelsOnly = Check_ArgIsTrue( Arg );
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? */ /* Are IRC operators allowed to use MODE in channels they aren't Op in? */
Conf_OperCanMode = Check_ArgIsTrue( Arg ); Conf_OperCanMode = Check_ArgIsTrue( Arg );
@@ -912,6 +926,21 @@ Handle_SERVER( int Line, char *Var, char *Arg )
} /* Handle_SERVER */ } /* Handle_SERVER */
static bool
Handle_Channelname(size_t chancount, const char *name)
{
size_t size = sizeof( Conf_Channel[chancount].name );
char *dest = Conf_Channel[chancount].name;
if (*name && *name != '#') {
*dest = '#';
--size;
++dest;
}
return size > strlcpy(dest, name, size);
}
static void static void
Handle_CHANNEL( int Line, char *Var, char *Arg ) Handle_CHANNEL( int Line, char *Var, char *Arg )
{ {
@@ -925,9 +954,7 @@ Handle_CHANNEL( int Line, char *Var, char *Arg )
chancount = Conf_Channel_Count - 1; chancount = Conf_Channel_Count - 1;
if( strcasecmp( Var, "Name" ) == 0 ) { if( strcasecmp( Var, "Name" ) == 0 ) {
/* Name of the channel */ if (!Handle_Channelname(chancount, Arg))
len = strlcpy( Conf_Channel[chancount].name, Arg, sizeof( Conf_Channel[chancount].name ));
if (len >= sizeof( Conf_Channel[chancount].name ))
Config_Error_TooLong( Line, Var ); Config_Error_TooLong( Line, Var );
return; return;
} }
@@ -945,6 +972,22 @@ Handle_CHANNEL( int Line, char *Var, char *Arg )
return; return;
} }
if( strcasecmp( Var, "Key" ) == 0 ) {
/* Initial Channel Key (mode k) */
len = strlcpy(Conf_Channel[chancount].key, Arg, sizeof(Conf_Channel[chancount].key));
if (len >= sizeof( Conf_Channel[chancount].key ))
Config_Error_TooLong(Line, Var);
return;
}
if( strcasecmp( Var, "MaxUsers" ) == 0 ) {
/* maximum user limit, mode l */
Conf_Channel[chancount].maxusers = (unsigned long) atol(Arg);
if (Conf_Channel[chancount].maxusers == 0)
Config_Error_NaN(Line, Var);
return;
}
Config_Error( LOG_ERR, "%s, line %d (section \"Channel\"): Unknown variable \"%s\"!", Config_Error( LOG_ERR, "%s, line %d (section \"Channel\"): Unknown variable \"%s\"!",
NGIRCd_ConfFile, Line, Var ); NGIRCd_ConfFile, Line, Var );
} /* Handle_CHANNEL */ } /* Handle_CHANNEL */
@@ -965,7 +1008,7 @@ Validate_Config(bool Configtest, bool Rehash)
do { do {
if (*ptr >= 'a' && *ptr <= 'z') continue; if (*ptr >= 'a' && *ptr <= 'z') continue;
if (*ptr >= 'A' && *ptr <= 'Z') continue; if (*ptr >= 'A' && *ptr <= 'Z') continue;
if (*ptr >= '1' && *ptr <= '0') continue; if (*ptr >= '0' && *ptr <= '9') continue;
if (ptr > Conf_ServerName) { if (ptr > Conf_ServerName) {
if (*ptr == '.' || *ptr == '-') if (*ptr == '.' || *ptr == '-')
continue; continue;

View File

@@ -8,7 +8,7 @@
* (at your option) any later version. * (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information. * Please read the file COPYING, README and AUTHORS for more information.
* *
* $Id: conf.h,v 1.40 2006/05/10 21:24:01 alex Exp $ * $Id: conf.h,v 1.40.2.2 2007/04/03 22:08:52 fw Exp $
* *
* Configuration management (header) * Configuration management (header)
*/ */
@@ -49,6 +49,8 @@ typedef struct _Conf_Channel
{ {
char name[CHANNEL_NAME_LEN]; /* Name of the channel */ char name[CHANNEL_NAME_LEN]; /* Name of the channel */
char modes[CHANNEL_MODE_LEN]; /* Initial channel modes */ char modes[CHANNEL_MODE_LEN]; /* Initial channel modes */
char key[CLIENT_PASS_LEN]; /* Channel key ("password", mode "k" ) */
unsigned long maxusers; /* maximum usercount for this channel, mode "l" */
array topic; /* Initial topic */ array topic; /* Initial topic */
} CONF_CHANNEL; } CONF_CHANNEL;
@@ -110,6 +112,8 @@ GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS];
/* Pre-defined channels */ /* Pre-defined channels */
GLOBAL CONF_CHANNEL Conf_Channel[MAX_DEFCHANNELS]; GLOBAL CONF_CHANNEL Conf_Channel[MAX_DEFCHANNELS];
GLOBAL unsigned int Conf_Channel_Count; GLOBAL unsigned int Conf_Channel_Count;
/* Pre-defined channels only */
GLOBAL bool Conf_PredefChannelsOnly;
/* Are IRC operators allowed to always use MODE? */ /* Are IRC operators allowed to always use MODE? */
GLOBAL bool Conf_OperCanMode; GLOBAL bool Conf_OperCanMode;

View File

@@ -8,7 +8,7 @@
* (at your option) any later version. * (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information. * Please read the file COPYING, README and AUTHORS for more information.
* *
* $Id: conn-func.h,v 1.5 2006/05/10 21:24:01 alex Exp $ * $Id: conn-func.h,v 1.5.2.1 2007/04/03 22:08:52 fw Exp $
* *
* Connection management: Global functions (header) * Connection management: Global functions (header)
*/ */
@@ -52,9 +52,9 @@ GLOBAL UINT16 Conn_Options PARAMS(( CONN_ID Idx ));
GLOBAL void Conn_ResetWCounter PARAMS(( void )); GLOBAL void Conn_ResetWCounter PARAMS(( void ));
GLOBAL long Conn_WCounter PARAMS(( void )); GLOBAL long Conn_WCounter PARAMS(( void ));
#define Conn_OPTION_ADD( x, opt ) ( (x)->options |= opt ) #define Conn_OPTION_ADD( x, opt ) ( (x)->options |= (opt) )
#define Conn_OPTION_DEL( x, opt ) ( (x)->options &= ~opt ) #define Conn_OPTION_DEL( x, opt ) ( (x)->options &= ~(opt) )
#define Conn_OPTION_ISSET( x, opt ) ( (x)->options & opt ) #define Conn_OPTION_ISSET( x, opt ) ( ((x)->options & (opt)) != 0)
#endif #endif

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2006 Alexander Barton (alex@barton.de) * Copyright (c)2001-2007 Alexander Barton (alex@barton.de)
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
/* enable more zlib related debug messages: */ /* enable more zlib related debug messages: */
/* #define DEBUG_ZLIB */ /* #define DEBUG_ZLIB */
static char UNUSED id[] = "$Id: conn-zip.c,v 1.11 2006/07/23 15:19:20 alex Exp $"; static char UNUSED id[] = "$Id: conn-zip.c,v 1.11.2.1 2007/05/18 22:11:19 alex Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -82,47 +82,63 @@ Zip_InitConn( CONN_ID Idx )
} /* Zip_InitConn */ } /* Zip_InitConn */
/**
* Copy data to the compression buffer of a connection. We do collect
* some data there until it's full so that we can achieve better
* compression ratios.
* If the (pre-)compression buffer is full, we try to flush it ("actually
* compress some data") and to add the new (uncompressed) data afterwards.
* @param Idx Connection handle.
* @param Data Pointer to the data.
* @param Len Length of the data to add.
* @return true on success, false otherwise. */
GLOBAL bool GLOBAL bool
Zip_Buffer( CONN_ID Idx, char *Data, size_t Len ) Zip_Buffer( CONN_ID Idx, char *Data, size_t Len )
{ {
/* Daten zum Komprimieren im "Kompressions-Puffer" sammeln. size_t buflen;
* Es wird true bei Erfolg, sonst false geliefert. */
assert( Idx > NONE ); assert( Idx > NONE );
assert( Data != NULL ); assert( Data != NULL );
assert( Len > 0 ); assert( Len > 0 );
assert( Len <= ZWRITEBUFFER_LEN );
if (Len > ZWRITEBUFFER_LEN) buflen = array_bytes(&My_Connections[Idx].zip.wbuf);
return false; if (buflen + Len >= WRITEBUFFER_SLINK_LEN) {
if ( array_bytes( &My_Connections[Idx].zip.wbuf ) >= ZWRITEBUFFER_LEN ) {
/* compression buffer is full, flush */ /* compression buffer is full, flush */
if( ! Zip_Flush( Idx )) return false; if( ! Zip_Flush( Idx )) return false;
} }
/* check again; if zip buf is still too large do not append data:
* otherwise the zip wbuf would grow too large */
buflen = array_bytes(&My_Connections[Idx].zip.wbuf);
if (buflen + Len >= WRITEBUFFER_SLINK_LEN)
return false;
return array_catb(&My_Connections[Idx].zip.wbuf, Data, Len); return array_catb(&My_Connections[Idx].zip.wbuf, Data, Len);
} /* Zip_Buffer */ } /* Zip_Buffer */
/**
* Compress data in ZIP buffer and move result to the write buffer of
* the connection.
* @param Idx Connection handle.
* @retrun true on success, false otherwise.
*/
GLOBAL bool GLOBAL bool
Zip_Flush( CONN_ID Idx ) Zip_Flush( CONN_ID Idx )
{ {
/* Daten komprimieren und in Schreibpuffer kopieren.
* Es wird true bei Erfolg, sonst false geliefert. */
int result; int result;
unsigned char zipbuf[WRITEBUFFER_LEN]; unsigned char zipbuf[WRITEBUFFER_SLINK_LEN];
int zipbuf_used = 0; int zipbuf_used = 0;
z_stream *out; z_stream *out;
out = &My_Connections[Idx].zip.out; out = &My_Connections[Idx].zip.out;
out->next_in = array_start(&My_Connections[Idx].zip.wbuf);
if (!out->next_in)
return false;
out->avail_in = (uInt)array_bytes(&My_Connections[Idx].zip.wbuf); out->avail_in = (uInt)array_bytes(&My_Connections[Idx].zip.wbuf);
if (!out->avail_in)
return true; /* nothing to do. */
out->next_in = array_start(&My_Connections[Idx].zip.wbuf);
assert(out->next_in != NULL);
out->next_out = zipbuf; out->next_out = zipbuf;
out->avail_out = (uInt)sizeof zipbuf; out->avail_out = (uInt)sizeof zipbuf;
@@ -139,14 +155,26 @@ Zip_Flush( CONN_ID Idx )
return false; return false;
} }
assert(out->avail_out <= WRITEBUFFER_LEN); if (out->avail_out <= 0) {
zipbuf_used = WRITEBUFFER_LEN - out->avail_out; /* Not all data was compressed, because data became
* bigger while compressing it. */
Log (LOG_ALERT, "Compression error: buffer overvlow!?");
Conn_Close(Idx, "Compression error!", NULL, false);
return false;
}
assert(out->avail_out <= WRITEBUFFER_SLINK_LEN);
zipbuf_used = WRITEBUFFER_SLINK_LEN - out->avail_out;
#ifdef DEBUG_ZIP #ifdef DEBUG_ZIP
Log(LOG_DEBUG, "zipbuf_used: %d", zipbuf_used); Log(LOG_DEBUG, "zipbuf_used: %d", zipbuf_used);
#endif #endif
if (!array_catb(&My_Connections[Idx].wbuf, if (!array_catb(&My_Connections[Idx].wbuf,
(char *)zipbuf, (size_t) zipbuf_used)) (char *)zipbuf, (size_t) zipbuf_used)) {
Log (LOG_ALERT, "Compression error: can't copy data!?");
Conn_Close(Idx, "Compression error!", NULL, false);
return false; return false;
}
My_Connections[Idx].bytes_out += zipbuf_used; My_Connections[Idx].bytes_out += zipbuf_used;
My_Connections[Idx].zip.bytes_out += array_bytes(&My_Connections[Idx].zip.wbuf); My_Connections[Idx].zip.bytes_out += array_bytes(&My_Connections[Idx].zip.wbuf);
@@ -178,10 +206,9 @@ Unzip_Buffer( CONN_ID Idx )
return true; return true;
in = &My_Connections[Idx].zip.in; in = &My_Connections[Idx].zip.in;
in->next_in = array_start(&My_Connections[Idx].zip.rbuf); in->next_in = array_start(&My_Connections[Idx].zip.rbuf);
if (!in->next_in) assert(in->next_in != NULL);
return false;
in->avail_in = z_rdatalen; in->avail_in = z_rdatalen;
in->next_out = unzipbuf; in->next_out = unzipbuf;

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2005 Alexander Barton <alex@barton.de> * Copyright (c)2001-2007 Alexander Barton (alex@barton.de)
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -17,7 +17,7 @@
#include "portab.h" #include "portab.h"
#include "io.h" #include "io.h"
static char UNUSED id[] = "$Id: conn.c,v 1.198 2006/07/23 23:05:20 alex Exp $"; static char UNUSED id[] = "$Id: conn.c,v 1.198.2.6 2007/05/18 22:11:19 alex Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -83,6 +83,7 @@ static char UNUSED id[] = "$Id: conn.c,v 1.198 2006/07/23 23:05:20 alex Exp $";
static bool Handle_Write PARAMS(( CONN_ID Idx )); static bool Handle_Write PARAMS(( CONN_ID Idx ));
static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
static int New_Connection PARAMS(( int Sock )); static int New_Connection PARAMS(( int Sock ));
static CONN_ID Socket2Index PARAMS(( int Sock )); static CONN_ID Socket2Index PARAMS(( int Sock ));
static void Read_Request PARAMS(( CONN_ID Idx )); static void Read_Request PARAMS(( CONN_ID Idx ));
@@ -123,7 +124,6 @@ cb_connserver(int sock, UNUSED short what)
{ {
int res, err; int res, err;
socklen_t sock_len; socklen_t sock_len;
CLIENT *c;
CONN_ID idx = Socket2Index( sock ); CONN_ID idx = Socket2Index( sock );
if (idx <= NONE) { if (idx <= NONE) {
LogDebug("cb_connserver wants to write on unknown socket?!"); LogDebug("cb_connserver wants to write on unknown socket?!");
@@ -150,14 +150,7 @@ cb_connserver(int sock, UNUSED short what)
Conf_Server[Conf_GetServer(idx)].port, Conf_Server[Conf_GetServer(idx)].port,
idx, strerror(err)); idx, strerror(err));
/* Clean up the CLIENT structure (to avoid silly log Conn_Close(idx, "Can't connect!", NULL, false);
* 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; return;
} }
@@ -384,7 +377,7 @@ NewListener( const UINT16 Port )
if( ! Init_Socket( sock )) return -1; if( ! Init_Socket( sock )) return -1;
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 )); Log( LOG_CRIT, "Can't bind socket (port %d) : %s!", Port, strerror( errno ));
close( sock ); close( sock );
return -1; return -1;
} }
@@ -615,51 +608,74 @@ va_dcl
} /* Conn_WriteStr */ } /* Conn_WriteStr */
GLOBAL bool /**
* Append Data to the outbound write buffer of a connection.
* @param Idx Index of the connection.
* @param Data pointer to the data.
* @param Len length of Data.
* @return true on success, false otherwise.
*/
static bool
Conn_Write( CONN_ID Idx, char *Data, size_t Len ) Conn_Write( CONN_ID Idx, char *Data, size_t Len )
{ {
/* Daten in Socket schreiben. Bei "fatalen" Fehlern wird CLIENT *c;
* der Client disconnectiert und false geliefert. */ size_t writebuf_limit = WRITEBUFFER_LEN;
assert( Idx > NONE ); assert( Idx > NONE );
assert( Data != NULL ); assert( Data != NULL );
assert( Len > 0 ); assert( Len > 0 );
/* Ist der entsprechende Socket ueberhaupt noch offen? In einem c = Conn_GetClient(Idx);
* "Handler-Durchlauf" kann es passieren, dass dem nicht mehr so assert( c != NULL);
* ist, wenn einer von mehreren Conn_Write()'s fehlgeschlagen ist.
* In diesem Fall wird hier einfach ein Fehler geliefert. */ /* Servers do get special write buffer limits, so they can generate
* all the messages that are required while peering. */
if (Client_Type(c) == CLIENT_SERVER)
writebuf_limit = WRITEBUFFER_SLINK_LEN;
/* Is the socket still open? A previous call to Conn_Write()
* may have closed the connection due to a fatal error.
* In this case it is sufficient to return an error, as well. */
if( My_Connections[Idx].sock <= NONE ) { if( My_Connections[Idx].sock <= NONE ) {
LogDebug("Skipped write on closed socket (connection %d).", Idx ); LogDebug("Skipped write on closed socket (connection %d).", Idx);
return false; return false;
} }
/* Pruefen, ob im Schreibpuffer genuegend Platz ist. Ziel ist es,
* moeglichts viel im Puffer zu haben und _nicht_ gleich alles auf den
* Socket zu schreiben (u.a. wg. Komprimierung). */
if( array_bytes(&My_Connections[Idx].wbuf) >= WRITEBUFFER_LEN) {
/* Der Puffer ist dummerweise voll. Jetzt versuchen, den Puffer
* zu schreiben, wenn das nicht klappt, haben wir ein Problem ... */
if( ! Handle_Write( Idx )) return false;
/* check again: if our writebuf is twice als large as the initial limit: Kill connection */
if( array_bytes(&My_Connections[Idx].wbuf) >= (WRITEBUFFER_LEN*2)) {
Log( LOG_NOTICE, "Write buffer overflow (connection %d)!", Idx );
Conn_Close( Idx, "Write buffer overflow!", NULL, false );
return false;
}
}
#ifdef ZLIB #ifdef ZLIB
if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) { if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) {
/* Daten komprimieren und in Puffer kopieren */ /* Compressed link:
if( ! Zip_Buffer( Idx, Data, Len )) return false; * Zip_Buffer() does all the dirty work for us: it flushes
* the (pre-)compression buffers if required and handles
* all error conditions. */
if (!Zip_Buffer(Idx, Data, Len))
return false;
} }
else else
#endif #endif
{ {
/* Daten in Puffer kopieren */ /* Uncompressed link:
if (!array_catb( &My_Connections[Idx].wbuf, Data, Len )) * Check if outbound buffer has enough space for the data. */
if (array_bytes(&My_Connections[Idx].wbuf) + Len >=
writebuf_limit) {
/* Buffer is full, flush it. Handle_Write deals with
* low-level errors, if any. */
if (!Handle_Write(Idx))
return false;
}
/* When the write buffer is still too big after flushing it,
* the connection will be killed. */
if (array_bytes(&My_Connections[Idx].wbuf) + Len >=
writebuf_limit) {
Log(LOG_NOTICE,
"Write buffer overflow (connection %d, size %lu byte)!",
Idx,
(unsigned long)array_bytes(&My_Connections[Idx].wbuf));
Conn_Close(Idx, "Write buffer overflow!", NULL, false);
return false;
}
/* Copy data to write buffer */
if (!array_catb(&My_Connections[Idx].wbuf, Data, Len))
return false; return false;
My_Connections[Idx].bytes_out += Len; My_Connections[Idx].bytes_out += Len;
@@ -700,7 +716,7 @@ Conn_Close( CONN_ID Idx, char *LogMsg, char *FwdMsg, bool InformClient )
/* Mark link as "closing" */ /* Mark link as "closing" */
Conn_OPTION_ADD( &My_Connections[Idx], CONN_ISCLOSING ); Conn_OPTION_ADD( &My_Connections[Idx], CONN_ISCLOSING );
if (LogMsg) if (LogMsg)
txt = LogMsg; txt = LogMsg;
else else
@@ -728,7 +744,6 @@ Conn_Close( CONN_ID Idx, char *LogMsg, char *FwdMsg, bool InformClient )
(double)My_Connections[Idx].bytes_out / 1024); (double)My_Connections[Idx].bytes_out / 1024);
} }
#endif #endif
/* Send ERROR to client (see RFC!) */ /* Send ERROR to client (see RFC!) */
if (FwdMsg) if (FwdMsg)
Conn_WriteStr(Idx, "ERROR :%s", FwdMsg); Conn_WriteStr(Idx, "ERROR :%s", FwdMsg);
@@ -872,24 +887,23 @@ Handle_Write( CONN_ID Idx )
wdatalen = array_bytes(&My_Connections[Idx].wbuf ); wdatalen = array_bytes(&My_Connections[Idx].wbuf );
#ifdef ZLIB #ifdef ZLIB
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 buffer?
* -> flush compression buffer! */
if (wdatalen == 0)
Zip_Flush(Idx);
#else
if (wdatalen == 0) { if (wdatalen == 0) {
io_event_del(My_Connections[Idx].sock, IO_WANTWRITE ); /* Write buffer is empty, so we try to flush the compression
return true; * buffer and get some data to work with from there :-) */
if (!Zip_Flush(Idx))
return false;
/* Now the write buffer most probably has changed: */
wdatalen = array_bytes(&My_Connections[Idx].wbuf);
} }
#endif #endif
/* Zip_Flush() may have changed the write buffer ... */ if (wdatalen == 0) {
wdatalen = array_bytes(&My_Connections[Idx].wbuf); /* Still no data, fine. */
io_event_del(My_Connections[Idx].sock, IO_WANTWRITE );
return true;
}
LogDebug LogDebug
("Handle_Write() called for connection %d, %ld bytes pending ...", ("Handle_Write() called for connection %d, %ld bytes pending ...",
Idx, wdatalen); Idx, wdatalen);
@@ -995,11 +1009,19 @@ New_Connection( int Sock )
Init_Conn_Struct(Pool_Size++); Init_Conn_Struct(Pool_Size++);
} }
/* register callback */
if (!io_event_create( new_sock, IO_WANTREAD, cb_clientserver)) {
Log(LOG_ALERT, "Can't accept connection: io_event_create failed!");
Simple_Message(new_sock, "ERROR :Internal error");
close(new_sock);
return -1;
}
c = Client_NewLocal( new_sock, inet_ntoa( new_addr.sin_addr ), CLIENT_UNKNOWN, false ); c = Client_NewLocal( new_sock, inet_ntoa( new_addr.sin_addr ), CLIENT_UNKNOWN, false );
if( ! c ) { if( ! c ) {
Log( LOG_ALERT, "Can't accept connection: can't create client structure!" ); Log(LOG_ALERT, "Can't accept connection: can't create client structure!");
Simple_Message( new_sock, "ERROR :Internal error" ); Simple_Message(new_sock, "ERROR :Internal error");
close( new_sock ); io_close(new_sock);
return -1; return -1;
} }
@@ -1008,13 +1030,6 @@ New_Connection( int Sock )
My_Connections[new_sock].addr = new_addr; My_Connections[new_sock].addr = new_addr;
My_Connections[new_sock].client = c; My_Connections[new_sock].client = c;
/* register callback */
if (!io_event_create( new_sock, IO_WANTREAD, cb_clientserver)) {
Simple_Message( new_sock, "ERROR :Internal error" );
Conn_Close( new_sock, "io_event_create() failed", NULL, false );
return -1;
}
Log( LOG_INFO, "Accepted connection %d from %s:%d on socket %d.", new_sock, 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 ); inet_ntoa( new_addr.sin_addr ), ntohs( new_addr.sin_port), Sock );
@@ -1050,47 +1065,52 @@ Socket2Index( int Sock )
} /* Socket2Index */ } /* Socket2Index */
/**
* Read data from the network to the read buffer. If an error occures,
* the socket of this connection will be shut down.
*/
static void static void
Read_Request( CONN_ID Idx ) Read_Request( CONN_ID Idx )
{ {
/* Daten von Socket einlesen und entsprechend behandeln.
* Tritt ein Fehler auf, so wird der Socket geschlossen. */
ssize_t len; ssize_t len;
char readbuf[1024]; char readbuf[READBUFFER_LEN];
CLIENT *c; CLIENT *c;
assert( Idx > NONE ); assert( Idx > NONE );
assert( My_Connections[Idx].sock > NONE ); assert( My_Connections[Idx].sock > NONE );
#ifdef ZLIB #ifdef ZLIB
if (( array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN ) || if ((array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN) ||
( array_bytes(&My_Connections[Idx].zip.rbuf) >= ZREADBUFFER_LEN )) (array_bytes(&My_Connections[Idx].zip.rbuf) >= READBUFFER_LEN))
#else #else
if ( array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN ) if (array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN)
#endif #endif
{ {
/* Der Lesepuffer ist voll */ /* Read buffer is full */
Log( LOG_ERR, "Receive buffer overflow (connection %d): %d bytes!", Idx, Log(LOG_ERR,
array_bytes(&My_Connections[Idx].rbuf)); "Receive buffer overflow (connection %d): %d bytes!",
Idx, array_bytes(&My_Connections[Idx].rbuf));
Conn_Close( Idx, "Receive buffer overflow!", NULL, false ); Conn_Close( Idx, "Receive buffer overflow!", NULL, false );
return; return;
} }
len = read( My_Connections[Idx].sock, readbuf, sizeof readbuf -1 ); len = read(My_Connections[Idx].sock, readbuf, sizeof(readbuf));
if( len == 0 ) { if (len == 0) {
Log( LOG_INFO, "%s:%d (%s) is closing the connection ...", Log(LOG_INFO, "%s:%d (%s) is closing the connection ...",
My_Connections[Idx].host, ntohs( My_Connections[Idx].addr.sin_port), My_Connections[Idx].host,
inet_ntoa( My_Connections[Idx].addr.sin_addr )); ntohs(My_Connections[Idx].addr.sin_port),
Conn_Close( Idx, "Socket closed!", "Client closed connection", false ); inet_ntoa( My_Connections[Idx].addr.sin_addr));
Conn_Close(Idx,
"Socket closed!", "Client closed connection",
false);
return; return;
} }
if( len < 0 ) { if (len < 0) {
if( errno == EAGAIN ) return; if( errno == EAGAIN ) return;
Log( LOG_ERR, "Read error on connection %d (socket %d): %s!", Idx, Log(LOG_ERR, "Read error on connection %d (socket %d): %s!",
My_Connections[Idx].sock, strerror( errno )); Idx, My_Connections[Idx].sock, strerror(errno));
Conn_Close( Idx, "Read error!", "Client closed connection", false ); Conn_Close(Idx, "Read error!", "Client closed connection",
false);
return; return;
} }
#ifdef ZLIB #ifdef ZLIB
@@ -1107,8 +1127,7 @@ Read_Request( CONN_ID Idx )
} else } else
#endif #endif
{ {
readbuf[len] = 0; if (!array_catb( &My_Connections[Idx].rbuf, readbuf, len)) {
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 ); 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 ); Conn_Close( Idx, "Receive buffer overflow!", NULL, false );
} }
@@ -1227,11 +1246,6 @@ Handle_Buffer( CONN_ID Idx )
/* The last Command activated Socket-Compression. /* The last Command activated Socket-Compression.
* Data that was read after that needs to be copied to Unzip-buf * Data that was read after that needs to be copied to Unzip-buf
* for decompression */ * for decompression */
if( array_bytes(&My_Connections[Idx].rbuf)> ZREADBUFFER_LEN ) {
Log( LOG_ALERT, "Connection %d: No space left in unzip buf (need %u bytes)!",
Idx, array_bytes(&My_Connections[Idx].rbuf ));
return false;
}
if (!array_copy( &My_Connections[Idx].zip.rbuf, &My_Connections[Idx].rbuf )) if (!array_copy( &My_Connections[Idx].zip.rbuf, &My_Connections[Idx].rbuf ))
return false; return false;
@@ -1639,9 +1653,9 @@ Conn_GetClient( CONN_ID Idx )
assert( Idx >= 0 ); assert( Idx >= 0 );
c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx); c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx);
assert(c != NULL); assert(c != NULL);
return c ? c->client : NULL; return c ? c->client : NULL;
} }

View File

@@ -8,7 +8,7 @@
* (at your option) any later version. * (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information. * Please read the file COPYING, README and AUTHORS for more information.
* *
* $Id: conn.h,v 1.42 2006/05/10 21:24:01 alex Exp $ * $Id: conn.h,v 1.42.2.1 2007/05/09 13:21:38 fw Exp $
* *
* Connection management (header) * Connection management (header)
*/ */
@@ -88,7 +88,6 @@ GLOBAL void Conn_ExitListeners PARAMS(( void ));
GLOBAL void Conn_Handler PARAMS(( void )); GLOBAL void Conn_Handler PARAMS(( void ));
GLOBAL bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, char *Format, ... )); GLOBAL 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_Close PARAMS(( CONN_ID Idx, char *LogMsg, char *FwdMsg, bool InformClient ));

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2005 Alexander Barton (alex@barton.de) * Copyright (c)2001-2007 Alexander Barton (alex@barton.de)
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -8,7 +8,7 @@
* (at your option) any later version. * (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information. * Please read the file COPYING, README and AUTHORS for more information.
* *
* $Id: defines.h,v 1.58 2006/06/15 20:28:15 alex Exp $ * $Id: defines.h,v 1.58.2.1 2007/05/18 22:11:19 alex Exp $
*/ */
@@ -70,13 +70,8 @@
connection in bytes. */ connection in bytes. */
#define WRITEBUFFER_LEN 4096 /* Size of the write buffer of a #define WRITEBUFFER_LEN 4096 /* Size of the write buffer of a
connection in bytes. */ connection in bytes. */
#define WRITEBUFFER_SLINK_LEN 51200 /* Size of the write buffer of a
#ifdef ZLIB server link connection in 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, #define PROTOVER "0210" /* Implemented IRC protocol version,
see RFC 2813 section 4.1.1. */ see RFC 2813 section 4.1.1. */

View File

@@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: hash.c,v 1.12 2005/07/31 20:13:08 alex Exp $"; static char UNUSED id[] = "$Id: hash.c,v 1.12.2.1 2006/12/02 13:18:22 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -31,7 +31,7 @@ static UINT32 jenkins_hash PARAMS(( register UINT8 *k, register UINT32 length, r
GLOBAL UINT32 GLOBAL UINT32
Hash( char *String ) Hash( const char *String )
{ {
/* Hash-Wert ueber String berechnen */ /* Hash-Wert ueber String berechnen */

View File

@@ -8,7 +8,7 @@
* (at your option) any later version. * (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information. * Please read the file COPYING, README and AUTHORS for more information.
* *
* $Id: hash.h,v 1.5 2005/03/19 18:43:48 fw Exp $ * $Id: hash.h,v 1.5.4.1 2006/12/02 13:18:22 fw Exp $
* *
* Hash calculation (header) * Hash calculation (header)
*/ */
@@ -17,8 +17,7 @@
#ifndef __hash_h__ #ifndef __hash_h__
#define __hash_h__ #define __hash_h__
GLOBAL UINT32 Hash PARAMS((const char *String ));
GLOBAL UINT32 Hash PARAMS((char *String ));
#endif #endif

View File

@@ -12,7 +12,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: io.c,v 1.16 2006/07/23 23:11:44 alex Exp $"; static char UNUSED id[] = "$Id: io.c,v 1.16.2.1 2007/04/03 22:08:52 fw Exp $";
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
@@ -34,25 +34,40 @@ typedef struct {
short what; short what;
} io_event; } io_event;
#define INIT_IOEVENT { NULL, -1, 0, NULL } #define INIT_IOEVENT { NULL, -1, 0, NULL }
#define IO_ERROR 4 #define IO_ERROR 4
#ifdef HAVE_EPOLL_CREATE #ifdef HAVE_EPOLL_CREATE
#define IO_USE_EPOLL 1 # define IO_USE_EPOLL 1
# ifdef HAVE_SELECT
# define IO_USE_SELECT 1
# endif
#else #else
# ifdef HAVE_KQUEUE # ifdef HAVE_KQUEUE
#define IO_USE_KQUEUE 1 # define IO_USE_KQUEUE 1
# else # else
#define IO_USE_SELECT 1 # ifdef HAVE_SYS_DEVPOLL_H
#endif # define IO_USE_DEVPOLL 1
#endif # else
# ifdef HAVE_POLL
# define IO_USE_POLL 1
# else
# ifdef HAVE_SELECT
# define IO_USE_SELECT 1
# else
# error "no IO API available!?"
# endif /* HAVE_SELECT */
# endif /* HAVE_POLL */
# endif /* HAVE_SYS_DEVPOLL_H */
# endif /* HAVE_KQUEUE */
#endif /* HAVE_EPOLL_CREATE */
static bool library_initialized; static bool library_initialized = false;
#ifdef IO_USE_EPOLL #ifdef IO_USE_EPOLL
#include <sys/epoll.h> #include <sys/epoll.h>
static int io_masterfd; static int io_masterfd = -1;
static bool io_event_change_epoll(int fd, short what, const int action); static bool io_event_change_epoll(int fd, short what, const int action);
static int io_dispatch_epoll(struct timeval *tv); static int io_dispatch_epoll(struct timeval *tv);
#endif #endif
@@ -67,6 +82,22 @@ static int io_dispatch_kqueue(struct timeval *tv);
static bool io_event_change_kqueue(int, short, const int action); static bool io_event_change_kqueue(int, short, const int action);
#endif #endif
#ifdef IO_USE_POLL
#include <poll.h>
static array pollfds;
static int poll_maxfd;
static bool io_event_change_poll(int fd, short what);
#endif
#ifdef IO_USE_DEVPOLL
#include <sys/devpoll.h>
static int io_masterfd;
static bool io_event_change_devpoll(int fd, short what);
#endif
#ifdef IO_USE_SELECT #ifdef IO_USE_SELECT
#include "defines.h" /* for conn.h */ #include "defines.h" /* for conn.h */
#include "conn.h" /* for CONN_IDX (needed by resolve.h) */ #include "conn.h" /* for CONN_IDX (needed by resolve.h) */
@@ -77,7 +108,11 @@ static fd_set readers;
static fd_set writers; static fd_set writers;
static int select_maxfd; /* the select() interface sucks badly */ static int select_maxfd; /* the select() interface sucks badly */
static int io_dispatch_select(struct timeval *tv); static int io_dispatch_select(struct timeval *tv);
#ifndef IO_USE_EPOLL
#define io_masterfd -1
#endif #endif
#endif /* IO_USE_SELECT */
static array io_events; static array io_events;
@@ -98,40 +133,45 @@ io_event_get(int fd)
} }
bool #ifdef IO_USE_DEVPOLL
io_library_init(unsigned int eventsize) static void
io_library_init_devpoll(unsigned int eventsize)
{ {
#if defined(IO_USE_EPOLL) || defined(IO_USE_KQUEUE) io_masterfd = open("/dev/poll", O_RDWR);
bool ret; if (io_masterfd >= 0)
library_initialized = true;
Log(LOG_INFO, "IO subsystem: /dev/poll (initial maxfd %u, masterfd %d).",
eventsize, io_masterfd);
}
#endif #endif
#ifdef IO_USE_EPOLL
int ecreate_hint = (int)eventsize;
if (ecreate_hint <= 0) #ifdef IO_USE_POLL
ecreate_hint = 128; static void
io_library_init_poll(unsigned int eventsize)
{
struct pollfd *p;
array_init(&pollfds);
poll_maxfd = 0;
Log(LOG_INFO, "IO subsystem: poll (initial maxfd %u).",
eventsize);
p = array_alloc(&pollfds, sizeof(struct pollfd), eventsize);
if (p) {
unsigned i;
p = array_start(&pollfds);
for (i = 0; i < eventsize; i++)
p[i].fd = -1;
library_initialized = true;
}
}
#endif #endif
if (library_initialized)
return true;
#ifdef IO_USE_SELECT #ifdef IO_USE_SELECT
#ifdef FD_SETSIZE static void
if (eventsize >= FD_SETSIZE) io_library_init_select(unsigned int eventsize)
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).", Log(LOG_INFO, "IO subsystem: select (initial maxfd %u).",
eventsize); eventsize);
FD_ZERO(&readers); FD_ZERO(&readers);
@@ -144,24 +184,82 @@ io_library_init(unsigned int eventsize)
Conf_MaxConnections = 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 */ #endif /* FD_SETSIZE */
library_initialized = true; library_initialized = true;
return true; }
#endif /* SELECT */ #endif /* SELECT */
#ifdef IO_USE_EPOLL
static void
io_library_init_epoll(unsigned int eventsize)
{
int ecreate_hint = (int)eventsize;
if (ecreate_hint <= 0)
ecreate_hint = 128;
io_masterfd = epoll_create(ecreate_hint);
if (io_masterfd >= 0) {
library_initialized = true;
Log(LOG_INFO,
"IO subsystem: epoll (hint size %d, initial maxfd %u, masterfd %d).",
ecreate_hint, eventsize, io_masterfd);
}
}
#endif
#ifdef IO_USE_KQUEUE #ifdef IO_USE_KQUEUE
static void
io_library_init_kqueue(unsigned int eventsize)
{
io_masterfd = kqueue(); io_masterfd = kqueue();
Log(LOG_INFO, Log(LOG_INFO,
"IO subsystem: kqueue (initial maxfd %u, masterfd %d)", "IO subsystem: kqueue (initial maxfd %u, masterfd %d)",
eventsize, io_masterfd); eventsize, io_masterfd);
ret = io_masterfd >= 0; if (io_masterfd >= 0)
if (ret) library_initialized = true; library_initialized = true;
}
return ret;
#endif #endif
bool
io_library_init(unsigned int eventsize)
{
if (library_initialized)
return true;
#ifdef IO_USE_SELECT
#ifndef FD_SETSIZE
Log(LOG_WARNING,
"FD_SETSIZE undefined, don't know how many descriptors select() can handle on your platform ...");
#else
if (eventsize >= FD_SETSIZE)
eventsize = FD_SETSIZE - 1;
#endif /* FD_SETSIZE */
#endif /* IO_USE_SELECT */
if ((eventsize > 0) && !array_alloc(&io_events, sizeof(io_event), (size_t)eventsize))
eventsize = 0;
#ifdef IO_USE_EPOLL
io_library_init_epoll(eventsize);
#ifdef IO_USE_SELECT
if (io_masterfd < 0)
Log(LOG_INFO, "Can't initialize epoll() IO interface, falling back to select() ...");
#endif
#endif
#ifdef IO_USE_KQUEUE
io_library_init_kqueue(eventsize);
#endif
#ifdef IO_USE_DEVPOLL
io_library_init_devpoll(eventsize);
#endif
#ifdef IO_USE_POLL
io_library_init_poll(eventsize);
#endif
#ifdef IO_USE_SELECT
if (! library_initialized)
io_library_init_select(eventsize);
#endif
return library_initialized;
} }
@@ -171,11 +269,15 @@ io_library_shutdown(void)
#ifdef IO_USE_SELECT #ifdef IO_USE_SELECT
FD_ZERO(&readers); FD_ZERO(&readers);
FD_ZERO(&writers); FD_ZERO(&writers);
#else #endif
close(io_masterfd); /* kqueue, epoll */ #ifdef IO_USE_EPOLL
if (io_masterfd >= 0)
close(io_masterfd);
io_masterfd = -1; io_masterfd = -1;
#endif #endif
#ifdef IO_USE_KQUEUE #ifdef IO_USE_KQUEUE
close(io_masterfd);
io_masterfd = -1;
array_free(&io_evcache); array_free(&io_evcache);
#endif #endif
library_initialized = false; library_initialized = false;
@@ -201,18 +303,14 @@ io_event_create(int fd, short what, void (*cbfunc) (int, short))
io_event *i; io_event *i;
assert(fd >= 0); assert(fd >= 0);
#if defined(IO_USE_SELECT) && defined(FD_SETSIZE)
#ifdef IO_USE_SELECT
#ifdef FD_SETSIZE
if (fd >= FD_SETSIZE) { if (fd >= FD_SETSIZE) {
Log(LOG_ERR, Log(LOG_ERR,
"fd %d exceeds FD_SETSIZE (%u) (select can't handle more file descriptors)", "fd %d exceeds FD_SETSIZE (%u) (select can't handle more file descriptors)",
fd, FD_SETSIZE); fd, FD_SETSIZE);
return false; return false;
} }
#endif /* FD_SETSIZE */ #endif
#endif /* IO_USE_SELECT */
i = (io_event *) array_alloc(&io_events, sizeof(io_event), (size_t) fd); i = (io_event *) array_alloc(&io_events, sizeof(io_event), (size_t) fd);
if (!i) { if (!i) {
Log(LOG_WARNING, Log(LOG_WARNING,
@@ -223,6 +321,12 @@ io_event_create(int fd, short what, void (*cbfunc) (int, short))
i->callback = cbfunc; i->callback = cbfunc;
i->what = 0; i->what = 0;
#ifdef IO_USE_DEVPOLL
ret = io_event_change_devpoll(fd, what);
#endif
#ifdef IO_USE_POLL
ret = io_event_change_poll(fd, what);
#endif
#ifdef IO_USE_EPOLL #ifdef IO_USE_EPOLL
ret = io_event_change_epoll(fd, what, EPOLL_CTL_ADD); ret = io_event_change_epoll(fd, what, EPOLL_CTL_ADD);
#endif #endif
@@ -230,13 +334,57 @@ io_event_create(int fd, short what, void (*cbfunc) (int, short))
ret = io_event_change_kqueue(fd, what, EV_ADD|EV_ENABLE); ret = io_event_change_kqueue(fd, what, EV_ADD|EV_ENABLE);
#endif #endif
#ifdef IO_USE_SELECT #ifdef IO_USE_SELECT
ret = io_event_add(fd, what); if (io_masterfd < 0)
ret = io_event_add(fd, what);
#endif #endif
if (ret) i->what = what; if (ret) i->what = what;
return ret; return ret;
} }
#ifdef IO_USE_DEVPOLL
static bool
io_event_change_devpoll(int fd, short what)
{
struct pollfd p;
p.events = 0;
if (what & IO_WANTREAD)
p.events = POLLIN | POLLPRI;
if (what & IO_WANTWRITE)
p.events |= POLLOUT;
p.fd = fd;
return write(io_masterfd, &p, sizeof p) == (ssize_t)sizeof p;
}
#endif
#ifdef IO_USE_POLL
static bool
io_event_change_poll(int fd, short what)
{
struct pollfd *p;
short events = 0;
if (what & IO_WANTREAD)
events = POLLIN | POLLPRI;
if (what & IO_WANTWRITE)
events |= POLLOUT;
p = array_alloc(&pollfds, sizeof *p, fd);
if (p) {
p->events = events;
p->fd = fd;
if (fd > poll_maxfd)
poll_maxfd = fd;
}
return p != NULL;
}
#endif
#ifdef IO_USE_EPOLL #ifdef IO_USE_EPOLL
static bool static bool
io_event_change_epoll(int fd, short what, const int action) io_event_change_epoll(int fd, short what, const int action)
@@ -260,7 +408,7 @@ io_event_kqueue_commit_cache(void)
struct kevent *events; struct kevent *events;
bool ret; bool ret;
int len = (int) array_length(&io_evcache, sizeof (struct kevent)); int len = (int) array_length(&io_evcache, sizeof (struct kevent));
if (!len) /* nothing to do */ if (!len) /* nothing to do */
return true; return true;
@@ -293,7 +441,7 @@ io_event_change_kqueue(int fd, short what, const int action)
ret = array_catb(&io_evcache, (char*) &kev, sizeof (kev)); ret = array_catb(&io_evcache, (char*) &kev, sizeof (kev));
if (!ret) if (!ret)
ret = kevent(io_masterfd, &kev,1, NULL, 0, NULL) == 0; ret = kevent(io_masterfd, &kev,1, NULL, 0, NULL) == 0;
} }
if (ret && (what & IO_WANTWRITE)) { if (ret && (what & IO_WANTWRITE)) {
EV_SET(&kev, fd, EVFILT_WRITE, action, 0, 0, 0); EV_SET(&kev, fd, EVFILT_WRITE, action, 0, 0, 0);
@@ -315,19 +463,27 @@ io_event_add(int fd, short what)
io_event *i = io_event_get(fd); io_event *i = io_event_get(fd);
if (!i) return false; if (!i) return false;
if (i->what == what) return true;
if ((i->what & what) == what) /* event type is already registered */
return true;
#ifdef DEBUG_IO #ifdef DEBUG_IO
Log(LOG_DEBUG, "io_event_add(): fd %d (arg: %d), what %d.", i->fd, fd, what); Log(LOG_DEBUG, "io_event_add(): fd %d, what %d.", fd, what);
#endif #endif
i->what |= what; i->what |= what;
#ifdef IO_USE_EPOLL #ifdef IO_USE_EPOLL
return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD); if (io_masterfd >= 0)
return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD);
#endif #endif
#ifdef IO_USE_KQUEUE #ifdef IO_USE_KQUEUE
return io_event_change_kqueue(fd, what, EV_ADD | EV_ENABLE); return io_event_change_kqueue(fd, what, EV_ADD | EV_ENABLE);
#endif #endif
#ifdef IO_USE_DEVPOLL
return io_event_change_devpoll(fd, i->what);
#endif
#ifdef IO_USE_POLL
return io_event_change_poll(fd, i->what);
#endif
#ifdef IO_USE_SELECT #ifdef IO_USE_SELECT
if (fd > select_maxfd) if (fd > select_maxfd)
select_maxfd = fd; select_maxfd = fd;
@@ -358,22 +514,77 @@ io_setnonblock(int fd)
} }
#ifdef IO_USE_DEVPOLL
static void
io_close_devpoll(int fd)
{
struct pollfd p;
p.events = POLLREMOVE;
p.fd = fd;
write(io_masterfd, &p, sizeof p);
}
#else
static inline void io_close_devpoll(int UNUSED x) { /* NOTHING */ }
#endif
#ifdef IO_USE_POLL
static void
io_close_poll(int fd)
{
struct pollfd *p;
p = array_get(&pollfds, sizeof *p, fd);
if (!p) return;
p->fd = -1;
if (fd == poll_maxfd) {
while (poll_maxfd > 0) {
--poll_maxfd;
p = array_get(&pollfds, sizeof *p, poll_maxfd);
if (p && p->fd >= 0)
break;
}
}
}
#else
static inline void io_close_poll(int UNUSED x) { /* NOTHING */ }
#endif
#ifdef IO_USE_SELECT
static void
io_close_select(int fd)
{
io_event *i;
if (io_masterfd >= 0) /* Are we using epoll()? */
return;
FD_CLR(fd, &writers);
FD_CLR(fd, &readers);
i = io_event_get(fd);
if (!i) return;
if (fd == select_maxfd) {
while (select_maxfd>0) {
--select_maxfd; /* find largest fd */
i = io_event_get(select_maxfd);
if (i && i->callback) break;
}
}
}
#else
static inline void io_close_select(int UNUSED x) { /* NOTHING */ }
#endif
bool bool
io_close(int fd) io_close(int fd)
{ {
io_event *i; 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); i = io_event_get(fd);
#ifdef IO_USE_KQUEUE #ifdef IO_USE_KQUEUE
if (array_length(&io_evcache, sizeof (struct kevent))) /* pending data in cache? */ if (array_length(&io_evcache, sizeof (struct kevent))) /* pending data in cache? */
@@ -385,8 +596,13 @@ io_close(int fd)
if (i) { if (i) {
io_event_change_kqueue(fd, i->what, EV_DELETE); io_event_change_kqueue(fd, i->what, EV_DELETE);
io_event_kqueue_commit_cache(); io_event_kqueue_commit_cache();
} }
#endif #endif
io_close_devpoll(fd);
io_close_poll(fd);
io_close_select(fd);
#ifdef IO_USE_EPOLL #ifdef IO_USE_EPOLL
io_event_change_epoll(fd, 0, EPOLL_CTL_DEL); io_event_change_epoll(fd, 0, EPOLL_CTL_DEL);
#endif #endif
@@ -409,8 +625,15 @@ io_event_del(int fd, short what)
i->what &= ~what; i->what &= ~what;
#ifdef IO_USE_DEVPOLL
return io_event_change_devpoll(fd, i->what);
#endif
#ifdef IO_USE_POLL
return io_event_change_poll(fd, i->what);
#endif
#ifdef IO_USE_EPOLL #ifdef IO_USE_EPOLL
return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD); if (io_masterfd >= 0)
return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD);
#endif #endif
#ifdef IO_USE_KQUEUE #ifdef IO_USE_KQUEUE
@@ -465,6 +688,92 @@ io_dispatch_select(struct timeval *tv)
#endif #endif
#ifdef IO_USE_DEVPOLL
static int
io_dispatch_devpoll(struct timeval *tv)
{
struct dvpoll dvp;
time_t sec = tv->tv_sec * 1000;
int i, total, ret, timeout = tv->tv_usec + sec;
short what;
struct pollfd p[100];
if (timeout < 0)
timeout = 1000;
total = 0;
do {
dvp.dp_timeout = timeout;
dvp.dp_nfds = 100;
dvp.dp_fds = p;
ret = ioctl(io_masterfd, DP_POLL, &dvp);
total += ret;
if (ret <= 0)
return total;
for (i=0; i < ret ; i++) {
what = 0;
if (p[i].revents & (POLLIN|POLLPRI))
what = IO_WANTREAD;
if (p[i].revents & POLLOUT)
what |= IO_WANTWRITE;
if (p[i].revents && !what) {
/* other flag is set, probably POLLERR */
what = IO_ERROR;
}
io_docallback(p[i].fd, what);
}
} while (ret == 100);
return total;
}
#endif
#ifdef IO_USE_POLL
static int
io_dispatch_poll(struct timeval *tv)
{
time_t sec = tv->tv_sec * 1000;
int i, ret, timeout = tv->tv_usec + sec;
int fds_ready;
short what;
struct pollfd *p = array_start(&pollfds);
if (timeout < 0)
timeout = 1000;
ret = poll(p, poll_maxfd + 1, timeout);
if (ret <= 0)
return ret;
fds_ready = ret;
for (i=0; i <= poll_maxfd; i++) {
what = 0;
if (p[i].revents & (POLLIN|POLLPRI))
what = IO_WANTREAD;
if (p[i].revents & POLLOUT)
what |= IO_WANTWRITE;
if (p[i].revents && !what) {
/* other flag is set, probably POLLERR */
what = IO_ERROR;
}
if (what) {
fds_ready--;
io_docallback(i, what);
}
if (fds_ready <= 0)
break;
}
return ret;
}
#endif
#ifdef IO_USE_EPOLL #ifdef IO_USE_EPOLL
static int static int
io_dispatch_epoll(struct timeval *tv) io_dispatch_epoll(struct timeval *tv)
@@ -516,7 +825,7 @@ io_dispatch_kqueue(struct timeval *tv)
int newevents_len; int newevents_len;
ts.tv_sec = tv->tv_sec; ts.tv_sec = tv->tv_sec;
ts.tv_nsec = tv->tv_usec * 1000; ts.tv_nsec = tv->tv_usec * 1000;
do { do {
newevents_len = (int) array_length(&io_evcache, sizeof (struct kevent)); newevents_len = (int) array_length(&io_evcache, sizeof (struct kevent));
newevents = (newevents_len > 0) ? array_start(&io_evcache) : NULL; newevents = (newevents_len > 0) ? array_start(&io_evcache) : NULL;
@@ -541,10 +850,10 @@ io_dispatch_kqueue(struct timeval *tv)
#ifdef DEBUG #ifdef DEBUG
LogDebug("kev.flag has EV_EOF set, setting IO_ERROR", LogDebug("kev.flag has EV_EOF set, setting IO_ERROR",
kev[i].filter, kev[i].ident); kev[i].filter, kev[i].ident);
#endif #endif
io_docallback((int)kev[i].ident, IO_ERROR); io_docallback((int)kev[i].ident, IO_ERROR);
continue; continue;
} }
switch (kev[i].filter) { switch (kev[i].filter) {
case EVFILT_READ: case EVFILT_READ:
@@ -575,14 +884,21 @@ io_dispatch_kqueue(struct timeval *tv)
int int
io_dispatch(struct timeval *tv) io_dispatch(struct timeval *tv)
{ {
#ifdef IO_USE_EPOLL
if (io_masterfd >= 0)
return io_dispatch_epoll(tv);
#endif
#ifdef IO_USE_SELECT #ifdef IO_USE_SELECT
return io_dispatch_select(tv); return io_dispatch_select(tv);
#endif #endif
#ifdef IO_USE_KQUEUE #ifdef IO_USE_KQUEUE
return io_dispatch_kqueue(tv); return io_dispatch_kqueue(tv);
#endif #endif
#ifdef IO_USE_EPOLL #ifdef IO_USE_DEVPOLL
return io_dispatch_epoll(tv); return io_dispatch_devpoll(tv);
#endif
#ifdef IO_USE_POLL
return io_dispatch_poll(tv);
#endif #endif
} }
@@ -597,9 +913,9 @@ io_docallback(int fd, short what)
#endif #endif
i = io_event_get(fd); i = io_event_get(fd);
if (i->callback) { /* callback might be NULL if a previous callback function if (i->callback) { /* callback might be NULL if a previous callback function
called io_close on this fd */ called io_close on this fd */
i->callback(fd, (what & IO_ERROR) ? i->what : what); i->callback(fd, (what & IO_ERROR) ? i->what : what);
} }
/* if error indicator is set, we return the event(s) that were registered */ /* if error indicator is set, we return the event(s) that were registered */
} }

View File

@@ -7,10 +7,10 @@
* *
* I/O abstraction interface header * I/O abstraction interface header
* *
* $Id: io.h,v 1.3 2005/07/14 09:15:58 alex Exp $ * $Id: io.h,v 1.3.2.1 2007/04/03 22:08:52 fw Exp $
*/ */
#ifndef io_H_inclucded #ifndef io_H_included
#define io_H_included #define io_H_included
#include "portab.h" #include "portab.h"

View File

@@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-channel.c,v 1.35 2006/03/16 20:14:16 fw Exp $"; static char UNUSED id[] = "$Id: irc-channel.c,v 1.35.2.5 2008/01/07 11:41:44 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -52,7 +52,9 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
assert( Req != NULL ); assert( Req != NULL );
/* Bad number of arguments? */ /* Bad number of arguments? */
if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); if (Req->argc < 1 || Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* Who is the sender? */ /* Who is the sender? */
if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix ); if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
@@ -78,8 +80,17 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
chan = NULL; flags = NULL; chan = NULL; flags = NULL;
/* wird der Channel neu angelegt? */ /* wird der Channel neu angelegt? */
if( Channel_Search( channame )) is_new_chan = false; if( Channel_Search( channame )) {
else is_new_chan = true; is_new_chan = false;
} else {
if (Conf_PredefChannelsOnly) { /* this server does not allow creation of channels */
IRC_WriteStrClient( Client, ERR_BANNEDFROMCHAN_MSG, Client_ID( Client ), channame );
/* Try next name, if any */
channame = strchr(channame, ',');
continue;
}
is_new_chan = true;
}
/* Hat ein Server Channel-User-Modes uebergeben? */ /* Hat ein Server Channel-User-Modes uebergeben? */
if( Client_Type( Client ) == CLIENT_SERVER ) if( Client_Type( Client ) == CLIENT_SERVER )
@@ -113,8 +124,8 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
chan = Channel_Search( channame ); chan = Channel_Search( channame );
assert( chan != NULL ); assert( chan != NULL );
is_banned = Lists_CheckBanned( target, chan ); is_banned = Lists_Check(Channel_GetListBans(chan), target );
is_invited = Lists_CheckInvited( target, chan ); is_invited = Lists_Check(Channel_GetListInvites(chan), target );
/* Testen, ob Client gebanned ist */ /* Testen, ob Client gebanned ist */
if(( is_banned == true) && ( is_invited == false )) if(( is_banned == true) && ( is_invited == false ))
@@ -123,7 +134,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
IRC_WriteStrClient( Client, ERR_BANNEDFROMCHAN_MSG, Client_ID( Client ), channame ); IRC_WriteStrClient( Client, ERR_BANNEDFROMCHAN_MSG, Client_ID( Client ), channame );
/* Try next name, if any */ /* Try next name, if any */
channame = strtok( NULL, "," ); channame = strchr(channame, ',');
continue; continue;
} }
@@ -134,7 +145,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
IRC_WriteStrClient( Client, ERR_INVITEONLYCHAN_MSG, Client_ID( Client ), channame ); IRC_WriteStrClient( Client, ERR_INVITEONLYCHAN_MSG, Client_ID( Client ), channame );
/* Try next name, if any */ /* Try next name, if any */
channame = strtok( NULL, "," ); channame = strchr(channame, ',');
continue; continue;
} }
@@ -145,7 +156,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
IRC_WriteStrClient( Client, ERR_BADCHANNELKEY_MSG, Client_ID( Client ), channame ); IRC_WriteStrClient( Client, ERR_BADCHANNELKEY_MSG, Client_ID( Client ), channame );
/* Try next name, if any */ /* Try next name, if any */
channame = strtok( NULL, "," ); channame = strchr(channame, ',');
continue; continue;
} }
@@ -156,7 +167,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
IRC_WriteStrClient( Client, ERR_CHANNELISFULL_MSG, Client_ID( Client ), channame ); IRC_WriteStrClient( Client, ERR_CHANNELISFULL_MSG, Client_ID( Client ), channame );
/* Try next name, if any */ /* Try next name, if any */
channame = strtok( NULL, "," ); channame = strchr(channame, ',');
continue; continue;
} }
} }
@@ -169,14 +180,14 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
* commands) in this list become deleted when a user * commands) in this list become deleted when a user
* joins a channel this way. */ * joins a channel this way. */
chan = Channel_Search( channame ); chan = Channel_Search( channame );
if( chan != NULL ) (void)Lists_CheckInvited( target, chan ); if( chan != NULL ) (void)Lists_Check(Channel_GetListInvites(chan), target);
} }
/* Channel joinen (und ggf. anlegen) */ /* Channel joinen (und ggf. anlegen) */
if( ! Channel_Join( target, channame )) if( ! Channel_Join( target, channame ))
{ {
/* naechsten Namen ermitteln */ /* naechsten Namen ermitteln */
channame = strtok( NULL, "," ); channame = strchr(channame, ',');
continue; continue;
} }
if( ! chan ) chan = Channel_Search( channame ); if( ! chan ) chan = Channel_Search( channame );
@@ -259,7 +270,9 @@ IRC_PART( CLIENT *Client, REQUEST *Req )
assert( Req != NULL ); assert( Req != NULL );
/* Falsche Anzahl Parameter? */ /* Falsche Anzahl Parameter? */
if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); if (Req->argc < 1 || Req->argc > 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
/* Wer ist der Absender? */ /* Wer ist der Absender? */
if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix ); if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
@@ -491,7 +504,7 @@ IRC_CHANINFO( CLIENT *Client, REQUEST *Req )
{ {
if( *ptr == 'l' ) if( *ptr == 'l' )
{ {
snprintf( l, sizeof( l ), " %ld", Channel_MaxUsers( chan )); snprintf( l, sizeof( l ), " %lu", Channel_MaxUsers( chan ));
strlcat( modes_add, l, sizeof( modes_add )); strlcat( modes_add, l, sizeof( modes_add ));
} }
if( *ptr == 'k' ) if( *ptr == 'k' )

View File

@@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-info.c,v 1.33 2006/05/10 21:24:01 alex Exp $"; static char UNUSED id[] = "$Id: irc-info.c,v 1.33.2.2 2006/12/02 14:26:53 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -542,7 +542,8 @@ GLOBAL bool
IRC_WHO( CLIENT *Client, REQUEST *Req ) IRC_WHO( CLIENT *Client, REQUEST *Req )
{ {
bool ok, only_ops; bool ok, only_ops;
char flags[8], *ptr; char flags[8];
const char *ptr;
CL2CHAN *cl2chan; CL2CHAN *cl2chan;
CHANNEL *chan, *cn; CHANNEL *chan, *cn;
CLIENT *c; CLIENT *c;
@@ -832,7 +833,10 @@ IRC_WHOWAS( CLIENT *Client, REQUEST *Req )
GLOBAL bool GLOBAL bool
IRC_Send_LUSERS( CLIENT *Client ) IRC_Send_LUSERS( CLIENT *Client )
{ {
long cnt; unsigned long cnt;
#ifndef STRICT_RFC
unsigned long max;
#endif
assert( Client != NULL ); assert( Client != NULL );
@@ -861,9 +865,17 @@ IRC_Send_LUSERS( CLIENT *Client )
#ifndef STRICT_RFC #ifndef STRICT_RFC
/* Maximum number of local users */ /* Maximum number of local users */
if( ! IRC_WriteStrClient( Client, RPL_LOCALUSERS_MSG, Client_ID( Client ), Client_MyUserCount( ), Client_MyMaxUserCount( ))) return DISCONNECTED; cnt = Client_MyUserCount();
max = Client_MyMaxUserCount();
if (! IRC_WriteStrClient(Client, RPL_LOCALUSERS_MSG, Client_ID(Client),
cnt, max, cnt, max))
return DISCONNECTED;
/* Maximum number of users in the network */ /* Maximum number of users in the network */
if( ! IRC_WriteStrClient( Client, RPL_NETUSERS_MSG, Client_ID( Client ), Client_UserCount( ), Client_MaxUserCount( ))) return DISCONNECTED; cnt = Client_UserCount();
max = Client_MaxUserCount();
if(! IRC_WriteStrClient(Client, RPL_NETUSERS_MSG, Client_ID(Client),
cnt, max, cnt, max))
return DISCONNECTED;
#endif #endif
return CONNECTED; return CONNECTED;
@@ -910,8 +922,10 @@ IRC_Show_MOTD( CLIENT *Client )
return IRC_WriteStrClient( Client, ERR_NOMOTD_MSG, Client_ID( Client ) ); return IRC_WriteStrClient( Client, ERR_NOMOTD_MSG, Client_ID( Client ) );
} }
if (!Show_MOTD_Start( Client )) if (!Show_MOTD_Start( Client )) {
return DISCONNECTED; fclose(fd);
return false;
}
while (fgets( line, (int)sizeof line, fd )) { while (fgets( line, (int)sizeof line, fd )) {
ngt_TrimLastChr( line, '\n'); ngt_TrimLastChr( line, '\n');

View File

@@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-login.c,v 1.49 2005/09/01 10:51:24 alex Exp $"; static char UNUSED id[] = "$Id: irc-login.c,v 1.49.2.2 2006/12/02 14:26:53 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -45,101 +45,119 @@ static bool Hello_User PARAMS(( CLIENT *Client ));
static void Kill_Nick PARAMS(( char *Nick, char *Reason )); static void Kill_Nick PARAMS(( char *Nick, char *Reason ));
/**
* Handler for the IRC command "PASS".
* See RFC 2813 section 4.1.1, and RFC 2812 section 3.1.1.
*/
GLOBAL bool GLOBAL bool
IRC_PASS( CLIENT *Client, REQUEST *Req ) IRC_PASS( CLIENT *Client, REQUEST *Req )
{ {
char *type, *orig_flags;
int protohigh, protolow;
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
/* Fehler liefern, wenn kein lokaler Client */ /* Return an error if this is not a local client */
if( Client_Conn( Client ) <= NONE ) return IRC_WriteStrClient( Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( Client ), Req->command ); if (Client_Conn(Client) <= NONE)
return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG,
Client_ID(Client), Req->command);
if(( Client_Type( Client ) == CLIENT_UNKNOWN ) && ( Req->argc == 1)) if (Client_Type(Client) == CLIENT_UNKNOWN && Req->argc == 1) {
{ /* Not yet registered "unknown" connection, PASS with one
/* noch nicht registrierte unbekannte Verbindung */ * argument: either a regular client, service, or server
Log( LOG_DEBUG, "Connection %d: got PASS command ...", Client_Conn( Client )); * using the old RFC 1459 section 4.1.1 syntax. */
LogDebug("Connection %d: got PASS command ...",
/* Passwort speichern */ Client_Conn(Client));
Client_SetPassword( Client, Req->argv[0] ); } else if ((Client_Type(Client) == CLIENT_UNKNOWN ||
Client_Type(Client) == CLIENT_UNKNOWNSERVER) &&
Client_SetType( Client, CLIENT_GOTPASS ); (Req->argc == 3 || Req->argc == 4)) {
return CONNECTED; /* Not yet registered "unknown" connection or outgoing server
* link, PASS with three or four argument: server using the
* RFC 2813 section 4.1.1 syntax. */
LogDebug("Connection %d: got PASS command (new server link) ...",
Client_Conn(Client));
} else if (Client_Type(Client) == CLIENT_UNKNOWN ||
Client_Type(Client) == CLIENT_UNKNOWNSERVER) {
/* Unregistered connection, but wrong number of arguments: */
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
} else {
/* Registered connection, PASS command is not allowed! */
return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG,
Client_ID(Client));
} }
else if((( Client_Type( Client ) == CLIENT_UNKNOWN ) || ( Client_Type( Client ) == CLIENT_UNKNOWNSERVER )) && (( Req->argc == 3 ) || ( Req->argc == 4 )))
{
char c2, c4, *type, *impl, *serverver, *flags, *ptr, *ircflags;
int protohigh, protolow;
/* noch nicht registrierte Server-Verbindung */ Client_SetPassword(Client, Req->argv[0]);
Log( LOG_DEBUG, "Connection %d: got PASS command (new server link) ...", Client_Conn( Client )); Client_SetType(Client, CLIENT_GOTPASS);
/* Passwort speichern */ /* Protocol version */
Client_SetPassword( Client, Req->argv[0] ); if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) {
int c2, c4;
/* Protokollversion ermitteln */ c2 = Req->argv[1][2];
if( strlen( Req->argv[1] ) >= 4 ) c4 = Req->argv[1][4];
{
c2 = Req->argv[1][2];
c4 = Req->argv[1][4];
Req->argv[1][4] = '\0'; Req->argv[1][4] = '\0';
protolow = atoi( &Req->argv[1][2] ); protolow = atoi(&Req->argv[1][2]);
Req->argv[1][2] = '\0'; Req->argv[1][2] = '\0';
protohigh = atoi( Req->argv[1] ); protohigh = atoi(Req->argv[1]);
Req->argv[1][2] = c2; Req->argv[1][2] = c2;
Req->argv[1][4] = c4; Req->argv[1][4] = c4;
} } else
else protohigh = protolow = 0; protohigh = protolow = 0;
/* Protokoll-Typ */ /* Protocol type, see doc/Protocol.txt */
if( strlen( Req->argv[1] ) > 4 ) type = &Req->argv[1][4]; if (Req->argc >= 2 && strlen(Req->argv[1]) > 4)
else type = NULL; type = &Req->argv[1][4];
else
type = NULL;
/* Protocol flags/options */
if (Req->argc >= 4)
orig_flags = Req->argv[3];
else
orig_flags = "";
/* IRC-Flags (nach RFC 2813) */ /* Implementation, version and IRC+ flags */
if( Req->argc >= 4 ) ircflags = Req->argv[3]; if (Req->argc >= 3) {
else ircflags = ""; char *impl, *ptr, *serverver, *flags;
/* Implementation, Version und ngIRCd-Flags */
impl = Req->argv[2]; impl = Req->argv[2];
ptr = strchr( impl, '|' ); ptr = strchr(impl, '|');
if( ptr ) *ptr = '\0'; if (ptr)
*ptr = '\0';
if( type && ( strcmp( type, PROTOIRCPLUS ) == 0 )) if (type && strcmp(type, PROTOIRCPLUS) == 0) {
{ /* The peer seems to be a server which supports the
/* auf der anderen Seite laeuft ein Server, der * IRC+ protocol (see doc/Protocol.txt). */
* ebenfalls das IRC+-Protokoll versteht */
serverver = ptr + 1; serverver = ptr + 1;
flags = strchr( serverver, ':' ); flags = strchr(serverver, ':');
if( flags ) if (flags) {
{
*flags = '\0'; *flags = '\0';
flags++; flags++;
} } else
else flags = ""; flags = "";
Log( LOG_INFO, "Peer announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").", impl, serverver, protohigh, protolow, flags ); Log(LOG_INFO,
} "Peer announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").",
else impl, serverver, protohigh, protolow, flags);
{ } else {
/* auf der anderen Seite laeuft ein Server, der /* The peer seems to be a server supporting the
* nur das Originalprotokoll unterstuetzt */ * "original" IRC protocol (RFC 2813). */
serverver = ""; serverver = "";
if( strchr( ircflags, 'Z' )) flags = "Z"; if (strchr(orig_flags, 'Z'))
else flags = ""; flags = "Z";
Log( LOG_INFO, "Peer announces itself as \"%s\" using protocol %d.%d (flags: \"%s\").", impl, protohigh, protolow, flags ); else
flags = "";
Log(LOG_INFO,
"Peer announces itself as \"%s\" using protocol %d.%d (flags: \"%s\").",
impl, protohigh, protolow, flags);
} }
Client_SetFlags(Client, flags);
Client_SetType( Client, CLIENT_GOTPASSSERVER );
Client_SetFlags( Client, flags );
return CONNECTED;
} }
else if(( Client_Type( Client ) == CLIENT_UNKNOWN ) || ( Client_Type( Client ) == CLIENT_UNKNOWNSERVER ))
{ return CONNECTED;
/* Falsche Anzahl Parameter? */
return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
}
else return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
} /* IRC_PASS */ } /* IRC_PASS */
@@ -268,13 +286,13 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
"NICK :%s", Req->argv[0] ); "NICK :%s", Req->argv[0] );
IRC_WriteStrRelatedPrefix( target, target, false, IRC_WriteStrRelatedPrefix( target, target, false,
"NICK :%s", Req->argv[0] ); "NICK :%s", Req->argv[0] );
/* Register old nickname for WHOWAS queries */ /* Register old nickname for WHOWAS queries */
Client_RegisterWhowas( target ); Client_RegisterWhowas( target );
/* Save new nickname */ /* Save new nickname */
Client_SetID( target, Req->argv[0] ); Client_SetID( target, Req->argv[0] );
IRC_SetPenalty( target, 2 ); IRC_SetPenalty( target, 2 );
} }
@@ -598,9 +616,15 @@ Hello_User( CLIENT *Client )
if( ! IRC_WriteStrClient( Client, RPL_MYINFO_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), PACKAGE_VERSION, USERMODES, CHANMODES )) return false; if( ! IRC_WriteStrClient( Client, RPL_MYINFO_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), PACKAGE_VERSION, USERMODES, CHANMODES )) return false;
#endif #endif
/* Features */ /* Features supported by this server (005 numeric, ISUPPORT),
if( ! IRC_WriteStrClient( Client, RPL_ISUPPORT_MSG, Client_ID( Client ), CLIENT_NICK_LEN - 1, * see <http://www.irc.org/tech_docs/005.html> for details. */
COMMAND_LEN - 23, CLIENT_AWAY_LEN - 1, Conf_MaxJoins )) return DISCONNECTED; if (! IRC_WriteStrClient(Client, RPL_ISUPPORT1_MSG, Client_ID(Client),
Conf_MaxJoins))
return DISCONNECTED;
if (! IRC_WriteStrClient(Client, RPL_ISUPPORT2_MSG, Client_ID(Client),
CHANNEL_NAME_LEN-1, CLIENT_NICK_LEN-1, COMMAND_LEN-23,
CLIENT_AWAY_LEN-1, COMMAND_LEN-113))
return DISCONNECTED;
Client_SetType( Client, CLIENT_USER ); Client_SetType( Client, CLIENT_USER );

View File

@@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-mode.c,v 1.45 2006/05/10 21:24:01 alex Exp $"; static char UNUSED id[] = "$Id: irc-mode.c,v 1.45.2.2 2007/04/03 20:23:31 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -69,7 +69,7 @@ IRC_MODE( CLIENT *Client, REQUEST *Req )
if( ! origin ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix ); if( ! origin ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
} }
else origin = Client; else origin = Client;
/* Channel or user mode? */ /* Channel or user mode? */
cl = NULL; chan = NULL; cl = NULL; chan = NULL;
if (Client_IsValidNick(Req->argv[0])) if (Client_IsValidNick(Req->argv[0]))
@@ -268,7 +268,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
switch( *mode_ptr ) switch( *mode_ptr )
{ {
case 'l': case 'l':
snprintf( argadd, sizeof( argadd ), " %ld", Channel_MaxUsers( Channel )); snprintf( argadd, sizeof( argadd ), " %lu", Channel_MaxUsers( Channel ));
strlcat( the_args, argadd, sizeof( the_args )); strlcat( the_args, argadd, sizeof( the_args ));
break; break;
case 'k': case 'k':
@@ -477,7 +477,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
Req->argv[arg_arg][0] = '\0'; Req->argv[arg_arg][0] = '\0';
arg_arg++; arg_arg++;
} }
else Lists_ShowInvites( Origin, Channel ); else Channel_ShowInvites( Origin, Channel );
break; break;
case 'b': /* Ban lists */ case 'b': /* Ban lists */
@@ -493,7 +493,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
Req->argv[arg_arg][0] = '\0'; Req->argv[arg_arg][0] = '\0';
arg_arg++; arg_arg++;
} }
else Lists_ShowBans( Origin, Channel ); else Channel_ShowBans( Origin, Channel );
break; break;
default: default:
@@ -644,11 +644,13 @@ Add_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
mask = Lists_MakeMask( Pattern ); mask = Lists_MakeMask( Pattern );
already = Lists_IsInviteEntry( mask, Channel ); already = Lists_CheckDupeMask(Channel_GetListInvites(Channel), mask );
if (!already) {
if( ! Lists_AddInvited( mask, Channel, false )) return CONNECTED; if( ! Channel_AddInvite(Channel, mask, false ))
return CONNECTED;
if(( Client_Type( Prefix ) == CLIENT_SERVER ) && ( already == true)) return CONNECTED; }
if ( already && ( Client_Type( Prefix ) == CLIENT_SERVER ))
return CONNECTED;
return Send_ListChange( "+I", Prefix, Client, Channel, mask ); return Send_ListChange( "+I", Prefix, Client, Channel, mask );
} /* Add_Invite */ } /* Add_Invite */
@@ -666,11 +668,13 @@ Add_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
mask = Lists_MakeMask( Pattern ); mask = Lists_MakeMask( Pattern );
already = Lists_IsBanEntry( mask, Channel ); already = Lists_CheckDupeMask(Channel_GetListBans(Channel), mask );
if (!already) {
if( ! Lists_AddBanned( mask, Channel )) return CONNECTED; if( ! Channel_AddBan(Channel, mask))
return CONNECTED;
if(( Client_Type( Prefix ) == CLIENT_SERVER ) && ( already == true)) return CONNECTED; }
if ( already && ( Client_Type( Prefix ) == CLIENT_SERVER ))
return CONNECTED;
return Send_ListChange( "+b", Prefix, Client, Channel, mask ); return Send_ListChange( "+b", Prefix, Client, Channel, mask );
} /* Add_Ban */ } /* Add_Ban */
@@ -686,7 +690,7 @@ Del_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
assert( Pattern != NULL ); assert( Pattern != NULL );
mask = Lists_MakeMask( Pattern ); mask = Lists_MakeMask( Pattern );
Lists_DelInvited( mask, Channel ); Lists_Del(Channel_GetListInvites(Channel), mask);
return Send_ListChange( "-I", Prefix, Client, Channel, mask ); return Send_ListChange( "-I", Prefix, Client, Channel, mask );
} /* Del_Invite */ } /* Del_Invite */
@@ -701,7 +705,7 @@ Del_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
assert( Pattern != NULL ); assert( Pattern != NULL );
mask = Lists_MakeMask( Pattern ); mask = Lists_MakeMask( Pattern );
Lists_DelBanned( mask, Channel ); Lists_Del(Channel_GetListBans(Channel), mask);
return Send_ListChange( "-b", Prefix, Client, Channel, mask ); return Send_ListChange( "-b", Prefix, Client, Channel, mask );
} /* Del_Ban */ } /* Del_Ban */

View File

@@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-op.c,v 1.15 2005/04/27 07:39:18 alex Exp $"; static char UNUSED id[] = "$Id: irc-op.c,v 1.15.4.2 2007/04/03 20:23:31 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -99,17 +99,17 @@ IRC_INVITE( CLIENT *Client, REQUEST *Req )
if( Channel_IsMemberOf( chan, target )) return IRC_WriteStrClient( from, ERR_USERONCHANNEL_MSG, Client_ID( from ), Req->argv[0], Req->argv[1] ); if( Channel_IsMemberOf( chan, target )) return IRC_WriteStrClient( from, ERR_USERONCHANNEL_MSG, Client_ID( from ), Req->argv[0], Req->argv[1] );
/* If the target user is banned on that channel: remember invite */ /* If the target user is banned on that channel: remember invite */
if( Lists_CheckBanned( target, chan )) remember = true; if( Lists_Check(Channel_GetListBans(chan), target )) remember = true;
if( remember ) if (remember) {
{ /* We must remember this invite */
/* We must memember this invite */ if( ! Channel_AddInvite(chan, Client_Mask( target ), true))
if( ! Lists_AddInvited( Client_Mask( target ), chan, true)) return CONNECTED; return CONNECTED;
} }
} }
Log( LOG_DEBUG, "User \"%s\" invites \"%s\" to \"%s\" ...", Client_Mask( from ), Req->argv[0], Req->argv[1] ); LogDebug("User \"%s\" invites \"%s\" to \"%s\" ...", Client_Mask(from), Req->argv[0], Req->argv[1]);
/* Inform target client */ /* Inform target client */
IRC_WriteStrClientPrefix( target, from, "INVITE %s %s", Req->argv[0], Req->argv[1] ); IRC_WriteStrClientPrefix( target, from, "INVITE %s %s", Req->argv[0], Req->argv[1] );

View File

@@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-server.c,v 1.39 2006/04/30 21:31:43 alex Exp $"; static char UNUSED id[] = "$Id: irc-server.c,v 1.39.2.3 2007/04/03 20:23:31 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -41,6 +41,54 @@ static char UNUSED id[] = "$Id: irc-server.c,v 1.39 2006/04/30 21:31:43 alex Exp
#include "irc-server.h" #include "irc-server.h"
#ifdef IRCPLUS
static bool
Synchronize_Lists( CLIENT *Client )
{
CHANNEL *c;
struct list_head *head;
struct list_elem *elem;
assert( Client != NULL );
c = Channel_First();
while (c) {
head = Channel_GetListBans(c);
elem = Lists_GetFirst(head);
while (elem) {
if( ! IRC_WriteStrClient( Client, "MODE %s +b %s",
Channel_Name(c), Lists_GetMask(elem)))
{
return false;
}
elem = Lists_GetNext(elem);
}
head = Channel_GetListInvites(c);
elem = Lists_GetFirst(head);
while (elem) {
if( ! IRC_WriteStrClient( Client, "MODE %s +I %s",
Channel_Name( c ), Lists_GetMask(elem)))
{
return false;
}
elem = Lists_GetNext(elem);
}
c = Channel_Next(c);
}
return true;
}
#endif
/**
* Handler for the IRC command "SERVER".
* See RFC 2813 section 4.1.2.
*/
GLOBAL bool GLOBAL bool
IRC_SERVER( CLIENT *Client, REQUEST *Req ) IRC_SERVER( CLIENT *Client, REQUEST *Req )
{ {
@@ -55,13 +103,16 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
/* Fehler liefern, wenn kein lokaler Client */ /* Return an error if this is not a local client */
if( Client_Conn( Client ) <= NONE ) return IRC_WriteStrClient( Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( Client ), Req->command ); if (Client_Conn(Client) <= NONE)
return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG,
Client_ID(Client), Req->command);
if( Client_Type( Client ) == CLIENT_GOTPASSSERVER ) if (Client_Type(Client) == CLIENT_GOTPASS) {
{ /* We got a PASS command from the peer, and now a SERVER
/* Verbindung soll als Server-Server-Verbindung registriert werden */ * command: the peer tries to register itself as a server. */
Log( LOG_DEBUG, "Connection %d: got SERVER command (new server link) ...", Client_Conn( Client )); LogDebug("Connection %d: got SERVER command (new server link) ...",
Client_Conn(Client));
/* Falsche Anzahl Parameter? */ /* Falsche Anzahl Parameter? */
if(( Req->argc != 2 ) && ( Req->argc != 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); if(( Req->argc != 2 ) && ( Req->argc != 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
@@ -207,7 +258,13 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
else else
{ {
/* "CHANINFO <chan> +<modes> <key> <limit> :<topic>" */ /* "CHANINFO <chan> +<modes> <key> <limit> :<topic>" */
if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s %s %ld :%s", Channel_Name( chan ), modes, strchr( Channel_Modes( chan ), 'k' ) ? Channel_Key( chan ) : "*", strchr( Channel_Modes( chan ), 'l' ) ? Channel_MaxUsers( chan ) : 0L, topic )) return DISCONNECTED; if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s %s %lu :%s",
Channel_Name( chan ), modes,
strchr( Channel_Modes( chan ), 'k' ) ? Channel_Key( chan ) : "*",
strchr( Channel_Modes( chan ), 'l' ) ? Channel_MaxUsers( chan ) : 0UL, topic ))
{
return DISCONNECTED;
}
} }
} }
} }
@@ -255,9 +312,7 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
"Synchronizing INVITE- and BAN-lists ..."); "Synchronizing INVITE- and BAN-lists ...");
#endif #endif
/* Synchronize INVITE- and BAN-lists */ /* Synchronize INVITE- and BAN-lists */
if (! Lists_SendInvites(Client)) if (!Synchronize_Lists(Client))
return DISCONNECTED;
if (! Lists_SendBans(Client))
return DISCONNECTED; return DISCONNECTED;
} }
#endif #endif

View File

@@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-write.c,v 1.20 2006/05/10 21:24:01 alex Exp $"; static char UNUSED id[] = "$Id: irc-write.c,v 1.20.2.1 2006/12/02 13:06:50 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -378,7 +378,7 @@ va_dcl
} }
cl2chan = Channel_NextMember( chan, cl2chan ); cl2chan = Channel_NextMember( chan, cl2chan );
} }
/* naechsten Channel */ /* naechsten Channel */
chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan ); chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan );
} }
@@ -403,12 +403,12 @@ GLOBAL void
IRC_SetPenalty( CLIENT *Client, time_t Seconds ) IRC_SetPenalty( CLIENT *Client, time_t Seconds )
{ {
CONN_ID c; CONN_ID c;
assert( Client != NULL ); assert( Client != NULL );
assert( Seconds > 0 ); assert( Seconds > 0 );
if( Client_Type( Client ) == CLIENT_SERVER ) return; if( Client_Type( Client ) == CLIENT_SERVER ) return;
c = Client_Conn( Client ); c = Client_Conn( Client );
if (c > NONE) if (c > NONE)
Conn_SetPenalty(c, Seconds); Conn_SetPenalty(c, Seconds);

View File

@@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: lists.c,v 1.18 2005/07/31 20:13:08 alex Exp $"; static char UNUSED id[] = "$Id: lists.c,v 1.18.2.3 2007/04/03 22:08:52 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -35,326 +35,131 @@ static char UNUSED id[] = "$Id: lists.c,v 1.18 2005/07/31 20:13:08 alex Exp $";
#include "exp.h" #include "exp.h"
#include "lists.h" #include "lists.h"
#define MASK_LEN (2*CLIENT_HOST_LEN)
#define MASK_LEN 2*CLIENT_HOST_LEN struct list_elem {
struct list_elem *next;
typedef struct _C2C
{
struct _C2C *next;
char mask[MASK_LEN]; char mask[MASK_LEN];
CHANNEL *channel;
bool onlyonce; bool onlyonce;
} C2C; };
static C2C *My_Invites, *My_Bans; GLOBAL const char *
Lists_GetMask(const struct list_elem *e)
static C2C *New_C2C PARAMS(( char *Mask, CHANNEL *Chan, bool OnlyOnce ));
static bool Check_List PARAMS(( C2C **Cl2Chan, CLIENT *Client, CHANNEL *Chan ));
static bool Already_Registered PARAMS(( C2C *Cl2Chan, char *Mask, CHANNEL *Chan ));
GLOBAL void
Lists_Init( void )
{ {
/* Modul initialisieren */ return e->mask;
}
My_Invites = My_Bans = NULL;
} /* Lists_Init */
GLOBAL void GLOBAL struct list_elem*
Lists_Exit( void ) Lists_GetFirst(const struct list_head *h)
{ {
/* Modul abmelden */ return h->first;
}
C2C *c2c, *next;
/* Invite-Lists freigeben */
c2c = My_Invites;
while( c2c )
{
next = c2c->next;
free( c2c );
c2c = next;
}
/* Ban-Lists freigeben */
c2c = My_Bans;
while( c2c )
{
next = c2c->next;
free( c2c );
c2c = next;
}
} /* Lists_Exit */
GLOBAL bool GLOBAL struct list_elem*
Lists_CheckInvited( CLIENT *Client, CHANNEL *Chan ) Lists_GetNext(const struct list_elem *e)
{ {
return Check_List( &My_Invites, Client, Chan ); return e->next;
} /* Lists_CheckInvited */ }
GLOBAL bool bool
Lists_IsInviteEntry( char *Mask, CHANNEL *Chan ) Lists_Add(struct list_head *header, const char *Mask, bool OnlyOnce )
{ {
struct list_elem *e, *newelem;
assert( header != NULL );
assert( Mask != NULL ); assert( Mask != NULL );
assert( Chan != NULL );
return Already_Registered( My_Invites, Mask, Chan );
} /* Lists_IsInviteEntry */
if (Lists_CheckDupeMask(header, Mask )) return true;
GLOBAL bool e = Lists_GetFirst(header);
Lists_AddInvited( char *Mask, CHANNEL *Chan, bool OnlyOnce )
{
C2C *c2c;
assert( Mask != NULL ); newelem = malloc(sizeof(struct list_elem));
assert( Chan != NULL ); if( ! newelem ) {
Log( LOG_EMERG, "Can't allocate memory for new Ban/Invite entry!" );
if( Already_Registered( My_Invites, Mask, Chan )) return true;
c2c = New_C2C( Mask, Chan, OnlyOnce );
if( ! c2c )
{
Log( LOG_ERR, "Can't add new invite list entry!" );
return false; return false;
} }
/* verketten */ strlcpy( newelem->mask, Mask, sizeof( newelem->mask ));
c2c->next = My_Invites; newelem->onlyonce = OnlyOnce;
My_Invites = c2c; newelem->next = e;
header->first = newelem;
Log( LOG_DEBUG, "Added \"%s\" to invite list for \"%s\".", Mask, Channel_Name( Chan )); LogDebug("Added \"%s\" to invite list", Mask);
return true; return true;
} /* Lists_AddInvited */ }
static void
Lists_Unlink(struct list_head *header, struct list_elem *p, struct list_elem *victim)
{
assert(victim != NULL);
assert(header != NULL);
if (p) p->next = victim->next;
else header->first = victim->next;
free(victim);
}
GLOBAL void GLOBAL void
Lists_DelInvited( char *Mask, CHANNEL *Chan ) Lists_Del(struct list_head *header, const char *Mask)
{ {
C2C *c2c, *last, *next; struct list_elem *e, *last, *victim;
assert( header != NULL );
assert( Mask != NULL ); assert( Mask != NULL );
assert( Chan != NULL );
last = NULL; last = NULL;
c2c = My_Invites; e = Lists_GetFirst(header);
while( c2c ) while( e ) {
{ if(strcasecmp( e->mask, Mask ) == 0 ) {
next = c2c->next; LogDebug("Deleted \"%s\" from list", e->mask);
if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 )) victim = e;
{ e = victim->next;
/* dieser Eintrag muss geloescht werden */ Lists_Unlink(header, last, victim);
Log( LOG_DEBUG, "Deleted \"%s\" from invite list for \"%s\"." , c2c->mask, Channel_Name( Chan )); continue;
if( last ) last->next = next;
else My_Invites = next;
free( c2c );
} }
else last = c2c; last = e;
c2c = next; e = e->next;
} }
} /* Lists_DelInvited */ }
GLOBAL bool
Lists_ShowInvites( CLIENT *Client, CHANNEL *Channel )
{
C2C *c2c;
assert( Client != NULL );
assert( Channel != NULL );
c2c = My_Invites;
while( c2c )
{
if( c2c->channel == Channel )
{
/* Eintrag fuer Channel gefunden; ausgeben: */
if( ! IRC_WriteStrClient( Client, RPL_INVITELIST_MSG, Client_ID( Client ), Channel_Name( Channel ), c2c->mask )) return DISCONNECTED;
}
c2c = c2c->next;
}
return IRC_WriteStrClient( Client, RPL_ENDOFINVITELIST_MSG, Client_ID( Client ), Channel_Name( Channel ));
} /* Lists_ShowInvites */
GLOBAL bool
Lists_SendInvites( CLIENT *Client )
{
C2C *c2c;
assert( Client != NULL );
c2c = My_Invites;
while( c2c )
{
if( ! IRC_WriteStrClient( Client, "MODE %s +I %s", Channel_Name( c2c->channel ), c2c->mask )) return DISCONNECTED;
c2c = c2c->next;
}
return CONNECTED;
} /* Lists_SendInvites */
GLOBAL bool
Lists_SendBans( CLIENT *Client )
{
C2C *c2c;
assert( Client != NULL );
c2c = My_Bans;
while( c2c )
{
if( ! IRC_WriteStrClient( Client, "MODE %s +b %s", Channel_Name( c2c->channel ), c2c->mask )) return DISCONNECTED;
c2c = c2c->next;
}
return CONNECTED;
} /* Lists_SendBans */
GLOBAL bool
Lists_CheckBanned( CLIENT *Client, CHANNEL *Chan )
{
return Check_List( &My_Bans, Client, Chan );
} /* Lists_CheckBanned */
GLOBAL bool
Lists_IsBanEntry( char *Mask, CHANNEL *Chan )
{
assert( Mask != NULL );
assert( Chan != NULL );
return Already_Registered( My_Bans, Mask, Chan );
} /* Lists_IsBanEntry */
GLOBAL bool
Lists_AddBanned( char *Mask, CHANNEL *Chan )
{
C2C *c2c;
assert( Mask != NULL );
assert( Chan != NULL );
if( Already_Registered( My_Bans, Mask, Chan )) return true;
c2c = New_C2C( Mask, Chan, false );
if( ! c2c )
{
Log( LOG_ERR, "Can't add new ban list entry!" );
return false;
}
/* verketten */
c2c->next = My_Bans;
My_Bans = c2c;
Log( LOG_DEBUG, "Added \"%s\" to ban list for \"%s\".", Mask, Channel_Name( Chan ));
return true;
} /* Lists_AddBanned */
GLOBAL void GLOBAL void
Lists_DelBanned( char *Mask, CHANNEL *Chan ) Lists_Free(struct list_head *head)
{ {
C2C *c2c, *last, *next; struct list_elem *e, *victim;
assert( Mask != NULL ); assert(head != NULL);
assert( Chan != NULL );
last = NULL; e = head->first;
c2c = My_Bans; head->first = NULL;
while( c2c ) while (e) {
{ LogDebug("Deleted \"%s\" from invite list" , e->mask);
next = c2c->next; victim = e;
if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 )) e = e->next;
{ free( victim );
/* dieser Eintrag muss geloescht werden */
Log( LOG_DEBUG, "Deleted \"%s\" from ban list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
if( last ) last->next = next;
else My_Bans = next;
free( c2c );
}
else last = c2c;
c2c = next;
} }
} /* Lists_DelBanned */ }
GLOBAL bool GLOBAL bool
Lists_ShowBans( CLIENT *Client, CHANNEL *Channel ) Lists_CheckDupeMask(const struct list_head *h, const char *Mask )
{ {
C2C *c2c; struct list_elem *e;
e = h->first;
assert( Client != NULL ); while (e) {
assert( Channel != NULL ); if (strcasecmp( e->mask, Mask ) == 0 )
return true;
c2c = My_Bans; e = e->next;
while( c2c )
{
if( c2c->channel == Channel )
{
/* Eintrag fuer Channel gefunden; ausgeben: */
if( ! IRC_WriteStrClient( Client, RPL_BANLIST_MSG, Client_ID( Client ), Channel_Name( Channel ), c2c->mask )) return DISCONNECTED;
}
c2c = c2c->next;
} }
return IRC_WriteStrClient( Client, RPL_ENDOFBANLIST_MSG, Client_ID( Client ), Channel_Name( Channel )); return false;
} /* Lists_ShowBans */ }
GLOBAL void
Lists_DeleteChannel( CHANNEL *Chan )
{
/* Channel wurde geloescht, Invite- und Ban-Lists aufraeumen */
C2C *c2c, *last, *next;
/* Invite-List */
last = NULL;
c2c = My_Invites;
while( c2c )
{
next = c2c->next;
if( c2c->channel == Chan )
{
/* dieser Eintrag muss geloescht werden */
Log( LOG_DEBUG, "Deleted \"%s\" from invite list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
if( last ) last->next = next;
else My_Invites = next;
free( c2c );
}
else last = c2c;
c2c = next;
}
/* Ban-List */
last = NULL;
c2c = My_Bans;
while( c2c )
{
next = c2c->next;
if( c2c->channel == Chan )
{
/* dieser Eintrag muss geloescht werden */
Log( LOG_DEBUG, "Deleted \"%s\" from ban list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
if( last ) last->next = next;
else My_Bans = next;
free( c2c );
}
else last = c2c;
c2c = next;
}
} /* Lists_DeleteChannel */
GLOBAL char * GLOBAL char *
@@ -407,82 +212,30 @@ Lists_MakeMask( char *Pattern )
} /* Lists_MakeMask */ } /* Lists_MakeMask */
static C2C *
New_C2C( char *Mask, CHANNEL *Chan, bool OnlyOnce ) bool
Lists_Check( struct list_head *header, CLIENT *Client)
{ {
C2C *c2c; struct list_elem *e, *last;
assert( Mask != NULL );
assert( Chan != NULL );
/* Speicher fuer Eintrag anfordern */ assert( header != NULL );
c2c = (C2C *)malloc( sizeof( C2C ));
if( ! c2c )
{
Log( LOG_EMERG, "Can't allocate memory! [New_C2C]" );
return NULL;
}
strlcpy( c2c->mask, Mask, sizeof( c2c->mask )); e = header->first;
c2c->channel = Chan;
c2c->onlyonce = OnlyOnce;
return c2c;
} /* New_C2C */
static bool
Check_List( C2C **Cl2Chan, CLIENT *Client, CHANNEL *Chan )
{
C2C *c2c, *last;
assert( Cl2Chan != NULL );
assert( Client != NULL );
assert( Chan != NULL );
c2c = *Cl2Chan;
last = NULL; last = NULL;
while( c2c ) while( e ) {
{ if( Match( e->mask, Client_Mask( Client ))) {
if( c2c->channel == Chan ) if( e->onlyonce ) { /* delete entry */
{ LogDebug("Deleted \"%s\" from list", e->mask);
/* Ok, richtiger Channel. Passt die Maske? */ Lists_Unlink(header, last, e);
if( Match( c2c->mask, Client_Mask( Client )))
{
/* Treffer! */
if( c2c->onlyonce )
{
/* Eintrag loeschen */
Log( LOG_DEBUG, "Deleted \"%s\" from %s list for \"%s\".", c2c->mask, *Cl2Chan == My_Invites ? "invite" : "ban", Channel_Name( Chan ));
if( last ) last->next = c2c->next;
else *Cl2Chan = c2c->next;
free( c2c );
}
return true;
} }
return true;
} }
last = c2c; last = e;
c2c = c2c->next; e = e->next;
} }
return false; return false;
} /* Check_List */ }
static bool
Already_Registered( C2C *List, char *Mask, CHANNEL *Chan )
{
C2C *c2c;
c2c = List;
while( c2c )
{
if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 )) return true;
c2c = c2c->next;
}
return false;
} /* Already_Registered */
/* -eof- */ /* -eof- */

View File

@@ -8,7 +8,7 @@
* (at your option) any later version. * (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information. * Please read the file COPYING, README and AUTHORS for more information.
* *
* $Id: lists.h,v 1.12 2005/03/19 18:43:49 fw Exp $ * $Id: lists.h,v 1.12.4.1 2007/04/03 20:23:31 fw Exp $
* *
* Management of IRC lists: ban, invite, ... (header) * Management of IRC lists: ban, invite, ... (header)
*/ */
@@ -16,31 +16,31 @@
#ifndef __lists_h__ #ifndef __lists_h__
#define __lists_h__ #define __lists_h__
#include "portab.h"
#include "client.h"
struct list_elem;
struct list_head {
struct list_elem *first;
};
GLOBAL void Lists_Init PARAMS(( void )); GLOBAL struct list_elem *Lists_GetFirst PARAMS((const struct list_head *));
GLOBAL void Lists_Exit PARAMS(( void )); GLOBAL struct list_elem *Lists_GetNext PARAMS((const struct list_elem *));
GLOBAL bool Lists_CheckInvited PARAMS(( CLIENT *Client, CHANNEL *Chan )); GLOBAL bool Lists_Check PARAMS((struct list_head *head, CLIENT *client ));
GLOBAL bool Lists_AddInvited PARAMS(( char *Mask, CHANNEL *Chan, bool OnlyOnce )); GLOBAL bool Lists_CheckDupeMask PARAMS((const struct list_head *head, const char *mask ));
GLOBAL void Lists_DelInvited PARAMS(( char *Mask, CHANNEL *Chan ));
GLOBAL bool Lists_ShowInvites PARAMS(( CLIENT *Client, CHANNEL *Channel ));
GLOBAL bool Lists_SendInvites PARAMS(( CLIENT *Client ));
GLOBAL bool Lists_IsInviteEntry PARAMS(( char *Mask, CHANNEL *Chan ));
GLOBAL bool Lists_CheckBanned PARAMS(( CLIENT *Client, CHANNEL *Chan )); GLOBAL bool Lists_Add PARAMS((struct list_head *header, const char *Mask, bool OnlyOnce ));
GLOBAL bool Lists_AddBanned PARAMS(( char *Mask, CHANNEL *Chan )); GLOBAL void Lists_Del PARAMS((struct list_head *head, const char *Mask ));
GLOBAL void Lists_DelBanned PARAMS(( char *Mask, CHANNEL *Chan ));
GLOBAL bool Lists_ShowBans PARAMS(( CLIENT *Client, CHANNEL *Channel ));
GLOBAL bool Lists_SendBans PARAMS(( CLIENT *Client ));
GLOBAL bool Lists_IsBanEntry PARAMS(( char *Mask, CHANNEL *Chan ));
GLOBAL void Lists_DeleteChannel PARAMS(( CHANNEL *Chan )); GLOBAL bool Lists_AlreadyRegistered PARAMS(( const struct list_head *head, const char *Mask));
GLOBAL void Lists_Free PARAMS(( struct list_head *head ));
GLOBAL char *Lists_MakeMask PARAMS(( char *Pattern )); GLOBAL char *Lists_MakeMask PARAMS(( char *Pattern ));
GLOBAL const char *Lists_GetMask PARAMS(( const struct list_elem *e ));
#endif #endif
/* -eof- */ /* -eof- */

View File

@@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: log.c,v 1.61 2006/07/23 23:23:45 alex Exp $"; static char UNUSED id[] = "$Id: log.c,v 1.61.2.1 2006/12/02 13:02:07 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -166,25 +166,21 @@ Log_Exit( void )
* Log function for debug messages. * Log function for debug messages.
* This function is only functional when the program is compiled with debug * This function is only functional when the program is compiled with debug
* code enabled; otherwise it is an empty function which the compiler will * code enabled; otherwise it is an empty function which the compiler will
* hopefully mangle down to "nothing". Therefore you should use LogDebug(...) * hopefully mangle down to "nothing" (see log.h). Therefore you should use
* in favor to Log(LOG_DEBUG, ...). * LogDebug(...) in favor to Log(LOG_DEBUG, ...).
* @param Format Format string like printf(). * @param Format Format string like printf().
* @param ... Further arguments. * @param ... Further arguments.
*/ */
#ifdef DEBUG
# ifdef PROTOTYPES # ifdef PROTOTYPES
GLOBAL void GLOBAL void
#ifdef DEBUG
LogDebug( const char *Format, ... ) LogDebug( const char *Format, ... )
#else
LogDebug( UNUSED const char *Format, ... )
#endif /* DEBUG */
# else # else
GLOBAL void GLOBAL void
LogDebug( Format, va_alist ) LogDebug( Format, va_alist )
const char *Format; const char *Format;
va_dcl va_dcl
# endif /* PROTOTYPES */ # endif /* PROTOTYPES */
#ifdef DEBUG
{ {
char msg[MAX_LOG_MSG_LEN]; char msg[MAX_LOG_MSG_LEN];
va_list ap; va_list ap;
@@ -199,14 +195,9 @@ va_dcl
va_end( ap ); va_end( ap );
Log(LOG_DEBUG, "%s", msg); Log(LOG_DEBUG, "%s", msg);
} }
#else
{
/* Do nothing.
* The compiler should optimize this out, please ;-) */
}
#endif /* DEBUG */ #endif /* DEBUG */
/** /**
* Logging function of ngIRCd. * Logging function of ngIRCd.
* This function logs messages to the console and/or syslog, whichever is * This function logs messages to the console and/or syslog, whichever is

View File

@@ -8,7 +8,7 @@
* (at your option) any later version. * (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information. * Please read the file COPYING, README and AUTHORS for more information.
* *
* $Id: log.h,v 1.19 2006/02/08 17:33:28 fw Exp $ * $Id: log.h,v 1.19.2.1 2006/12/02 13:02:07 fw Exp $
* *
* Logging functions (header) * Logging functions (header)
*/ */
@@ -39,7 +39,13 @@ GLOBAL void Log_Init PARAMS(( bool Daemon_Mode ));
GLOBAL void Log_Exit PARAMS(( void )); GLOBAL void Log_Exit PARAMS(( void ));
GLOBAL void Log PARAMS(( int Level, const char *Format, ... )); GLOBAL void Log PARAMS(( int Level, const char *Format, ... ));
#ifdef DEBUG
GLOBAL void LogDebug PARAMS(( const char *Format, ... )); GLOBAL void LogDebug PARAMS(( const char *Format, ... ));
#else
static inline void LogDebug PARAMS(( UNUSED const char *Format, ... )){/* Do nothing. The compiler should optimize this out, please ;-) */}
#endif
GLOBAL void Log_Init_Resolver PARAMS(( void )); GLOBAL void Log_Init_Resolver PARAMS(( void ));
GLOBAL void Log_Exit_Resolver PARAMS(( void )); GLOBAL void Log_Exit_Resolver PARAMS(( void ));

View File

@@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: match.c,v 1.4 2005/07/31 20:13:08 alex Exp $"; static char UNUSED id[] = "$Id: match.c,v 1.4.2.1 2006/12/02 13:01:11 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -32,8 +32,8 @@ static char UNUSED id[] = "$Id: match.c,v 1.4 2005/07/31 20:13:08 alex Exp $";
*/ */
static int Matche PARAMS(( char *p, char *t )); static int Matche PARAMS(( const char *p, const char *t ));
static int Matche_After_Star PARAMS(( char *p, char *t )); static int Matche_After_Star PARAMS(( const char *p, const char *t ));
#define MATCH_PATTERN 6 /* bad pattern */ #define MATCH_PATTERN 6 /* bad pattern */
@@ -45,7 +45,7 @@ static int Matche_After_Star PARAMS(( char *p, char *t ));
GLOBAL bool GLOBAL bool
Match( char *Pattern, char *String ) Match( const char *Pattern, const char *String )
{ {
/* Pattern mit String vergleichen */ /* Pattern mit String vergleichen */
if( Matche( Pattern, String ) == MATCH_VALID ) return true; if( Matche( Pattern, String ) == MATCH_VALID ) return true;
@@ -54,7 +54,7 @@ Match( char *Pattern, char *String )
static int static int
Matche( char *p, char *t ) Matche( const char *p, const char *t )
{ {
register char range_start, range_end; register char range_start, range_end;
bool invert; bool invert;
@@ -201,7 +201,7 @@ Matche( char *p, char *t )
static int static int
Matche_After_Star( char *p, char *t ) Matche_After_Star( const char *p, const char *t )
{ {
register int nextp, match = 0; register int nextp, match = 0;

View File

@@ -8,7 +8,7 @@
* (at your option) any later version. * (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information. * Please read the file COPYING, README and AUTHORS for more information.
* *
* $Id: match.h,v 1.3 2005/03/19 18:43:49 fw Exp $ * $Id: match.h,v 1.3.4.1 2006/12/02 13:01:11 fw Exp $
* *
* Wildcard pattern matching (header) * Wildcard pattern matching (header)
*/ */
@@ -18,7 +18,7 @@
#define __match_h__ #define __match_h__
GLOBAL bool Match PARAMS(( char *Pattern, char *String )); GLOBAL bool Match PARAMS(( const char *Pattern, const char *String ));
#endif #endif

View File

@@ -8,7 +8,7 @@
* (at your option) any later version. * (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information. * Please read the file COPYING, README and AUTHORS for more information.
* *
* $Id: messages.h,v 1.67 2005/09/02 12:50:25 alex Exp $ * $Id: messages.h,v 1.67.2.2 2006/12/02 14:26:53 fw Exp $
* *
* IRC numerics (Header) * IRC numerics (Header)
*/ */
@@ -22,7 +22,8 @@
#define RPL_YOURHOST_MSG "002 %s :Your host is %s, running version ngircd-%s (%s/%s/%s)" #define RPL_YOURHOST_MSG "002 %s :Your host is %s, running version ngircd-%s (%s/%s/%s)"
#define RPL_CREATED_MSG "003 %s :This server has been started %s" #define RPL_CREATED_MSG "003 %s :This server has been started %s"
#define RPL_MYINFO_MSG "004 %s %s ngircd-%s %s %s" #define RPL_MYINFO_MSG "004 %s %s ngircd-%s %s %s"
#define RPL_ISUPPORT_MSG "005 %s NICKLEN=%d TOPICLEN=%d AWAYLEN=%d MAXCHANNELS=%d :are supported on this server" #define RPL_ISUPPORT1_MSG "005 %s RFC2812 CASEMAPPING=ascii PREFIX=(ov)@+ CHANTYPES=# CHANMODES=bI,k,l,imnPst CHANLIMIT=#:%d :are supported on this server"
#define RPL_ISUPPORT2_MSG "005 %s CHANNELLEN=%d NICKLEN=%d TOPICLEN=%d AWAYLEN=%d KICKLEN=%d PENALTY :are supported on this server"
#define RPL_TRACELINK_MSG "200 %s Link %s-%s %s %s V%s %ld %d %d" #define RPL_TRACELINK_MSG "200 %s Link %s-%s %s %s V%s %ld %d %d"
#define RPL_TRACEOPERATOR_MSG "204 %s Oper 2 :%s" #define RPL_TRACEOPERATOR_MSG "204 %s Oper 2 :%s"
@@ -32,17 +33,17 @@
#define RPL_ENDOFSTATS_MSG "219 %s %c :End of STATS report" #define RPL_ENDOFSTATS_MSG "219 %s %c :End of STATS report"
#define RPL_UMODEIS_MSG "221 %s +%s" #define RPL_UMODEIS_MSG "221 %s +%s"
#define RPL_LUSERCLIENT_MSG "251 %s :There are %ld users and %ld services on %ld servers" #define RPL_LUSERCLIENT_MSG "251 %s :There are %ld users and %ld services on %ld servers"
#define RPL_LUSEROP_MSG "252 %s %ld :operator(s) online" #define RPL_LUSEROP_MSG "252 %s %lu :operator(s) online"
#define RPL_LUSERUNKNOWN_MSG "253 %s %ld :unknown connection(s)" #define RPL_LUSERUNKNOWN_MSG "253 %s %lu :unknown connection(s)"
#define RPL_LUSERCHANNELS_MSG "254 %s %ld :channels formed" #define RPL_LUSERCHANNELS_MSG "254 %s %lu :channels formed"
#define RPL_LUSERME_MSG "255 %s :I have %ld users, %ld services and %ld servers" #define RPL_LUSERME_MSG "255 %s :I have %lu users, %lu services and %lu servers"
#define RPL_ADMINME_MSG "256 %s %s :Administrative info" #define RPL_ADMINME_MSG "256 %s %s :Administrative info"
#define RPL_ADMINLOC1_MSG "257 %s :%s" #define RPL_ADMINLOC1_MSG "257 %s :%s"
#define RPL_ADMINLOC2_MSG "258 %s :%s" #define RPL_ADMINLOC2_MSG "258 %s :%s"
#define RPL_ADMINEMAIL_MSG "259 %s :%s" #define RPL_ADMINEMAIL_MSG "259 %s :%s"
#define RPL_TRACEEND_MSG "262 %s %s %s-%s.%s :End of TRACE" #define RPL_TRACEEND_MSG "262 %s %s %s-%s.%s :End of TRACE"
#define RPL_LOCALUSERS_MSG "265 %s :Current local users: %ld, Max: %ld" #define RPL_LOCALUSERS_MSG "265 %s %lu %lu :Current local users: %lu, Max: %lu"
#define RPL_NETUSERS_MSG "266 %s :Current global users: %ld, Max: %ld" #define RPL_NETUSERS_MSG "266 %s %lu %lu :Current global users: %lu, Max: %lu"
#define RPL_AWAY_MSG "301 %s %s :%s" #define RPL_AWAY_MSG "301 %s %s :%s"
#define RPL_USERHOST_MSG "302 %s :" #define RPL_USERHOST_MSG "302 %s :"

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2006 Alexander Barton (alex@barton.de). * Copyright (c)2001-2007 Alexander Barton (alex@barton.de).
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -12,7 +12,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: ngircd.c,v 1.113 2006/07/23 12:07:33 alex Exp $"; static char UNUSED id[] = "$Id: ngircd.c,v 1.113.2.2 2007/05/05 20:25:47 alex Exp $";
/** /**
* @file * @file
@@ -271,7 +271,6 @@ main( int argc, const char *argv[] )
/* Initialize modules, part II: these functions are eventually /* Initialize modules, part II: these functions are eventually
* called with already dropped privileges ... */ * called with already dropped privileges ... */
Lists_Init( );
Channel_Init( ); Channel_Init( );
Client_Init( ); Client_Init( );
#ifdef ZEROCONF #ifdef ZEROCONF
@@ -328,7 +327,6 @@ main( int argc, const char *argv[] )
#endif #endif
Client_Exit( ); Client_Exit( );
Channel_Exit( ); Channel_Exit( );
Lists_Exit( );
Log_Exit( ); Log_Exit( );
} }
Pidfile_Delete( ); Pidfile_Delete( );
@@ -548,7 +546,7 @@ static void
Show_Version( void ) Show_Version( void )
{ {
puts( NGIRCd_Version ); puts( NGIRCd_Version );
puts( "Copyright (c)2001-2006 Alexander Barton (<alex@barton.de>) and Contributors." ); puts( "Copyright (c)2001-2007 Alexander Barton (<alex@barton.de>) and Contributors." );
puts( "Homepage: <http://ngircd.barton.de/>\n" ); puts( "Homepage: <http://ngircd.barton.de/>\n" );
puts( "This is free software; see the source for copying conditions. There is NO" ); 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." ); puts( "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." );

View File

@@ -12,7 +12,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: parse.c,v 1.67 2006/04/23 10:37:27 fw Exp $"; static char UNUSED id[] = "$Id: parse.c,v 1.67.2.1 2008/02/05 13:15:05 fw Exp $";
/** /**
* @file * @file
@@ -348,7 +348,7 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
char str[LINE_LEN]; char str[LINE_LEN];
bool result; bool result;
COMMAND *cmd; COMMAND *cmd;
int i; int i, client_type;
assert( Idx >= 0 ); assert( Idx >= 0 );
assert( Req != NULL ); assert( Req != NULL );
@@ -406,6 +406,7 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
} }
cmd = My_Commands; cmd = My_Commands;
client_type = Client_Type( client );
while( cmd->name ) while( cmd->name )
{ {
/* Befehl suchen */ /* Befehl suchen */
@@ -414,7 +415,7 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
cmd++; continue; cmd++; continue;
} }
if( Client_Type( client ) & cmd->type ) if( client_type & cmd->type )
{ {
/* Command is allowed for this client: call it and count produced bytes */ /* Command is allowed for this client: call it and count produced bytes */
Conn_ResetWCounter( ); Conn_ResetWCounter( );
@@ -422,7 +423,7 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
cmd->bytes += Conn_WCounter( ); cmd->bytes += Conn_WCounter( );
/* Adjust counters */ /* Adjust counters */
if( Client_Type( client ) != CLIENT_SERVER ) cmd->lcount++; if( client_type != CLIENT_SERVER ) cmd->lcount++;
else cmd->rcount++; else cmd->rcount++;
return result; return result;

View File

@@ -14,7 +14,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: resolve.c,v 1.24 2006/05/10 21:24:01 alex Exp $"; static char UNUSED id[] = "$Id: resolve.c,v 1.24.2.2 2006/12/17 22:59:56 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
@@ -313,7 +313,8 @@ register_callback( RES_STAT *s, void (*cbfunc)(int, short))
return true; return true;
Log( LOG_CRIT, "Resolver: Could not register callback function: %s!", strerror(errno)); Log( LOG_CRIT, "Resolver: Could not register callback function: %s!", strerror(errno));
Resolve_Shutdown(s); close(s->resolver_fd);
Resolve_Init(s);
return false; return false;
} }
@@ -333,40 +334,31 @@ Resolve_Shutdown( RES_STAT *s)
return ret; return ret;
} }
/** /**
* Read result of resolver sub-process from pipe * Read result of resolver sub-process from pipe
*/ */
GLOBAL size_t GLOBAL size_t
Resolve_Read( RES_STAT *s, void* readbuf, size_t buflen) Resolve_Read( RES_STAT *s, void* readbuf, size_t buflen)
{ {
int err;
ssize_t bytes_read; ssize_t bytes_read;
assert(buflen > 0); assert(buflen > 0);
/* Read result from pipe */ /* Read result from pipe */
errno = 0;
bytes_read = read(s->resolver_fd, readbuf, buflen); bytes_read = read(s->resolver_fd, readbuf, buflen);
if (bytes_read < 0) { if (bytes_read < 0) {
if (errno != EAGAIN) { 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;
}
return 0;
}
Resolve_Shutdown(s); Log( LOG_CRIT, "Resolver: Can't read result: %s!", strerror(errno));
if (bytes_read == 0) { /* EOF: lookup failed */ bytes_read = 0;
}
#ifdef DEBUG #ifdef DEBUG
else if (bytes_read == 0)
Log( LOG_DEBUG, "Resolver: Can't read result: EOF"); Log( LOG_DEBUG, "Resolver: Can't read result: EOF");
#endif #endif
return 0; Resolve_Shutdown(s);
}
return (size_t)bytes_read; return (size_t)bytes_read;
} }
/* -eof- */ /* -eof- */

View File

@@ -1,16 +1,17 @@
#!/bin/sh #!/bin/sh
# ngIRCd Test Suite # ngIRCd Test Suite
# $Id: getpid.sh,v 1.4 2003/08/22 11:31:18 alex Exp $ # $Id: getpid.sh,v 1.4.6.1 2006/12/17 13:49:49 alex Exp $
# did we get a name? # did we get a name?
[ $# -ne 1 ] && exit 1 [ $# -ne 1 ] && exit 1
# detect flags for "ps" and "head" # detect flags for "ps" and "head"
if [ `uname` = "FreeBSD" ]; then UNAME=`uname`
if [ $UNAME = "FreeBSD" -o $UNAME = "SunOS" ]; then
PS_FLAGS="-a"; PS_PIDCOL="1"; HEAD_FLAGS="-n 1" PS_FLAGS="-a"; PS_PIDCOL="1"; HEAD_FLAGS="-n 1"
elif [ `uname` = "A/UX" ]; then elif [ $UNAME = "A/UX" ]; then
PS_FLAGS="-ae"; PS_PIDCOL="1"; HEAD_FLAGS="-1" PS_FLAGS="-ae"; PS_PIDCOL="1"; HEAD_FLAGS="-1"
elif [ `uname` = "GNU" ]; then elif [ $UNAME = "GNU" ]; then
PS_FLAGS="-ax"; PS_PIDCOL="2"; HEAD_FLAGS="-n 1" PS_FLAGS="-ax"; PS_PIDCOL="2"; HEAD_FLAGS="-n 1"
else else
PS_FLAGS="-f"; PS_PIDCOL="2"; HEAD_FLAGS="-n 1" PS_FLAGS="-f"; PS_PIDCOL="2"; HEAD_FLAGS="-n 1"
@@ -19,13 +20,17 @@ else
fi fi
# debug output # debug output
#echo "$0: UNAME=$UNAME"
#echo "$0: PS_FLAGS=$PS_FLAGS" #echo "$0: PS_FLAGS=$PS_FLAGS"
#echo "$0: PS_PIDCOL=$PS_PIDCOL" #echo "$0: PS_PIDCOL=$PS_PIDCOL"
#echo "$0: HEAD_FLAGS=$HEAD_FLAGS" #echo "$0: HEAD_FLAGS=$HEAD_FLAGS"
# search PID # search PID
ps $PS_FLAGS > procs.tmp ps $PS_FLAGS > procs.tmp
cat procs.tmp | grep -v "$0" | grep "$1" | awk "{print \$$PS_PIDCOL}" | sort -n > pids.tmp cat procs.tmp | \
grep -v "$0" | grep "$1" | \
awk "{print \$$PS_PIDCOL}" | \
sort -n > pids.tmp
pid=`head $HEAD_FLAGS pids.tmp` pid=`head $HEAD_FLAGS pids.tmp`
rm -rf procs.tmp pids.tmp rm -rf procs.tmp pids.tmp