1
0
mirror of https://github.com/osmarks/ngircd.git synced 2025-10-17 23:57:39 +00:00

Compare commits

..

16 Commits

Author SHA1 Message Date
Florian Westphal
3b69da0c52 io.c: fix select FD_SETSIZE check when using epoll as io backend 2008-04-07 13:37:49 +02:00
Alexander Barton
04933f5b8b Fixed indentation ... too late for 0.11.1 :-/ 2008-04-07 13:37:46 +02:00
Alexander Barton
45df522bcb ngIRCd 0.11.1. 2008-02-26 19:37:34 +00:00
Alexander Barton
51260c2e9f Updated NEWS and ChangeLog for 0.11.1. 2008-02-26 19:22:06 +00:00
Florian Westphal
55865d7fc6 From: Rolf Eike Beer <eike@sf-mail.de>
Fix sending of JOINs between servers

I found a bug in "sending join between servers".
This does hit only operators that join a channel with at least 2 servers active in the net
the server the oper connects to sends "channel^Go" to the other servers
the other server first searches for the channel and then strips the modes from the channel name
he has to do the other way round: first strip and then check the channel name.
2008-02-26 12:07:41 +00:00
Florian Westphal
082a92beef send "G" flag in WHOIS replies instead of "H" if client is marked as being away.
(reported by Dana Dahlstrom)
2008-02-26 12:06:57 +00:00
Florian Westphal
e92c889580 From: Dana Dahlstrom <dana+70@cs.ucsd.edu>
Under some circumstances ngIRCd currently issues a channel MODE message
with a trailing space after the last parameter, which isn't permitted by
the grammar in RFC 2812 section 2.3.1:

http://tools.ietf.org/html/rfc2812#section-2.3.1

The following patch modifies mode-test.e to expose this, and modifies
irc-mode.c to correct it. [from HEAD]
2008-02-16 11:26:11 +00:00
Florian Westphal
de4676f066 [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:11:20 +00:00
Florian Westphal
64a98338d5 [LOGIN] irc_login, w CVSDATE defined, used strncpy with overlapping src/dest.
use memmove instead (from HEAD).
2008-02-05 11:48:37 +00:00
Alexander Barton
f4709082fe ngIRCd 0.11.0 2008-01-15 20:45:52 +00:00
Alexander Barton
997abc6889 Documented NoDNS configuration option. [from HEAD] 2008-01-07 23:10:28 +00:00
Alexander Barton
b7047f2e3b Updated ChangeLog to reflect changes from 0.10.x branch. 2008-01-07 23:09:25 +00:00
Alexander Barton
e990d96c61 ngIRCd 0.11.0-pre2 2008-01-07 21:25:35 +00:00
Florian Westphal
d986cd372f IRC_PART could reference invalid memory. 2008-01-07 11:42:13 +00:00
Florian Westphal
762aec0e08 Remove entry about ngircd failing on Linux 2.4: ngircd can now fall back to select. 2008-01-02 22:36:48 +00:00
Alexander Barton
f8cb8e3f20 Fixed year of release (2009 vs. 2008) ... ooops ;-) 2008-01-02 21:39:59 +00:00
151 changed files with 4035 additions and 10413 deletions

7
.cvsignore Normal file
View File

@@ -0,0 +1,7 @@
Makefile
Makefile.in
aclocal.m4
autom4te.cache
config.log
config.status
configure

19
.gitignore vendored
View File

@@ -1,19 +0,0 @@
Makefile
Makefile.in
aclocal.m4
ansi2knr.1
ansi2knr.c
ansi2knr.h
autom4te.cache
config.log
config.status
configure
configure.lineno
depcomp
install-sh
missing
.deps
*.a
*.o
debian
build-stamp-ngircd*

21
AUTHORS
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server ngIRCd - Next Generation IRC Server
(c)2001-2009 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,23 +19,14 @@ directly, if possible!
Main Authors Main Authors
~~~~~~~~~~~~ ~~~~~~~~~~~~
Alexander Barton, <alex@barton.de> (alex) Alexander Barton, <alex@barton.de> (alex)
Florian Westphal, <fw@strlen.de> Florian Westphal, <westphal@foo.fh-furtwangen.de> (fw)
Contributors Contributors
~~~~~~~~~~~~ ~~~~~~~~~~~~
Ali Shemiran, <ashemira@ucsd.edu> Goetz Hoffart, <goetz@hoffart.de> (goetz)
Ask Bjørn Hansen, <ask@develooper.com> Ilja Osthoff, <i.osthoff@gmx.net> (ilja)
Benjamin Pineau, <ben@zouh.org> Benjamin Pineau, <ben@zouh.org>
Brandon Beresini, <beresini@google.com>
Bryan Caldwell, <bcaldwel@ucsd.edu>
Dana Dahlstrom, <dana+ngIRCd@cs.ucsd.edu>
Eric Grunow, <egrunow@ucsd.edu>
Goetz Hoffart, <goetz@hoffart.de>
Ilja Osthoff, <i.osthoff@gmx.net>
Jari Aalto, <jari.aalto@cante.net>
Rolf Eike Beer, <eike@sf-mail.de>
Scott Perry, <scperry@ucsd.edu>
Sean Reifschneider, <jafo-rpms@tummy.com> Sean Reifschneider, <jafo-rpms@tummy.com>
@@ -44,3 +35,7 @@ Code snippets
J. Kercheval: pattern matching functions J. Kercheval: pattern matching functions
Patrick Powell, <papowell@astart.com>: snprintf()-function Patrick Powell, <papowell@astart.com>: snprintf()-function
Andrew Tridgell & Martin Pool: strl{cpy|cat}()-functions Andrew Tridgell & Martin Pool: strl{cpy|cat}()-functions
--
$Id: AUTHORS,v 1.13 2007/10/04 15:18:48 alex Exp $

188
ChangeLog
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server ngIRCd - Next Generation IRC Server
(c)2001-2009 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
@@ -10,173 +10,6 @@
-- ChangeLog -- -- ChangeLog --
ngIRCd Release 16
ngIRCd 16~rc1 (2010-03-25)
- Various fixes to the build system and code cleanups.
- contrib/platformtest.sh: Only show latest commit.
- Updatet doc/Platforms.txt, added new README-Interix.txt documenting
how to tun ngIRCd on Microsoft Services for UNIX (MS SFU, MS SUA).
- Updated links to the ngIRCd homepage (bug tracker, mailing list).
- Added missing modes to USERMODES #define
- Show our name (IRCD=ngIRCd) in ISUPPORT (005) numeric
- Quote received messages of ERROR commands in log output.
- ngircd.conf manual page: document missing "Password" variable.
- Implement WEBIRC command used by some Web-IRC frontends. The password
required to secure this command must be configured using the new
"WebircPassword" variable in the ngircd.conf file.
- Don't use port 6668 as example for both "Ports" and "SSLPorts".
- Remove limit on max number of configured irc operators.
- Only link "nsl" library when really needed.
- A new channel mode "secure connections only" (+z) has been implemented:
Only clients using a SSL encrypted connection to the server are allowed
to join such a channel.
But please note three things: a) already joined clients are not checked
when setting this mode, b) IRC operators are always allowed to join
every channel, and c) remote clients using a server not supporting this
mode are not checked either and therefore always allowed to join.
ngIRCd Release 15 (2009-11-07)
- "ngircd --configtest": print SSL configuration options even when unset.
ngIRCd 15~rc1 (2009-10-15)
- Do not add default listening port (6667) if SSL ports were specified, so
ngIRCd can be configured to only accept SSL-encrypted connections now.
- Enable IRC operators to use the IRC command SQUIT (insted of the already
implemented but non-standard DISCONNECT command).
- New configuration option "AllowRemoteOper" (disabled by default) that
enables remote IRC operators to use the IRC commands SQUIT and CONNECT
on the local server.
- Mac OS X: fix test for packagemaker(1) tool in Makefile and use gcc 4.0
for Mac OS X 10.4 compatibility in the Xcode project file.
- Fix --with-{openssl|gnutls} to accept path names.
- Fix LSB header of Debian init script.
- Updated doc/Platforms.txt and include new script contrib/platformtest.sh
to ease generating platform reports.
- Fix connection information for already registered connections.
- Enforce upper limit on maximum number of handled commands. This implements
a throttling scheme: an IRC client can send up to 3 commands or 256 bytes
per second before a one second pause is enforced.
- Fix connection counter.
- Fix a few error handling glitches for SSL/TLS connections.
- Minor fixes to manual pages and documentation.
ngIRCd Release 14.1 (2009-05-05)
- Security: fix remotely triggerable crash in SSL/TLS code.
- BSD start script contrib/ngircd.sh has been renamed to ngircd-bsd.sh.
- New start/stop script for RedHat-based distributions:
contrib/ngircd-redhat.init, thanks to Naoya Nakazawa <naoya@sanow.net>.
- Doxygen: update source code repository link to GIT.
- Debian: build ngircd-full-dbg package.
- Allow ping timeout quit messages to show the timeout value.
- Fix error handling on compressed links.
- Fix server list announcement.
- Do not remove hostnames from info text.
ngIRCd Release 14 (2009-04-20)
- Display IPv6 addresses as "[<addr>]" when accepting connections.
ngIRCd 14~rc1 (2009-03-29)
- Updated Debian/Linux init script (see contrib/Debian/ngircd.init).
- Allow creation of persistent modeless channels.
- The INFO command reports the compile time now (if available).
- Spell check and enhance ngIRCd manual pages.
- Channel mode changes: break on syntax errors in MODE command.
- Support individual channel keys for pre-defined channels: introduce
new configuration variable "KeyFile" in [Channel] sections in ngircd.conf,
here a file can be configured for each pre-defined channel which contains
individual channel keys for different users.
- Remove limit on maximum number of predefined channels in ngircd.conf.
- Updated ngircd.spec file for building RPM packages.
- Add new and missing files to Mac OS X Xcode project, and update project.
- Reject masks with wildcard after last dot.
- TLS/SSL: remove useless error message when ssl connection is closed.
- Fix memory leak when a encrypted and compressed server link goes down.
(closes bug #95, reported by Christoph, fiesh@fiesh.homeip.net)
- Fix handling of channels containing dots.
(closes ug #93, reported by Gonosz Csiga)
ngIRCd Release 13 (2008-12-25)
- Updated documentation, especially doc/Services.txt and doc/SSL.txt.
- Make the test suite work on OpenSolaris.
ngIRCd 13~rc1 (2008-11-21):
- New version number scheme :-)
- Initial support for IRC services, using a RFC1459 style interface,
tested with IRCServices (http://www.ircservices.za.net/) version 5.1.13.
For this to work, ngIRCd now supports server-server links conforming
to RFC 1459. New ngircd.conf(5) option: ServiceMask.
- Support for SSL-encrypted server-server and client-server links using
OpenSSL (configure: --with-openssl) or GNUTLS (configure: --with-gnutls).
New ngircd.conf(5) options: SSLPorts, SSLKeyFile, SSLKeyFilePassword,
SSLCertFile, SSLDHFile, and SSLConnect.
- Server local channels have been implemented, prefix "&", that are only
visible to users of the same server and are not visible in the network.
In addition ngIRCd creates a "special" channel &SERVER on startup and logs
all the messages to it that a user with mode +s receives.
- New make target "osxpkg" to build a Mac OS X installer package.
- Debug mode: enable support for GNU libc memory tracing (see mtrace(3)).
- SysV init script: use LSB logging functions, if available.
- Added some more FAQ entries (regarding logging and IRC operators).
- Allow IRC operators to overwrite channel limits.
- Support for enhanced PRIVMSG and NOTICE message targets.
- More tests have been added to the test-suite ("make check"), and two
servers are started for testing server-server linking.
- Added a timestamp to log messages to the console.
- New configuration option "NoIdent" to disable IDENT lookups even if the
daemon is compiled with IDENT support.
ngIRCd 0.12.1 (2008-07-09)
- Allow mixed line terminations (CR+LF/CR/LF) in non-RFC-compliant mode
- Don't allow stray \r or \n in command parameters
- --configtest: return non-zero exit code if there are errors
- Update ngIRCd manual pages
- Add option aliases -V (for --version) and -h (for --help).
- Fix 'no-ipv6' compile error.
- Make Listen parameter a comma-separated list of addresses. This also
obsoletes ListenIPv4 and ListenIPv6 options. If Listen is unset, it
is treated as Listen="::,0.0.0.0".
Note: ListenIPv4 and ListenIPv6 options are still recognized,
but ngircd will print a warning if they are used in the config file.
ngIRCd 0.12.0 (2008-05-13)
- Fix Bug: 85: "WHO #SecretChannel" that user is not a member of now returns
proper RPL_ENDOFWHO_MSG instead of nothing. (Ali Shemiran)
- Fix compile on FreeBSD 5.4 and AIX.
- If bind() fails, also print IP address and not just the port number.
ngIRCd 0.12.0-pre2 (2008-04-29)
- IPv6: Add config options to disable ipv4/ipv6 support.
- Don't include doc/CVS.txt in distribution archive, use doc/GIT.txt now!
- Documentation: get rid of some more references to CVS, switch to GIT.
- Get rid of cvs-version.* and CVSDATE definition.
- Report ERR_NOTONCHANNEL when trying to part a channel one is not member of.
- Testsuite: remove erroneous ConfUID setting in config file.
ngIRCd 0.12.0-pre1 (2008-04-20)
- Include Mac OS X Xcode project in distribution archives.
- Do not exit on SIGHUP or /REHASH if the config file cannot opened.
- Add IPv6 support.
- Install a LaunchDaemon script to start/stop ngIRCd on Mac OS X.
- Implemented IRC commands INFO, SUMMON (dummy), and USERS (dummy) and
enhanced test suite to check these commands. (Dana Dahlstrom)
- RPL_WHOREPLY messages generated by IRC_WHO didn't include flags (*,@,+).
(Dana Dahlstrom)
- IRC_WHO now supports search patterns and will test this against user
nickname/servername/hostname, etc. as required by RFC 2812, Section 3.6.1.
(reported by Dana Dahlstrom)
- Add test cases for "WHO" command. (Dana Dahlstrom)
- Implement RFC 2812 handling of "0" argument to 'JOIN': must be treated
as if the user had sent PART commands for all channels the user is a
member of. (Dana Dahlstrom)
- Allow NOTICEs to be sent to a channel. (Fabian Schlager)
ngIRCd 0.11.1 (2008-02-26) ngIRCd 0.11.1 (2008-02-26)
- Fix sending of JOIN commands between servers when remote server appended - Fix sending of JOIN commands between servers when remote server appended
@@ -189,17 +22,17 @@ ngIRCd 0.11.0 (2008-01-15)
ngIRCd 0.11.0-pre2 (2008-01-07) ngIRCd 0.11.0-pre2 (2008-01-07)
- SECURITY: IRC_PART could reference invalid memory, causing - SECURITY: IRC_PART could reference invalid memory, causing
ngircd to crash [from HEAD]. (CVE-2008-0285) ngircd to crash [from HEAD].
ngIRCd 0.11.0-pre1 (2008-01-02) ngIRCd 0.11.0-pre1 (2008-01-02)
- Use dotted-decimal IP address if hostname is >= 64. - Use dotted-decimal IP address if hostname is >= 64.
- Add support for /STAT u (server uptime) command. - Add support for /STAT u (server uptime) command.
- New [Server] configuration Option "Bind" allows to specify - New [Server] configuration Option "Bind" allows to specify
the source IP address to use when connecting to remote server. the source ip adress to use when connecting to remote server.
- New configuration option "MaxNickLength" to specify the allowed maximum - New configuration option "MaxNickLength" to specify the allowed maximum
length of user nick names. Note: must be unique in an IRC network! length of user nick names. Note: must be unique in an IRC network!
- Enhanced the IRC+ protocol to support an enhanced "server handshake" and - Enhanced the IRC+ protocol to support an enhanced "server handshake" and
enable server to recognize numeric 005 (ISUPPORT) and 376 (ENDOFMOTD). enable server to recognice numeric 005 (ISUPPORT) and 376 (ENDOFMOTD).
See doc/Protocol.txt for details. See doc/Protocol.txt for details.
- Re-added doc/SSL.txt to distribution -- got lost somewhere!? - Re-added doc/SSL.txt to distribution -- got lost somewhere!?
- Fixes the wrong logging output when nested servers are introduced - Fixes the wrong logging output when nested servers are introduced
@@ -223,13 +56,12 @@ ngIRCd 0.11.0 (2008-01-15)
ngIRCd 0.10.4 (2008-01-07) ngIRCd 0.10.4 (2008-01-07)
- SECURITY: IRC_PART could reference invalid memory, causing - SECURITY: IRC_PART could reference invalid memory, causing
ngircd to crash [from HEAD]. (CVE-2008-0285) ngircd to crash [from HEAD].
ngIRCd 0.10.3 (2007-08-01) ngIRCd 0.10.3 (2007-08-01)
- SECURITY: Fixed a severe bug in handling JOIN commands, which could - SECURITY: Fixed a severe bug in handling JOIN commands, which could
cause the server to crash. Thanks to Sebastian Vesper, <net@veoson.net>. cause the server to crash. Thanks to Sebastian Vesper, <net@veoson.net>.
(CVE-2007-6062)
ngIRCd 0.10.2 (2007-06-08) ngIRCd 0.10.2 (2007-06-08)
@@ -364,13 +196,13 @@ ngIRCd 0.8.3 (2005-02-03)
- Fixed a bug that could case a root exploit when the daemon is compiled - Fixed a bug that could case a root exploit when the daemon is compiled
to do IDENT lookups and is logging to syslog. Bug discovered by CoKi, to do IDENT lookups and is logging to syslog. Bug discovered by CoKi,
<coki@nosystem.com.ar>, thanks a lot! <coki@nosystem.com.ar>, thanks a lot!
(CVE-2005-0226; http://www.nosystem.com.ar/advisories/advisory-11.txt) (http://www.nosystem.com.ar/advisories/advisory-11.txt)
ngIRCd 0.8.2 (2005-01-26) ngIRCd 0.8.2 (2005-01-26)
- Added doc/SSL.txt to distribution. - Added doc/SSL.txt to distribution.
- Fixed a buffer overflow that could cause the daemon to crash. Bug found - Fixed a buffer overflow that could cause the daemon to crash. Bug found
by Florian Westphal, <westphal@foo.fh-furtwangen.de>. (CVE-2005-0199) by Florian Westphal, <westphal@foo.fh-furtwangen.de>.
- Fixed a possible buffer underrun when reading the MOTD file. Thanks - Fixed a possible buffer underrun when reading the MOTD file. Thanks
to Florian Westphal, <westphal@foo.fh-furtwangen.de>. to Florian Westphal, <westphal@foo.fh-furtwangen.de>.
- Fixed detection of IRC lines which are too long to send. Detected by - Fixed detection of IRC lines which are too long to send. Detected by
@@ -528,7 +360,7 @@ ngIRCd 0.7.0 (2003-05-01)
- Better error reporting to clients on connect. - Better error reporting to clients on connect.
- Enhanced manual pages ngircd(8) and ngircd.conf(5). - Enhanced manual pages ngircd(8) and ngircd.conf(5).
- Documentation is now installed in $(datadir)/doc/ngircd. - Documentation is now installed in $(datadir)/doc/ngircd.
- Enhanced handling of NJOIN in case of nick collisions. - Enhanced hanling of NJOIN in case of nick collisions.
ngIRCd 0.6.1, 2003-01-21 ngIRCd 0.6.1, 2003-01-21
@@ -907,3 +739,7 @@ ngIRCd 0.0.2, 06.01.2002
ngIRCd 0.0.1, 31.12.2001 ngIRCd 0.0.1, 31.12.2001
- erste oeffentliche Version von ngIRCd als "public preview" :-) - erste oeffentliche Version von ngIRCd als "public preview" :-)
--
$Id: ChangeLog,v 1.332.2.11 2008/02/26 20:35:05 alex Exp $

10
INSTALL
View File

@@ -51,9 +51,9 @@ on modern UNIX-like systems that are supported by GNU autoconf and GNU
automake ("configure") should be no problem. automake ("configure") should be no problem.
The normal installation procedure after getting (and expanding) the source The normal installation procedure after getting (and expanding) the source
files (using a distribution archive or GIT) is as following: files (using a distribution archive or CVS) is as following:
1) ./autogen.sh [only necessary when using GIT] 1) ./autogen.sh [only necessary when using CVS]
2) ./configure 2) ./configure
3) make 3) make
4) make install 4) make install
@@ -77,7 +77,7 @@ doc/ directory: sample-ngircd.conf.
The first step, autogen.sh, is only necessary if the configure-script isn't The first step, autogen.sh, is only necessary if the configure-script isn't
already generated. This never happens in official ("stable") releases in already generated. This never happens in official ("stable") releases in
tar.gz-archives, but when using GIT. tar.gz-archives, but when using CVS.
This step is therefore only interesting for developers. This step is therefore only interesting for developers.
@@ -244,3 +244,7 @@ These parameters could be passed to the ngIRCd:
Use "--help" to see a short help text describing all available parameters Use "--help" to see a short help text describing all available parameters
the server understands, with "--version" the ngIRCd shows its version the server understands, with "--version" the ngIRCd shows its version
number. In both cases the server exits after the output. number. In both cases the server exits after the output.
--
$Id: INSTALL,v 1.26 2007/04/08 11:39:08 alex Exp $

View File

@@ -1,6 +1,6 @@
# #
# ngIRCd -- The Next Generation IRC Daemon # ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton (alex@barton.de) # Copyright (c)2001-2003 by 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,6 +8,8 @@
# (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.17 2005/07/22 21:01:52 alex Exp $
#
AUTOMAKE_OPTIONS = gnu AUTOMAKE_OPTIONS = gnu
@@ -15,7 +17,6 @@ SUBDIRS = doc src man contrib
clean-local: clean-local:
rm -f build-stamp* rm -f build-stamp*
rm -rf ngircd.dest
maintainer-clean-local: maintainer-clean-local:
rm -rf autom4te.cache rm -rf autom4te.cache
@@ -23,59 +24,23 @@ maintainer-clean-local:
rm -f mkinstalldirs missing depcomp install-sh rm -f mkinstalldirs missing depcomp install-sh
rm -f config.log debian rm -f config.log debian
testsuite:
make -C src/testsuite check
lint: lint:
make -C src/ngircd lint make -C src/ngircd lint
srcdoc: srcdoc:
make -C doc srcdoc make -C doc srcdoc
have-xcodebuild: xcode:
@xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -list \ @xcodebuild -project contrib/MacOSX/ngIRCd.xcode -list >/dev/null 2>&1 \
>/dev/null 2>&1 \
|| ( echo; echo "Error: \"xcodebuild\" not found!"; echo; exit 1 ) || ( echo; echo "Error: \"xcodebuild\" not found!"; echo; exit 1 )
xcodebuild -project contrib/MacOSX/ngIRCd.xcode -alltargets \
xcode: have-xcodebuild -buildstyle Development
rel=`grep AC_INIT configure.in | cut -d' ' -f2 | cut -d')' -f1`; \
def="GCC_PREPROCESSOR_DEFINITIONS=\"VERSION=\\\"$$rel\\\"\""; \
xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -alltargets \
-configuration Default $$def build
xcode-clean: have-xcodebuild
xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -alltargets \
-configuration Default clean
rm -fr contrib/MacOSX/build
rpm: distcheck rpm: distcheck
rpm -ta ngircd-*.tar.gz rpm -ta ngircd-*.tar.gz
deb: deb:
[ -f debian/rules ] || ln -s contrib/Debian debian [ -f debian/rules ] || ln -s contrib/Debian debian
dpkg-buildpackage -rfakeroot -i dpkg-buildpackage -rfakeroot
osxpkg: have-xcodebuild
@packagemaker >/dev/null 2>&1; [ $$? -le 1 ] \
|| ( echo; echo "Error: \"packagemaker\" not found!"; echo; exit 2)
make clean
./configure --prefix=/opt/ngircd
make xcode
make -C contrib/MacOSX de.barton.ngircd.plist
mkdir -p ngircd.dest/opt/ngircd/sbin
DESTDIR="$$PWD/ngircd.dest" make -C doc install
DESTDIR="$$PWD/ngircd.dest" make -C contrib install
DESTDIR="$$PWD/ngircd.dest" make -C man install
cp contrib/MacOSX/build/Default/ngIRCd \
ngircd.dest/opt/ngircd/sbin/ngircd
rm ngircd.dest/opt/ngircd/etc/ngircd.conf
echo "Have a nice day IRCing!" >ngircd.dest/opt/ngircd/etc/ngircd.motd
chmod -R a-s,og-w,a+rX ngircd.dest
cd contrib/MacOSX && packagemaker \
--doc ngIRCd.pmdoc \
--out ../../$(distdir).mpkg
rm -f $(distdir).mpkg.zip
zip -ro9 $(distdir).mpkg.zip $(distdir).mpkg
rm -rf ngircd.dest $(distdir).mpkg
# -eof- # -eof-

99
NEWS
View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server ngIRCd - Next Generation IRC Server
(c)2001-2010 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
@@ -10,104 +10,11 @@
-- NEWS -- -- NEWS --
ngIRCd Release 16
ngIRCd 16~rc1 (2010-03-25)
- Implement WEBIRC command used by some Web-IRC frontends. The password
required to secure this command must be configured using the new
"WebircPassword" variable in the ngircd.conf file.
- Remove limit on max number of configured irc operators.
- A new channel mode "secure connections only" (+z) has been implemented:
Only clients using a SSL encrypted connection to the server are allowed
to join such a channel.
But please note three things: a) already joined clients are not checked
when setting this mode, b) IRC operators are always allowed to join
every channel, and c) remote clients using a server not supporting this
mode are not checked either and therefore always allowed to join.
ngIRCd Release 15 (2009-11-07)
ngIRCd 15~rc1 (2009-10-15)
- Do not add default listening port (6667) if SSL ports were specified, so
ngIRCd can be configured to only accept SSL-encrypted connections now.
- Enable IRC operators to use the IRC command SQUIT (insted of the already
implemented but non-standard DISCONNECT command).
- New configuration option "AllowRemoteOper" (disabled by default) that
enables remote IRC operators to use the IRC commands SQUIT and CONNECT
on the local server.
- Enforce upper limit on maximum number of handled commands. This implements
a throttling scheme: an IRC client can send up to 3 commands or 256 bytes
per second before a one second pause is enforced.
ngIRCd Release 14.1 (2009-05-05)
- Security: fix remotely triggerable crash in SSL/TLS code.
- Debian: build ngircd-full-dbg package.
- Allow ping timeout quit messages to show the timeout value.
ngIRCd Release 14 (2009-04-20)
ngIRCd 14~rc1 (2009-03-29)
- Allow creation of persistent modeless channels.
- The INFO command reports the compile time now (if available).
- Support individual channel keys for pre-defined channels: introduce
new configuration variable "KeyFile" in [Channel] sections in ngircd.conf,
here a file can be configured for each pre-defined channel which contains
individual channel keys for different users.
- Remove limit on maximum number of predefined channels in ngircd.conf.
ngIRCd Release 13 (2008-12-25)
ngIRCd 13~rc1 (2008-11-21):
- New version number scheme :-)
- Initial support for IRC services, using a RFC1459 style interface,
tested with IRCServices (http://www.ircservices.za.net/) version 5.1.13.
For this to work, ngIRCd now supports server-server links conforming
to RFC 1459. New ngircd.conf(5) option: ServiceMask.
- Support for SSL-encrypted server-server and client-server links using
OpenSSL (configure: --with-openssl) or GNUTLS (configure: --with-gnutls).
New ngircd.conf(5) options: SSLPorts, SSLKeyFile, SSLKeyFilePassword,
SSLCertFile, SSLDHFile, and SSLConnect.
- Server local channels have been implemented, prefix "&", that are only
visible to users of the same server and are not visible in the network.
In addition ngIRCd creates a "special" channel &SERVER on startup and logs
all the messages to it that a user with mode +s receives.
- New make target "osxpkg" to build a Mac OS X installer package.
- New configuration option "NoIdent" to disable IDENT lookups even if the
daemon is compiled with IDENT support.
ngIRCd 0.12.1 (2008-07-09)
- Add option aliases -V (for --version) and -h (for --help).
- Make Listen parameter a comma-separated list of addresses. This also
obsoletes ListenIPv4 and ListenIPv6 options. If Listen is unset, it
is treated as Listen="::,0.0.0.0".
Note: ListenIPv4 and ListenIPv6 options are still recognized,
but ngircd will print a warning if they are used in the config file.
ngIRCd 0.12.0 (2008-05-13)
ngIRCd 0.12.0-pre2 (2008-04-29)
- IPv6: Add config options to disable ipv4/ipv6 support.
ngIRCd 0.12.0-pre1 (2008-04-20)
- Add IPv6 support.
- Install a LaunchDaemon script to start/stop ngIRCd on Mac OS X.
- Implemented IRC commands INFO, SUMMON (dummy), and USERS (dummy) and
enhanced test suite to check these commands. (Dana Dahlstrom)
- IRC_WHO now supports search patterns and will test this against user
nickname/servername/hostname, etc. as required by RFC 2812, Section 3.6.1.
(reported by Dana Dahlstrom)
- Implement RFC 2812 handling of "0" argument to 'JOIN': must be treated
as if the user had sent PART commands for all channels the user is a
member of. (Dana Dahlstrom)
- Allow NOTICEs to be sent to a channel. (Fabian Schlager)
ngIRCd 0.11.0 (2008-01-15) ngIRCd 0.11.0 (2008-01-15)
- Add support for /STAT u (server uptime) command. - Add support for /STAT u (server uptime) command.
- New [Server] configuration Option "Bind" allows to specify - New [Server] configuration Option "Bind" allows to specify
the source IP address to use when connecting to remote server. the source ip adress to use when connecting to remote server.
- New configuration option "MaxNickLength" to specify the allowed maximum - New configuration option "MaxNickLength" to specify the allowed maximum
length of user nick names. Note: must be unique in an IRC network! length of user nick names. Note: must be unique in an IRC network!
- Numeric 317: implemented "signon time" (displayed in WHOIS result). - Numeric 317: implemented "signon time" (displayed in WHOIS result).
@@ -344,4 +251,4 @@ ngIRCd 0.0.1, 31.12.2001
-- --
$Id: NEWS,v 1.88 2008/02/26 22:05:42 fw Exp $ $Id: NEWS,v 1.83.2.4 2008/02/26 19:22:07 alex Exp $

14
README
View File

@@ -67,9 +67,9 @@ the newest information about the ngIRCd and the most recent ("stable")
releases there. releases there.
If you are interested in the latest development versions (which are not If you are interested in the latest development versions (which are not
always stable), then please read the section about "GIT" on the homepage and always stable), then please read the section "CVS" on the homepage and
the file "doc/GIT.txt" which describes the use of GIT, the version control the file "doc/CVS.txt" which describes the use of CVS, the "Concurrent
system used by ngIRCd (homepage: http://git.or.cz/). Versioning System".
VI. Bugs VI. Bugs
@@ -78,10 +78,14 @@ VI. Bugs
If you find bugs in the ngIRCd (which might be there :-), please report If you find bugs in the ngIRCd (which might be there :-), please report
them at the following URL: them at the following URL:
<http://ngircd.barton.de/bugtracker.php> <http://ngircd.barton.de/#bugs>
There you can read about known bugs and limitations, too. There you can read about known bugs and limitations, too.
If you have critics, patches or something else, please feel free to post a If you have critics, patches or something else, please feel free to post a
mail to the ngIRCd mailing list: <ngircd-ml@arthur.ath.cx> (please see mail to the ngIRCd mailing list: <ngircd-ml@arthur.ath.cx> (please see
<http://ngircd.barton.de/support.php#ml> for details). <http://ngircd.barton.de/#ml> for details).
--
$Id: README,v 1.25 2007/10/04 15:18:48 alex Exp $

View File

@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# #
# ngIRCd -- The Next Generation IRC Daemon # ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de> # Copyright (c)2001-2004 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
@@ -9,8 +9,11 @@
# (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.
# #
# Usage: # $Id: autogen.sh,v 1.15 2007/10/07 13:02:15 alex Exp $
# [VAR=<value>] ./autogen.sh [<configure-args>] #
#
# Usage: [VAR=<value>] ./autogen.sh [<configure-args>]
# #
# This script generates the ./configure script using GNU automake and # This script generates the ./configure script using GNU automake and
# GNU autoconf. It tries to be smart in finding the correct/usable/available # GNU autoconf. It tries to be smart in finding the correct/usable/available
@@ -121,6 +124,20 @@ if [ -z "$EXIST" ]; then
fi fi
[ "$VERBOSE" = "1" ] && echo "Using \"$EXIST\" to test for tools." [ "$VERBOSE" = "1" ] && echo "Using \"$EXIST\" to test for tools."
# We want to use GNU automake 1.9, if available (WANT_AUTOMAKE is used by
# the wrapper scripts of Gentoo Linux, AUTOMAKE_VERSION is used by OpenBSD);
# same applies for GNU autoconf, we want to use version 2.59. -- But only
# set these preferences if not already set!
if [ -z "$AUTOMAKE_VERSION" -a -z "$WANT_AUTOMAKE" ]; then
AUTOMAKE_VERSION=1.9
WANT_AUTOMAKE=1.9
fi
if [ -z "$AUTOCONF_VERSION" -a -z "$WANT_AUTOCONF" ]; then
AUTOCONF_VERSION=2.59
WANT_AUTOCONF=2.59
fi
export AUTOMAKE_VERSION WANT_AUTOMAKE AUTOCONF_VERSION WANT_AUTOCONF
# Try to detect the needed tools when no environment variable already # Try to detect the needed tools when no environment variable already
# specifies one: # specifies one:
echo "Searching tools ..." echo "Searching tools ..."
@@ -138,12 +155,12 @@ echo "Searching tools ..."
[ -z "$GO" -a $# -gt 0 ] && GO=1 [ -z "$GO" -a $# -gt 0 ] && GO=1
# Verify that all tools have been found # Verify that all tools have been found
[ -z "$ACLOCAL" ] && Notfound aclocal [ -z "$AUTOCONF" ] && Notfound autoconf
[ -z "$AUTOHEADER" ] && Notfound autoheader [ -z "$AUTOHEADER" ] && Notfound autoheader
[ -z "$AUTOMAKE" ] && Notfound automake [ -z "$AUTOMAKE" ] && Notfound automake
[ -z "$AUTOCONF" ] && Notfound autoconf [ -z "$AUTOCONF" ] && Notfound autoconf
export ACLOCAL AUTOHEADER AUTOMAKE AUTOCONF export AUTOCONF AUTOHEADER AUTOMAKE AUTOCONF
# Generate files # Generate files
echo "Generating files ..." echo "Generating files ..."

32
config.guess vendored
View File

@@ -1,10 +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, 2006, 2007, 2008 # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
# Free Software Foundation, Inc. # Inc.
timestamp='2008-01-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
@@ -56,8 +56,8 @@ version="\
GNU config.guess ($timestamp) GNU config.guess ($timestamp)
Originally written by Per Bothner. Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -330,7 +330,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;; exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) i86pc:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;; exit ;;
sun4*:SunOS:6*:*) sun4*:SunOS:6*:*)
@@ -532,7 +532,7 @@ EOF
echo rs6000-ibm-aix3.2 echo rs6000-ibm-aix3.2
fi fi
exit ;; exit ;;
*:AIX:*:[456]) *:AIX:*:[45])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000 IBM_ARCH=rs6000
@@ -799,9 +799,6 @@ EOF
EM64T | authenticamd) EM64T | authenticamd)
echo x86_64-unknown-interix${UNAME_RELEASE} echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;; exit ;;
IA64)
echo ia64-unknown-interix${UNAME_RELEASE}
exit ;;
esac ;; 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
@@ -836,14 +833,7 @@ EOF
echo ${UNAME_MACHINE}-pc-minix echo ${UNAME_MACHINE}-pc-minix
exit ;; exit ;;
arm*:Linux:*:*) arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
echo ${UNAME_MACHINE}-unknown-linux-gnu echo ${UNAME_MACHINE}-unknown-linux-gnu
else
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
fi
exit ;; exit ;;
avr32*:Linux:*:*) avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -964,8 +954,8 @@ EOF
x86_64:Linux:*:*) x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu echo x86_64-unknown-linux-gnu
exit ;; exit ;;
xtensa*:Linux:*:*) xtensa:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu echo xtensa-unknown-linux-gnu
exit ;; 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
@@ -1484,9 +1474,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you the operating system you are using. It is advised that you
download the most up to date version of the config scripts from download the most up to date version of the config scripts from
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
and and
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
If the version you run ($0) is already up to date, please If the version you run ($0) is already up to date, please
send the following data and any information you think might be send the following data and any information you think might be

52
config.sub vendored
View File

@@ -1,10 +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, 2006, 2007, 2008 # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
# Free Software Foundation, Inc. # Inc.
timestamp='2008-01-16' 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
@@ -72,8 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\ version="\
GNU config.sub ($timestamp) GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -369,14 +369,10 @@ case $basic_machine in
| v850-* | v850e-* | vax-* \ | v850-* | v850e-* | vax-* \
| we32k-* \ | we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
| xstormy16-* | xtensa*-* \ | xstormy16-* | xtensa-* \
| ymp-* \ | ymp-* \
| z8k-*) | z8k-*)
;; ;;
# Recognize the basic CPU types without company name, with glob match.
xtensa*)
basic_machine=$basic_machine-unknown
;;
# 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)
@@ -447,14 +443,6 @@ case $basic_machine in
basic_machine=ns32k-sequent basic_machine=ns32k-sequent
os=-dynix os=-dynix
;; ;;
blackfin)
basic_machine=bfin-unknown
os=-linux
;;
blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
c90) c90)
basic_machine=c90-cray basic_machine=c90-cray
os=-unicos os=-unicos
@@ -487,8 +475,8 @@ case $basic_machine in
basic_machine=craynv-cray basic_machine=craynv-cray
os=-unicosmp os=-unicosmp
;; ;;
cr16) cr16c)
basic_machine=cr16-unknown basic_machine=cr16c-unknown
os=-elf os=-elf
;; ;;
crds | unos) crds | unos)
@@ -680,14 +668,6 @@ case $basic_machine in
basic_machine=m68k-isi basic_machine=m68k-isi
os=-sysv os=-sysv
;; ;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
;;
m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
m88k-omron*) m88k-omron*)
basic_machine=m88k-omron basic_machine=m88k-omron
;; ;;
@@ -703,10 +683,6 @@ case $basic_machine in
basic_machine=i386-pc basic_machine=i386-pc
os=-mingw32 os=-mingw32
;; ;;
mingw32ce)
basic_machine=arm-unknown
os=-mingw32ce
;;
miniframe) miniframe)
basic_machine=m68000-convergent basic_machine=m68000-convergent
;; ;;
@@ -833,14 +809,6 @@ case $basic_machine in
basic_machine=i860-intel basic_machine=i860-intel
os=-osf os=-osf
;; ;;
parisc)
basic_machine=hppa-unknown
os=-linux
;;
parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
pbd) pbd)
basic_machine=sparc-tti basic_machine=sparc-tti
;; ;;
@@ -1049,10 +1017,6 @@ case $basic_machine in
basic_machine=tic6x-unknown basic_machine=tic6x-unknown
os=-coff os=-coff
;; ;;
tile*)
basic_machine=tile-unknown
os=-linux-gnu
;;
tx39) tx39)
basic_machine=mipstx39-unknown basic_machine=mipstx39-unknown
;; ;;

View File

@@ -1,6 +1,6 @@
# #
# ngIRCd -- The Next Generation IRC Daemon # ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2009 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,18 +8,18 @@
# (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.125.2.4 2008/02/26 19:37:34 alex Exp $
#
# -- Initialisation -- # -- Initialisation --
AC_PREREQ(2.50) AC_PREREQ(2.50)
AC_INIT(ngircd, 16~rc1) AC_INIT(ngircd, 0.11.1)
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)
AM_CONFIG_HEADER(src/config.h) AM_CONFIG_HEADER(src/config.h)
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# -- Templates for config.h -- # -- Templates for config.h --
AH_TEMPLATE([DEBUG], [Define if debug-mode should be enabled]) AH_TEMPLATE([DEBUG], [Define if debug-mode should be enabled])
@@ -30,10 +30,8 @@ AH_TEMPLATE([SYSLOG], [Define if syslog should be used for logging])
AH_TEMPLATE([ZLIB], [Define if zlib compression should be enabled]) AH_TEMPLATE([ZLIB], [Define if zlib compression should be enabled])
AH_TEMPLATE([TCPWRAP], [Define if TCP wrappers should be used]) AH_TEMPLATE([TCPWRAP], [Define if TCP wrappers should be used])
AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used]) AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used])
AH_TEMPLATE([WANT_IPV6], [Define if IPV6 protocol should be enabled])
AH_TEMPLATE([ZEROCONF], [Define if support for Zeroconf should be included]) AH_TEMPLATE([ZEROCONF], [Define if support for Zeroconf should be included])
AH_TEMPLATE([IDENTAUTH], [Define if the server should do IDENT requests]) AH_TEMPLATE([IDENTAUTH], [Define if the server should do IDENT requests])
AH_TEMPLATE([HAVE_sockaddr_in_len], [Define if sockaddr_in.sin_len exists])
AH_TEMPLATE([TARGET_OS], [Target operating system name]) AH_TEMPLATE([TARGET_OS], [Target operating system name])
AH_TEMPLATE([TARGET_VENDOR], [Target system vendor]) AH_TEMPLATE([TARGET_VENDOR], [Target system vendor])
@@ -74,6 +72,7 @@ AC_DEFUN([GCC_STACK_PROTECT_CC],[
fi 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"
@@ -105,8 +104,7 @@ AC_CHECK_HEADERS([ \
strings.h sys/socket.h sys/time.h unistd.h \ strings.h sys/socket.h sys/time.h unistd.h \
],,AC_MSG_ERROR([required C header missing!])) ],,AC_MSG_ERROR([required C header missing!]))
AC_CHECK_HEADERS([ \ AC_CHECK_HEADERS([arpa/inet.h ctype.h malloc.h stdbool.h stddef.h varargs.h])
arpa/inet.h ctype.h malloc.h netinet/ip.h stdbool.h stddef.h varargs.h])
# -- Datatypes -- # -- Datatypes --
@@ -126,16 +124,12 @@ AC_TRY_COMPILE([
AC_TYPE_SIGNAL AC_TYPE_SIGNAL
AC_TYPE_SIZE_T AC_TYPE_SIZE_T
AC_CHECK_MEMBER([struct sockaddr_in.sin_len], AC_DEFINE(HAVE_sockaddr_in_len),,
[#include <arpa/inet.h>])
# -- Libraries -- # -- Libraries --
# A/UX needs this.
AC_CHECK_LIB(UTIL,memmove) AC_CHECK_LIB(UTIL,memmove)
# needed on solaris. GNU libc also has a libnsl, but we do not need it.
AC_SEARCH_LIBS(gethostbyname,nsl)
AC_CHECK_LIB(socket,bind) AC_CHECK_LIB(socket,bind)
AC_CHECK_LIB(nsl,gethostent)
# -- Functions -- # -- Functions --
@@ -143,11 +137,11 @@ AC_FUNC_FORK
AC_FUNC_STRFTIME AC_FUNC_STRFTIME
AC_CHECK_FUNCS([ \ AC_CHECK_FUNCS([ \
bind gethostbyaddr gethostbyname gethostname inet_ntoa \ bind gethostbyaddr gethostbyname gethostname inet_ntoa malloc memmove \
setsid setsockopt socket strcasecmp waitpid],,AC_MSG_ERROR([required function missing!])) memset realloc setsid setsockopt socket strcasecmp strchr strcspn strerror \
strstr waitpid],,AC_MSG_ERROR([required function missing!]))
AC_CHECK_FUNCS(getaddrinfo getnameinfo inet_aton isdigit sigaction snprintf \ AC_CHECK_FUNCS(inet_aton isdigit sigaction snprintf vsnprintf strdup strlcpy strlcat)
vsnprintf strdup strlcpy strlcat strtok_r)
# -- Configuration options -- # -- Configuration options --
@@ -317,52 +311,6 @@ if test "$x_io_backend" = "none"; then
AC_MSG_ERROR([No useabe IO API activated/found!?]) AC_MSG_ERROR([No useabe IO API activated/found!?])
fi fi
# use SSL?
AC_ARG_WITH(openssl,
[ --with-openssl enable SSL support using OpenSSL],
[ 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_LIB(crypto, BIO_s_mem)
AC_CHECK_LIB(ssl, SSL_library_init)
AC_CHECK_FUNCS(SSL_library_init, x_ssl_openssl=yes,
AC_MSG_ERROR([Can't enable openssl])
)
fi
]
)
AC_ARG_WITH(gnutls,
[ --with-gnutls enable SSL support using gnutls],
[ 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_LIB(gnutls, gnutls_global_init)
AC_CHECK_FUNCS(gnutls_global_init, x_ssl_gnutls=yes,
AC_MSG_ERROR([Can't enable gnutls])
)
fi
]
)
x_ssl_lib="no"
if test "$x_ssl_gnutls" = "yes"; then
if test "$x_ssl_openssl" = "yes";then
AC_MSG_ERROR([Cannot enable both gnutls and openssl])
fi
x_ssl_lib=gnutls
fi
if test "$x_ssl_openssl" = "yes"; then
x_ssl_lib=openssl
fi
# use TCP wrappers? # use TCP wrappers?
x_tcpwrap_on=no x_tcpwrap_on=no
@@ -478,21 +426,6 @@ if test "$x_ircplus_on" = "yes"; then
AC_DEFINE(IRCPLUS, 1) AC_DEFINE(IRCPLUS, 1)
fi fi
# enable support for IPv6?
x_ipv6_on=no
AC_ARG_ENABLE(ipv6,
[ --enable-ipv6 enable IPv6 protocol support],
if test "$enableval" = "yes"; then x_ipv6_on=yes; fi
)
if test "$x_ipv6_on" = "yes"; then
# getaddrinfo() and getnameinfo() are optional when not compiling
# with IPv6 support, but are required for IPv6 to work!
AC_CHECK_FUNCS([ \
getaddrinfo getnameinfo \
],,AC_MSG_ERROR([required function missing for IPv6 support!]))
AC_DEFINE(WANT_IPV6, 1)
fi
# compile in IRC "sniffer"? # compile in IRC "sniffer"?
x_sniffer_on=no; x_debug_on=no x_sniffer_on=no; x_debug_on=no
@@ -513,7 +446,6 @@ AC_ARG_ENABLE(debug,
if test "$x_debug_on" = "yes"; then if test "$x_debug_on" = "yes"; then
AC_DEFINE(DEBUG, 1) AC_DEFINE(DEBUG, 1)
test "$GCC" = "yes" && CFLAGS="-pedantic $CFLAGS" test "$GCC" = "yes" && CFLAGS="-pedantic $CFLAGS"
AC_CHECK_FUNCS(mtrace)
fi fi
# enable "strict RFC rules"? # enable "strict RFC rules"?
@@ -545,7 +477,6 @@ AC_OUTPUT([ \
doc/src/Makefile \ doc/src/Makefile \
src/Makefile \ src/Makefile \
src/portab/Makefile \ src/portab/Makefile \
src/ipaddr/Makefile \
src/tool/Makefile \ src/tool/Makefile \
src/ngircd/Makefile \ src/ngircd/Makefile \
src/testsuite/Makefile \ src/testsuite/Makefile \
@@ -553,8 +484,6 @@ AC_OUTPUT([ \
contrib/Makefile \ contrib/Makefile \
contrib/Debian/Makefile \ contrib/Debian/Makefile \
contrib/MacOSX/Makefile \ contrib/MacOSX/Makefile \
contrib/MacOSX/ngIRCd.xcodeproj/Makefile \
contrib/MacOSX/ngIRCd.pmdoc/Makefile \
]) ])
type dpkg >/dev/null 2>&1 type dpkg >/dev/null 2>&1
@@ -643,12 +572,6 @@ test "$x_identauth_on" = "yes" \
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_N " IPv6 protocol: $ECHO_C"
echo $ECHO_N "$x_ipv6_on $ECHO_C"
echo $ECHO_N " SSL support: $ECHO_C"
echo "$x_ssl_lib"
echo echo
# -eof- # -eof-

2
contrib/.cvsignore Normal file
View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -1,13 +0,0 @@
*.log
*.debhelper
*.substvars
files
ngircd/
ngircd-full/
ngircd-full.default
ngircd-full.init
ngircd-full.postinst
ngircd-full-dbg/
ngircd-full-dbg.default
ngircd-full-dbg.init
ngircd-full-dbg.postinst

View File

@@ -1,6 +1,6 @@
# #
# ngIRCd -- The Next Generation IRC Daemon # ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2009 Alexander Barton (alex@barton.de) # Copyright (c)2001-2003 by 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,9 +8,11 @@
# (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.4 2004/05/11 00:32:31 alex Exp $
#
EXTRA_DIST = rules changelog compat control copyright \ EXTRA_DIST = rules changelog compat control copyright \
ngircd.init ngircd.default ngircd.postinst ngircd.init ngircd.postinst
maintainer-clean-local: maintainer-clean-local:
rm -f Makefile Makefile.in rm -f Makefile Makefile.in
@@ -20,10 +22,7 @@ clean-local:
ngircd.prerm.debhelper ngircd.substvars ngircd.prerm.debhelper ngircd.substvars
rm -f ngircd-full.postinst.debhelper ngircd-full.postrm.debhelper \ rm -f ngircd-full.postinst.debhelper ngircd-full.postrm.debhelper \
ngircd-full.prerm.debhelper ngircd-full.substvars ngircd-full.prerm.debhelper ngircd-full.substvars
rm -f ngircd-full-dbg.postinst.debhelper \ rm -rf ngircd ngircd-full
ngircd-full-dbg.postrm.debhelper ngircd-full-dbg.prerm.debhelper \
ngircd-full-dbg.substvars
rm -rf ngircd ngircd-full ngircd-full-dbg
rm -f files rm -f files
# -eof- # -eof-

View File

@@ -1,96 +1,14 @@
ngircd (16~rc1-0ab1) unstable; urgency=low ngircd (0.11.1-0ab1) unstable; urgency=low
* New "upstream" release candidate 1 for ngIRCd Release 16. * New "upstream" release 0.11.1.
-- Alexander Barton <alex@barton.de> Thu, 25 Mar 2010 15:56:03 +0100 -- Alexander Barton <alex@barton.de> Tue, 26 Feb 2008 20:24:55 +0100
ngircd (15-0ab1) unstable; urgency=low ngircd (0.11.0-0ab1) unstable; urgency=low
* New "upstream" release: ngIRCd 15. * New "upstream" release 0.11.0.
-- Alexander Barton <alex@barton.de> Thu, 7 Nov 2009 12:07:08 +0200 -- Alexander Barton <alex@barton.de> Tue, 15 Jan 2008 21:43:46 +0100
ngircd (15~rc1-0ab1) unstable; urgency=low
* New "upstream" release candidate 1 for ngIRCd Release 15.
-- Alexander Barton <alex@barton.de> Thu, 15 Oct 2009 10:01:08 +0200
ngircd (14.1-0ab1) unstable; urgency=high
* New "upstream" release ngIRCd 14.1, fixing a security-related bug.
-- Alexander Barton <alex@barton.de> Tue, 5 May 2009 13:13:38 +0200
ngircd (14-0ab3) unstable; urgency=low
* Fixed "Conflicts:" line in debian/control: missing comma.
-- Alexander Barton <alex@barton.de> Mon, 4 May 2009 11:21:55 +0200
ngircd (14-0ab2) unstable; urgency=low
* Add new "ngircd-full-dbg" package including degug code and both
the --debug and --sniffer options, and containing debug symbols.
-- Alexander Barton <alex@barton.de> Wed, 29 Apr 2009 01:13:03 +0200
ngircd (14-0ab1) unstable; urgency=low
* New "upstream" release: ngIRCd 14.
-- Alexander Barton <alex@barton.de> Mon, 20 Apr 2009 11:09:12 +0200
ngircd (14~rc1-0ab1) unstable; urgency=low
* New "upstream" release candidate 1 for ngIRCd Release 14.
-- Alexander Barton <alex@barton.de> Sun, 29 Mar 2009 17:09:17 +0200
ngircd (13-0ab1) unstable; urgency=low
* New "upstream" release: ngIRCd 13.
-- Alexander Barton <alex@barton.de> Thu, 25 Dec 2008 23:09:58 +0100
ngircd (13~rc1-0ab1) unstable; urgency=low
* New "upstream" release candidate 1 for ngIRCd Release 13.
-- Alexander Barton <alex@barton.de> Fri, 21 Nov 2008 22:04:41 +0100
ngircd (0.12.1-0ab1+dev) unstable; urgency=low
* Update package for testing the new "upstream" features:
- Support for IRC services (see http://www.ircservices.za.net),
- Encrypted connections using GNU TLS (ngircd-full),
- Support for the IPv6 protocol (ngircd-full).
-- Alexander Barton <alex@barton.de> Fri, 03 Oct 2008 16:22:55 +0200
ngircd (0.12.1-0ab1) unstable; urgency=low
* New "upstream" release ngIRCd 0.12.1.
-- Alexander Barton <alex@barton.de> Wed, 9 Jul 2008 11:27:00 +0200
ngircd (0.12.0-0ab1) unstable; urgency=low
* New "upstream" release ngIRCd 0.12.0.
-- Alexander Barton <alex@barton.de> Tue, 13 May 2008 12:30:31 +0200
ngircd (0.12.0-0ab0-pre2) unstable; urgency=low
* Second prerelease of upcoming new "upstrem" release 0.12.0-pre1.
-- Alexander Barton <alex@barton.de> Tue, 29 Apr 2008 23:06:14 +0200
ngircd (0.12.0-0ab0-pre1) unstable; urgency=low
* Prereloease of upcoming new "upstrem" release 0.12.0-pre1.
-- Alexander Barton <alex@barton.de> Sun, 20 Apr 2008 15:43:34 +0200
ngircd (0.11.0-0ab0-pre2) unstable; urgency=low ngircd (0.11.0-0ab0-pre2) unstable; urgency=low

View File

@@ -2,8 +2,8 @@ Source: ngircd
Section: net 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, libwrap0-dev, libident-dev, libgnutls-dev Build-Depends: debhelper (>> 4.0.0), libz-dev, libwrap-dev, libident-dev
Standards-Version: 3.8.0 Standards-Version: 3.7.2.1
Package: ngircd Package: ngircd
Architecture: any Architecture: any
@@ -15,9 +15,7 @@ Description: A lightweight daemon for the Internet Relay Chat (IRC)
IRCd like many others. IRCd like many others.
. .
This package contains the "standard distribution", including support for This package contains the "standard distribution", including support for
syslog logging and compressed server-links using zlib. Please have a look syslog logging and compressed server-links using zlib.
at the "ngircd-full" package if you need advanced functionality like support
for IPv6 or SSL.
. .
Advantages of ngIRCd: Advantages of ngIRCd:
- no problems with servers using changing/non-static IP addresses. - no problems with servers using changing/non-static IP addresses.
@@ -32,41 +30,14 @@ Package: ngircd-full
Architecture: any Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends} Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: ircd Provides: ircd
Conflicts: ngircd, ngircd-dbg 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)
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
IRCd like many others. IRCd like many others.
. .
In addition to the features of the "standard package", this package This package includes support for TCP wrappers and IDENT requests in
includes support for TCP wrappers, IDENT requests, the IPv6 protocol and addition to the features of the "standard package".
SSL encrypted client and server links.
.
Advantages of ngIRCd:
- no problems with servers using changing/non-static IP addresses.
- small and lean configuration file.
- free, modern and open source C code.
- still under active development.
.
ngIRCd is compatible to the "original" ircd 2.10.3p3, so you can run
mixed networks.
Package: ngircd-full-dbg
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Provides: ircd
Conflicts: ngircd, ngircd-full
Description: A lightweight 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
IRCd like many others.
.
In addition to the features of the "standard package", this package
includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
SSL encrypted client and server links.
.
And in addition to the "full" variant, the binaries contained in this
package are build with debug code and contain debug symbols.
. .
Advantages of ngIRCd: Advantages of ngIRCd:
- no problems with servers using changing/non-static IP addresses. - no problems with servers using changing/non-static IP addresses.

View File

@@ -1,19 +1,19 @@
#!/bin/sh #!/bin/sh
# #
# ngIRCd start and stop script for Debian-based systems # ngIRCd start and stop script for Debian-based systems
# Copyright 2008,2009 Alexander Barton <alex@barton.de> #
# $Id: ngircd.init,v 1.7 2006/12/26 14:43:46 alex Exp $
# #
### BEGIN INIT INFO ### BEGIN INIT INFO
# Provides: ngircd # Provides: ircd
# Required-Start: $network $remote_fs # Required-Start: $local_fs
# Required-Stop: # Required-Stop: $local_fs
# Should-Start: $syslog $named # Should-Start: $syslog $network
# Should-Stop: $syslog # Should-Stop: $syslog $network
# Default-Start: 2 3 4 5 # Default-Start: 2 3 4 5
# Default-Stop: 0 1 6 # Default-Stop: 0 1 6
# Short-Description: Next Generation IRC Server # Short-Description: Next Generation IRC Server
# Description: IRC daemon written from scratch
### END INIT INFO ### 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
@@ -21,155 +21,66 @@ DAEMON=/usr/sbin/ngircd
NAME=ngIRCd NAME=ngIRCd
DESC="IRC daemon" DESC="IRC daemon"
PARAMS="" PARAMS=""
STARTTIME=1
DIETIME=10
test -x $DAEMON || exit 5
test -h "$0" && me=`readlink $0` || me="$0" test -h "$0" && me=`readlink $0` || me="$0"
BASENAME=`basename $me` BASENAME=`basename $me`
test -r /etc/default/$BASENAME && . /etc/default/$BASENAME test -f /etc/default/$BASENAME && . /etc/default/$BASENAME
# LSB compatibility functions that become used if there is no local test -x $DAEMON || exit 0
# include file available.
log_daemon_msg() {
echo -n "$*"
}
log_end_msg() {
[ "$1" == "0" ] && echo "." || echo " failed!"
}
log_failure_msg() {
echo "$*"
}
log_warning_msg() {
log_failure_msg "$*"
}
# Include LSB functions, if available:
test -r /lib/lsb/init-functions && . /lib/lsb/init-functions
PIDFILE=`$DAEMON $PARAMS -t | tr -d ' ' | grep "^PidFile=" | cut -d'=' -f2`
[ -n "$PIDFILE" ] || PIDFILE="/var/run/ircd/ngircd.pid"
r=3
Check_Config() Check_Config()
{ {
# Make sure that the configuration of ngIRCd is valid: $DAEMON --configtest >/dev/null 2>&1
$DAEMON $PARAMS --configtest >/dev/null 2>&1 if [ $? -ne 0 ]; then
[ $? -eq 0 ] && return 0 echo "Configuration of $NAME is not valide, won't (re)start!"
log_end_msg 1 echo "Please run \"$DAEMON --configtest\" manually and fix it up ..."
log_failure_msg "Configuration of $NAME is not valid, won't (re)start!"
log_failure_msg "Run \"$DAEMON --configtest\" and fix it up ..."
exit 6
}
Prepare() {
# Make sure the PID file directory exists and is writable:
user=`$DAEMON $PARAMS -t|tr -d ' '|grep "^ServerUID="|cut -d'=' -f2`
group=`$DAEMON $PARAMS -t|tr -d ' '|grep "^ServerGID="|cut -d'=' -f2`
piddir=`dirname "$PIDFILE"`
[ -d "$piddir" ] || mkdir -p "$piddir" 2>/dev/null
chown "$user:$group" "$piddir" 2>/dev/null
[ $? -eq 0 ] && return 0
log_end_msg 1
log_failure_msg "Failed to prepare '$piddir' for user '$user'!"
exit 1 exit 1
}
Do_Start() {
if Do_Status; then
log_end_msg 0
log_warning_msg "$NAME seems to be already running, nothing to do."
exit 0
fi fi
start-stop-daemon --start \
--quiet --exec $DAEMON -- $PARAMS
sleep $STARTTIME
Do_Status || return 7
return 0
} }
Do_Stop() { Try_Start()
if ! Do_Status; then {
log_end_msg 0 [ ! -d /var/run/ircd ] || chown irc:irc /var/run/ircd
log_warning_msg "$NAME seems not to be running, nothing to do." start-stop-daemon --start --quiet --exec $DAEMON -- $PARAMS
exit 0 if [ $? -ne 0 ]; then
echo "$NAME failed!"
exit 1
fi fi
Do_ForceStop echo "$NAME."
return $?
}
Do_ForceStop() {
[ -e $PIDFILE ] \
&& pidfile="--pidfile $PIDFILE" \
|| pidfile=""
start-stop-daemon --stop \
--quiet --oknodo --exec $DAEMON $pidfile
for i in `seq 1 $DIETIME`; do
Do_Status || return 0
sleep 1
done
return 1
}
Do_Reload() {
start-stop-daemon --stop --signal 1 --quiet --exec $DAEMON
return $?
}
Do_Status() {
[ -e $PIDFILE ] \
&& pidfile="--pidfile $PIDFILE" \
|| pidfile=""
start-stop-daemon --stop \
--quiet --signal 0 --exec $DAEMON $pidfile >/dev/null
return $?
} }
case "$1" in case "$1" in
start) start)
log_daemon_msg "Starting $DESC" "$NAME"
Check_Config Check_Config
Prepare echo -n "Starting $DESC: "
Do_Start; r=$? Try_Start
log_end_msg $r
;; ;;
stop) stop)
log_daemon_msg "Stopping $DESC" "$NAME" echo -n "Stopping $DESC: "
Do_Stop; r=$? start-stop-daemon --stop --quiet --pidfile /var/run/ircd/ngircd.pid --exec $DAEMON \
log_end_msg $r && echo "$NAME." \
|| echo "(none running)"
;; ;;
reload|force-reload) reload|force-reload)
log_daemon_msg "Reloading $DESC" "$NAME"
Check_Config Check_Config
Do_Reload; r=$? echo "Reloading $DESC configuration files."
log_end_msg $r start-stop-daemon --stop --signal 1 --quiet --exec $DAEMON
;; ;;
restart) restart)
log_daemon_msg "Restarting $DESC" "$NAME"
Check_Config Check_Config
Prepare echo -n "Restarting $DESC: "
Do_ForceStop start-stop-daemon --stop --quiet --oknodo --exec $DAEMON
Do_Start; r=$? sleep 1
log_end_msg $r Try_Start
;;
status)
log_daemon_msg "Checking for $DESC" "$NAME"
Do_Status; r=$?
log_end_msg $r
;;
test)
Check_Config
echo "Configuration of $DAEMON seems to be ok."; r=0
;; ;;
*) *)
N=/etc/init.d/$NAME; r=2 N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|reload|force-reload|status|test}" >&2 echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
exit 1
;; ;;
esac esac
exit $r exit 0
# -eof- # -eof-

View File

@@ -1,7 +1,7 @@
#!/usr/bin/make -f #!/usr/bin/make -f
# #
# ngIRCd -- The Next Generation IRC Daemon # ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2009 Alexander Barton <alex@barton.de> # Copyright (c)2001-2003 by 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
@@ -11,6 +11,8 @@
# #
# debian/rules for ngIRCd # debian/rules for ngIRCd
# #
# $Id: rules,v 1.3 2005/02/07 23:09:31 alex Exp $
#
# Based on the sample debian/rules that uses debhelper, # Based on the sample debian/rules that uses debhelper,
# GNU copyright 1997 to 1999 by Joey Hess. # GNU copyright 1997 to 1999 by Joey Hess.
# #
@@ -52,22 +54,7 @@ configure-ngircd-full: configure
--prefix=/usr \ --prefix=/usr \
--sysconfdir=/etc/ngircd \ --sysconfdir=/etc/ngircd \
--mandir=\$${prefix}/share/man \ --mandir=\$${prefix}/share/man \
--with-syslog --with-zlib \ --with-syslog --with-zlib --with-tcp-wrappers --with-ident
--with-gnutls --with-ident --with-tcp-wrappers \
--enable-ipv6
configure-ngircd-full-dbg: configure
dh_testdir
# configure "full debug" variant:
./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) \
--prefix=/usr \
--sysconfdir=/etc/ngircd \
--mandir=\$${prefix}/share/man \
--enable-debug --enable-sniffer \
--with-syslog --with-zlib \
--with-gnutls --with-ident --with-tcp-wrappers \
--enable-ipv6
build: build:
dh_clean -k dh_clean -k
@@ -92,16 +79,6 @@ build-stamp-ngircd-full: configure-ngircd-full
touch build-stamp-ngircd-full touch build-stamp-ngircd-full
build-ngircd-full-dbg: build-stamp-ngircd-full-dbg
build-stamp-ngircd-full-dbg: configure-ngircd-full-dbg
dh_testdir
rm -f build-stamp-*
# Add here commands to compile the "full debug" package:
$(MAKE)
touch build-stamp-ngircd-full
clean: clean:
dh_testdir dh_testdir
dh_testroot dh_testroot
@@ -109,12 +86,9 @@ clean:
rm -f $(CURDIR)/debian/ngircd-full.default rm -f $(CURDIR)/debian/ngircd-full.default
rm -f $(CURDIR)/debian/ngircd-full.init rm -f $(CURDIR)/debian/ngircd-full.init
rm -f $(CURDIR)/debian/ngircd-full.postinst rm -f $(CURDIR)/debian/ngircd-full.postinst
rm -f $(CURDIR)/debian/ngircd-full-dbg.default
rm -f $(CURDIR)/debian/ngircd-full-dbg.postinst
rm -f $(CURDIR)/debian/ngircd-full-dbg.init
# Add here commands to clean up after the build process: # Add here commands to clean up after the build process:
[ ! -f Makefile ] || $(MAKE) distclean -$(MAKE) clean
ifneq "$(wildcard /usr/share/misc/config.sub)" "" ifneq "$(wildcard /usr/share/misc/config.sub)" ""
cp -f /usr/share/misc/config.sub config.sub cp -f /usr/share/misc/config.sub config.sub
@@ -124,7 +98,7 @@ ifneq "$(wildcard /usr/share/misc/config.guess)" ""
endif endif
dh_clean dh_clean
install: install-ngircd install-ngircd-full install-ngircd-full-dbg install: install-ngircd install-ngircd-full
install-ngircd: build-ngircd install-ngircd: build-ngircd
dh_testdir dh_testdir
@@ -164,26 +138,6 @@ install-ngircd-full: build-ngircd-full
>$(CURDIR)/debian/ngircd-full/etc/ngircd/ngircd.conf >$(CURDIR)/debian/ngircd-full/etc/ngircd/ngircd.conf
touch $(CURDIR)/debian/ngircd-full/etc/ngircd/ngircd.motd touch $(CURDIR)/debian/ngircd-full/etc/ngircd/ngircd.motd
install-ngircd-full-dbg: build-ngircd-full-dbg
dh_testdir
dh_testroot
dh_installdirs
# Add here commands to install the "full" package into debian/ngircd-full:
$(MAKE) install DESTDIR=$(CURDIR)/debian/ngircd-full-dbg
rm $(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd/INSTALL*
rm $(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd/COPYING*
mv $(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd \
$(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd-full-dbg
mkdir -p $(CURDIR)/debian/ngircd-full-dbg/var/run/ircd
cat $(CURDIR)/debian/ngircd-full-dbg/usr/share/doc/ngircd-full-dbg/sample-ngircd.conf | \
sed -e "s/;ServerUID = 65534/ServerUID = irc/g" | \
sed -e "s/;ServerGID = 65534/ServerGID = irc/g" | \
sed -e "s/;MotdFile = \/usr\/local\/etc\/ngircd.motd/MotdFile = \/etc\/ngircd\/ngircd.motd/g" | \
sed -e "s/;PidFile = \/var\/run\/ngircd\/ngircd.pid/PidFile = \/var\/run\/ircd\/ngircd.pid/g" \
>$(CURDIR)/debian/ngircd-full-dbg/etc/ngircd/ngircd.conf
touch $(CURDIR)/debian/ngircd-full-dbg/etc/ngircd/ngircd.motd
# Build architecture-independent files here. # Build architecture-independent files here.
binary-indep: binary-indep:
# We have nothing to do by default. # We have nothing to do by default.
@@ -197,19 +151,12 @@ binary-arch: build install
ln -s $(CURDIR)/debian/ngircd.postinst \ ln -s $(CURDIR)/debian/ngircd.postinst \
$(CURDIR)/debian/ngircd-full.postinst $(CURDIR)/debian/ngircd-full.postinst
ln -s $(CURDIR)/debian/ngircd.default \
$(CURDIR)/debian/ngircd-full-dbg.default
ln -s $(CURDIR)/debian/ngircd.init \
$(CURDIR)/debian/ngircd-full-dbg.init
ln -s $(CURDIR)/debian/ngircd.postinst \
$(CURDIR)/debian/ngircd-full-dbg.postinst
dh_testdir dh_testdir
dh_testroot dh_testroot
dh_installchangelogs -a -A ChangeLog dh_installchangelogs -a -A ChangeLog
dh_installdocs -a dh_installdocs -a
dh_installinit -a dh_installinit -a
dh_strip -a --no-package=ngircd-full-dbg dh_strip -a
dh_compress -a dh_compress -a
dh_fixperms -a dh_fixperms -a
dh_installdeb -a dh_installdeb -a

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -1,2 +0,0 @@
build
de.barton.ngircd.plist

View File

@@ -1,6 +1,6 @@
# #
# ngIRCd -- The Next Generation IRC Daemon # ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de> # Copyright (c)2001-2004 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,43 +8,11 @@
# (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 2004/05/11 00:34:26 alex Exp $
SUBDIRS = ngIRCd.xcodeproj ngIRCd.pmdoc #
EXTRA_DIST = de.barton.ngircd.plist.tmpl config.h preinstall.sh postinstall.sh
SUFFIXES = .tmpl .
.tmpl:
sed \
-e s@:SBINDIR:@${sbindir}@ \
<$< >$@
install-data-local:
[ `uname -s` != "Darwin" ] || make install-sys-darwin
install-sys-darwin:
@if [ `id -u` -eq 0 ]; then \
make install-sys-darwin-root; \
else \
echo; \
echo " ** NOTE: Not installing with root privileges, so the LaunchDaemon script"; \
echo " ** \"/Library/LaunchDaemons/de.barton.ngircd.plist\" can't be installed/updated!"; \
echo; \
fi
install-sys-darwin-root: de.barton.ngircd.plist
install -d -m 755 -o root -g wheel $(DESTDIR)/Library/LaunchDaemons
install -c -m 644 -b -o root -g wheel de.barton.ngircd.plist \
$(DESTDIR)/Library/LaunchDaemons/de.barton.ngircd.plist
@echo
@echo " ** \"/Library/LaunchDaemons/de.barton.ngircd.plist\" has been installed,"
@echo " ** but is disabled. Use launchctl(8) to enable/run ngIRCd on Darwin/Mac OS X."
@echo
clean-local: clean-local:
rm -rf build rm -rf build
rm -f de.barton.ngircd.plist
maintainer-clean-local: maintainer-clean-local:
rm -f Makefile Makefile.in rm -f Makefile Makefile.in

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2009 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,20 +8,15 @@
* (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: config.h,v 1.1 2007/11/19 22:11:36 alex Exp $
*
* Static configuration file for Mac OS X Xcode project * Static configuration file for Mac OS X Xcode project
*/ */
#define PACKAGE_NAME "ngircd" #define PACKAGE_NAME "ngircd"
#ifndef VERSION #define VERSION "??"
#define VERSION "??("__DATE__")"
#endif
#define SYSCONFDIR "/etc/ngircd" #define SYSCONFDIR "/etc/ngircd"
#ifndef TARGET_VENDOR
#define TARGET_VENDOR "apple"
#define TARGET_OS "darwin"
#endif
/* -- Build options -- */ /* -- Build options -- */
/* Define if debug-mode should be enabled */ /* Define if debug-mode should be enabled */
@@ -48,9 +43,6 @@
/* Define if zlib compression should be enabled */ /* Define if zlib compression should be enabled */
#define ZLIB 1 #define ZLIB 1
/* Define if IPV6 protocol should be enabled */
#define WANT_IPV6 1
/* -- Supported features -- */ /* -- Supported features -- */
/* Define if SSP C support is enabled. */ /* Define if SSP C support is enabled. */
@@ -71,8 +63,6 @@
#define HAVE_STDBOOL_H 1 #define HAVE_STDBOOL_H 1
/* Define to 1 if you have the <arpa/inet.h> header file. */ /* Define to 1 if you have the <arpa/inet.h> header file. */
#define HAVE_ARPA_INET_H 1 #define HAVE_ARPA_INET_H 1
/* Define to 1 if you have the <netinet/ip.h> header file. */
#define HAVE_NETINET_IP_H 1
/* Define to 1 if you have the `kqueue' function. */ /* Define to 1 if you have the `kqueue' function. */
#define HAVE_KQUEUE 1 #define HAVE_KQUEUE 1
@@ -88,12 +78,6 @@
#define HAVE_STRDUP 1 #define HAVE_STRDUP 1
/* Define to 1 if you have the `vsnprintf' function. */ /* Define to 1 if you have the `vsnprintf' function. */
#define HAVE_VSNPRINTF 1 #define HAVE_VSNPRINTF 1
/* Define to 1 if you have the `inet_aton' function. */
#define HAVE_INET_ATON 1
/* Define to 1 if you have the `getaddrinfo' function. */
#define HAVE_GETADDRINFO 1
/* Define to 1 if you have the `getnameinfo' function. */
#define HAVE_GETNAMEINFO 1
/* Define if socklen_t exists */ /* Define if socklen_t exists */
#define HAVE_socklen_t 1 #define HAVE_socklen_t 1

View File

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>de.barton.ngIRCd</string>
<key>ProgramArguments</key>
<array>
<string>:SBINDIR:/ngircd</string>
<string>--nodaemon</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/Library/Logs/ngIRCd.log</string>
<key>StandardOutPath</key>
<string>/Library/Logs/ngIRCd.log</string>
</dict>
</plist>

View File

@@ -1 +0,0 @@
<pkg-contents spec="1.12"/>

View File

@@ -1 +0,0 @@
<pkgref spec="1.12" uuid="6AF4DF80-E7DE-45E7-8B40-890A10AE51D0"><config><identifier>de.barton.ngircd.daemon.pkg</identifier><version>1</version><description></description><post-install type="none"/><requireAuthorization/><installFrom relative="true">../../ngircd.dest</installFrom><installTo>/</installTo><flags><followSymbolicLinks/></flags><packageStore type="internal"></packageStore><mod>parent</mod><mod>scripts.postinstall.path</mod><mod>scripts.postinstall.isRelativeType</mod><mod>scripts.preupgrade.path</mod><mod>installFrom.isRelativeType</mod><mod>version</mod><mod>scripts.preinstall.isRelativeType</mod><mod>identifier</mod><mod>installTo</mod></config><scripts><preinstall relative="true" mod="true">preinstall.sh</preinstall><preupgrade relative="true" mod="true">preinstall.sh</preupgrade></scripts></pkgref>

View File

@@ -1 +0,0 @@
<pkg-contents spec="1.12"/>

View File

@@ -1 +0,0 @@
<pkgref spec="1.12" uuid="F0954DA7-0607-4277-AE10-D882AC7C38CA"><config><identifier>de.barton.ngircd.launchscript.pkg</identifier><version>1</version><description></description><post-install type="none"/><requireAuthorization/><installFrom relative="true">de.barton.ngircd.plist</installFrom><installTo mod="true">/Library/LaunchDaemons</installTo><flags><followSymbolicLinks/></flags><packageStore type="internal"></packageStore><mod>parent</mod><mod>scripts.postinstall.path</mod><mod>scripts.postupgrade.path</mod><mod>installFrom.isRelativeType</mod><mod>installTo.path</mod><mod>installTo</mod><mod>identifier</mod></config><scripts><postinstall relative="true" mod="true">postinstall.sh</postinstall><postupgrade relative="true" mod="true">postinstall.sh</postupgrade></scripts></pkgref>

View File

@@ -1,18 +0,0 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
EXTRA_DIST = index.xml \
01ngircd-contents.xml 01ngircd.xml 02de-contents.xml 02de.xml
maintainer-clean-local:
rm -f Makefile Makefile.in
# -eof-

View File

@@ -1,190 +0,0 @@
<pkmkdoc spec="1.12"><properties><title>ngIRCd</title><build>/Users/alex/Desktop/ngIRCd.mpkg</build><organization>de.barton.ngircd</organization><userSees ui="both"/><min-target os="2"/><domain anywhere="true"/></properties><distribution><versions min-spec="1.000000"/><scripts></scripts></distribution><description>ngIRCd next generation IRC (Internet Relay Chat) server daemon</description><contents><choice title="ngIRCd daemon" id="choicengircd" tooltip="ngIRCd daemon, documentation and manual pages" description="Binaries, documentation and manual pages of the ngIRCd, the next generation IRC (Internet Relay Chat) daemon. This package will be installed into /opt/ngircd." starts_selected="true" starts_enabled="true" starts_hidden="false"><customLoc>/</customLoc><pkgref id="de.barton.ngircd.daemon.pkg"/></choice><choice title="Start and stop script" id="choicelaunchscript" tooltip="LaunchDaemon start and stop script" description="Installs the ngIRCd start and stop script for the &quot;launch daemon&quot;. If this is an update/upgrade, and ngIRCd is already running, it will be automatically restarted." starts_selected="true" starts_enabled="true" starts_hidden="false"><customLoc>/Library/LaunchDaemons</customLoc><pkgref id="de.barton.ngircd.launchscript.pkg"/></choice></contents><resources bg-scale="none" bg-align="topleft"><locale lang="en"><resource mime-type="text/rtf" kind="embedded" type="license"><![CDATA[{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf430
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
\f0\i\fs24 \cf0 ngIRCd -- The Next Generation IRC Daemon\
Copyright (c)2001-2009 Alexander Barton and Contributors.\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\i0 \cf0 \
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. \
\
Please see below and read the file COPYING, README and AUTHORS for more information.\
\
\
\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
\b \cf0 GNU GENERAL PUBLIC LICENSE\
Version 2, June 1991\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\b0 \cf0 \
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
\cf0 Copyright (C) 1989, 1991 Free Software Foundation, Inc.\
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\
Everyone is permitted to copy and distribute verbatim copies\
of this license document, but changing it is not allowed.\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\cf0 \
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
\b \cf0 Preamble\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\b0 \cf0 \
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.\
\
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.\
\
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.\
\
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.\
\
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.\
\
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.\
\
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.\
\
The precise terms and conditions for copying, distribution and modification follow.\
\page \
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
\b \cf0 GNU GENERAL PUBLIC LICENSE\
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION\
AND MODIFICATION\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\b0 \cf0 \
0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law:\
that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".\
\
Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the\
Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.\
\
1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.\
\
You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.\
\
2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1above, provided that you also meet all of these conditions:\
\
a) You must cause the modified files to carry prominent notices\
stating that you changed the files and the date of any change.\
\
b) You must cause any work that you distribute or publish, that in\
whole or in part contains or is derived from the Program or any\
part thereof, to be licensed as a whole at no charge to all third\
parties under the terms of this License.\
\
c) If the modified program normally reads commands interactively\
when run, you must cause it, when started running for such\
interactive use in the most ordinary way, to print or display an\
announcement including an appropriate copyright notice and a\
notice that there is no warranty (or else, saying that you provide\
a warranty) and that users may redistribute the program under\
these conditions, and telling the user how to view a copy of this\
License. (Exception: if the Program itself is interactive but\
does not normally print such an announcement, your work based on\
the Program is not required to print an announcement.)\
\page \
These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.\
\
Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.\
\
In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.\
\
3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:\
\
a) Accompany it with the complete corresponding machine-readable\
source code, which must be distributed under the terms of Sections\
1 and 2 above on a medium customarily used for software\
interchange; or,\
\
b) Accompany it with a written offer, valid for at least three\
years, to give any third party, for a charge no more than your\
cost of physically performing source distribution, a complete\
machine-readable copy of the corresponding source code, to be\
distributed under the terms of Sections 1 and 2 above on a medium\
customarily used for software interchange; or,\
\
c) Accompany it with the information you received as to the offer\
to distribute corresponding source code. (This alternative is\
allowed only for noncommercial distribution and only if you\
received the program in object code or executable form with such\
an offer, in accord with Subsection b above.)\
\
The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.\
\
If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not\
compelled to copy the source along with the object code.\
\
4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.\
\
5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.\
\
6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.\
\
7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.\
\
If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.\
\
It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.\
\
This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.\
\page \
8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.\
\
9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.\
\
Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.\
\
10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.\
\
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
\b \cf0 NO WARRANTY
\b0 \
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
\cf0 \
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\
\
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\
}]]></resource><resource mime-type="text/rtf" kind="embedded" type="welcome"><![CDATA[{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf430
{\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\f0\fs26 \cf0 ngIRCd is a free open source daemon for the Internet Relay Chat (IRC) protocol, developed under the GNU General Public License (GPL). It's written from scratch, is quite portable and is not based upon the original IRCd like many others.\
\
Homepage: http://ngircd.barton.de\
\
You will be guided through all steps necessary to install this software.}]]></resource><resource mime-type="text/rtf" kind="embedded" type="conclusion"><![CDATA[{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf430
{\fonttbl\f0\fnil\fcharset0 LucidaGrande;\f1\fnil\fcharset0 Monaco;}
{\colortbl;\red255\green255\blue255;}
{\*\listtable{\list\listtemplateid1\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid1}
{\list\listtemplateid2\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace360\levelindent0{\*\levelmarker \{hyphen\}}{\leveltext\leveltemplateid0\'02\'05.;}{\levelnumbers\'01;}}{\listname ;}\listid2}}
{\*\listoverridetable{\listoverride\listid1\listoverridecount0\ls1}{\listoverride\listid2\listoverridecount0\ls2}}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\f0\fs26 \cf0 ngIRCd has been successfully installed/upgraded.\
\
It has been restarted if it was already running before and you have installed the LaunchDaemon start and stop script (which is the default).\
\
If you installed ngIRCd the first time (or had the LaunchDaemon script disabled before), you can start ngIRCd using the following terminal command:\
\
\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\ql\qnatural\pardirnatural
\ls1\ilvl0
\f1\fs24 \cf0 sudo launchctl load -w \\\
/Library/LaunchDaemons/de.barton.ngircd.plist\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\f0\fs26 \cf0 \
To disable automatic starting of ngIRCd, use this command:\
\
\pard\tx220\tx720\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li720\fi-720\ql\qnatural\pardirnatural
\ls2\ilvl0
\f1\fs24 \cf0 sudo launchctl unload -w \\\
/Library/LaunchDaemons/de.barton.ngircd.plist\
}]]></resource></locale></resources><flags/><item type="file">01ngircd.xml</item><item type="file">02de.xml</item><mod>properties.customizeOption</mod><mod>properties.title</mod><mod>description</mod><mod>properties.anywhereDomain</mod><mod>properties.systemDomain</mod></pkmkdoc>

View File

@@ -1,2 +0,0 @@
*.mode1v3
*.pbxuser

View File

@@ -1,17 +0,0 @@
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
EXTRA_DIST = project.pbxproj
maintainer-clean-local:
rm -f Makefile Makefile.in
# -eof-

View File

@@ -34,9 +34,6 @@
FA322D4D0CEF74B1001761B3 /* resolve.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D0C0CEF74B1001761B3 /* resolve.c */; }; FA322D4D0CEF74B1001761B3 /* resolve.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D0C0CEF74B1001761B3 /* resolve.c */; };
FA322DBE0CEF7766001761B3 /* tool.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D330CEF74B1001761B3 /* tool.c */; }; FA322DBE0CEF7766001761B3 /* tool.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D330CEF74B1001761B3 /* tool.c */; };
FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA322DC00CEF77CB001761B3 /* libz.dylib */; }; FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA322DC00CEF77CB001761B3 /* libz.dylib */; };
FA407F2E0DB159F400271AF1 /* ng_ipaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */; };
FA85178C0FA061EC006A1F5A /* op.c in Sources */ = {isa = PBXBuildFile; fileRef = FA85178B0FA061EC006A1F5A /* op.c */; };
FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA3D2790F139CDC00B2447E /* conn-ssl.c */; };
FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */ = {isa = PBXBuildFile; fileRef = FAE5CC2D0CF2308A007D69B6 /* numeric.c */; }; FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */ = {isa = PBXBuildFile; fileRef = FAE5CC2D0CF2308A007D69B6 /* numeric.c */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@@ -53,10 +50,10 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
FA1A6BBC0D6857BB00AA8F71 /* misc-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "misc-test.e"; sourceTree = "<group>"; };
FA1A6BBD0D6857D900AA8F71 /* who-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "who-test.e"; sourceTree = "<group>"; };
FA322BBA0CEF72E4001761B3 /* ngIRCd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ngIRCd; sourceTree = BUILT_PRODUCTS_DIR; }; FA322BBA0CEF72E4001761B3 /* ngIRCd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ngIRCd; sourceTree = BUILT_PRODUCTS_DIR; };
FA322CD50CEF74B1001761B3 /* .cvsignore */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = .cvsignore; sourceTree = "<group>"; };
FA322CD60CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; }; FA322CD60CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322CD80CEF74B1001761B3 /* .cvsignore */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = .cvsignore; sourceTree = "<group>"; };
FA322CD90CEF74B1001761B3 /* array.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = array.c; sourceTree = "<group>"; }; FA322CD90CEF74B1001761B3 /* array.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = array.c; sourceTree = "<group>"; };
FA322CDA0CEF74B1001761B3 /* array.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = array.h; sourceTree = "<group>"; }; FA322CDA0CEF74B1001761B3 /* array.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = array.h; sourceTree = "<group>"; };
FA322CDB0CEF74B1001761B3 /* channel.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = channel.c; sourceTree = "<group>"; }; FA322CDB0CEF74B1001761B3 /* channel.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = channel.c; sourceTree = "<group>"; };
@@ -110,6 +107,7 @@
FA322D0B0CEF74B1001761B3 /* rendezvous.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = rendezvous.h; sourceTree = "<group>"; }; FA322D0B0CEF74B1001761B3 /* rendezvous.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = rendezvous.h; sourceTree = "<group>"; };
FA322D0C0CEF74B1001761B3 /* resolve.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = resolve.c; sourceTree = "<group>"; }; FA322D0C0CEF74B1001761B3 /* resolve.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = resolve.c; sourceTree = "<group>"; };
FA322D0D0CEF74B1001761B3 /* resolve.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = resolve.h; sourceTree = "<group>"; }; FA322D0D0CEF74B1001761B3 /* resolve.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = resolve.h; sourceTree = "<group>"; };
FA322D0F0CEF74B1001761B3 /* .cvsignore */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = .cvsignore; sourceTree = "<group>"; };
FA322D100CEF74B1001761B3 /* ansi2knr.1 */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.man; path = ansi2knr.1; sourceTree = "<group>"; }; FA322D100CEF74B1001761B3 /* ansi2knr.1 */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.man; path = ansi2knr.1; sourceTree = "<group>"; };
FA322D110CEF74B1001761B3 /* ansi2knr.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = ansi2knr.c; sourceTree = "<group>"; }; FA322D110CEF74B1001761B3 /* ansi2knr.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = ansi2knr.c; sourceTree = "<group>"; };
FA322D120CEF74B1001761B3 /* exp.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = exp.h; sourceTree = "<group>"; }; FA322D120CEF74B1001761B3 /* exp.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = exp.h; sourceTree = "<group>"; };
@@ -121,6 +119,7 @@
FA322D180CEF74B1001761B3 /* strdup.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = strdup.c; sourceTree = "<group>"; }; FA322D180CEF74B1001761B3 /* strdup.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = strdup.c; sourceTree = "<group>"; };
FA322D190CEF74B1001761B3 /* strlcpy.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = strlcpy.c; sourceTree = "<group>"; }; FA322D190CEF74B1001761B3 /* strlcpy.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = strlcpy.c; sourceTree = "<group>"; };
FA322D1A0CEF74B1001761B3 /* vsnprintf.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = vsnprintf.c; sourceTree = "<group>"; }; FA322D1A0CEF74B1001761B3 /* vsnprintf.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = vsnprintf.c; sourceTree = "<group>"; };
FA322D1C0CEF74B1001761B3 /* .cvsignore */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = .cvsignore; sourceTree = "<group>"; };
FA322D1D0CEF74B1001761B3 /* channel-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "channel-test.e"; sourceTree = "<group>"; }; FA322D1D0CEF74B1001761B3 /* channel-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "channel-test.e"; sourceTree = "<group>"; };
FA322D1E0CEF74B1001761B3 /* check-idle.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "check-idle.e"; sourceTree = "<group>"; }; FA322D1E0CEF74B1001761B3 /* check-idle.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "check-idle.e"; sourceTree = "<group>"; };
FA322D1F0CEF74B1001761B3 /* connect-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "connect-test.e"; sourceTree = "<group>"; }; FA322D1F0CEF74B1001761B3 /* connect-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "connect-test.e"; sourceTree = "<group>"; };
@@ -128,6 +127,7 @@
FA322D210CEF74B1001761B3 /* getpid.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = getpid.sh; sourceTree = "<group>"; }; FA322D210CEF74B1001761B3 /* getpid.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = getpid.sh; sourceTree = "<group>"; };
FA322D220CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; }; FA322D220CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322D230CEF74B1001761B3 /* mode-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "mode-test.e"; sourceTree = "<group>"; }; FA322D230CEF74B1001761B3 /* mode-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "mode-test.e"; sourceTree = "<group>"; };
FA322D240CEF74B1001761B3 /* ngircd-test.conf */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "ngircd-test.conf"; sourceTree = "<group>"; };
FA322D250CEF74B1001761B3 /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = README; sourceTree = "<group>"; }; FA322D250CEF74B1001761B3 /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
FA322D260CEF74B1001761B3 /* start-server.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = "start-server.sh"; sourceTree = "<group>"; }; FA322D260CEF74B1001761B3 /* start-server.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = "start-server.sh"; sourceTree = "<group>"; };
FA322D270CEF74B1001761B3 /* stop-server.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = "stop-server.sh"; sourceTree = "<group>"; }; FA322D270CEF74B1001761B3 /* stop-server.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = "stop-server.sh"; sourceTree = "<group>"; };
@@ -137,6 +137,7 @@
FA322D2B0CEF74B1001761B3 /* test-loop.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = "test-loop.sh"; sourceTree = "<group>"; }; FA322D2B0CEF74B1001761B3 /* test-loop.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = "test-loop.sh"; sourceTree = "<group>"; };
FA322D2C0CEF74B1001761B3 /* tests.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = tests.sh; sourceTree = "<group>"; }; FA322D2C0CEF74B1001761B3 /* tests.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = tests.sh; sourceTree = "<group>"; };
FA322D2D0CEF74B1001761B3 /* wait-tests.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = "wait-tests.sh"; sourceTree = "<group>"; }; FA322D2D0CEF74B1001761B3 /* wait-tests.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = "wait-tests.sh"; sourceTree = "<group>"; };
FA322D2F0CEF74B1001761B3 /* .cvsignore */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = .cvsignore; sourceTree = "<group>"; };
FA322D300CEF74B1001761B3 /* ansi2knr.1 */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.man; path = ansi2knr.1; sourceTree = "<group>"; }; FA322D300CEF74B1001761B3 /* ansi2knr.1 */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.man; path = ansi2knr.1; sourceTree = "<group>"; };
FA322D310CEF74B1001761B3 /* ansi2knr.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = ansi2knr.c; sourceTree = "<group>"; }; FA322D310CEF74B1001761B3 /* ansi2knr.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = ansi2knr.c; sourceTree = "<group>"; };
FA322D320CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; }; FA322D320CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
@@ -153,6 +154,8 @@
FA322D630CEF750F001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ../../Makefile.am; sourceTree = SOURCE_ROOT; }; FA322D630CEF750F001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ../../Makefile.am; sourceTree = SOURCE_ROOT; };
FA322D640CEF750F001761B3 /* NEWS */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = NEWS; path = ../../NEWS; sourceTree = SOURCE_ROOT; }; FA322D640CEF750F001761B3 /* NEWS */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = NEWS; path = ../../NEWS; sourceTree = SOURCE_ROOT; };
FA322D650CEF750F001761B3 /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = README; path = ../../README; sourceTree = SOURCE_ROOT; }; FA322D650CEF750F001761B3 /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = README; path = ../../README; sourceTree = SOURCE_ROOT; };
FA322D670CEF7523001761B3 /* .cvsignore */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = .cvsignore; sourceTree = "<group>"; };
FA322D690CEF7523001761B3 /* .cvsignore */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = .cvsignore; sourceTree = "<group>"; };
FA322D6A0CEF7523001761B3 /* changelog */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = changelog; sourceTree = "<group>"; }; FA322D6A0CEF7523001761B3 /* changelog */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = changelog; sourceTree = "<group>"; };
FA322D6B0CEF7523001761B3 /* compat */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = compat; sourceTree = "<group>"; }; FA322D6B0CEF7523001761B3 /* compat */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = compat; sourceTree = "<group>"; };
FA322D6C0CEF7523001761B3 /* control */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = control; sourceTree = "<group>"; }; FA322D6C0CEF7523001761B3 /* control */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = control; sourceTree = "<group>"; };
@@ -162,6 +165,7 @@
FA322D700CEF7523001761B3 /* ngircd.init */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = ngircd.init; sourceTree = "<group>"; }; FA322D700CEF7523001761B3 /* ngircd.init */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = ngircd.init; sourceTree = "<group>"; };
FA322D710CEF7523001761B3 /* ngircd.postinst */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = ngircd.postinst; sourceTree = "<group>"; }; FA322D710CEF7523001761B3 /* ngircd.postinst */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = ngircd.postinst; sourceTree = "<group>"; };
FA322D720CEF7523001761B3 /* rules */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = rules; sourceTree = "<group>"; }; FA322D720CEF7523001761B3 /* rules */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = rules; sourceTree = "<group>"; };
FA322D740CEF7523001761B3 /* .cvsignore */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = .cvsignore; sourceTree = "<group>"; };
FA322D8D0CEF7523001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; }; FA322D8D0CEF7523001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322D8E0CEF7523001761B3 /* ngIRCd.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = ngIRCd.xcodeproj; sourceTree = "<group>"; }; FA322D8E0CEF7523001761B3 /* ngIRCd.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = ngIRCd.xcodeproj; sourceTree = "<group>"; };
FA322D910CEF7523001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; }; FA322D910CEF7523001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
@@ -170,6 +174,8 @@
FA322D940CEF7523001761B3 /* ngircd.spec */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngircd.spec; sourceTree = "<group>"; }; FA322D940CEF7523001761B3 /* ngircd.spec */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngircd.spec; sourceTree = "<group>"; };
FA322D950CEF7523001761B3 /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = README; sourceTree = "<group>"; }; FA322D950CEF7523001761B3 /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
FA322D960CEF7523001761B3 /* systrace.policy */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = systrace.policy; sourceTree = "<group>"; }; FA322D960CEF7523001761B3 /* systrace.policy */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = systrace.policy; sourceTree = "<group>"; };
FA322D980CEF752C001761B3 /* .cvsignore */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = .cvsignore; sourceTree = "<group>"; };
FA322D990CEF752C001761B3 /* CVS.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = CVS.txt; sourceTree = "<group>"; };
FA322D9A0CEF752C001761B3 /* FAQ.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = FAQ.txt; sourceTree = "<group>"; }; FA322D9A0CEF752C001761B3 /* FAQ.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = FAQ.txt; sourceTree = "<group>"; };
FA322D9B0CEF752C001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; }; FA322D9B0CEF752C001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322D9C0CEF752C001761B3 /* Platforms.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Platforms.txt; sourceTree = "<group>"; }; FA322D9C0CEF752C001761B3 /* Platforms.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Platforms.txt; sourceTree = "<group>"; };
@@ -178,6 +184,7 @@
FA322D9F0CEF752C001761B3 /* README-BeOS.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "README-BeOS.txt"; sourceTree = "<group>"; }; FA322D9F0CEF752C001761B3 /* README-BeOS.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "README-BeOS.txt"; sourceTree = "<group>"; };
FA322DA00CEF752C001761B3 /* RFC.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = RFC.txt; sourceTree = "<group>"; }; FA322DA00CEF752C001761B3 /* RFC.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = RFC.txt; sourceTree = "<group>"; };
FA322DA10CEF752C001761B3 /* sample-ngircd.conf */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "sample-ngircd.conf"; sourceTree = "<group>"; }; FA322DA10CEF752C001761B3 /* sample-ngircd.conf */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "sample-ngircd.conf"; sourceTree = "<group>"; };
FA322DA30CEF752C001761B3 /* .cvsignore */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = .cvsignore; sourceTree = "<group>"; };
FA322DA40CEF752C001761B3 /* Doxyfile */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Doxyfile; sourceTree = "<group>"; }; FA322DA40CEF752C001761B3 /* Doxyfile */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Doxyfile; sourceTree = "<group>"; };
FA322DA50CEF752C001761B3 /* footer.inc.html */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.html; path = footer.inc.html; sourceTree = "<group>"; }; FA322DA50CEF752C001761B3 /* footer.inc.html */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.html; path = footer.inc.html; sourceTree = "<group>"; };
FA322DA60CEF752C001761B3 /* header.inc.html */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.html; path = header.inc.html; sourceTree = "<group>"; }; FA322DA60CEF752C001761B3 /* header.inc.html */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.html; path = header.inc.html; sourceTree = "<group>"; };
@@ -185,39 +192,13 @@
FA322DA80CEF752C001761B3 /* ngircd-doc.css */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.css; path = "ngircd-doc.css"; sourceTree = "<group>"; }; FA322DA80CEF752C001761B3 /* ngircd-doc.css */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.css; path = "ngircd-doc.css"; sourceTree = "<group>"; };
FA322DA90CEF752C001761B3 /* SSL.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = SSL.txt; sourceTree = "<group>"; }; FA322DA90CEF752C001761B3 /* SSL.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = SSL.txt; sourceTree = "<group>"; };
FA322DAA0CEF752C001761B3 /* Zeroconf.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Zeroconf.txt; sourceTree = "<group>"; }; FA322DAA0CEF752C001761B3 /* Zeroconf.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Zeroconf.txt; sourceTree = "<group>"; };
FA322DAC0CEF7538001761B3 /* .cvsignore */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = .cvsignore; sourceTree = "<group>"; };
FA322DAD0CEF7538001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; }; FA322DAD0CEF7538001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FA322DAE0CEF7538001761B3 /* ngircd.8.tmpl */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngircd.8.tmpl; sourceTree = "<group>"; }; FA322DAE0CEF7538001761B3 /* ngircd.8.tmpl */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngircd.8.tmpl; sourceTree = "<group>"; };
FA322DAF0CEF7538001761B3 /* ngircd.conf.5.tmpl */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngircd.conf.5.tmpl; sourceTree = "<group>"; }; FA322DAF0CEF7538001761B3 /* ngircd.conf.5.tmpl */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngircd.conf.5.tmpl; sourceTree = "<group>"; };
FA322DB10CEF7565001761B3 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; }; FA322DB10CEF7565001761B3 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
FA322DBB0CEF773C001761B3 /* cvs-version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "cvs-version.h"; sourceTree = "<group>"; };
FA322DC00CEF77CB001761B3 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; }; FA322DC00CEF77CB001761B3 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
FA407F2B0DB159F400271AF1 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; name = Makefile.am; path = ipaddr/Makefile.am; sourceTree = "<group>"; };
FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = ng_ipaddr.c; path = ipaddr/ng_ipaddr.c; sourceTree = "<group>"; };
FA407F2D0DB159F400271AF1 /* ng_ipaddr.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = ng_ipaddr.h; path = ipaddr/ng_ipaddr.h; sourceTree = "<group>"; };
FA407F380DB15AC700271AF1 /* GIT.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = GIT.txt; sourceTree = "<group>"; };
FA85178A0FA061EC006A1F5A /* op.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = op.h; sourceTree = "<group>"; };
FA85178B0FA061EC006A1F5A /* op.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = op.c; sourceTree = "<group>"; };
FAA3D2700F139CB300B2447E /* invite-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "invite-test.e"; sourceTree = "<group>"; };
FAA3D2710F139CB300B2447E /* join-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "join-test.e"; sourceTree = "<group>"; };
FAA3D2720F139CB300B2447E /* kick-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "kick-test.e"; sourceTree = "<group>"; };
FAA3D2730F139CB300B2447E /* message-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "message-test.e"; sourceTree = "<group>"; };
FAA3D2740F139CB300B2447E /* ngircd-test1.conf */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "ngircd-test1.conf"; sourceTree = "<group>"; };
FAA3D2750F139CB300B2447E /* ngircd-test2.conf */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "ngircd-test2.conf"; sourceTree = "<group>"; };
FAA3D2760F139CB300B2447E /* opless-channel-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "opless-channel-test.e"; sourceTree = "<group>"; };
FAA3D2770F139CB300B2447E /* server-link-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "server-link-test.e"; sourceTree = "<group>"; };
FAA3D2780F139CDC00B2447E /* conf-ssl.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = "conf-ssl.h"; sourceTree = "<group>"; };
FAA3D2790F139CDC00B2447E /* conn-ssl.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = "conn-ssl.c"; sourceTree = "<group>"; };
FAA3D27A0F139CDC00B2447E /* conn-ssl.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = "conn-ssl.h"; sourceTree = "<group>"; };
FAA3D27C0F139CF800B2447E /* strtok_r.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = strtok_r.c; sourceTree = "<group>"; };
FAA3D27D0F139CF800B2447E /* waitpid.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = waitpid.c; sourceTree = "<group>"; };
FAA3D2800F139D1500B2447E /* Services.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Services.txt; sourceTree = "<group>"; };
FAA3D2820F139D2E00B2447E /* 01ngircd-contents.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = "01ngircd-contents.xml"; sourceTree = "<group>"; };
FAA3D2830F139D2E00B2447E /* 01ngircd.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = 01ngircd.xml; sourceTree = "<group>"; };
FAA3D2840F139D2E00B2447E /* 02de-contents.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = "02de-contents.xml"; sourceTree = "<group>"; };
FAA3D2850F139D2E00B2447E /* 02de.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = 02de.xml; sourceTree = "<group>"; };
FAA3D2860F139D2E00B2447E /* index.xml */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.xml; path = index.xml; sourceTree = "<group>"; };
FAA3D2880F139D2E00B2447E /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
FAA3D28A0F139D2E00B2447E /* postinstall.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = postinstall.sh; sourceTree = "<group>"; };
FAA3D28B0F139D2E00B2447E /* preinstall.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = preinstall.sh; sourceTree = "<group>"; };
FAE5CC2C0CF2308A007D69B6 /* numeric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = numeric.h; sourceTree = "<group>"; }; FAE5CC2C0CF2308A007D69B6 /* numeric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = numeric.h; sourceTree = "<group>"; };
FAE5CC2D0CF2308A007D69B6 /* numeric.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = numeric.c; sourceTree = "<group>"; }; FAE5CC2D0CF2308A007D69B6 /* numeric.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = numeric.c; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@@ -270,10 +251,10 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FA322CD70CEF74B1001761B3 /* ngircd */, FA322CD70CEF74B1001761B3 /* ngircd */,
FA407F270DB1598D00271AF1 /* ipaddr */,
FA322D0E0CEF74B1001761B3 /* portab */, FA322D0E0CEF74B1001761B3 /* portab */,
FA322D1B0CEF74B1001761B3 /* testsuite */, FA322D1B0CEF74B1001761B3 /* testsuite */,
FA322D2E0CEF74B1001761B3 /* tool */, FA322D2E0CEF74B1001761B3 /* tool */,
FA322CD50CEF74B1001761B3 /* .cvsignore */,
FA322CD60CEF74B1001761B3 /* Makefile.am */, FA322CD60CEF74B1001761B3 /* Makefile.am */,
); );
name = src; name = src;
@@ -283,9 +264,7 @@
FA322CD70CEF74B1001761B3 /* ngircd */ = { FA322CD70CEF74B1001761B3 /* ngircd */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FAA3D2780F139CDC00B2447E /* conf-ssl.h */, FA322CD80CEF74B1001761B3 /* .cvsignore */,
FAA3D2790F139CDC00B2447E /* conn-ssl.c */,
FAA3D27A0F139CDC00B2447E /* conn-ssl.h */,
FA322CD90CEF74B1001761B3 /* array.c */, FA322CD90CEF74B1001761B3 /* array.c */,
FA322CDA0CEF74B1001761B3 /* array.h */, FA322CDA0CEF74B1001761B3 /* array.h */,
FA322CDB0CEF74B1001761B3 /* channel.c */, FA322CDB0CEF74B1001761B3 /* channel.c */,
@@ -335,8 +314,6 @@
FA322D070CEF74B1001761B3 /* ngircd.h */, FA322D070CEF74B1001761B3 /* ngircd.h */,
FAE5CC2D0CF2308A007D69B6 /* numeric.c */, FAE5CC2D0CF2308A007D69B6 /* numeric.c */,
FAE5CC2C0CF2308A007D69B6 /* numeric.h */, FAE5CC2C0CF2308A007D69B6 /* numeric.h */,
FA85178A0FA061EC006A1F5A /* op.h */,
FA85178B0FA061EC006A1F5A /* op.c */,
FA322D080CEF74B1001761B3 /* parse.c */, FA322D080CEF74B1001761B3 /* parse.c */,
FA322D090CEF74B1001761B3 /* parse.h */, FA322D090CEF74B1001761B3 /* parse.h */,
FA322D0A0CEF74B1001761B3 /* rendezvous.c */, FA322D0A0CEF74B1001761B3 /* rendezvous.c */,
@@ -350,8 +327,7 @@
FA322D0E0CEF74B1001761B3 /* portab */ = { FA322D0E0CEF74B1001761B3 /* portab */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FAA3D27C0F139CF800B2447E /* strtok_r.c */, FA322D0F0CEF74B1001761B3 /* .cvsignore */,
FAA3D27D0F139CF800B2447E /* waitpid.c */,
FA322D100CEF74B1001761B3 /* ansi2knr.1 */, FA322D100CEF74B1001761B3 /* ansi2knr.1 */,
FA322D110CEF74B1001761B3 /* ansi2knr.c */, FA322D110CEF74B1001761B3 /* ansi2knr.c */,
FA322D120CEF74B1001761B3 /* exp.h */, FA322D120CEF74B1001761B3 /* exp.h */,
@@ -370,22 +346,15 @@
FA322D1B0CEF74B1001761B3 /* testsuite */ = { FA322D1B0CEF74B1001761B3 /* testsuite */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FAA3D2700F139CB300B2447E /* invite-test.e */, FA322D1C0CEF74B1001761B3 /* .cvsignore */,
FAA3D2710F139CB300B2447E /* join-test.e */,
FAA3D2720F139CB300B2447E /* kick-test.e */,
FAA3D2730F139CB300B2447E /* message-test.e */,
FAA3D2740F139CB300B2447E /* ngircd-test1.conf */,
FAA3D2750F139CB300B2447E /* ngircd-test2.conf */,
FAA3D2760F139CB300B2447E /* opless-channel-test.e */,
FAA3D2770F139CB300B2447E /* server-link-test.e */,
FA322D1D0CEF74B1001761B3 /* channel-test.e */, FA322D1D0CEF74B1001761B3 /* channel-test.e */,
FA322D1E0CEF74B1001761B3 /* check-idle.e */, FA322D1E0CEF74B1001761B3 /* check-idle.e */,
FA322D1F0CEF74B1001761B3 /* connect-test.e */, FA322D1F0CEF74B1001761B3 /* connect-test.e */,
FA322D200CEF74B1001761B3 /* functions.inc */, FA322D200CEF74B1001761B3 /* functions.inc */,
FA322D210CEF74B1001761B3 /* getpid.sh */, FA322D210CEF74B1001761B3 /* getpid.sh */,
FA322D220CEF74B1001761B3 /* Makefile.am */, FA322D220CEF74B1001761B3 /* Makefile.am */,
FA1A6BBC0D6857BB00AA8F71 /* misc-test.e */,
FA322D230CEF74B1001761B3 /* mode-test.e */, FA322D230CEF74B1001761B3 /* mode-test.e */,
FA322D240CEF74B1001761B3 /* ngircd-test.conf */,
FA322D250CEF74B1001761B3 /* README */, FA322D250CEF74B1001761B3 /* README */,
FA322D260CEF74B1001761B3 /* start-server.sh */, FA322D260CEF74B1001761B3 /* start-server.sh */,
FA322D270CEF74B1001761B3 /* stop-server.sh */, FA322D270CEF74B1001761B3 /* stop-server.sh */,
@@ -395,7 +364,6 @@
FA322D2B0CEF74B1001761B3 /* test-loop.sh */, FA322D2B0CEF74B1001761B3 /* test-loop.sh */,
FA322D2C0CEF74B1001761B3 /* tests.sh */, FA322D2C0CEF74B1001761B3 /* tests.sh */,
FA322D2D0CEF74B1001761B3 /* wait-tests.sh */, FA322D2D0CEF74B1001761B3 /* wait-tests.sh */,
FA1A6BBD0D6857D900AA8F71 /* who-test.e */,
); );
path = testsuite; path = testsuite;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -403,6 +371,7 @@
FA322D2E0CEF74B1001761B3 /* tool */ = { FA322D2E0CEF74B1001761B3 /* tool */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FA322D2F0CEF74B1001761B3 /* .cvsignore */,
FA322D300CEF74B1001761B3 /* ansi2knr.1 */, FA322D300CEF74B1001761B3 /* ansi2knr.1 */,
FA322D310CEF74B1001761B3 /* ansi2knr.c */, FA322D310CEF74B1001761B3 /* ansi2knr.c */,
FA322D320CEF74B1001761B3 /* Makefile.am */, FA322D320CEF74B1001761B3 /* Makefile.am */,
@@ -415,6 +384,7 @@
FA322D660CEF7523001761B3 /* contrib */ = { FA322D660CEF7523001761B3 /* contrib */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FA322D670CEF7523001761B3 /* .cvsignore */,
FA322D680CEF7523001761B3 /* Debian */, FA322D680CEF7523001761B3 /* Debian */,
FA322D730CEF7523001761B3 /* MacOSX */, FA322D730CEF7523001761B3 /* MacOSX */,
FA322D910CEF7523001761B3 /* Makefile.am */, FA322D910CEF7523001761B3 /* Makefile.am */,
@@ -431,6 +401,7 @@
FA322D680CEF7523001761B3 /* Debian */ = { FA322D680CEF7523001761B3 /* Debian */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FA322D690CEF7523001761B3 /* .cvsignore */,
FA322D6A0CEF7523001761B3 /* changelog */, FA322D6A0CEF7523001761B3 /* changelog */,
FA322D6B0CEF7523001761B3 /* compat */, FA322D6B0CEF7523001761B3 /* compat */,
FA322D6C0CEF7523001761B3 /* control */, FA322D6C0CEF7523001761B3 /* control */,
@@ -447,13 +418,12 @@
FA322D730CEF7523001761B3 /* MacOSX */ = { FA322D730CEF7523001761B3 /* MacOSX */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FAA3D2810F139D2E00B2447E /* ngIRCd.pmdoc */, FA322D740CEF7523001761B3 /* .cvsignore */,
FAA3D28A0F139D2E00B2447E /* postinstall.sh */,
FAA3D28B0F139D2E00B2447E /* preinstall.sh */,
FA322D750CEF7523001761B3 /* build */, FA322D750CEF7523001761B3 /* build */,
FA322D8D0CEF7523001761B3 /* Makefile.am */, FA322D8D0CEF7523001761B3 /* Makefile.am */,
FA322D8E0CEF7523001761B3 /* ngIRCd.xcodeproj */, FA322D8E0CEF7523001761B3 /* ngIRCd.xcodeproj */,
FA322DB10CEF7565001761B3 /* config.h */, FA322DB10CEF7565001761B3 /* config.h */,
FA322DBB0CEF773C001761B3 /* cvs-version.h */,
); );
path = MacOSX; path = MacOSX;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -539,8 +509,8 @@
FA322D970CEF752C001761B3 /* doc */ = { FA322D970CEF752C001761B3 /* doc */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FAA3D2800F139D1500B2447E /* Services.txt */, FA322D980CEF752C001761B3 /* .cvsignore */,
FA407F380DB15AC700271AF1 /* GIT.txt */, FA322D990CEF752C001761B3 /* CVS.txt */,
FA322D9A0CEF752C001761B3 /* FAQ.txt */, FA322D9A0CEF752C001761B3 /* FAQ.txt */,
FA322D9B0CEF752C001761B3 /* Makefile.am */, FA322D9B0CEF752C001761B3 /* Makefile.am */,
FA322D9C0CEF752C001761B3 /* Platforms.txt */, FA322D9C0CEF752C001761B3 /* Platforms.txt */,
@@ -560,6 +530,7 @@
FA322DA20CEF752C001761B3 /* src */ = { FA322DA20CEF752C001761B3 /* src */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FA322DA30CEF752C001761B3 /* .cvsignore */,
FA322DA40CEF752C001761B3 /* Doxyfile */, FA322DA40CEF752C001761B3 /* Doxyfile */,
FA322DA50CEF752C001761B3 /* footer.inc.html */, FA322DA50CEF752C001761B3 /* footer.inc.html */,
FA322DA60CEF752C001761B3 /* header.inc.html */, FA322DA60CEF752C001761B3 /* header.inc.html */,
@@ -572,6 +543,7 @@
FA322DAB0CEF7538001761B3 /* man */ = { FA322DAB0CEF7538001761B3 /* man */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FA322DAC0CEF7538001761B3 /* .cvsignore */,
FA322DAD0CEF7538001761B3 /* Makefile.am */, FA322DAD0CEF7538001761B3 /* Makefile.am */,
FA322DAE0CEF7538001761B3 /* ngircd.8.tmpl */, FA322DAE0CEF7538001761B3 /* ngircd.8.tmpl */,
FA322DAF0CEF7538001761B3 /* ngircd.conf.5.tmpl */, FA322DAF0CEF7538001761B3 /* ngircd.conf.5.tmpl */,
@@ -580,29 +552,6 @@
path = ../../man; path = ../../man;
sourceTree = SOURCE_ROOT; sourceTree = SOURCE_ROOT;
}; };
FA407F270DB1598D00271AF1 /* ipaddr */ = {
isa = PBXGroup;
children = (
FA407F2B0DB159F400271AF1 /* Makefile.am */,
FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */,
FA407F2D0DB159F400271AF1 /* ng_ipaddr.h */,
);
name = ipaddr;
sourceTree = "<group>";
};
FAA3D2810F139D2E00B2447E /* ngIRCd.pmdoc */ = {
isa = PBXGroup;
children = (
FAA3D2820F139D2E00B2447E /* 01ngircd-contents.xml */,
FAA3D2830F139D2E00B2447E /* 01ngircd.xml */,
FAA3D2840F139D2E00B2447E /* 02de-contents.xml */,
FAA3D2850F139D2E00B2447E /* 02de.xml */,
FAA3D2860F139D2E00B2447E /* index.xml */,
FAA3D2880F139D2E00B2447E /* Makefile.am */,
);
path = ngIRCd.pmdoc;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@@ -679,9 +628,6 @@
FA322D4D0CEF74B1001761B3 /* resolve.c in Sources */, FA322D4D0CEF74B1001761B3 /* resolve.c in Sources */,
FA322DBE0CEF7766001761B3 /* tool.c in Sources */, FA322DBE0CEF7766001761B3 /* tool.c in Sources */,
FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */, FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */,
FA407F2E0DB159F400271AF1 /* ng_ipaddr.c in Sources */,
FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */,
FA85178C0FA061EC006A1F5A /* op.c in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -691,85 +637,27 @@
1DEB928708733DD80010E9CD /* Default */ = { 1DEB928708733DD80010E9CD /* Default */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_MODEL_TUNING = G5;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
GCC_WARN_MISSING_PARENTHESES = YES;
GCC_WARN_PEDANTIC = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VALUE = YES;
INSTALL_PATH = /usr/local/bin; INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = ngIRCd; PRODUCT_NAME = ngIRCd;
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
}; };
name = Default; name = Default;
}; };
1DEB928B08733DD80010E9CD /* Default */ = { 1DEB928B08733DD80010E9CD /* Default */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)"; ARCHS = (
ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc"; ppc,
GCC_VERSION = 4.0; i386,
);
GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO; PREBINDING = NO;
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk"; SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
}; };
name = Default; name = Default;
}; };
FAB0570C105D917F006AF9E2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
GCC_DEBUGGING_SYMBOLS = full;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = 4.0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
};
name = Debug;
};
FAB0570D105D917F006AF9E2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
GCC_WARN_MISSING_PARENTHESES = YES;
GCC_WARN_PEDANTIC = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
GCC_WARN_UNINITIALIZED_AUTOS = NO;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VALUE = YES;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = ngIRCd;
SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
};
name = Debug;
};
/* End XCBuildConfiguration section */ /* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */ /* Begin XCConfigurationList section */
@@ -777,7 +665,6 @@
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
1DEB928708733DD80010E9CD /* Default */, 1DEB928708733DD80010E9CD /* Default */,
FAB0570D105D917F006AF9E2 /* Debug */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Default; defaultConfigurationName = Default;
@@ -786,7 +673,6 @@
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
1DEB928B08733DD80010E9CD /* Default */, 1DEB928B08733DD80010E9CD /* Default */,
FAB0570C105D917F006AF9E2 /* Debug */,
); );
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Default; defaultConfigurationName = Default;

View File

@@ -1,42 +0,0 @@
#!/bin/sh
# ngIRCd Mac OS X postinstall/postupgrade script
LDPLIST="/Library/LaunchDaemons/de.barton.ngircd.plist"
if [ ! -e /etc/ngircd ]; then
echo "Creating symlink: /opt/ngircd/etc -> /etc/ngircd"
ln -s /opt/ngircd/etc /etc/ngircd || exit 1
else
echo "/etc/ngircd already exists. Don't create symlink."
fi
if [ ! -e /opt/ngircd/etc/ngircd.conf ]; then
echo "Creating default configuration: /opt/ngircd/etc/ngircd.conf"
cp /opt/ngircd/share/doc/ngircd/sample-ngircd.conf \
/opt/ngircd/etc/ngircd.conf || exit 1
else
echo "/opt/ngircd/etc/ngircd.conf exists. Don't copy sample file."
fi
chmod o-rwx /opt/ngircd/etc/ngircd.conf
if [ -f "$LDPLIST" ]; then
echo "Fixing ownership and permissions of LaunchDaemon script ..."
chown root:wheel "$LDPLIST" || exit 1
chmod 644 "$LDPLIST" || exit 1
fi
if [ -f /tmp/ngircd_needs_restart ]; then
echo "ngIRCd should be (re-)started ..."
if [ -r "$LDPLIST" ]; then
echo "LaunchDaemon script found, starting daemon ..."
launchctl load -w "$LDPLIST" || exit 1
echo "OK, LaunchDaemon script loaded successfully."
else
echo "LaunchDaemon script not installed. Can't start daemon."
fi
else
echo "Not loading LaunchDaemon script."
fi
rm -f /tmp/ngircd_needs_restart
# -eof-

View File

@@ -1,25 +0,0 @@
#!/bin/sh
# ngIRCd Mac OS X preinstall/preupgrade script
LDPLIST="/Library/LaunchDaemons/de.barton.ngircd.plist"
rm -f /tmp/ngircd_needs_restart || exit 1
if [ -r "$LDPLIST" ]; then
echo "LaunchDaemon script found, checking status ..."
launchctl list | fgrep "de.barton.ngIRCd" >/dev/null 2>&1
if [ $? -eq 0 ]; then
# ngIRCd is already running; stop it and touch a
# "stamp file" so that we know that we have to
# restart it after installation/upgrade.
echo "ngIRCd is already running; stop it ..."
launchctl unload "$LDPLIST" || exit 1
echo "Daemon has been stopped."
touch /tmp/ngircd_needs_restart || exit 1
else
echo "ngIRCd is not running."
fi
else
echo "LaunchDaemon script not found."
fi
# -eof-

View File

@@ -1,18 +1,20 @@
# #
# ngIRCd -- The Next Generation IRC Daemon # ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2009 Alexander Barton (alex@barton.de) # Copyright (c)2001-2004 Alexander Barton <alex@barton.de>
# #
# This program is free software; you can redistribute it and/or modify # Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
# it under the terms of the GNU General Public License as published by # der GNU General Public License (GPL), wie von der Free Software Foundation
# the Free Software Foundation; either version 2 of the License, or # herausgegeben, weitergeben und/oder modifizieren, entweder unter Version 2
# (at your option) any later version. # der Lizenz oder (wenn Sie es wuenschen) jeder spaeteren Version.
# Please read the file COPYING, README and AUTHORS for more information. # Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
#
# $Id: Makefile.am,v 1.4 2004/04/28 12:18:02 alex Exp $
# #
SUBDIRS = Debian MacOSX SUBDIRS = Debian MacOSX
EXTRA_DIST = README ngircd.spec systrace.policy ngindent ngircd-bsd.sh \ EXTRA_DIST = README ngircd.spec systrace.policy
ngircd-redhat.init platformtest.sh
maintainer-clean-local: maintainer-clean-local:
rm -f Makefile Makefile.in rm -f Makefile Makefile.in

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server ngIRCd - Next Generation IRC Server
(c)2001-2009 Alexander Barton, (c)2001-2005 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,17 +19,15 @@ MacOSX/
ngindent ngindent
- Script to indent the code of ngIRCd in the "standard way". - Script to indent the code of ngIRCd in the "standard way".
ngircd-bsd.sh ngircd.sh
- Start script for FreeBSD. - Start script for FreeBSD.
ngircd-redhat.init
- Start/stop script for RedHat-based distributions (like CentOS).
ngircd.spec ngircd.spec
- RPM "spec" file. - RPM "spec" file.
platformtest.sh
- Build ngIRCd and output a "result line" suitable for doc/Platforms.txt.
systrace.policy systrace.policy
- Systrace policy file for OpenBSD (and probably NetBSD). - Systrace policy file for OpenBSD (and probably NetBSD).
--
$Id: README,v 1.3 2006/07/23 11:34:32 alex Exp $

View File

@@ -1,119 +0,0 @@
#!/bin/sh
#
# ngIRCd start and stop script for RedHat based distributions.
# Written by Naoya Nakazawa <naoya@sanow.net> for CentOS 5.2, 2009.
#
# chkconfig: 2345 01
# description: ngIRCd is an Open Source server for \
# the Internet Relay Chat (IRC), which \
# is developed and published under \
# the terms of the GNU General Public
# 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 \
# "grandfather of IRC daemons", the daemon of the IRCNet.
#
# processname: /usr/sbin/ngircd
# config: /etc/ngircd
# pidfile: /var/run/ngircd.pid
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/ngircd
NAME=ngIRCd
BASENAME=ngircd
CONF=/etc/$BASENAME.conf
DESC="IRC daemon"
PARAMS="-f $CONF"
# Source function library.
. /etc/init.d/functions
# Get config.
test -f /etc/sysconfig/network && . /etc/sysconfig/network
test -f /etc/sysconfig/makuosan && . /etc/sysconfig/makuosan
# Check that networking is up.
[ "${NETWORKING}" = "yes" ] || exit 0
[ -x $DAEMON ] || exit 1
[ -f $CONF ] || exit 2
RETVAL=0
start(){
echo -n $"Starting $NAME: "
daemon $DAEMON $PARAMS
RETVAL=$?
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$BASENAME
echo
return $RETVAL
}
stop(){
echo -n $"Stopping $NAME: "
killproc $DAEMON
RETVAL=$?
if [ $RETVAL -eq 0 ] ; then
rm -f /var/lock/subsys/$BASENAME
fi
echo
return $RETVAL
}
reload(){
echo -n $"Reloading configuration: "
killproc $DAEMON -HUP
RETVAL=$?
echo
return $RETVAL
}
restart(){
stop
start
}
condrestart(){
[ -e /var/lock/subsys/$BASENAME ] && restart
return 0
}
check_config(){
$DAEMON $PARAMS --configtest >/dev/null 2>&1
[ $? -eq 0 ] && return 0
echo -n $"Configuration of $NAME is not valid, won't (re)start!"
echo -n $"Run \"$DAEMON --configtest\" and fix it up ..."
exit 6
}
# See how we were called.
case "$1" in
start)
check_config
start
;;
stop)
stop
;;
status)
status $NAME
;;
restart)
restart
;;
reload)
reload
;;
condrestart)
condrestart
;;
test)
check_config
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|reload|test}"
RETVAL=1
esac
exit $RETVAL

View File

@@ -1,5 +1,5 @@
%define name ngircd %define name ngircd
%define version 16~rc1 %define version 0.11.1
%define release 1 %define release 1
%define prefix %{_prefix} %define prefix %{_prefix}
@@ -7,12 +7,12 @@ Summary: A lightweight daemon for the Internet Relay Chat (IRC)
Name: %{name} Name: %{name}
Version: %{version} Version: %{version}
Release: %{release} Release: %{release}
License: GPLv2+ Copyright: GPL
Group: System Environment/Daemons Group: Networking/Daemons
URL: http://ngircd.barton.de/ URL: http://arthur.ath.cx/~alex/ngircd/
Source: %{name}-%{version}.tar.gz Source: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Packager: Sean Reifschneider <jafo-rpms@tummy.com>
BuildRequires: zlib-devel, openssl-devel BuildRoot: /var/tmp/%{name}-root
%description %description
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),
@@ -29,13 +29,10 @@ ngIRCd is compatible to the "original" ircd 2.10.3p3, so you can run
mixed networks. mixed networks.
%prep %prep
%setup -q %setup
%build %build
%configure \ %configure
--with-zlib \ make
--with-openssl
make %{?_smp_mflags}
%install %install
[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT" [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"
@@ -45,7 +42,6 @@ make %{?_smp_mflags}
( cd usr/sbin; mv *-ngircd ngircd ) ( cd usr/sbin; mv *-ngircd ngircd )
( cd usr/share/man/man5; mv *-ngircd.conf.5 ngircd.conf.5 ) ( cd usr/share/man/man5; mv *-ngircd.conf.5 ngircd.conf.5 )
( cd usr/share/man/man8; mv *-ngircd.8 ngircd.8 ) ( cd usr/share/man/man8; mv *-ngircd.8 ngircd.8 )
rm -fr usr/share/doc/ngircd
) )
%clean %clean
@@ -53,8 +49,7 @@ make %{?_smp_mflags}
%files %files
%defattr(755,root,root) %defattr(755,root,root)
%doc AUTHORS COPYING ChangeLog INSTALL NEWS README doc/* %doc AUTHORS COPYING ChangeLog INSTALL NEWS README
%config(noreplace) /etc %config(noreplace) /etc
%{_prefix}/sbin %{_prefix}/sbin
%{_mandir}/man5/ngircd.conf* %{_prefix}/share/man/
%{_mandir}/man8/ngircd.8*

View File

@@ -1,143 +0,0 @@
#!/bin/sh
#
# ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2009 Alexander Barton <alex@barton.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
# This script analyzes the build process of ngIRCd and generates output
# suitable for inclusion in doc/Platforms.txt -- please send reports
# to the ngIRCd mailing list: <ngircd-ml@ngircd.barton.de>.
NAME=`basename "$0"`
VERBOSE=
PLATFORM=
COMPILER="unknown"
VERSION="unknown"
DATE=`date "+%y-%m-%d"`
CONFIGURE=
MAKE=
CHECK=
RUN=
COMMENT=
while [ $# -gt 0 ]; do
case "$1" in
"-v")
VERBOSE=1
;;
*)
echo "Usage: $NAME [-v]"
exit 2
esac
shift
done
echo "$NAME: Checking ngIRCd base source directory ..."
grep "ngIRCd" ./ChangeLog >/dev/null 2>&1
if [ $? -ne 0 ]; then
grep "ngIRCd" ../ChangeLog >/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "$NAME: ngIRCd base source directory not found!?"
exit 1
fi
cd ..
fi
echo "$NAME: Checking for ./configure script ..."
if [ ! -e ./configure ]; then
echo "$NAME: Not found. Running ./autogen.sh ..."
[ -n "$VERBOSE" ] && ./autogen.sh || ./autogen.sh >/dev/null
fi
if [ -e ./configure ]; then
echo "$NAME: Running \"./configure\" script ..."
[ -n "$VERBOSE" ] && ./configure || ./configure >/dev/null
if [ $? -eq 0 -a -e ./Makefile ]; then
CONFIGURE=1
echo "$NAME: Running \"make\" ..."
[ -n "$VERBOSE" ] && make || make >/dev/null
if [ $? -eq 0 -a -x src/ngircd/ngircd ]; then
MAKE=1
echo "$NAME: Running \"make check\" ..."
[ -n "$VERBOSE" ] && make check || make check >/dev/null
if [ $? -eq 0 ]; then
CHECK=1
RUN=$CHECK
else
./src/ngircd/ngircd --help 2>/dev/null \
| grep "^ngircd" >/dev/null
[ $? -eq 0 ] && RUN=1
fi
fi
fi
fi
# Get target platform information
if [ -r "src/config.h" ]; then
CPU=`grep "TARGET_CPU" "src/config.h" | cut -d'"' -f2`
OS=`grep "TARGET_OS" "src/config.h" | cut -d'"' -f2`
VENDOR=`grep "TARGET_VENDOR" "src/config.h" | cut -d'"' -f2`
PLATFORM="$CPU/$VENDOR/$OS"
fi
if [ -z "$PLATFORM" ]; then
PLATFORM="`uname 2>/dev/null` `uname -r 2>/dev/null`, `uname -m 2>/dev/null`"
fi
# Get compiler information
if [ -r "Makefile" ]; then
eval $(grep "^CC = " Makefile | sed -e 's/ //g')
$CC --version 2>&1 | grep -i "GCC" >/dev/null
if [ $? -eq 0 ]; then
COMPILER=$($CC --version | head -n 1 | awk "{ print \$3 }" \
| cut -d'-' -f1)
COMPILER="gcc $COMPILER"
fi
fi
# Get ngIRCd version information
if [ -d ".git" ]; then
VERSION=`git log --abbrev-commit --pretty=oneline HEAD~1.. \
| head -1 | cut -d' ' -f1 | tr -d '.'`
elif [ -r "Makefile" ]; then
eval $(grep "^VERSION = " Makefile | sed -e 's/ //g')
fi
[ -n "$VERSION" ] || VERSION="unknown"
# Get IO interface information
if [ "$OS" = "linux-gnu" ]; then
COMMENT="(1)"
else
grep "^#define HAVE_SYS_DEVPOLL_H 1" src/config.h >/dev/null 2>&1
[ $? -eq 0 ] && COMMENT="(4)"
grep "^#define HAVE_EPOLL_CREATE 1" src/config.h >/dev/null 2>&1
[ $? -eq 0 ] && COMMENT="(5)"
grep "^#define HAVE_KQUEUE 1" src/config.h >/dev/null 2>&1
[ $? -eq 0 ] && COMMENT="(3)"
fi
[ -n "$CONFIGURE" ] && C="Y" || C="N"
[ -n "$MAKE" ] && M="Y" || M="N"
[ -n "$CHECK" ] && T="Y" || T="N"
[ -n "$RUN" ] && R="Y" || R="N"
[ -n "$COMMENT" ] && COMMENT=" $COMMENT"
echo
echo " the executable works (\"runs\") as expected --+"
echo " tests run successfully (\"make check\") --+ |"
echo " ngIRCd compiles (\"make\") --+ | |"
echo " ./configure works --+ | | |"
echo " | | | |"
echo "Platform Compiler ngIRCd Date Tester C M T R See"
echo "--------------------------- ------------ ---------- -------- ------ - - - - ---"
printf "%-27s %-12s %-10s %s %-6s %s %s %s %s%s" \
"$PLATFORM" "$COMPILER" "$VERSION" "$DATE" "$USER" \
"$C" "$M" "$T" "$R" "$COMMENT"
echo; echo

2
doc/.cvsignore Normal file
View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

57
doc/CVS.txt Normal file
View File

@@ -0,0 +1,57 @@
ngIRCd - Next Generation IRC Server
(c)2001-2006 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- CVS.txt --
The source code of ngIRCd is maintained using the "Concurrent Versions
System" (CVS). Thereby several developers can work with the source tree at
the same time.
I. Anonymous read-only Access
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To access the source tree anonymously in read-only mode, follow these steps:
Login to the CVS server:
$ cvs -d:pserver:anonymous@ngircd.barton.de:/srv/cvs/ngircd login
Use "anonymous" as user name and no password (just hit Return). Now you can
check out the sources:
$ cvs -d:pserver:anonymous@ngircd.barton.de:/srv/cvs/ngircd checkout ngircd
Thereby a new folder "ngircd" will be created containing all the individual
source files. (Substitute the last "ngircd" with "website" to check out all
the files of the homepage of ngIRCd.)
The newly created folder ("ngircd" or "website") is the "working folder", all
CVS commands will be executed from within this folder in the future.
Please note: When checking out a fresh copy of ngIRCd from CVS, the
configure script doesn't exist; you have to run the autogen.sh shell script
(which is included in the source tree) to generate it. This requires you to
have GNU automake and GNU autoconf installed on your system.
Updating the CVS tree:
$ cvs update -d -P [<filename>]
You can update a single file or the complete source tree.
II. Write Access
~~~~~~~~~~~~~~~~
If you want to contribute a couple of patches and write access to the CVS
repository would be handy, please contact Alex Barton, <alex@barton.de>.
--
$Id: CVS.txt,v 1.9 2006/08/03 14:37:29 alex Exp $

View File

@@ -54,10 +54,6 @@ A: Most probably you are using version 1.5 of GNU automake which seems to be
III. Runtime III. Runtime
~~~~~~~~~~~~ ~~~~~~~~~~~~
Q: Where is the log file located?
A: ngIRCd does not write its own log file. Instead, ngIRCd uses
syslog(3). Check the files in /var/log/ and/or consult the
documentation for your system logger daemon.
Q: I cannot connect to remote peers when I use the chroot option, the Q: I cannot connect to remote peers when I use the chroot option, the
following is logged: "Can't resolve example.com: unknown error!". following is logged: "Can't resolve example.com: unknown error!".
A: On Linux/glibc with chroot enabled you need to put some libraries inside A: On Linux/glibc with chroot enabled you need to put some libraries inside
@@ -65,14 +61,7 @@ A: On Linux/glibc with chroot enabled you need to put some libraries inside
linking ngircd statically does not help this. The only known workaround linking ngircd statically does not help this. The only known workaround
is to either disable chroot support or to link against dietlibc instead is to either disable chroot support or to link against dietlibc instead
of glibc. (tnx to Sebastian Siewior) of glibc. (tnx to Sebastian Siewior)
Q: I have added an [Oper] section, how do i log on as IRC operator?
A: You can use the /OPER command in your IRC client to become an IRC operator.
ngIRCd will also log all OPER requests (using syslog), if OPER fails you
can look there to determine why it did not work (bad password, unauthorized
host mask, etc.)
Q: I am an IRC operator, but MODE doesn't work!
A: You need to set 'OperCanUseMode = yes' in ngircd.conf to enable MODE for IRC
operators.
IV. Bugs!? IV. Bugs!?
~~~~~~~~~~ ~~~~~~~~~~
@@ -87,4 +76,4 @@ A: Please file a bug report at <http://ngircd.barton.de/bugzilla/index.cgi>!
-- --
$Id: FAQ.txt,v 1.12 2008/01/02 22:47:58 alex Exp $ $Id: FAQ.txt,v 1.11.4.1 2008/01/02 22:36:48 fw Exp $

View File

@@ -1,45 +0,0 @@
ngIRCd - Next Generation IRC Server
-- GIT.txt --
The source code of ngIRCd is maintained using git, the stupid content
tracker.
I. Getting the source code
~~~~~~~~~~~~~~~~~~~~~~~~~~
To access the source tree anonymously, run:
$ git clone git://ngircd.barton.de/ngircd.git
Thereby a new folder "ngircd" will be created containing all the individual
source files.
The newly created directory ("ngircd") is the "working directory", all
git commands will be executed from within this directory in the future.
Please note: When checking out a fresh copy of ngIRCd using git, the
configure script doesn't exist; you have to run the autogen.sh shell script
(which is included in the source tree) to generate it. This requires you to
have GNU automake and GNU autoconf installed on your system.
To update the git tree:
$ git pull
This retrieves all changes and merges them into the current branch.
II. Contributing
~~~~~~~~~~~~~~~~
Patches should be sent to the ngircd mailing list. List homepage:
http://arthur.barton.de/mailman/listinfo/ngircd-ml
If you do not want to send them to the list, you can also mail them
to Alex Barton, <alex@barton.de>.
III. Write Access
~~~~~~~~~~~~~~~~~
If you want to contribute a couple of patches and write access to the git
repository would be handy, please contact Alex Barton, <alex@barton.de>.

View File

@@ -1,6 +1,6 @@
# #
# ngIRCd -- The Next Generation IRC Daemon # ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton (alex@barton.de) # Copyright (c)2001-2007 by Alexander Barton (alex@barton.de)
# #
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen # Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
# der GNU General Public License (GPL), wie von der Free Software Foundation # der GNU General Public License (GPL), wie von der Free Software Foundation
@@ -9,12 +9,13 @@
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste # Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS. # der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
# #
# $Id: Makefile.am,v 1.22 2007/11/20 21:39:35 alex Exp $
#
SUBDIRS = src SUBDIRS = src
EXTRA_DIST = FAQ.txt GIT.txt Protocol.txt Platforms.txt README-AUX.txt \ EXTRA_DIST = CVS.txt FAQ.txt Protocol.txt Platforms.txt README-AUX.txt \
README-BeOS.txt RFC.txt Services.txt SSL.txt Zeroconf.txt \ README-BeOS.txt RFC.txt SSL.txt Zeroconf.txt sample-ngircd.conf
sample-ngircd.conf
maintainer-clean-local: maintainer-clean-local:
rm -f Makefile Makefile.in rm -f Makefile Makefile.in

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server ngIRCd - Next Generation IRC Server
(c)2001-2009 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
@@ -29,32 +29,20 @@ 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 13~rc1 08-12-02 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
hppa2.0w-hp-hpux11.11 gcc 4.2.3 14.1 09-07-22 goetz Y Y Y Y
i386/apple/darwin9.7.0 gcc 4.0.1 14.1 09-08-04 alex Y Y Y Y (3)
i386/apple/darwin10.0.0b2 gcc 4.2.1 14.1 09-07-27 alex Y Y Y Y (3)
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 14.1 09-08-03 alex Y Y Y Y (4) 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.0 gcc 3.4.4 0.10.0-p1 06-08-04 alex Y Y Y Y (3) 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/freebsd6.1 gcc 3.4.4 CVSHEAD 06-05-07 fw Y Y Y Y (3)
i386/unknown/freebsd6.2 gcc 3.4.6 14.1 09-07-27 alex Y Y Y Y (3)
i386/unknown/freebsd7.0 gcc 4.2.1 14.1 09-07-28 alex Y Y Y Y (3)
i386/unknown/freebsd7.2 gcc 4.2.1 14.1 09-08-03 alex 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
i686/unknown/gnu0.3 gcc 4.3.1 14.1 09-07-28 alex Y Y Y Y
i686/unkn./kfreebsd7.2-gnu gcc 4.3.4 15 09-12-02 alex Y Y Y Y (3)
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/netbsdelf3.0.1 gcc 3.3.3 0.10.0-p1 06-08-30 alex Y Y Y Y (3)
i386/unknown/netbsdelf4.0 gcc 4.1.2 14.1 09-07-28 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) i386/unknown/openbsd3.9 gcc 3.3.5 0.10.0-p1 06-08-30 alex Y Y Y Y (3)
i386/unknown/openbsd4.1 gcc 3.3.5 14.1 09-07-28 alex Y Y Y Y (3)
i586/pc/interix3.5 gcc 3.3 15 10-01-22 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/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.5 14.1 09-08-04 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 13~rc1 08-12-05 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)
i686/pc/linux-gnu gcc 4.3.2 14.1 09-08-04 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 ? ?
@@ -67,25 +55,23 @@ 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
x86_64/unknown/linux-gnu gcc 4.3.2 14.1 09-08-04 alex Y Y Y Y (1)
Notes Notes
~~~~~ ~~~~~
(1) i686/pc/linux-gnu & x86_64/unknown/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 (starting with 2.95.x and up to various versions of the GNU C compiler (starting with 2.95.x and up to
version 4.3.x). The eldest glibc used was glibc-2.0.7. ngIRCd compiled version 4.1.x). The eldest glibc used was glibc-2.0.7. ngIRCd compiled
and run on all these systems without problems. and run on all these systems without problems.
Actual Linux kernels (2.6.x) and glibc's support the epoll() IO interface. 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) Using the kqueue() IO interface. (3) Using the kqueue() IO interface.
(4) Using the /dev/poll IO interface. --
$Id: Platforms.txt,v 1.18 2006/10/08 14:09:16 alex Exp $
(5) Using the epoll() IO interface.

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server ngIRCd - Next Generation IRC Server
(c)2001-2008 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
@@ -85,8 +85,6 @@ The following <serverflags> are defined at the moment:
- o: IRC operators are allowed to change channel- and channel-user-modes - o: IRC operators are allowed to change channel- and channel-user-modes
even if they aren't channel-operator of the affected channel. even if they aren't channel-operator of the affected channel.
- S: The server supports the SERVICE command (on this link).
- Z: Compressed server links are supported by the server. - Z: Compressed server links are supported by the server.
Example for a complete <flags> string: "ngircd|0.7.5:CZ". Example for a complete <flags> string: "ngircd|0.7.5:CZ".
@@ -161,3 +159,6 @@ and therefore can't be omitted. The parameter <limit> must be ignored when
a channel has no user limit (the parameter <modes> doesn't list the "l" a channel has no user limit (the parameter <modes> doesn't list the "l"
channel mode). In this case <limit> should be "0". channel mode). In this case <limit> should be "0".
--
$Id: Protocol.txt,v 1.14 2007/11/21 12:16:35 alex Exp $

View File

@@ -37,7 +37,7 @@ The following software packages are needed:
ftp://arthur.barton.de/pub/unix/aux/libraries/libUTIL-2.1.tar.gz ftp://arthur.barton.de/pub/unix/aux/libraries/libUTIL-2.1.tar.gz
This library contains functions that are common on other UNIX This library contains functions that are common on other UNIX
systems but not on A/UX e.g. memmove(), strerror() and strdup(). systems but not on A/UX e.g. memmove(), strerror() und strdup().
After installation of these packages just do a "./configure" and "make" to After installation of these packages just do a "./configure" and "make" to
@@ -60,7 +60,7 @@ A few hints in case of errors:
the 'config.status' script. Better rename /bin/sh to /bin/sh.AUX and the 'config.status' script. Better rename /bin/sh to /bin/sh.AUX and
replace it by a symbolic link to /bin/ksh (ln -s /bin/ksh /bin/sh as replace it by a symbolic link to /bin/ksh (ln -s /bin/ksh /bin/sh as
root). root).
These procedure shouldn't cause you into problems and is recommended These procedure should'nt cause you into problems and is recommended
even if you don't use ngIRCd. even if you don't use ngIRCd.
-- --

View File

@@ -24,7 +24,7 @@ mit diesem Fehler ab:
select(): Bad file descriptor! select(): Bad file descriptor!
Es sieht leider so aus, als ob das select() von BeOS nicht mit File-Handles Es sieht leider so aus, als ob das select() von BeOS nicht mit File-Handles
von Pipes verschiedener Prozesse umgehen kann: sobald der Resolver asynchron von Pipes verschiedener Prozesse umgehen kann: sobald der Resolver asyncron
gestartet wird, also Pipe-Handles im select() vorhanden sind, fuehrt das zu gestartet wird, also Pipe-Handles im select() vorhanden sind, fuehrt das zu
obiger Meldung. obiger Meldung.

View File

@@ -1,37 +0,0 @@
ngIRCd - Next Generation IRC Server
(c)2001-2010 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- README-Interix.txt --
ngIRCd release 15 has successfully been tested on Microsoft Windows XP
Professional using the Services for UNIX (SFU) version 3.5 and Microsoft
Windows 7 with the bundled Subsystem for UNIX Applications (SUA).
SFU are supported on Windows 2000, Windows 2000 Server, Windows XP, and
Windows Server 2003. SUA is supported on Windows Server 2003 R2, Windows
Server 2008 & 2008 R2, Windows Vista, and Windows 7 -- so ngIRCd should be
able to run on all of these platforms.
But please note that the poll() API function is not fully implemented by
SFU/SUA and therefore can't be used by ngIRCd -- which normally would be
the default. Please see <http://www.suacommunity.com/faqs.aspx> section
4.25 for details:
"If you do try to use the poll() API your program will block on the
API call forever. You must direct your program to build using the
select() API."
So when running the ./configure script, you HAVE TO DISABLE poll() support:
./configure --without-poll
ngIRCd then defaults to using the select() API function which works fine.

View File

@@ -1,7 +1,7 @@
ngIRCd - Next Generation IRC Server ngIRCd - Next Generation IRC Server
(c)2001-2008 Alexander Barton, (c)2001-2004 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
@@ -10,73 +10,17 @@
-- SSL.txt -- -- SSL.txt --
ngIRCd supports SSL/TLSv1 encrypted connections using the OpenSSL or GnuTLS ngIRCd actually doesn't support secure connections for client-server or
libraries. Both encrypted server-server links as well as client-server links server-server links using SSL, the Secure Socket Layer, by itself. But you can
are supported. use the stunnel(8) command to make this work.
SSL is a compile-time option which is disabled by default. Use one of these
options of the ./configure script to enable it:
--with-openssl enable SSL support using OpenSSL
--with-gnutls enable SSL support using GnuTLS
You also need a key/certificate, see below for how to create a self-signed one.
From a feature point of view, ngIRCds support for both libraries is
comparable. The only major difference (at this time) is that ngircd with gnutls
does not support password protected private keys.
Configuration
~~~~~~~~~~~~~
To enable SSL connections a separate port must be configured: it is NOT
possible to handle unencrypted and encrypted connections on the same port!
This is a limitation of the IRC protocol ...
You have to set (at least) the following configuration variables in the
[GLOBAL] section of ngircd.conf(5): SSLPorts, SSLKeyFile, and SSLCertFile.
Now IRC clients are able to connect using SSL on the configured port(s).
(Using port 6697 for encrypted connections is common.)
To enable encrypted server-server links, you have to additionally set
SSLConnect to "yes" in the corresponding [SERVER] section.
Creating a self-signed certificate
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
OpenSSL:
Creating a self-signed certificate and key:
$ openssl req -newkey rsa:2048 -x509 -keyout server-key.pem \
-out server-cert.pem -days 1461
Create DH parameters (optional):
$ openssl dhparam -2 -out dhparams.pem 2048
GnuTLS:
Creating a self-signed certificate and key:
$ certtool --generate-privkey --bits 2048 --outfile server-key.pem
$ certtool --generate-self-signed --load-privkey server-key.pem \
--outfile server-cert.pem
Create DH parameters (optional):
$ certtool --generate-dh-params --bits 2048 --outfile dhparams.pem
Alternate approach using stunnel(1)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Alternatively (or if you are using ngIRCd compiled without support
for GnuTLS/OpenSSL), you can use external programs/tools like stunnel(1) to
get SSL encrypted connections:
<http://stunnel.mirt.net/> <http://stunnel.mirt.net/>
<http://www.stunnel.org/> <http://www.stunnel.org/>
Stefan Sperling (stefan at binarchy dot net) mailed the following text as a Stefan Sperling (stefan at binarchy dot net) mailed me the following text as a
short "how-to", thanks Stefan! short "how-to", thanks Stefan!
=== snip === === snip ===
! This guide applies to stunnel 4.x ! ! This guide applies to stunnel 4.x !
@@ -104,7 +48,11 @@ short "how-to", thanks Stefan!
That's it. That's it.
Don't forget to activate ssl support in your irc client ;) Don't forget to activate ssl support in your irc client ;)
The main drawback of this approach compared to using builtin ssl
is that from ngIRCds point of view, all ssl-enabled client connections will
originate from the host running stunnel.
=== snip === === snip ===
Probably ngIRCd will include support for SSL in the future ...
--
$Id: SSL.txt,v 1.2 2004/12/27 01:11:40 alex Exp $

View File

@@ -1,70 +0,0 @@
ngIRCd - Next Generation IRC Server
(c)2001-2008 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
terms of the GNU General Public License.
-- Services.txt --
At the moment, ngIRCd doesn't implement a "special IRC services interface".
But services acting as a "regular server" are supported, either using the IRC
protocol defined in RFC 1459 or RFC 2812.
Services have been tested using "IRC Services" version 5.x by Andrew Church,
homepage: <http://www.ircservices.za.net/>. This document describes setting up
ngIRCd and these services.
Setting up ngIRCd
~~~~~~~~~~~~~~~~~
The "pseudo server" handling the IRC services is configured as a regular
remote server in the ngircd.conf(5). In addition the variable "ServiceMask"
should be set, enabling this ngIRCd to recognize the "pseudo users" as IRC
services instead of regular IRC users.
Example:
[SERVER]
Name = services.irc.net
MyPassword = 123abc
PeerPassword = 123abc
ServiceMask = *Serv
Setting up IRC Services 5.1.x
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
IRC Services 5.1.3 and above can be used with ngIRCd using the "rfc1459"
protocol module.
Please note that versions up to and including 5.1.3 contain a bug that
sometimes causes IRC Services to hang on startup. There are two workarounds:
a) send the services process a HUP signal ("killall -HUP ircservices")
b) apply this patch to the IRC Services source tree:
<ftp://ngircd.barton.de/ngircd/contrib/IRCServices513-FlushBuffer.patch>
At least the following settings have to be tweaked, in addition to all the
settings marked as required by IRC Services:
In ircservices.conf:
Variable Example value
RemoteServer server.irc.net 6667 "123abc"
ServerName "services.irc.net"
LoadModule protocol/rfc1459
In modules.conf:
Module protocol/rfc1459
The documentation of IRC Services can be found here:
<http://www.ircservices.za.net/docs/>
Please let us know if you are successfully using other IRC service packages or
which problems you encounter, thanks!

View File

@@ -20,7 +20,7 @@ To use this features you can use one of two APIs:
of the newer Avahi[5] library. 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
available API will be autodetected and the required additional libraries will avalable API will be autodetected and the required additional libraries will
be linked to the ngircd binary as required. be linked to the ngircd binary as required.
ngIRCd then registers a DNS-SD service for each port it is listening on using ngIRCd then registers a DNS-SD service for each port it is listening on using

View File

@@ -1,19 +1,18 @@
# $Id: sample-ngircd.conf,v 1.43.2.1 2008/01/07 23:10:28 alex Exp $
# #
# This is a sample configuration file for the ngIRCd IRC daemon, which must # This is a sample configuration file for the ngIRCd, which must be adepted
# be customized to the local preferences and needs. # to the local preferences and needs.
# #
# Comments are started with "#" or ";". # Comments are started with "#" or ";".
# #
# A lot of configuration options in this file start with a ";". You have # A lot of configuration options in this file start with a ";". You have
# to remove the ";" in front of each variable to actually set a value! # to remove the ";" in front of each variable to actually set a value!
# The disabled variables are shown with example values for completeness only # The disabled variables are shown with example values for completeness.
# and the daemon is using compiled-in default settings.
# #
# Use "ngircd --configtest" (see manual page ngircd(8)) to validate that the # Use "ngircd --configtest" (see manual page ngircd(8)) to validate that the
# server interprets the configuration file as expected! # server interprets the configuration file as expected!
# #
# Please see ngircd.conf(5) for a complete list of configuration options.
#
[Global] [Global]
# The [Global] section of this file is used to define the main # The [Global] section of this file is used to define the main
@@ -28,15 +27,9 @@
# LINKS requests for example. # LINKS requests for example.
Info = Server Info Text Info = Server Info Text
# Global password for all users needed to connect to the server. # Global password for all users needed to connect to the server
# (Default: not set)
;Password = abc ;Password = abc
# Password required for using the WEBIRC command used by some
# Web-to-IRC gateways. If not set/empty, the WEBIRC command can't
# be used. (Default: not set)
;WebircPassword = xyz
# Information about the server and the administrator, used by the # Information about the server and the administrator, used by the
# ADMIN command. Not required by server but by RFC! # ADMIN command. Not required by server but by RFC!
;AdminInfo1 = Description ;AdminInfo1 = Description
@@ -47,26 +40,9 @@
# one port, separated with ",". (Default: 6667) # one port, separated with ",". (Default: 6667)
;Ports = 6667, 6668, 6669 ;Ports = 6667, 6668, 6669
# Additional Listen Ports that expect SSL/TLS encrypted connections # IP address on which the server should listen. (Default: empty,
;SSLPorts = 6697, 9999 # so the server listens on all IP addresses of the system)
;Listen = 1.2.3.4
# SSL Server Key
;SSLKeyFile = /usr/local/etc/ngircd/ssl/server-key.pem
# password to decrypt SSLKeyFile (OpenSSL only)
;SSLKeyFilePassword = secret
# SSL Server Key Certificate
;SSLCertFile = /usr/local/etc/ngircd/ssl/server-cert.pem
# Diffie-Hellman parameters
;SSLDHFile = /usr/local/etc/ngircd/ssl/dhparams.pem
# comma separated list of IP addresses on which the server should
# listen. Default values are:
# "0.0.0.0" or (if compiled with IPv6 support) "::,0.0.0.0"
# so the server listens on all IP addresses of the system by default.
;Listen = 127.0.0.1,192.168.0.1
# Text file with the "message of the day" (MOTD). This message will # Text file with the "message of the day" (MOTD). This message will
# be shown to all users connecting to the server: # be shown to all users connecting to the server:
@@ -121,26 +97,14 @@
# server? (This is a compatibility hack for ircd-irc2 servers) # server? (This is a compatibility hack for ircd-irc2 servers)
;OperServerMode = no ;OperServerMode = no
# Are remote IRC operators allowed to control this server, e. g.
# use commands like CONNECT, SQUIT, DIE, ...?
;AllowRemoteOper = no
# Allow Pre-Defined Channels only (see Section [Channels]) # Allow Pre-Defined Channels only (see Section [Channels])
;PredefChannelsOnly = no ;PredefChannelsOnly = no
# Don't do any DNS lookups when a client connects to the server. # Don't do any DNS lookups when a client connects to the server.
;NoDNS = no ;NoDNS = no
# Don't do any IDENT lookups, even if ngIRCd has been compiled # Maximum number of simultaneous connection the server is allowed
# with support for it. # to accept (0: unlimited):
;NoIdent = no
# try to connect to other irc servers using ipv4 and ipv6, if possible
;ConnectIPv6 = yes
;ConnectIPv4 = yes
# Maximum number of simultaneous in- and outbound connections the
# server is allowed to accept (0: unlimited):
;MaxConnections = 0 ;MaxConnections = 0
# Maximum number of simultaneous connections from a single IP address # Maximum number of simultaneous connections from a single IP address
@@ -193,8 +157,8 @@
# this server should establish the connection). # this server should establish the connection).
;Host = connect-to-host.the.net ;Host = connect-to-host.the.net
# IP address to use as _source_ address for the connection. if # IP address to use as _source_ address for the connection. if unspecified,
# unspecified, ngircd will let the operating system pick an address. # ngircd will let the operating system pick an address.
;Bind = 10.0.0.1 ;Bind = 10.0.0.1
# Port of the server to which the ngIRCd should connect. If you # Port of the server to which the ngIRCd should connect. If you
@@ -214,24 +178,11 @@
# Set the "Passive" option to "yes" if you don't want this ngIRCd to # Set the "Passive" option to "yes" if you don't want this ngIRCd to
# connect to the configured peer (same as leaving the "Port" variable # connect to the configured peer (same as leaving the "Port" variable
# empty). The advantage of this option is that you can actually # empty). The advantage of this option is that you can actually configure
# configure a port an use the IRC command CONNECT more easily to # a port an use the IRC command CONNECT more easily to manually connect
# manually connect this specific server later. # this specific server later.
;Passive = no ;Passive = no
# Connect to the remote server using TLS/SSL (Default: false)
;SSLConnect = yes
# Define a (case insensitive) mask matching nick names that should be
# treated as IRC services when introduced via this remote server.
# REGULAR SERVERS DON'T NEED this parameter, so leave it empty
# (which is the default).
# When you are connecting IRC services which mask as a IRC server
# and which use "virtual users" to communicate with, for example
# "NickServ" and "ChanServ", you should set this parameter to
# something like "*Serv".
;ServiceMask = *Serv
[Server] [Server]
# More [Server] sections, if you like ... # More [Server] sections, if you like ...
@@ -255,10 +206,6 @@
# initial channel password (mode k) # initial channel password (mode k)
;Key = Secret ;Key = Secret
# Key file, syntax for each line: "<user>:<nick>:<key>".
# Default: none.
;KeyFile = /etc/ngircd/#chan.key
# maximum users per channel (mode l) # maximum users per channel (mode l)
;MaxUsers = 23 ;MaxUsers = 23

3
doc/src/.cvsignore Normal file
View File

@@ -0,0 +1,3 @@
Makefile
Makefile.in
html

1
doc/src/.gitignore vendored
View File

@@ -1 +0,0 @@
html

View File

@@ -1,6 +1,6 @@
# #
# ngIRCd -- The Next Generation IRC Daemon # ngIRCd -- The Next Generation IRC Daemon
# Copyright (c)2001-2008 Alexander Barton (alex@barton.de) # Copyright (c)2001-2006 Alexander Barton (alex@barton.de)
# #
# This program is free software; you can redistribute it and/or modify # 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,8 +8,8 @@
# (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.3 2006/12/28 14:04:28 alex Exp $
EXTRA_DIST = Doxyfile header.inc.html footer.inc.html ngircd-doc.css #
maintainer-clean-local: maintainer-clean-local:
rm -f Makefile Makefile.in rm -f Makefile Makefile.in

View File

@@ -3,7 +3,7 @@
<p> <p>
ngIRCd ngIRCd
<a href="http://ngircd.barton.de/">Homepage</a>, <a href="http://ngircd.barton.de/">Homepage</a>,
<a href="http://ngircd.barton.de/cgi-bin/gitweb.cgi?p=ngircd.git">GIT-Repository</a>, <a href="http://arthur.barton.de/cgi-bin/viewcvs.cgi/ngircd/">CVS-Repository</a>,
<a href="http://ngircd.barton.de/bugzilla/index.cgi">Bug-Tracker</a>. <a href="http://ngircd.barton.de/bugzilla/index.cgi">Bug-Tracker</a>.
</p> </p>

View File

@@ -1,2 +1,4 @@
Makefile
Makefile.in
ngircd.8 ngircd.8
ngircd.conf.5 ngircd.conf.5

View File

@@ -1,7 +1,7 @@
.\" .\"
.\" ngircd(8) manual page template .\" $Id: ngircd.8.tmpl,v 1.2 2007/11/15 01:03:29 fw Exp $
.\" .\"
.TH ngircd 8 "Dec 2008" ngircd "ngIRCd Manual" .TH ngircd 8 "August 2005" ngircd "ngIRCd Manual"
.SH NAME .SH NAME
ngIRCd \- the next generation IRC daemon ngIRCd \- the next generation IRC daemon
.SH SYNOPSIS .SH SYNOPSIS
@@ -50,10 +50,10 @@ CONNECT later on as IRC Operator to link this ngIRCd to other servers.
\fB\-t\fR, \fB\-\-configtest\fR \fB\-t\fR, \fB\-\-configtest\fR
Read, validate and display the configuration; then exit. Read, validate and display the configuration; then exit.
.TP .TP
\fB\-V\fR, \fB\-\-version\fR \fB\-\-version\fR
Output version information and exit. Output version information and exit.
.TP .TP
\fB\-h\fR, \fB\-\-help\fR \fB\-\-help\fR
Display a brief help text and exit. Display a brief help text and exit.
.SH FILES .SH FILES
.I :ETCDIR:/ngircd.conf .I :ETCDIR:/ngircd.conf
@@ -64,16 +64,15 @@ The system wide default configuration file.
.RS .RS
Default "message of the day" (MOTD). Default "message of the day" (MOTD).
.RE .RE
.SH HINTS
It's wise to use "ngircd \-\-configtest" to validate the configuration file
after changing it.
.SH AUTHOR .SH AUTHOR
Alexander Barton, Alexander Barton,
.UR mailto:alex@barton.de .UR mailto:alex@barton.de
alex@barton.de
.UE .UE
.br .br
Homepage: Homepage:
.UR http://ngircd.barton.de/ .UR http://ngircd.barton.de/
http://ngircd.barton.de/
.UE .UE
.SH "SEE ALSO" .SH "SEE ALSO"
.BR ngircd.conf (5), .BR ngircd.conf (5),

View File

@@ -1,7 +1,7 @@
.\" .\"
.\" ngircd.conf(5) manual page template .\" $Id: ngircd.conf.5.tmpl,v 1.7 2007/11/23 16:26:03 fw Exp $
.\" .\"
.TH ngircd.conf 5 "Dec 2008" ngircd "ngIRCd Manual" .TH ngircd.conf 5 "August 2005" ngircd "ngIRCd Manual"
.SH NAME .SH NAME
ngircd.conf \- configuration file of ngIRCd ngircd.conf \- configuration file of ngIRCd
.SH SYNOPSIS .SH SYNOPSIS
@@ -12,9 +12,6 @@ is the configuration file of the
.BR ngircd (8) .BR ngircd (8)
Internet Relay Chat (IRC) daemon which you should adept to your local Internet Relay Chat (IRC) daemon which you should adept to your local
preferences and needs. preferences and needs.
.PP
Most variables can be modified while the ngIRCd daemon is already running:
It will reload its configuration when a HUP signal is received.
.SH "FILE FORMAT" .SH "FILE FORMAT"
The file consists of sections and parameters. A section begins with the name The file consists of sections and parameters. A section begins with the name
of the section in square brackets and continues until the next section of the section in square brackets and continues until the next section
@@ -29,20 +26,19 @@ Sections contain parameters of the form
.RE .RE
.PP .PP
Empty lines and any line beginning with a semicolon (';') or a hash ('#') Empty lines and any line beginning with a semicolon (';') or a hash ('#')
character are treated as a comment and will be ignored. Leading and trailing character is treated as a comment and will be ignored.
whitespaces are trimmed before any processing takes place.
.PP .PP
The file format is line-based - that means, each non-empty newline-terminated The file format is line-based - that means, each newline-terminated line
line represents either a comment, a section name, or a parameter. represents either a comment, a section name or a parameter.
.PP .PP
Section and parameter names are not case sensitive. Section and parameter names are not case sensitive.
.SH "SECTION OVERVIEW" .SH "SECTION OVERVIEW"
The file can contain blocks of four types: [Global], [Operator], [Server], The file can contain blocks of four types: [Global], [Operator], [Server],
and [Channel]. and [Channel].
.PP .PP
The main configuration of the server is stored in the In the
.I [Global] .I [Global]
section, like the server name, administrative information and the section, there is the main configuration like the server name and the
ports on which the server should be listening. IRC operators of this ports on which the server should be listening. IRC operators of this
server are defined in server are defined in
.I [Operator] .I [Operator]
@@ -61,60 +57,23 @@ section is used to define the server main configuration, like the server
name and the ports on which the server should be listening. name and the ports on which the server should be listening.
.TP .TP
\fBName\fR \fBName\fR
Server name in the IRC network. This is an individual name of the IRC Server name in the IRC network
server, it is not related to the DNS host name. It must be unique in the
IRC network and must contain at least one dot (".") character.
.TP .TP
\fBInfo\fR \fBInfo\fR
Info text of the server. This will be shown by WHOIS and LINKS requests for Info text of the server. This will be shown by WHOIS and LINKS requests for
example. example.
.TP .TP
\fBPassword\fR
Global password for all users needed to connect to the server. The default
is empty, so no password is required.
.TP
\fBWebircPassword\fR
Password required for using the WEBIRC command used by some Web-to-IRC
gateways. If not set or empty, the WEBIRC command can't be used.
Default: not set.
.TP
\fBAdminInfo1\fR, \fBAdminInfo2\fR, \fBAdminEMail\fR \fBAdminInfo1\fR, \fBAdminInfo2\fR, \fBAdminEMail\fR
Information about the server and the administrator, used by the ADMIN Information about the server and the administrator, used by the ADMIN
command. command.
.TP .TP
\fBPorts\fR \fBPorts\fR
Ports on which the server should listen. There may be more than one port, Ports on which the server should listen. There may be more than one port,
separated with commas (","). Default: 6667, unless \fBSSL_Ports\fR are also separated with ','. Default: 6667.
specified.
.TP
\fBSSLPorts\fR
Same as \fBPorts\fR , except that ngIRCd will expect incoming connections
to be SSL/TLS encrypted. Common port numbers for SSL-encrypted IRC are 6669
and 6697. Default: none.
.TP
\fBSSLKeyFile\fR
Filename of SSL Server Key to be used for SSL connections. This is required for
SSL/TLS support.
.TP
\fBSSLKeyFilePassword\fR
(OpenSSL only:) Password to decrypt private key.
.TP
\fBSSLCertFile\fR
Certificate file of the private key.
.TP
\fBSSLDHFile\fR
Name of the Diffie-Hellman Parameter file. Can be created with gnutls
"certtool \-\-generate-dh-params" or "openssl dhparam".
If this file is not present, it will be generated on startup when ngIRCd
was compiled with gnutls support (this may take some time). If ngIRCd
was compiled with OpenSSL, then (Ephemeral)-Diffie-Hellman Key Exchanges and several
Cipher Suites will not be available.
.TP .TP
\fBListen\fR \fBListen\fR
A comma separated list of IP address on which the server should listen. The IP address on which the server should listen. Default is empty, so
If unset, the defaults value is "0.0.0.0" or, if ngIRCd was compiled the server listens on all configured IP addresses and interfaces.
with IPv6 support, "::,0.0.0.0". So the server listens on all configured
IP addresses and interfaces by default.
.TP .TP
\fBMotdFile\fR \fBMotdFile\fR
Text file with the "message of the day" (MOTD). This message will be shown Text file with the "message of the day" (MOTD). This message will be shown
@@ -122,8 +81,7 @@ to all users connecting to the server.
.TP .TP
\fBMotdPhrase\fR \fBMotdPhrase\fR
A simple Phrase (<256 chars) if you don't want to use a MOTD file. A simple Phrase (<256 chars) if you don't want to use a MOTD file.
If this variable is set, no \fBMotdFile\fR will be read at all which can be If it is set no MotdFile will be read at all.
handy if the daemon should run inside a chroot directory.
.TP .TP
\fBServerUID\fR \fBServerUID\fR
User ID under which the server should run; you can use the name of the user User ID under which the server should run; you can use the name of the user
@@ -184,44 +142,25 @@ Should IRC Operators be allowed to use the MODE command even if they are
not(!) channel-operators? Default: no. not(!) channel-operators? Default: no.
.TP .TP
\fBOperServerMode\fR \fBOperServerMode\fR
If \fBOperCanUseMode\fR is enabled, this may lead the compatibility problems with 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
\fBAllowRemoteOper\fR
Are IRC operators connected to remote servers allowed to control this server,
e. g. are they allowed to use administrative commands like CONNECT, DIE,
SQUIT, ... that affect this server? Default: no.
.TP
\fBPredefChannelsOnly\fR \fBPredefChannelsOnly\fR
If enabled, no new channels can be created. Useful if If enabled, no new channels can be created. Useful if
you do not want to have channels other than those defined in you do not want to have channels other than those defined in
[Channel] sections in the configuration file. the config file.
Default: no. Default: No.
.TP .TP
\fBNoDNS\fR \fBNoDNS\fR
If set to true, ngIRCd will not make DNS lookups when clients connect. If enabled, ngircd will not make DNS lookups when clients connect.
If you configure the daemon to connect to other servers, ngIRCd may still If you configure ngircd to connect to other servers, ngircd may still
perform a DNS lookup if required. perform a DNS lookup if required.
Default: no. Default: No.
.TP
\fBNoIdent\fR
If ngIRCd is compiled with IDENT support this can be used to disable IDENT
lookups at run time.
Default: no.
.TP
\fBConnectIPv4\fR
Set this to no if you do not want ngIRCd to connect to other IRC servers using
IPv4. This allows usage of ngIRCd in IPv6-only setups.
Default: yes.
.TP
\fBConnectIPv6\fR
Set this to no if you do not want ngIRCd to connect to other irc servers using IPv6.
Default: yes.
.TP .TP
\fBMaxConnections\fR \fBMaxConnections\fR
Maximum number of simultaneous in- and outbound connections the server is Maximum number of simultaneous connection the server is allowed to accept
allowed to accept (0: unlimited). Default: 0. (0: unlimited). Default: 0.
.TP .TP
\fBMaxConnectionsIP\fR \fBMaxConnectionsIP\fR
Maximum number of simultaneous connections from a single IP address that Maximum number of simultaneous connections from a single IP address that
@@ -255,62 +194,45 @@ Example: nick!ident@*.example.com
Other servers are configured in Other servers are configured in
.I [Server] .I [Server]
sections. If you configure a port for the connection, then this ngIRCd sections. If you configure a port for the connection, then this ngIRCd
tries to connect to to the other server on the given port (active); tries to connect to to the other server on the given port; if not, it waits
if not, it waits for the other server to connect (passive). for the other server to connect.
.PP .PP
ngIRCd supports "server groups": You can assign an "ID" to every server The ngIRCd allows "server groups": You can assign an "ID" to every server
with which you want this ngIRCd to link, and the daemon ensures that at with which you want this ngIRCd to link. If a server of a group won't
any given time only one direct link exists to servers with the same ID. answer, the ngIRCd tries to connect to the next server in the given group.
So if a server of a group won't answer, ngIRCd tries to connect to the next But ngIRCd never tries to connect to two servers with the same group ID.
server in the given group (="with the same ID"), but never tries to connect
to more than one server of this group simultaneously.
.PP .PP
There may be more than one There may be more than one
.I [Server] .I [Server]
block. block.
.TP .TP
\fBName\fR \fBName\fR
IRC name of the remote server. IRC name of the server
.TP .TP
\fBHost\fR \fBHost\fR
Internet host name (or IP address) of the peer. Internet host name of the peer
.TP .TP
\fBBind\fR \fBBind\fR
IP address to use as source IP for the outgoing connection. Default is IP address to use as source IP for the outgoing connection. Default ist
to let the operating system decide. to let the operating system decide.
.TP .TP
\fBPort\fR \fBPort\fR
Port of the remote server to which ngIRCd should connect (active). Port of the server to which the ngIRCd should connect. If you assign no port
If no port is assigned to a configured server, the daemon only waits for the ngIRCd waits for incoming connections.
incoming connections (passive, default).
.TP .TP
\fBMyPassword\fR \fBMyPassword\fR
Own password for this connection. This password has to be configured as Own password for this connection. This password has to be configured as
\fBPeerPassword\fR on the other server. Must not have ':' as first character. "PeerPassword" on the other server. Must not have ':' as first character.
.TP .TP
\fBPeerPassword\fR \fBPeerPassword\fR
Foreign password for this connection. This password has to be configured as Foreign password for this connection. This password has to be configured as
\fBMyPassword\fR on the other server. "MyPassword" on the other server.
.TP .TP
\fBGroup\fR \fBGroup\fR
Group of this server (optional). Group of this server (optional).
.TP
\fBPassive\fR \fBPassive\fR
Disable automatic connection even if port value is specified. Default: false. Disable automatic connection even if port value is specified. Default: false.
You can use the IRC Operator command CONNECT later on to create the link. You can use the IRC Operator command CONNECT later on to create the link.
.TP
\fBSSLConnect\fR
Connect to the remote server using TLS/SSL. Default: false.
.TP
\fBServiceMask\fR
Define a (case insensitive) mask matching nick names that should be treated as
IRC services when introduced via this remote server. REGULAR SERVERS DON'T NEED
this parameter, so leave it empty (which is the default).
.PP
.RS
When you are connecting IRC services which mask as a IRC server and which use
"virtual users" to communicate with, for example "NickServ" and "ChanServ",
you should set this parameter to something like "*Serv".
.SH [CHANNEL] .SH [CHANNEL]
Pre-defined channels can be configured in Pre-defined channels can be configured in
.I [Channel] .I [Channel]
@@ -325,75 +247,33 @@ There may be more than one
block. block.
.TP .TP
\fBName\fR \fBName\fR
Name of the channel, including channel prefix ("#" or "&"). Name of the channel
.TP .TP
\fBTopic\fR \fBTopic\fR
Topic for this channel. Topic for this channel
.TP .TP
\fBModes\fR \fBModes\fR
Initial channel modes. Initial channel modes.
.TP .TP
\fBKey\fR \fBKey\fR
Sets initial channel key (only relevant if channel mode "k" is set). Sets initial channel key (only relevant if mode k is set)
.TP
\fBKeyFile\fR
Path and file name of a "key file" containing individual channel keys for
different users. The file consists of plain text lines with the following
syntax (without spaces!):
.PP
.RS
.RS
.I user
:
.I nick
:
.I key
.RE
.PP
.I user
and
.I nick
can contain the wildcard character "*".
.br
.I key
is an arbitrary password.
.PP
Valid examples are:
.PP
.RS
*:*:KeY
.br
*:nick:123
.br
~user:*:xyz
.RE
.PP
The key file is read on each JOIN command when this channel has a key
(channel mode +k). Access is granted, if a) the channel key set using the
MODE +k command or b) one of the lines in the key file match.
.PP
.B Please note:
.br
The file is not reopened on each access, so you can modify and overwrite it
without problems, but moving or deleting the file will have not effect until
the daemon re-reads its configuration!
.RE
.TP .TP
\fBMaxUsers\fR \fBMaxUsers\fR
Set maximum user limit for this channel (only relevant if channel mode "l" Set maximum user limit for this channel (only relevant if mode l is set)
is set).
.SH HINTS .SH HINTS
It's wise to use "ngircd \-\-configtest" to validate the configuration file It's wise to use "ngircd --configtest" to validate the configuration file
after changing it. See after changing it. See
.BR ngircd (8) .BR ngircd (8)
for details. for details.
.SH AUTHOR .SH AUTHOR
Alexander Barton, Alexander Barton,
.UR mailto:alex@barton.de .UR mailto:alex@barton.de
alex@barton.de
.UE .UE
.br .br
Homepage: Homepage:
.UR http://ngircd.barton.de/ .UR http://ngircd.barton.de/
http://ngircd.barton.de/
.UE .UE
.SH "SEE ALSO" .SH "SEE ALSO"
.BR ngircd (8) .BR ngircd (8)

View File

@@ -1,4 +1,5 @@
Makefile
Makefile.in
config.h config.h
config.h.in config.h.in
config.h.in~
stamp-h1 stamp-h1

View File

@@ -8,10 +8,10 @@
# (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.8 2008/02/26 22:04:15 fw Exp $ # $Id: Makefile.am,v 1.7 2005/07/22 21:01:03 alex Exp $
# #
SUBDIRS = portab tool ipaddr ngircd testsuite SUBDIRS = portab tool ngircd testsuite
maintainer-clean-local: maintainer-clean-local:
rm -f Makefile Makefile.in config.h config.h.in stamp-h.in rm -f Makefile Makefile.in config.h config.h.in stamp-h.in

View File

@@ -1,14 +0,0 @@
AUTOMAKE_OPTIONS = ansi2knr
INCLUDES = -I$(srcdir)/../portab
noinst_LIBRARIES = libngipaddr.a
libngipaddr_a_SOURCES = ng_ipaddr.c
noinst_HEADERS = ng_ipaddr.h
maintainer-clean-local:
rm -f Makefile Makefile.in
# -eof-

View File

@@ -1,174 +0,0 @@
/*
* Functions for AF_ agnostic ipv4/ipv6 handling.
*
* (c) 2008 Florian Westphal <fw@strlen.de>, public domain.
*/
#include "portab.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_GETADDRINFO
#include <netdb.h>
#include <sys/types.h>
#endif
#include "ng_ipaddr.h"
GLOBAL bool
ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
{
#ifdef HAVE_GETADDRINFO
int ret;
char portstr[64];
struct addrinfo *res0;
struct addrinfo hints;
assert(ip_str);
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_NUMERICHOST;
#ifndef WANT_IPV6 /* do not convert ipv6 addresses */
hints.ai_family = AF_INET;
#endif
/* some getaddrinfo implementations require that ai_socktype is set. */
hints.ai_socktype = SOCK_STREAM;
/* silly, but ngircd stores UINT16 in server config, not string */
snprintf(portstr, sizeof(portstr), "%u", (unsigned int) port);
ret = getaddrinfo(ip_str, portstr, &hints, &res0);
if (ret != 0)
return false;
assert(sizeof(*addr) >= res0->ai_addrlen);
if (sizeof(*addr) >= res0->ai_addrlen)
memcpy(addr, res0->ai_addr, res0->ai_addrlen);
else
ret = -1;
freeaddrinfo(res0);
return ret == 0;
#else /* HAVE_GETADDRINFO */
assert(ip_str);
memset(addr, 0, sizeof *addr);
#ifdef HAVE_sockaddr_in_len
addr->sin4.sin_len = sizeof(addr->sin4);
#endif
addr->sin4.sin_family = AF_INET;
# ifdef HAVE_INET_ATON
if (inet_aton(ip_str, &addr->sin4.sin_addr) == 0)
return false;
# else
addr->sin4.sin_addr.s_addr = inet_addr(ip_str);
if (addr->sin4.sin_addr.s_addr == (unsigned) -1)
return false;
# endif
ng_ipaddr_setport(addr, port);
return true;
#endif /* HAVE_GETADDRINFO */
}
GLOBAL void
ng_ipaddr_setport(ng_ipaddr_t *a, UINT16 port)
{
#ifdef WANT_IPV6
int af;
assert(a != NULL);
af = a->sa.sa_family;
assert(af == AF_INET || af == AF_INET6);
switch (af) {
case AF_INET:
a->sin4.sin_port = htons(port);
break;
case AF_INET6:
a->sin6.sin6_port = htons(port);
break;
}
#else /* WANT_IPV6 */
assert(a != NULL);
assert(a->sin4.sin_family == AF_INET);
a->sin4.sin_port = htons(port);
#endif /* WANT_IPV6 */
}
GLOBAL bool
ng_ipaddr_ipequal(const ng_ipaddr_t *a, const ng_ipaddr_t *b)
{
assert(a != NULL);
assert(b != NULL);
#ifdef WANT_IPV6
if (a->sa.sa_family != b->sa.sa_family)
return false;
assert(ng_ipaddr_salen(a) == ng_ipaddr_salen(b));
switch (a->sa.sa_family) {
case AF_INET6:
return IN6_ARE_ADDR_EQUAL(&a->sin6.sin6_addr, &b->sin6.sin6_addr);
case AF_INET:
return memcmp(&a->sin4.sin_addr, &b->sin4.sin_addr, sizeof(a->sin4.sin_addr)) == 0;
}
return false;
#else
assert(a->sin4.sin_family == AF_INET);
assert(b->sin4.sin_family == AF_INET);
return memcmp(&a->sin4.sin_addr, &b->sin4.sin_addr, sizeof(a->sin4.sin_addr)) == 0;
#endif
}
#ifdef WANT_IPV6
GLOBAL const char *
ng_ipaddr_tostr(const ng_ipaddr_t *addr)
{
static char strbuf[NG_INET_ADDRSTRLEN];
strbuf[0] = 0;
ng_ipaddr_tostr_r(addr, strbuf);
return strbuf;
}
/* str must be at least NG_INET_ADDRSTRLEN bytes long */
GLOBAL bool
ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *str)
{
#ifdef HAVE_GETNAMEINFO
const struct sockaddr *sa = (const struct sockaddr *) addr;
int ret;
*str = 0;
ret = getnameinfo(sa, ng_ipaddr_salen(addr),
str, NG_INET_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
/*
* avoid leading ':'.
* causes mis-interpretation of client host in e.g. /WHOIS
*/
if (*str == ':') {
char tmp[NG_INET_ADDRSTRLEN] = "0";
ret = getnameinfo(sa, ng_ipaddr_salen(addr),
tmp + 1, (socklen_t)sizeof(tmp) - 1,
NULL, 0, NI_NUMERICHOST);
if (ret == 0)
strlcpy(str, tmp, NG_INET_ADDRSTRLEN);
}
assert (ret == 0);
return ret == 0;
#else
abort(); /* WANT_IPV6 depends on HAVE_GETNAMEINFO */
#endif
}
#endif /* WANT_IPV6 */
/* -eof- */

View File

@@ -1,117 +0,0 @@
/*
* Functions for AF_ agnostic ipv4/ipv6 handling.
*
* (c) 2008 Florian Westphal <fw@strlen.de>, public domain.
*/
#ifndef NG_IPADDR_HDR
#define NG_IPADDR_HDR
#include "portab.h"
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#else
# define PF_INET AF_INET
#endif
#ifdef WANT_IPV6
#define NG_INET_ADDRSTRLEN INET6_ADDRSTRLEN
#else
#define NG_INET_ADDRSTRLEN 16
#endif
#ifdef WANT_IPV6
typedef union {
struct sockaddr sa;
struct sockaddr_in sin4;
struct sockaddr_in6 sin6;
} ng_ipaddr_t;
#else
/* assume compiler can't deal with typedef struct {... */
struct NG_IP_ADDR_DONTUSE {
struct sockaddr_in sin4;
};
typedef struct NG_IP_ADDR_DONTUSE ng_ipaddr_t;
#endif
static inline int
ng_ipaddr_af(const ng_ipaddr_t *a)
{
#ifdef WANT_IPV6
return a->sa.sa_family;
#else
assert(a->sin4.sin_family == 0 || a->sin4.sin_family == AF_INET);
return a->sin4.sin_family;
#endif
}
static inline socklen_t
ng_ipaddr_salen(const ng_ipaddr_t *a)
{
#ifdef WANT_IPV6
assert(a->sa.sa_family == AF_INET || a->sa.sa_family == AF_INET6);
if (a->sa.sa_family == AF_INET6)
return (socklen_t)sizeof(a->sin6);
#endif
assert(a->sin4.sin_family == AF_INET);
return (socklen_t)sizeof(a->sin4);
}
static inline UINT16
ng_ipaddr_getport(const ng_ipaddr_t *a)
{
#ifdef WANT_IPV6
int af = a->sa.sa_family;
assert(af == AF_INET || af == AF_INET6);
if (af == AF_INET6)
return ntohs(a->sin6.sin6_port);
#endif /* WANT_IPV6 */
assert(a->sin4.sin_family == AF_INET);
return ntohs(a->sin4.sin_port);
}
/*
* init a ng_ipaddr_t object.
* @param addr: pointer to ng_ipaddr_t to initialize.
* @param ip_str: ip address in dotted-decimal (ipv4) or hexadecimal (ipv6) notation
* @param port: transport layer port number to use.
*/
GLOBAL bool ng_ipaddr_init PARAMS((ng_ipaddr_t *addr, const char *ip_str, UINT16 port));
/* set sin4/sin6_port, depending on a->sa_family */
GLOBAL void ng_ipaddr_setport PARAMS((ng_ipaddr_t *a, UINT16 port));
/* return true if a and b have the same IP address. If a and b have different AF, return false. */
GLOBAL bool ng_ipaddr_ipequal PARAMS((const ng_ipaddr_t *a, const ng_ipaddr_t *b));
#ifdef WANT_IPV6
/* convert struct sockaddr to string, returns pointer to static buffer */
GLOBAL const char *ng_ipaddr_tostr PARAMS((const ng_ipaddr_t *addr));
/* convert struct sockaddr to string. dest must be NG_INET_ADDRSTRLEN bytes long */
GLOBAL bool ng_ipaddr_tostr_r PARAMS((const ng_ipaddr_t *addr, char *dest));
#else
static inline const char *
ng_ipaddr_tostr(const ng_ipaddr_t *addr) { return inet_ntoa(addr->sin4.sin_addr); }
static inline bool
ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *d)
{
strlcpy(d, inet_ntoa(addr->sin4.sin_addr), NG_INET_ADDRSTRLEN);
return true;
}
#endif
#endif
/* -eof- */

8
src/ngircd/.cvsignore Normal file
View File

@@ -0,0 +1,8 @@
Makefile
Makefile.in
.deps
check-help
check-version
cvs-version.h
cvs-version.new
ngircd

View File

@@ -1,3 +0,0 @@
check-help
check-version
ngircd

View File

@@ -8,12 +8,12 @@
# (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.51 2008/02/26 22:04:17 fw Exp $ # $Id: Makefile.am,v 1.50 2007/11/21 12:16:36 alex Exp $
# #
AUTOMAKE_OPTIONS = ../portab/ansi2knr AUTOMAKE_OPTIONS = ../portab/ansi2knr
INCLUDES = -I$(srcdir)/../portab -I$(srcdir)/../tool -I$(srcdir)/../ipaddr INCLUDES = -I$(srcdir)/../portab -I$(srcdir)/../tool
LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN \ LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN \
-varuse -retvalother -emptyret -unrecog -varuse -retvalother -emptyret -unrecog
@@ -21,22 +21,22 @@ LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN \
sbin_PROGRAMS = ngircd sbin_PROGRAMS = ngircd
ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.c \ ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.c \
conn-ssl.c conn-zip.c hash.c io.c irc.c irc-channel.c irc-info.c irc-login.c \ conn-zip.c hash.c io.c irc.c irc-channel.c irc-info.c irc-login.c \
irc-mode.c irc-op.c irc-oper.c irc-server.c irc-write.c lists.c log.c \ irc-mode.c irc-op.c irc-oper.c irc-server.c irc-write.c lists.c log.c \
match.c op.c numeric.c parse.c rendezvous.c resolve.c match.c numeric.c parse.c rendezvous.c resolve.c
ngircd_LDFLAGS = -L../portab -L../tool -L../ipaddr ngircd_LDFLAGS = -L../portab -L../tool
ngircd_LDADD = -lngportab -lngtool -lngipaddr ngircd_LDADD = -lngportab -lngtool
noinst_HEADERS = ngircd.h array.h channel.h client.h conf.h conf-ssl.h conn.h \ noinst_HEADERS = ngircd.h array.h channel.h client.h conf.h conn.h conn-func.h \
conn-func.h conn-ssl.h conn-zip.h hash.h io.h irc.h irc-channel.h \ conn-zip.h hash.h io.h irc.h irc-channel.h irc-info.h irc-login.h \
irc-info.h irc-login.h irc-mode.h irc-op.h irc-oper.h irc-server.h \ irc-mode.h irc-op.h irc-oper.h irc-server.h irc-write.h lists.h log.h \
irc-write.h lists.h log.h match.h numeric.h op.h parse.h rendezvous.h \ match.h numeric.h parse.h rendezvous.h resolve.h \
resolve.h defines.h messages.h defines.h messages.h
clean-local: clean-local:
rm -f check-version check-help lint.out rm -f check-version check-help lint.out cvs-version.*
maintainer-clean-local: maintainer-clean-local:
rm -f Makefile Makefile.in rm -f Makefile Makefile.in
@@ -77,6 +77,23 @@ lint:
|| echo "Result: no warnings found."; \ || echo "Result: no warnings found."; \
echo; [ $$warnings -gt 0 ] && exit 1 echo; [ $$warnings -gt 0 ] && exit 1
ngircd.c: cvs-version.h
irc-login.c: cvs-version.h
irc-info.c: cvs-version.h
cvs-version.h: cvs-date
cvs-date:
grep VERSION ../config.h | grep "CVS" \
&& echo "#define CVSDATE \"$$( grep "\$$Id" $(srcdir)/*.c \
| $(AWK) "{ print \$$9 }" | sort | tail -1 \
| sed -e "s/\//-/g" )\"" > cvs-version.new \
|| echo "" > cvs-version.new
diff cvs-version.h cvs-version.new 2>/dev/null \
|| cp cvs-version.new cvs-version.h
TESTS = check-version check-help TESTS = check-version check-help
# -eof- # -eof-

View File

@@ -281,14 +281,6 @@ array_free(array * a)
a->used = 0; a->used = 0;
} }
void
array_free_wipe(array *a)
{
size_t bytes = a->allocated;
if (bytes)
memset(a->mem, 0, bytes);
array_free(a);
}
void * void *
array_start(const array * const a) array_start(const array * const a)

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2009 Alexander Barton (alex@barton.de) * Copyright (c)2001-2005 by 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,12 +17,13 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: channel.c,v 1.63 2007/06/11 20:06:46 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <stdio.h>
#include <strings.h> #include <strings.h>
#include "defines.h" #include "defines.h"
@@ -40,7 +41,6 @@
#include "lists.h" #include "lists.h"
#include "log.h" #include "log.h"
#include "messages.h" #include "messages.h"
#include "match.h"
#include "exp.h" #include "exp.h"
@@ -56,27 +56,17 @@ static CL2CHAN *My_Cl2Chan;
static CL2CHAN *Get_Cl2Chan PARAMS(( CHANNEL *Chan, CLIENT *Client )); static CL2CHAN *Get_Cl2Chan PARAMS(( CHANNEL *Chan, CLIENT *Client ));
static CL2CHAN *Add_Client PARAMS(( CHANNEL *Chan, CLIENT *Client )); static CL2CHAN *Add_Client PARAMS(( CHANNEL *Chan, CLIENT *Client ));
static bool Remove_Client PARAMS(( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const char *Reason, bool InformServer )); static bool Remove_Client PARAMS(( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, char *Reason, bool InformServer ));
static CL2CHAN *Get_First_Cl2Chan PARAMS(( CLIENT *Client, CHANNEL *Chan )); static CL2CHAN *Get_First_Cl2Chan PARAMS(( CLIENT *Client, CHANNEL *Chan ));
static CL2CHAN *Get_Next_Cl2Chan PARAMS(( CL2CHAN *Start, CLIENT *Client, CHANNEL *Chan )); static CL2CHAN *Get_Next_Cl2Chan PARAMS(( CL2CHAN *Start, CLIENT *Client, CHANNEL *Chan ));
static void Delete_Channel PARAMS(( CHANNEL *Chan )); static bool Delete_Channel PARAMS(( CHANNEL *Chan ));
static void Free_Channel PARAMS(( CHANNEL *Chan ));
static void Set_KeyFile PARAMS((CHANNEL *Chan, const char *KeyFile));
GLOBAL void GLOBAL void
Channel_Init( void ) Channel_Init( void )
{ {
CHANNEL *sc;
My_Channels = NULL; My_Channels = NULL;
My_Cl2Chan = NULL; My_Cl2Chan = NULL;
sc = Channel_Create("&SERVER");
if (sc) {
Channel_SetModes(sc, "mnPt");
Channel_SetTopic(sc, Client_ThisServer(), "Server Messages");
}
} /* Channel_Init */ } /* Channel_Init */
@@ -99,71 +89,59 @@ Channel_GetListInvites(CHANNEL *c)
GLOBAL void GLOBAL void
Channel_InitPredefined( void ) Channel_InitPredefined( void )
{ {
/* Generate predefined persistent channels */ /* Vordefinierte persistente Channels erzeugen */
CHANNEL *new_chan; CHANNEL *chan;
const struct Conf_Channel *conf_chan; char *c;
const char *c; unsigned int i;
size_t i, channel_count = array_length(&Conf_Channels, sizeof(*conf_chan));
conf_chan = array_start(&Conf_Channels); for( i = 0; i < Conf_Channel_Count; i++ )
assert(channel_count == 0 || conf_chan != NULL);
for (i = 0; i < channel_count; i++, conf_chan++) {
if (!conf_chan->name[0] || !Channel_IsValidName(conf_chan->name)) {
Log(LOG_ERR, "Can't create pre-defined channel: invalid name: \"%s\"",
conf_chan->name);
continue;
}
new_chan = Channel_Search(conf_chan->name);
if (new_chan) {
Log(LOG_INFO,
"Can't create pre-defined channel \"%s\": name already in use.",
conf_chan->name);
Set_KeyFile(new_chan, conf_chan->keyfile);
continue;
}
new_chan = Channel_Create(conf_chan->name);
if (!new_chan) {
Log(LOG_ERR, "Can't create pre-defined channel \"%s\"",
conf_chan->name);
continue;
}
Log(LOG_INFO, "Created pre-defined channel \"%s\"",
conf_chan->name);
Channel_ModeAdd(new_chan, 'P');
if (conf_chan->topic[0])
Channel_SetTopic(new_chan, NULL, conf_chan->topic);
c = conf_chan->modes;
while (*c)
Channel_ModeAdd(new_chan, *c++);
Channel_SetKey(new_chan, conf_chan->key);
Channel_SetMaxUsers(new_chan, conf_chan->maxusers);
Set_KeyFile(new_chan, conf_chan->keyfile);
}
if (channel_count)
array_free(&Conf_Channels);
} /* Channel_InitPredefined */
static void
Free_Channel(CHANNEL *chan)
{ {
array_free(&chan->topic); /* Ist ein Name konfiguriert? */
array_free(&chan->keyfile); if( ! Conf_Channel[i].name[0] ) continue;
Lists_Free(&chan->list_bans);
Lists_Free(&chan->list_invites);
free(chan); /* Gueltiger Channel-Name? */
if( ! Channel_IsValidName( Conf_Channel[i].name ))
{
Log( LOG_ERR, "Can't create pre-defined channel: invalid name: \"%s\"!", Conf_Channel[i].name );
array_free(&Conf_Channel[i].topic);
continue;
} }
/* Gibt es den Channel bereits? */
chan = Channel_Search( Conf_Channel[i].name );
if( chan )
{
Log( LOG_INFO, "Can't create pre-defined channel \"%s\": name already in use.", Conf_Channel[i].name );
array_free(&Conf_Channel[i].topic);
continue;
}
/* Create channel */
chan = Channel_Create(Conf_Channel[i].name);
if (chan) {
Channel_ModeAdd(chan, 'P');
if (array_start(&Conf_Channel[i].topic) != NULL)
Channel_SetTopic(chan, NULL,
array_start(&Conf_Channel[i].topic));
array_free(&Conf_Channel[i].topic);
c = Conf_Channel[i].modes;
while (*c)
Channel_ModeAdd(chan, *c++);
Channel_SetKey(chan, Conf_Channel[i].key);
Channel_SetMaxUsers(chan, Conf_Channel[i].maxusers);
Log(LOG_INFO, "Created pre-defined channel \"%s\".",
Conf_Channel[i].name );
}
else Log(LOG_ERR, "Can't create pre-defined channel \"%s\"!",
Conf_Channel[i].name );
}
} /* Channel_InitPredefined */
GLOBAL void GLOBAL void
Channel_Exit( void ) Channel_Exit( void )
@@ -171,17 +149,20 @@ Channel_Exit( void )
CHANNEL *c, *c_next; CHANNEL *c, *c_next;
CL2CHAN *cl2chan, *cl2chan_next; CL2CHAN *cl2chan, *cl2chan_next;
/* free struct Channel */ /* Channel-Strukturen freigeben */
c = My_Channels; c = My_Channels;
while (c) { while( c )
{
c_next = c->next; c_next = c->next;
Free_Channel(c); array_free(&c->topic);
free( c );
c = c_next; c = c_next;
} }
/* Free Channel allocation table */ /* Channel-Zuordnungstabelle freigeben */
cl2chan = My_Cl2Chan; cl2chan = My_Cl2Chan;
while (cl2chan) { while( c )
{
cl2chan_next = cl2chan->next; cl2chan_next = cl2chan->next;
free( cl2chan ); free( cl2chan );
cl2chan = cl2chan_next; cl2chan = cl2chan_next;
@@ -189,59 +170,39 @@ Channel_Exit( void )
} /* Channel_Exit */ } /* Channel_Exit */
/**
* Join Channel
* This function lets a client join a channel. First, the function
* checks that the specified channel name is valid and that the client
* isn't already a member. If the specified channel doesn't exist,
* a new channel is created. Client is added to channel by function
* Add_Client().
*/
GLOBAL bool GLOBAL bool
Channel_Join( CLIENT *Client, const char *Name ) Channel_Join( CLIENT *Client, char *Name )
{ {
CHANNEL *chan; CHANNEL *chan;
assert( Client != NULL ); assert( Client != NULL );
assert( Name != NULL ); assert( Name != NULL );
/* Check that the channel name is valid */
if( ! Channel_IsValidName( Name )) { if( ! Channel_IsValidName( Name )) {
IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG, IRC_WriteStrClient( Client, ERR_NOSUCHCHANNEL_MSG, Client_ID( Client ), Name );
Client_ID(Client), Name);
return false; return false;
} }
chan = Channel_Search( Name ); chan = Channel_Search( Name );
if( chan ) { if( chan ) {
/* Check if the client is already in the channel */ /* Ist der Client bereits Mitglied? */
if (Get_Cl2Chan(chan, Client)) if( Get_Cl2Chan( chan, Client )) return false;
return false; }
} else { else
/* If the specified channel does not exist, the channel {
* is now created */ /* Gibt es noch nicht? Dann neu anlegen: */
chan = Channel_Create( Name ); chan = Channel_Create( Name );
if (!chan) if (!chan) return false;
return false;
} }
/* Add user to Channel */ /* User dem Channel hinzufuegen */
if (! Add_Client(chan, Client)) if( ! Add_Client( chan, Client )) return false;
return false; else return true;
return true;
} /* Channel_Join */ } /* Channel_Join */
/**
* Part client from channel.
* This function lets a client part from a channel. First, the function checks
* if the channel exists and the client is a member of it and sends out
* appropriate error messages if not. The real work is done by the function
* Remove_Client().
*/
GLOBAL bool GLOBAL bool
Channel_Part(CLIENT * Client, CLIENT * Origin, const char *Name, const char *Reason) Channel_Part( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason )
{ {
CHANNEL *chan; CHANNEL *chan;
@@ -249,45 +210,29 @@ Channel_Part(CLIENT * Client, CLIENT * Origin, const char *Name, const char *Rea
assert( Name != NULL ); assert( Name != NULL );
assert( Reason != NULL ); assert( Reason != NULL );
/* Check that specified channel exists */
chan = Channel_Search( Name ); chan = Channel_Search( Name );
if (!chan) { if(( ! chan ) || ( ! Get_Cl2Chan( chan, Client )))
IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG, {
Client_ID(Client), Name); IRC_WriteStrClient( Client, ERR_NOSUCHCHANNEL_MSG, Client_ID( Client ), Name );
return false; return false;
} }
/* Check that the client is in the channel */ /* User aus Channel entfernen */
if (!Get_Cl2Chan(chan, Client)) { if( ! Remove_Client( REMOVE_PART, chan, Client, Origin, Reason, true)) return false;
IRC_WriteStrClient(Client, ERR_NOTONCHANNEL_MSG, else return true;
Client_ID(Client), Name);
return false;
}
/* Part client from channel */
if (!Remove_Client(REMOVE_PART, chan, Client, Origin, Reason, true))
return false;
else
return true;
} /* Channel_Part */ } /* Channel_Part */
/**
* Kick user from Channel
*/
GLOBAL void GLOBAL void
Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name, Channel_Kick( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason )
const char *Reason )
{ {
CHANNEL *chan; CHANNEL *chan;
assert(Peer != NULL); assert( Client != NULL );
assert(Target != NULL);
assert( Origin != NULL ); assert( Origin != NULL );
assert( Name != NULL ); assert( Name != NULL );
assert( Reason != NULL ); assert( Reason != NULL );
/* Check that channel exists */
chan = Channel_Search( Name ); chan = Channel_Search( Name );
if( ! chan ) if( ! chan )
{ {
@@ -295,37 +240,32 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
return; return;
} }
if (Client_Type(Peer) != CLIENT_SERVER && if( ! Channel_IsMemberOf( chan, Origin ))
Client_Type(Origin) != CLIENT_SERVICE) { {
/* Check that user is on the specified channel */ IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG, Client_ID( Origin ), Name );
if (!Channel_IsMemberOf(chan, Origin)) {
IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG,
Client_ID(Origin), Name);
return; return;
} }
/* Check if user has operator status */ /* Is User Channel-Operator? */
if (!strchr(Channel_UserModes(chan, Origin), 'o')) { if( ! strchr( Channel_UserModes( chan, Origin ), 'o' ))
IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG, {
Client_ID(Origin), Name); IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Name);
return;
}
}
/* Check that the client to be kicked is on the specified channel */
if (!Channel_IsMemberOf(chan, Target)) {
IRC_WriteStrClient(Origin, ERR_USERNOTINCHANNEL_MSG,
Client_ID(Origin), Client_ID(Target), Name );
return; return;
} }
/* Kick Client from channel */ /* Ist the kickED User member of channel? */
Remove_Client( REMOVE_KICK, chan, Target, Origin, Reason, true); if( ! Channel_IsMemberOf( chan, Client ))
{
IRC_WriteStrClient( Origin, ERR_USERNOTINCHANNEL_MSG, Client_ID( Origin ), Client_ID( Client ), Name );
return;
}
Remove_Client( REMOVE_KICK, chan, Client, Origin, Reason, true);
} /* Channel_Kick */ } /* Channel_Kick */
GLOBAL void GLOBAL void
Channel_Quit( CLIENT *Client, const char *Reason ) Channel_Quit( CLIENT *Client, char *Reason )
{ {
CHANNEL *c, *next_c; CHANNEL *c, *next_c;
@@ -399,6 +339,7 @@ Channel_CountForUser( CLIENT *Client )
} /* Channel_CountForUser */ } /* Channel_CountForUser */
GLOBAL const char * GLOBAL const char *
Channel_Name( const CHANNEL *Chan ) Channel_Name( const CHANNEL *Chan )
{ {
@@ -447,9 +388,9 @@ Channel_Next( CHANNEL *Chan )
GLOBAL CHANNEL * GLOBAL CHANNEL *
Channel_Search( const char *Name ) Channel_Search( char *Name )
{ {
/* Search channel structure */ /* Channel-Struktur suchen */
CHANNEL *c; CHANNEL *c;
UINT32 search_hash; UINT32 search_hash;
@@ -462,7 +403,7 @@ Channel_Search( const char *Name )
{ {
if( search_hash == c->hash ) if( search_hash == c->hash )
{ {
/* hash hit */ /* lt. Hash-Wert: Treffer! */
if( strcasecmp( Name, c->name ) == 0 ) return c; if( strcasecmp( Name, c->name ) == 0 ) return c;
} }
c = c->next; c = c->next;
@@ -526,14 +467,7 @@ Channel_IsValidName( const char *Name )
{ {
assert( Name != NULL ); assert( Name != NULL );
#ifdef STRICT_RFC if(( Name[0] != '#' ) || ( strlen( Name ) >= CHANNEL_NAME_LEN )) return false;
if (strlen(Name) <= 1)
return false;
#endif
if (strchr("#&+", Name[0]) == NULL)
return false;
if (strlen(Name) >= CHANNEL_NAME_LEN)
return false;
return Name[strcspn(Name, " ,:\007")] == 0; return Name[strcspn(Name, " ,:\007")] == 0;
} /* Channel_IsValidName */ } /* Channel_IsValidName */
@@ -703,7 +637,7 @@ Channel_TopicWho(CHANNEL *Chan)
GLOBAL void GLOBAL void
Channel_SetTopic(CHANNEL *Chan, CLIENT *Client, const char *Topic) Channel_SetTopic(CHANNEL *Chan, CLIENT *Client, char *Topic)
{ {
size_t len; size_t len;
assert( Chan != NULL ); assert( Chan != NULL );
@@ -731,7 +665,7 @@ Channel_SetTopic(CHANNEL *Chan, CLIENT *Client, const char *Topic)
GLOBAL void GLOBAL void
Channel_SetModes( CHANNEL *Chan, const char *Modes ) Channel_SetModes( CHANNEL *Chan, char *Modes )
{ {
assert( Chan != NULL ); assert( Chan != NULL );
assert( Modes != NULL ); assert( Modes != NULL );
@@ -741,7 +675,7 @@ Channel_SetModes( CHANNEL *Chan, const char *Modes )
GLOBAL void GLOBAL void
Channel_SetKey( CHANNEL *Chan, const char *Key ) Channel_SetKey( CHANNEL *Chan, char *Key )
{ {
assert( Chan != NULL ); assert( Chan != NULL );
assert( Key != NULL ); assert( Key != NULL );
@@ -761,65 +695,42 @@ Channel_SetMaxUsers(CHANNEL *Chan, unsigned long Count)
} /* Channel_SetMaxUsers */ } /* Channel_SetMaxUsers */
static bool
Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
{
bool is_member, has_voice, is_op;
is_member = has_voice = is_op = false;
/* The server itself always can send messages :-) */
if (Client_ThisServer() == From)
return true;
if (Channel_IsMemberOf(Chan, From)) {
is_member = true;
if (strchr(Channel_UserModes(Chan, From), 'v'))
has_voice = true;
if (strchr(Channel_UserModes(Chan, From), 'o'))
is_op = true;
}
/*
* Is the client allowed to write to channel?
*
* If channel mode n set: non-members cannot send to channel.
* If channel mode m set: need voice.
*/
if (strchr(Channel_Modes(Chan), 'n') && !is_member)
return false;
if (is_op || has_voice)
return true;
if (strchr(Channel_Modes(Chan), 'm'))
return false;
return !Lists_Check(&Chan->list_bans, From);
}
GLOBAL bool GLOBAL bool
Channel_Write(CHANNEL *Chan, CLIENT *From, CLIENT *Client, const char *Command, Channel_Write( CHANNEL *Chan, CLIENT *From, CLIENT *Client, char *Text )
bool SendErrors, const char *Text)
{ {
if (!Can_Send_To_Channel(Chan, From)) { bool is_member, has_voice, is_op, ok;
if (! SendErrors)
return CONNECTED; /* no error, see RFC 2812 */ /* Okay, target is a channel */
return IRC_WriteStrClient(From, ERR_CANNOTSENDTOCHAN_MSG, is_member = has_voice = is_op = false;
Client_ID(From), Channel_Name(Chan)); if( Channel_IsMemberOf( Chan, From ))
{
is_member = true;
if( strchr( Channel_UserModes( Chan, From ), 'v' )) has_voice = true;
if( strchr( Channel_UserModes( Chan, From ), 'o' )) is_op = true;
} }
if (Client_Conn(From) > NONE) /* Is the client allowed to write to channel? */
Conn_UpdateIdle(Client_Conn(From)); ok = true;
if( strchr( Channel_Modes( Chan ), 'n' ) && ( ! is_member )) ok = false;
if( strchr( Channel_Modes( Chan ), 'm' ) && ( ! is_op ) && ( ! has_voice )) ok = false;
return IRC_WriteStrChannelPrefix(Client, Chan, From, true, /* Is the client banned? */
"%s %s :%s", Command, Channel_Name(Chan), Text); if( Lists_Check(&Chan->list_bans, From))
{
/* Client is banned, but is he channel operator or has voice? */
if(( ! has_voice ) && ( ! is_op )) ok = false;
} }
if( ! ok ) return IRC_WriteStrClient( From, ERR_CANNOTSENDTOCHAN_MSG, Client_ID( From ), Channel_Name( Chan ));
/* Send text */
if( Client_Conn( From ) > NONE ) Conn_UpdateIdle( Client_Conn( From ));
return IRC_WriteStrChannelPrefix( Client, Chan, From, true, "PRIVMSG %s :%s", Channel_Name( Chan ), Text );
} /* Channel_Write */
GLOBAL CHANNEL * GLOBAL CHANNEL *
Channel_Create( const char *Name ) Channel_Create( char *Name )
{ {
/* Create new CHANNEL structure and add it to linked list */ /* Create new CHANNEL structure and add it to linked list */
CHANNEL *c; CHANNEL *c;
@@ -868,7 +779,7 @@ Add_Client( CHANNEL *Chan, CLIENT *Client )
assert( Chan != NULL ); assert( Chan != NULL );
assert( Client != NULL ); assert( Client != NULL );
/* Create new CL2CHAN structure */ /* neue CL2CHAN-Struktur anlegen */
cl2chan = (CL2CHAN *)malloc( sizeof( CL2CHAN )); cl2chan = (CL2CHAN *)malloc( sizeof( CL2CHAN ));
if( ! cl2chan ) if( ! cl2chan )
{ {
@@ -879,18 +790,18 @@ Add_Client( CHANNEL *Chan, CLIENT *Client )
cl2chan->client = Client; cl2chan->client = Client;
strcpy( cl2chan->modes, "" ); strcpy( cl2chan->modes, "" );
/* concatenate */ /* Verketten */
cl2chan->next = My_Cl2Chan; cl2chan->next = My_Cl2Chan;
My_Cl2Chan = cl2chan; My_Cl2Chan = cl2chan;
LogDebug("User \"%s\" joined channel \"%s\".", Client_Mask(Client), Chan->name); Log( LOG_DEBUG, "User \"%s\" joined channel \"%s\".", Client_Mask( Client ), Chan->name );
return cl2chan; return cl2chan;
} /* Add_Client */ } /* Add_Client */
static bool static bool
Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const char *Reason, bool InformServer ) Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, char *Reason, bool InformServer )
{ {
CL2CHAN *cl2chan, *last_cl2chan; CL2CHAN *cl2chan, *last_cl2chan;
CHANNEL *c; CHANNEL *c;
@@ -900,11 +811,6 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch
assert( Origin != NULL ); assert( Origin != NULL );
assert( Reason != NULL ); assert( Reason != NULL );
/* Do not inform other servers if the channel is local to this server,
* regardless of what the caller requested! */
if(InformServer)
InformServer = !Channel_IsLocal(Chan);
last_cl2chan = NULL; last_cl2chan = NULL;
cl2chan = My_Cl2Chan; cl2chan = My_Cl2Chan;
while( cl2chan ) while( cl2chan )
@@ -918,7 +824,7 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch
c = cl2chan->channel; c = cl2chan->channel;
assert( c != NULL ); assert( c != NULL );
/* maintain cl2chan list */ /* Aus Verkettung loesen und freigeben */
if( last_cl2chan ) last_cl2chan->next = cl2chan->next; if( last_cl2chan ) last_cl2chan->next = cl2chan->next;
else My_Cl2Chan = cl2chan->next; else My_Cl2Chan = cl2chan->next;
free( cl2chan ); free( cl2chan );
@@ -926,16 +832,14 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch
switch( Type ) switch( Type )
{ {
case REMOVE_QUIT: case REMOVE_QUIT:
/* QUIT: other servers have already been notified, /* QUIT: other servers have already been notified, see Client_Destroy();
* see Client_Destroy(); so only inform other clients * so only inform other clients in same channel. */
* in same channel. */
assert( InformServer == false ); assert( InformServer == false );
LogDebug("User \"%s\" left channel \"%s\" (%s).", LogDebug("User \"%s\" left channel \"%s\" (%s).",
Client_Mask( Client ), c->name, Reason ); Client_Mask( Client ), c->name, Reason );
break; break;
case REMOVE_KICK: case REMOVE_KICK:
/* User was KICKed: inform other servers (public /* User was KICKed: inform other servers and all users in channel */
* channels) and all users in the channel */
if( InformServer ) if( InformServer )
IRC_WriteStrServersPrefix( Client_NextHop( Origin ), IRC_WriteStrServersPrefix( Client_NextHop( Origin ),
Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason); Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason);
@@ -947,7 +851,7 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch
IRC_WriteStrClientPrefix(Client, Origin, "KICK %s %s :%s", IRC_WriteStrClientPrefix(Client, Origin, "KICK %s %s :%s",
c->name, Client_ID( Client ), Reason); c->name, Client_ID( Client ), Reason);
} }
LogDebug("User \"%s\" has been kicked off \"%s\" by \"%s\": %s.", LogDebug("User \"%s\" has been kicked of \"%s\" by \"%s\": %s.",
Client_Mask( Client ), c->name, Client_ID(Origin), Reason); Client_Mask( Client ), c->name, Client_ID(Origin), Reason);
break; break;
default: /* PART */ default: /* PART */
@@ -966,7 +870,7 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch
} }
} }
/* When channel is empty and is not pre-defined, delete */ /* Wenn Channel nun leer und nicht pre-defined: loeschen */
if( ! strchr( Channel_Modes( Chan ), 'P' )) if( ! strchr( Channel_Modes( Chan ), 'P' ))
{ {
if( ! Get_First_Cl2Chan( NULL, Chan )) Delete_Channel( Chan ); if( ! Get_First_Cl2Chan( NULL, Chan )) Delete_Channel( Chan );
@@ -1038,76 +942,6 @@ Channel_ShowInvites( CLIENT *Client, CHANNEL *Channel )
} }
/**
* Log a message to the local &SERVER channel, if it exists.
*/
GLOBAL void
Channel_LogServer(const char *msg)
{
CHANNEL *sc;
CLIENT *c;
assert(msg != NULL);
sc = Channel_Search("&SERVER");
if (!sc)
return;
c = Client_ThisServer();
Channel_Write(sc, c, c, "PRIVMSG", false, msg);
} /* Channel_LogServer */
GLOBAL bool
Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const char *Key)
{
char *file_name, line[COMMAND_LEN], *nick, *pass;
FILE *fd;
assert(Chan != NULL);
assert(Client != NULL);
assert(Key != NULL);
if (!strchr(Chan->modes, 'k'))
return true;
if (strcmp(Chan->key, Key) == 0)
return true;
if (*Key == '\0')
return false;
file_name = array_start(&Chan->keyfile);
if (!file_name)
return false;
fd = fopen(file_name, "r");
if (!fd) {
Log(LOG_ERR, "Can't open channel key file \"%s\" for %s: %s",
file_name, Chan->name, strerror(errno));
return false;
}
while (fgets(line, (int)sizeof(line), fd) != NULL) {
ngt_TrimStr(line);
if (! (nick = strchr(line, ':')))
continue;
*nick++ = '\0';
if (!Match(line, Client_User(Client)))
continue;
if (! (pass = strchr(nick, ':')))
continue;
*pass++ = '\0';
if (!Match(nick, Client_ID(Client)))
continue;
if (strcmp(Key, pass) != 0)
continue;
fclose(fd);
return true;
}
fclose(fd);
return false;
} /* Channel_CheckKey */
static CL2CHAN * static CL2CHAN *
Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan ) Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan )
{ {
@@ -1133,64 +967,36 @@ Get_Next_Cl2Chan( CL2CHAN *Start, CLIENT *Client, CHANNEL *Channel )
} /* Get_Next_Cl2Chan */ } /* Get_Next_Cl2Chan */
/** static bool
* Remove a channel and free all of its data structures.
*/
static void
Delete_Channel( CHANNEL *Chan ) Delete_Channel( CHANNEL *Chan )
{ {
/* Channel-Struktur loeschen */
CHANNEL *chan, *last_chan; CHANNEL *chan, *last_chan;
last_chan = NULL; last_chan = NULL;
chan = My_Channels; chan = My_Channels;
while (chan) { while( chan )
if (chan == Chan) {
break; if( chan == Chan ) break;
last_chan = chan; last_chan = chan;
chan = chan->next; chan = chan->next;
} }
if( ! chan ) return false;
assert(chan != NULL); Log( LOG_DEBUG, "Freed channel structure for \"%s\".", Chan->name );
if (!chan)
return;
/* maintain channel list */ /* Invite- und Ban-Lists aufraeumen */
if (last_chan) Lists_Free( &chan->list_bans );
last_chan->next = chan->next; Lists_Free( &chan->list_invites );
else
My_Channels = chan->next;
LogDebug("Freed channel structure for \"%s\".", Chan->name); /* Neu verketten und freigeben */
Free_Channel(Chan); if( last_chan ) last_chan->next = chan->next;
else My_Channels = chan->next;
free( chan );
return true;
} /* Delete_Channel */ } /* Delete_Channel */
static void
Set_KeyFile(CHANNEL *Chan, const char *KeyFile)
{
size_t len;
assert(Chan != NULL);
assert(KeyFile != NULL);
len = strlen(KeyFile);
if (len < array_bytes(&Chan->keyfile)) {
Log(LOG_INFO, "Channel key file of %s removed.", Chan->name);
array_free(&Chan->keyfile);
}
if (len < 1)
return;
if (!array_copyb(&Chan->keyfile, KeyFile, len+1))
Log(LOG_WARNING,
"Could not set new channel key file \"%s\" for %s: %s",
KeyFile, Chan->name, strerror(errno));
else
Log(LOG_INFO|LOG_snotice,
"New local channel key file \"%s\" for %s activated.",
KeyFile, Chan->name);
} /* Set_KeyFile */
/* -eof- */ /* -eof- */

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 by Alexander Barton (alex@barton.de) * Copyright (c)2001,2002 by 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,6 +8,8 @@
* (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.33 2006/12/07 22:23:39 fw Exp $
*
* Channel management (header) * Channel management (header)
*/ */
@@ -37,7 +39,6 @@ typedef struct _CHANNEL
unsigned 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_bans; /* list head of banned users */
struct list_head list_invites; /* list head of invited users */ struct list_head list_invites; /* list head of invited users */
array keyfile; /* Name of the channel key file */
} CHANNEL; } CHANNEL;
typedef struct _CLIENT2CHAN typedef struct _CLIENT2CHAN
@@ -45,7 +46,7 @@ typedef struct _CLIENT2CHAN
struct _CLIENT2CHAN *next; struct _CLIENT2CHAN *next;
CLIENT *client; CLIENT *client;
CHANNEL *channel; CHANNEL *channel;
char modes[CHANNEL_MODE_LEN]; /* User-Modes in Channel */ char modes[CHANNEL_MODE_LEN]; /* User-Modes in dem Channel */
} CL2CHAN; } CL2CHAN;
#else #else
@@ -62,13 +63,12 @@ GLOBAL void Channel_Init PARAMS(( void ));
GLOBAL void Channel_InitPredefined PARAMS(( void )); GLOBAL void Channel_InitPredefined PARAMS(( void ));
GLOBAL void Channel_Exit PARAMS(( void )); GLOBAL void Channel_Exit PARAMS(( void ));
GLOBAL bool Channel_Join PARAMS(( CLIENT *Client, const char *Name )); GLOBAL bool Channel_Join PARAMS(( CLIENT *Client, char *Name ));
GLOBAL bool Channel_Part PARAMS(( CLIENT *Client, CLIENT *Origin, const char *Name, const char *Reason )); GLOBAL bool Channel_Part PARAMS(( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason ));
GLOBAL void Channel_Quit PARAMS(( CLIENT *Client, const char *Reason )); GLOBAL void Channel_Quit PARAMS(( CLIENT *Client, char *Reason ));
GLOBAL void Channel_Kick PARAMS((CLIENT *Peer, CLIENT *Target, CLIENT *Origin, GLOBAL void Channel_Kick PARAMS(( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason ));
const char *Name, const char *Reason));
GLOBAL unsigned long Channel_Count PARAMS(( void )); GLOBAL unsigned long Channel_Count PARAMS(( void ));
GLOBAL unsigned long Channel_MemberCount PARAMS(( CHANNEL *Chan )); GLOBAL unsigned long Channel_MemberCount PARAMS(( CHANNEL *Chan ));
@@ -80,12 +80,12 @@ GLOBAL char *Channel_Topic PARAMS(( CHANNEL *Chan ));
GLOBAL char *Channel_Key PARAMS(( CHANNEL *Chan )); GLOBAL char *Channel_Key PARAMS(( CHANNEL *Chan ));
GLOBAL unsigned long Channel_MaxUsers PARAMS(( CHANNEL *Chan )); GLOBAL unsigned long Channel_MaxUsers PARAMS(( CHANNEL *Chan ));
GLOBAL void Channel_SetTopic PARAMS(( CHANNEL *Chan, CLIENT *Client, const char *Topic )); GLOBAL void Channel_SetTopic PARAMS(( CHANNEL *Chan, CLIENT *Client, char *Topic ));
GLOBAL void Channel_SetModes PARAMS(( CHANNEL *Chan, const char *Modes )); GLOBAL void Channel_SetModes PARAMS(( CHANNEL *Chan, char *Modes ));
GLOBAL void Channel_SetKey PARAMS(( CHANNEL *Chan, const char *Key )); GLOBAL void Channel_SetKey PARAMS(( CHANNEL *Chan, char *Key ));
GLOBAL void Channel_SetMaxUsers PARAMS(( CHANNEL *Chan, unsigned long Count )); GLOBAL void Channel_SetMaxUsers PARAMS(( CHANNEL *Chan, unsigned long Count ));
GLOBAL CHANNEL *Channel_Search PARAMS(( const char *Name )); GLOBAL CHANNEL *Channel_Search PARAMS(( char *Name ));
GLOBAL CHANNEL *Channel_First PARAMS(( void )); GLOBAL CHANNEL *Channel_First PARAMS(( void ));
GLOBAL CHANNEL *Channel_Next PARAMS(( CHANNEL *Chan )); GLOBAL CHANNEL *Channel_Next PARAMS(( CHANNEL *Chan ));
@@ -109,11 +109,9 @@ GLOBAL char *Channel_UserModes PARAMS(( CHANNEL *Chan, CLIENT *Client ));
GLOBAL bool Channel_IsMemberOf PARAMS(( CHANNEL *Chan, CLIENT *Client )); GLOBAL bool Channel_IsMemberOf PARAMS(( CHANNEL *Chan, CLIENT *Client ));
GLOBAL bool Channel_Write PARAMS((CHANNEL *Chan, CLIENT *From, CLIENT *Client, GLOBAL bool Channel_Write PARAMS(( CHANNEL *Chan, CLIENT *From, CLIENT *Client, char *Text ));
const char *Command, bool SendErrors,
const char *Text));
GLOBAL CHANNEL *Channel_Create PARAMS(( const char *Name )); GLOBAL CHANNEL *Channel_Create PARAMS(( char *Name ));
#ifndef STRICT_RFC #ifndef STRICT_RFC
GLOBAL unsigned int Channel_TopicTime PARAMS(( CHANNEL *Chan )); GLOBAL unsigned int Channel_TopicTime PARAMS(( CHANNEL *Chan ));
@@ -125,15 +123,5 @@ GLOBAL bool Channel_AddBan PARAMS((CHANNEL *c, const char *Mask ));
GLOBAL bool Channel_ShowBans PARAMS((CLIENT *client, CHANNEL *c)); GLOBAL bool Channel_ShowBans PARAMS((CLIENT *client, CHANNEL *c));
GLOBAL bool Channel_ShowInvites PARAMS((CLIENT *client, CHANNEL *c)); GLOBAL bool Channel_ShowInvites PARAMS((CLIENT *client, CHANNEL *c));
GLOBAL void Channel_LogServer PARAMS((const char *msg));
GLOBAL bool Channel_CheckKey PARAMS((CHANNEL *Chan, CLIENT *Client,
const char *Key));
#define Channel_IsLocal(c) (Channel_Name(c)[0] == '&')
#define Channel_IsModeless(c) (Channel_Name(c)[0] == '+')
#endif #endif
/* -eof- */ /* -eof- */

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de) * Copyright (c)2001-2005 by 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,6 +17,8 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: client.c,v 1.97 2007/11/21 12:16:36 alex Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
#include <unistd.h> #include <unistd.h>
@@ -49,10 +51,10 @@
static CLIENT *This_Server, *My_Clients; static CLIENT *This_Server, *My_Clients;
static char GetID_Buffer[GETID_LEN];
static WHOWAS My_Whowas[MAX_WHOWAS]; static WHOWAS My_Whowas[MAX_WHOWAS];
static int Last_Whowas = -1; static int Last_Whowas = -1;
static long Max_Users, My_Max_Users;
static unsigned long Count PARAMS(( CLIENT_TYPE Type )); static unsigned long Count PARAMS(( CLIENT_TYPE Type ));
@@ -63,13 +65,11 @@ static void Generate_MyToken PARAMS(( CLIENT *Client ));
static void Adjust_Counters PARAMS(( CLIENT *Client )); static void Adjust_Counters PARAMS(( CLIENT *Client ));
static CLIENT *Init_New_Client PARAMS((CONN_ID Idx, CLIENT *Introducer, static CLIENT *Init_New_Client PARAMS((CONN_ID Idx, CLIENT *Introducer,
CLIENT *TopServer, int Type, const char *ID, CLIENT *TopServer, int Type, char *ID, char *User, char *Hostname,
const char *User, const char *Hostname, const char *Info, char *Info, int Hops, int Token, char *Modes, bool Idented));
int Hops, int Token, const char *Modes,
bool Idented));
static void Destroy_UserOrService PARAMS((CLIENT *Client,const char *Txt, const char *FwdMsg,
bool SendQuit)); long Max_Users = 0, My_Max_Users = 0;
GLOBAL void GLOBAL void
@@ -141,7 +141,7 @@ Client_ThisServer( void )
* @return New CLIENT structure. * @return New CLIENT structure.
*/ */
GLOBAL CLIENT * GLOBAL CLIENT *
Client_NewLocal(CONN_ID Idx, const char *Hostname, int Type, bool Idented) Client_NewLocal(CONN_ID Idx, char *Hostname, int Type, bool Idented)
{ {
return Init_New_Client(Idx, This_Server, NULL, Type, NULL, NULL, return Init_New_Client(Idx, This_Server, NULL, Type, NULL, NULL,
Hostname, NULL, 0, 0, NULL, Idented); Hostname, NULL, 0, 0, NULL, Idented);
@@ -153,8 +153,8 @@ Client_NewLocal(CONN_ID Idx, const char *Hostname, int Type, bool Idented)
* @return New CLIENT structure. * @return New CLIENT structure.
*/ */
GLOBAL CLIENT * GLOBAL CLIENT *
Client_NewRemoteServer(CLIENT *Introducer, const char *Hostname, CLIENT *TopServer, Client_NewRemoteServer(CLIENT *Introducer, char *Hostname, CLIENT *TopServer,
int Hops, int Token, const char *Info, bool Idented) int Hops, int Token, char *Info, bool Idented)
{ {
return Init_New_Client(NONE, Introducer, TopServer, CLIENT_SERVER, return Init_New_Client(NONE, Introducer, TopServer, CLIENT_SERVER,
Hostname, NULL, Hostname, Info, Hops, Token, NULL, Idented); Hostname, NULL, Hostname, Info, Hops, Token, NULL, Idented);
@@ -166,8 +166,8 @@ Client_NewRemoteServer(CLIENT *Introducer, const char *Hostname, CLIENT *TopServ
* @return New CLIENT structure. * @return New CLIENT structure.
*/ */
GLOBAL CLIENT * GLOBAL CLIENT *
Client_NewRemoteUser(CLIENT *Introducer, const char *Nick, int Hops, const char *User, Client_NewRemoteUser(CLIENT *Introducer, char *Nick, int Hops, char *User,
const char *Hostname, int Token, const char *Modes, const char *Info, bool Idented) char *Hostname, int Token, char *Modes, char *Info, bool Idented)
{ {
return Init_New_Client(NONE, Introducer, NULL, CLIENT_USER, Nick, return Init_New_Client(NONE, Introducer, NULL, CLIENT_USER, Nick,
User, Hostname, Info, Hops, Token, Modes, Idented); User, Hostname, Info, Hops, Token, Modes, Idented);
@@ -181,8 +181,8 @@ Client_NewRemoteUser(CLIENT *Introducer, const char *Nick, int Hops, const char
*/ */
static CLIENT * static CLIENT *
Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer,
int Type, const char *ID, const char *User, const char *Hostname, int Type, char *ID, char *User, char *Hostname, char *Info, int Hops,
const char *Info, int Hops, int Token, const char *Modes, bool Idented) int Token, char *Modes, bool Idented)
{ {
CLIENT *client; CLIENT *client;
@@ -191,35 +191,31 @@ Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer,
assert( Hostname != NULL ); assert( Hostname != NULL );
client = New_Client_Struct( ); client = New_Client_Struct( );
if (!client) if( ! client ) return NULL;
return NULL;
/* Initialisieren */
client->starttime = time(NULL); client->starttime = time(NULL);
client->conn_id = Idx; client->conn_id = Idx;
client->introducer = Introducer; client->introducer = Introducer;
client->topserver = TopServer; client->topserver = TopServer;
client->type = Type; client->type = Type;
if (ID) if( ID ) Client_SetID( client, ID );
Client_SetID(client, ID); if( User ) Client_SetUser( client, User, Idented );
if (User) if( Hostname ) Client_SetHostname( client, Hostname );
Client_SetUser(client, User, Idented); if( Info ) Client_SetInfo( client, Info );
if (Hostname)
Client_SetHostname(client, Hostname);
if (Info)
Client_SetInfo(client, Info);
client->hops = Hops; client->hops = Hops;
client->token = Token; client->token = Token;
if (Modes) if( Modes ) Client_SetModes( client, Modes );
Client_SetModes(client, Modes); if( Type == CLIENT_SERVER ) Generate_MyToken( client );
if (Type == CLIENT_SERVER)
Generate_MyToken(client);
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 */
client->next = (POINTER *)My_Clients; client->next = (POINTER *)My_Clients;
My_Clients = client; My_Clients = client;
/* Adjust counters */
Adjust_Counters( client ); Adjust_Counters( client );
return client; return client;
@@ -227,13 +223,12 @@ Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer,
GLOBAL void GLOBAL void
Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool SendQuit ) Client_Destroy( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit )
{ {
/* remove a client */ /* Client entfernen. */
CLIENT *last, *c; CLIENT *last, *c;
char msg[LINE_LEN]; char msg[LINE_LEN], *txt;
const char *txt;
assert( Client != NULL ); assert( Client != NULL );
@@ -241,7 +236,7 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen
else txt = FwdMsg; else txt = FwdMsg;
if( ! txt ) txt = "Reason unknown."; if( ! txt ) txt = "Reason unknown.";
/* netsplit message */ /* Netz-Split-Nachricht vorbereiten (noch nicht optimal) */
if( Client->type == CLIENT_SERVER ) { if( Client->type == CLIENT_SERVER ) {
strlcpy(msg, This_Server->id, sizeof (msg)); strlcpy(msg, This_Server->id, sizeof (msg));
strlcat(msg, " ", sizeof (msg)); strlcat(msg, " ", sizeof (msg));
@@ -254,16 +249,8 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen
{ {
if(( Client->type == CLIENT_SERVER ) && ( c->introducer == Client ) && ( c != Client )) if(( Client->type == CLIENT_SERVER ) && ( c->introducer == Client ) && ( c != Client ))
{ {
/* /* der Client, der geloescht wird ist ein Server. Der Client, den wir gerade
* The client that is about to be removed is a server, * pruefen, ist ein Child von diesem und muss daher auch entfernt werden */
* the client we are checking right now is a child of that
* server and thus has to be removed, too.
*
* Call Client_Destroy() recursively with the server as the
* new "object to be removed". This starts the cycle again, until
* all servers that are linked via the original server have been
* removed.
*/
Client_Destroy( c, NULL, msg, false ); Client_Destroy( c, NULL, msg, false );
last = NULL; last = NULL;
c = My_Clients; c = My_Clients;
@@ -271,12 +258,45 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen
} }
if( c == Client ) if( c == Client )
{ {
/* found the client: remove it */ /* Wir haben den Client gefunden: entfernen */
if( last ) last->next = c->next; if( last ) last->next = c->next;
else My_Clients = (CLIENT *)c->next; else My_Clients = (CLIENT *)c->next;
if(c->type == CLIENT_USER || c->type == CLIENT_SERVICE) if( c->type == CLIENT_USER )
Destroy_UserOrService(c, txt, FwdMsg, SendQuit); {
if( c->conn_id != NONE )
{
/* Ein lokaler User */
Log( LOG_NOTICE, "User \"%s\" unregistered (connection %d): %s", Client_Mask( c ), c->conn_id, txt );
if( SendQuit )
{
/* Alle andere Server informieren! */
if( FwdMsg ) IRC_WriteStrServersPrefix( NULL, c, "QUIT :%s", FwdMsg );
else IRC_WriteStrServersPrefix( NULL, c, "QUIT :" );
}
}
else
{
/* Remote User */
Log( LOG_DEBUG, "User \"%s\" unregistered: %s", Client_Mask( c ), txt );
if( SendQuit )
{
/* Andere Server informieren, ausser denen, die "in
* Richtung dem liegen", auf dem der User registriert
* ist. Von denen haben wir das QUIT ja wohl bekommen. */
if( FwdMsg ) IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "QUIT :%s", FwdMsg );
else IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "QUIT :" );
}
}
/* Unregister client from channels */
Channel_Quit( c, FwdMsg ? FwdMsg : c->id );
/* Register client in My_Whowas structure */
Client_RegisterWhowas( c );
}
else if( c->type == CLIENT_SERVER ) else if( c->type == CLIENT_SERVER )
{ {
if( c != This_Server ) if( c != This_Server )
@@ -285,7 +305,7 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen
else Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" unregistered: %s", c->id, txt ); else Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" unregistered: %s", c->id, txt );
} }
/* inform other servers */ /* andere Server informieren */
if( ! NGIRCd_SignalQuit ) if( ! NGIRCd_SignalQuit )
{ {
if( FwdMsg ) IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "SQUIT %s :%s", c->id, FwdMsg ); if( FwdMsg ) IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "SQUIT %s :%s", c->id, FwdMsg );
@@ -314,8 +334,10 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen
GLOBAL void GLOBAL void
Client_SetHostname( CLIENT *Client, const char *Hostname ) Client_SetHostname( CLIENT *Client, char *Hostname )
{ {
/* Hostname eines Clients setzen */
assert( Client != NULL ); assert( Client != NULL );
assert( Hostname != NULL ); assert( Hostname != NULL );
@@ -324,8 +346,10 @@ Client_SetHostname( CLIENT *Client, const char *Hostname )
GLOBAL void GLOBAL void
Client_SetID( CLIENT *Client, const char *ID ) Client_SetID( CLIENT *Client, char *ID )
{ {
/* Hostname eines Clients setzen, Hash-Wert berechnen */
assert( Client != NULL ); assert( Client != NULL );
assert( ID != NULL ); assert( ID != NULL );
@@ -337,16 +361,16 @@ Client_SetID( CLIENT *Client, const char *ID )
GLOBAL void GLOBAL void
Client_SetUser( CLIENT *Client, const char *User, bool Idented ) Client_SetUser( CLIENT *Client, char *User, bool Idented )
{ {
/* set clients username */ /* Username eines Clients setzen */
assert( Client != NULL ); assert( Client != NULL );
assert( User != NULL ); assert( User != NULL );
if (Idented) { if( Idented ) strlcpy( Client->user, User, sizeof( Client->user ));
strlcpy(Client->user, User, sizeof(Client->user)); else
} else { {
Client->user[0] = '~'; Client->user[0] = '~';
strlcpy( Client->user + 1, User, sizeof( Client->user ) - 1 ); strlcpy( Client->user + 1, User, sizeof( Client->user ) - 1 );
} }
@@ -354,9 +378,9 @@ Client_SetUser( CLIENT *Client, const char *User, bool Idented )
GLOBAL void GLOBAL void
Client_SetInfo( CLIENT *Client, const char *Info ) Client_SetInfo( CLIENT *Client, char *Info )
{ {
/* set client hostname */ /* Hostname eines Clients setzen */
assert( Client != NULL ); assert( Client != NULL );
assert( Info != NULL ); assert( Info != NULL );
@@ -366,8 +390,10 @@ Client_SetInfo( CLIENT *Client, const char *Info )
GLOBAL void GLOBAL void
Client_SetModes( CLIENT *Client, const char *Modes ) Client_SetModes( CLIENT *Client, char *Modes )
{ {
/* Modes eines Clients setzen */
assert( Client != NULL ); assert( Client != NULL );
assert( Modes != NULL ); assert( Modes != NULL );
@@ -376,8 +402,10 @@ Client_SetModes( CLIENT *Client, const char *Modes )
GLOBAL void GLOBAL void
Client_SetFlags( CLIENT *Client, const char *Flags ) Client_SetFlags( CLIENT *Client, char *Flags )
{ {
/* Flags eines Clients setzen */
assert( Client != NULL ); assert( Client != NULL );
assert( Flags != NULL ); assert( Flags != NULL );
@@ -386,9 +414,9 @@ Client_SetFlags( CLIENT *Client, const char *Flags )
GLOBAL void GLOBAL void
Client_SetPassword( CLIENT *Client, const char *Pwd ) Client_SetPassword( CLIENT *Client, char *Pwd )
{ {
/* set password sent by client */ /* Von einem Client geliefertes Passwort */
assert( Client != NULL ); assert( Client != NULL );
assert( Pwd != NULL ); assert( Pwd != NULL );
@@ -398,7 +426,7 @@ Client_SetPassword( CLIENT *Client, const char *Pwd )
GLOBAL void GLOBAL void
Client_SetAway( CLIENT *Client, const char *Txt ) Client_SetAway( CLIENT *Client, char *Txt )
{ {
/* Set AWAY reason of client */ /* Set AWAY reason of client */
@@ -406,8 +434,7 @@ Client_SetAway( CLIENT *Client, const char *Txt )
assert( Txt != NULL ); assert( Txt != NULL );
strlcpy( Client->away, Txt, sizeof( Client->away )); strlcpy( Client->away, Txt, sizeof( Client->away ));
LogDebug("%s \"%s\" is away: %s", Client_TypeText(Client), Log( LOG_DEBUG, "User \"%s\" is away: %s", Client_Mask( Client ), Txt );
Client_Mask(Client), Txt);
} /* Client_SetAway */ } /* Client_SetAway */
@@ -467,7 +494,9 @@ Client_ModeAdd( CLIENT *Client, char Mode )
assert( Client != NULL ); assert( Client != NULL );
x[0] = Mode; x[1] = '\0'; x[0] = Mode; x[1] = '\0';
if (!strchr( Client->modes, x[0])) { if( ! strchr( Client->modes, x[0] ))
{
/* Client hat den Mode noch nicht -> setzen */
strlcat( Client->modes, x, sizeof( Client->modes )); strlcat( Client->modes, x, sizeof( Client->modes ));
return true; return true;
} }
@@ -503,7 +532,7 @@ Client_ModeDel( CLIENT *Client, char Mode )
GLOBAL CLIENT * GLOBAL CLIENT *
Client_Search( const char *Nick ) Client_Search( char *Nick )
{ {
/* return Client-Structure that has the corresponding Nick. /* return Client-Structure that has the corresponding Nick.
* If none is found, return NULL. * If none is found, return NULL.
@@ -523,9 +552,13 @@ Client_Search( const char *Nick )
search_hash = Hash( search_id ); search_hash = Hash( search_id );
c = My_Clients; c = My_Clients;
while (c) { while( c )
if (c->hash == search_hash && strcasecmp(c->id, search_id) == 0) {
return c; if( c->hash == search_hash )
{
/* lt. Hash-Wert: Treffer! */
if( strcasecmp( c->id, search_id ) == 0 ) return c;
}
c = (CLIENT *)c->next; c = (CLIENT *)c->next;
} }
return NULL; return NULL;
@@ -545,10 +578,9 @@ Client_GetFromToken( CLIENT *Client, int Token )
assert( Token > 0 ); assert( Token > 0 );
c = My_Clients; c = My_Clients;
while (c) { while( c )
if ((c->type == CLIENT_SERVER) && (c->introducer == Client) && {
(c->token == Token)) if(( c->type == CLIENT_SERVER ) && ( c->introducer == Client ) && ( c->token == Token )) return c;
return c;
c = (CLIENT *)c->next; c = (CLIENT *)c->next;
} }
return NULL; return NULL;
@@ -681,14 +713,11 @@ Client_NextHop( CLIENT *Client )
} /* Client_NextHop */ } /* Client_NextHop */
/**
* return Client-ID ("client!user@host"), this ID is needed for e.g.
* prefixes. Returnes pointer to static buffer.
*/
GLOBAL char * GLOBAL char *
Client_Mask( CLIENT *Client ) Client_Mask( CLIENT *Client )
{ {
static char GetID_Buffer[GETID_LEN]; /* Client-"ID" liefern, wie sie z.B. fuer
* Prefixe benoetigt wird. */
assert( Client != NULL ); assert( Client != NULL );
@@ -726,6 +755,8 @@ Client_HasMode( CLIENT *Client, char Mode )
GLOBAL char * GLOBAL char *
Client_Away( CLIENT *Client ) Client_Away( CLIENT *Client )
{ {
/* AWAY-Text liefern */
assert( Client != NULL ); assert( Client != NULL );
return Client->away; return Client->away;
} /* Client_Away */ } /* Client_Away */
@@ -758,6 +789,8 @@ Client_CheckNick( CLIENT *Client, char *Nick )
GLOBAL bool GLOBAL bool
Client_CheckID( CLIENT *Client, char *ID ) Client_CheckID( CLIENT *Client, char *ID )
{ {
/* Nick ueberpruefen */
char str[COMMAND_LEN]; char str[COMMAND_LEN];
CLIENT *c; CLIENT *c;
@@ -765,21 +798,23 @@ Client_CheckID( CLIENT *Client, char *ID )
assert( Client->conn_id > NONE ); assert( Client->conn_id > NONE );
assert( ID != NULL ); assert( ID != NULL );
/* ID too long? */ /* Nick zu lang? */
if (strlen(ID) > CLIENT_ID_LEN) { if( strlen( ID ) > CLIENT_ID_LEN )
{
IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), ID ); IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), ID );
return false; return false;
} }
/* ID already in use? */ /* ID bereits vergeben? */
c = My_Clients; c = My_Clients;
while (c) { while( c )
if (strcasecmp(c->id, ID) == 0) { {
if( strcasecmp( c->id, ID ) == 0 )
{
/* die Server-ID gibt es bereits */
snprintf( str, sizeof( str ), "ID \"%s\" already registered", ID ); snprintf( str, sizeof( str ), "ID \"%s\" already registered", ID );
if (c->conn_id != NONE) if( Client->conn_id != c->conn_id ) Log( LOG_ERR, "%s (on connection %d)!", str, c->conn_id );
Log(LOG_ERR, "%s (on connection %d)!", str, c->conn_id); else Log( LOG_ERR, "%s (via network)!", str );
else
Log(LOG_ERR, "%s (via network)!", str);
Conn_Close( Client->conn_id, str, str, true); Conn_Close( Client->conn_id, str, str, true);
return false; return false;
} }
@@ -793,6 +828,8 @@ Client_CheckID( CLIENT *Client, char *ID )
GLOBAL CLIENT * GLOBAL CLIENT *
Client_First( void ) Client_First( void )
{ {
/* Ersten Client liefern. */
return My_Clients; return My_Clients;
} /* Client_First */ } /* Client_First */
@@ -800,6 +837,9 @@ Client_First( void )
GLOBAL CLIENT * GLOBAL CLIENT *
Client_Next( CLIENT *c ) Client_Next( CLIENT *c )
{ {
/* Naechsten Client liefern. Existiert keiner,
* so wird NULL geliefert. */
assert( c != NULL ); assert( c != NULL );
return (CLIENT *)c->next; return (CLIENT *)c->next;
} /* Client_Next */ } /* Client_Next */
@@ -1038,7 +1078,7 @@ Generate_MyToken( CLIENT *Client )
else c = (CLIENT *)c->next; else c = (CLIENT *)c->next;
} }
Client->mytoken = token; Client->mytoken = token;
LogDebug("Assigned token %d to server \"%s\".", token, Client->id); Log( LOG_DEBUG, "Assigned token %d to server \"%s\".", token, Client->id );
} /* Generate_MyToken */ } /* Generate_MyToken */
@@ -1104,71 +1144,4 @@ Client_RegisterWhowas( CLIENT *Client )
} /* Client_RegisterWhowas */ } /* Client_RegisterWhowas */
GLOBAL char *
Client_TypeText(CLIENT *Client)
{
assert(Client != NULL);
switch (Client_Type(Client)) {
case CLIENT_USER:
return "User";
break;
case CLIENT_SERVICE:
return "Service";
break;
case CLIENT_SERVER:
return "Server";
break;
default:
return "Client";
}
} /* Client_TypeText */
/**
* Destroy user or service client.
*/
static void
Destroy_UserOrService(CLIENT *Client, const char *Txt, const char *FwdMsg, bool SendQuit)
{
if(Client->conn_id != NONE) {
/* Local (directly connected) client */
Log(LOG_NOTICE,
"%s \"%s\" unregistered (connection %d): %s",
Client_TypeText(Client), Client_Mask(Client),
Client->conn_id, Txt);
if (SendQuit) {
/* Inforam all the other servers */
if (FwdMsg)
IRC_WriteStrServersPrefix(NULL,
Client, "QUIT :%s", FwdMsg );
else
IRC_WriteStrServersPrefix(NULL,
Client, "QUIT :");
}
} else {
/* Remote client */
LogDebug("%s \"%s\" unregistered: %s",
Client_TypeText(Client), Client_Mask(Client), Txt);
if(SendQuit) {
/* Inform all the other servers, but the ones in the
* direction we got the QUIT from */
if(FwdMsg)
IRC_WriteStrServersPrefix(Client_NextHop(Client),
Client, "QUIT :%s", FwdMsg );
else
IRC_WriteStrServersPrefix(Client_NextHop(Client),
Client, "QUIT :" );
}
}
/* Unregister client from channels */
Channel_Quit(Client, FwdMsg ? FwdMsg : Client->id);
/* Register client in My_Whowas structure */
Client_RegisterWhowas(Client);
} /* Destroy_UserOrService */
/* -eof- */ /* -eof- */

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de) * Copyright (c)2001,2002 by 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,12 +8,16 @@
* (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.46 2007/01/23 16:07:19 alex Exp $
*
* Client management (header) * Client management (header)
*/ */
#ifndef __client_h__ #ifndef __client_h__
#define __client_h__ #define __client_h__
#define CLIENT_UNKNOWN 1 /* connection of unknown type */ #define CLIENT_UNKNOWN 1 /* connection of unknown type */
#define CLIENT_GOTPASS 2 /* client did send PASS */ #define CLIENT_GOTPASS 2 /* client did send PASS */
#define CLIENT_GOTNICK 4 /* client did send NICK */ #define CLIENT_GOTNICK 4 /* client did send NICK */
@@ -22,7 +26,6 @@
#define CLIENT_SERVER 32 /* client is a server */ #define CLIENT_SERVER 32 /* client is a server */
#define CLIENT_SERVICE 64 /* client is a service */ #define CLIENT_SERVICE 64 /* client is a service */
#define CLIENT_UNKNOWNSERVER 128 /* unregistered server connection */ #define CLIENT_UNKNOWNSERVER 128 /* unregistered server connection */
#define CLIENT_GOTPASS_2813 256 /* client did send PASS, RFC 2813 style */
#define CLIENT_TYPE int #define CLIENT_TYPE int
@@ -72,17 +75,17 @@ typedef struct _WHOWAS
GLOBAL void Client_Init PARAMS(( void )); GLOBAL void Client_Init PARAMS(( void ));
GLOBAL void Client_Exit PARAMS(( void )); GLOBAL void Client_Exit PARAMS(( void ));
GLOBAL CLIENT *Client_NewLocal PARAMS(( CONN_ID Idx, const char *Hostname, int Type, bool Idented )); GLOBAL CLIENT *Client_NewLocal PARAMS(( CONN_ID Idx, char *Hostname, int Type, bool Idented ));
GLOBAL CLIENT *Client_NewRemoteServer PARAMS(( CLIENT *Introducer, const char *Hostname, CLIENT *TopServer, int Hops, int Token, const char *Info, bool Idented )); GLOBAL CLIENT *Client_NewRemoteServer PARAMS(( CLIENT *Introducer, char *Hostname, CLIENT *TopServer, int Hops, int Token, char *Info, bool Idented ));
GLOBAL CLIENT *Client_NewRemoteUser PARAMS(( CLIENT *Introducer, const char *Nick, int Hops, const char *User, const char *Hostname, int Token, const char *Modes, const 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, const char *LogMsg, const char *FwdMsg, bool SendQuit )); GLOBAL void Client_Destroy PARAMS(( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit ));
GLOBAL CLIENT *Client_ThisServer PARAMS(( void )); GLOBAL CLIENT *Client_ThisServer PARAMS(( void ));
GLOBAL CLIENT *Client_GetFromToken PARAMS(( CLIENT *Client, int Token )); GLOBAL CLIENT *Client_GetFromToken PARAMS(( CLIENT *Client, int Token ));
GLOBAL CLIENT *Client_Search PARAMS(( const char *ID )); GLOBAL CLIENT *Client_Search PARAMS(( char *ID ));
GLOBAL CLIENT *Client_First PARAMS(( void )); GLOBAL CLIENT *Client_First PARAMS(( void ));
GLOBAL CLIENT *Client_Next PARAMS(( CLIENT *c )); GLOBAL CLIENT *Client_Next PARAMS(( CLIENT *c ));
@@ -108,19 +111,19 @@ GLOBAL time_t Client_StartTime PARAMS(( CLIENT *Client ));
GLOBAL bool Client_HasMode PARAMS(( CLIENT *Client, char Mode )); GLOBAL bool Client_HasMode PARAMS(( CLIENT *Client, char Mode ));
GLOBAL void Client_SetHostname PARAMS(( CLIENT *Client, const char *Hostname )); GLOBAL void Client_SetHostname PARAMS(( CLIENT *Client, char *Hostname ));
GLOBAL void Client_SetID PARAMS(( CLIENT *Client, const char *Nick )); GLOBAL void Client_SetID PARAMS(( CLIENT *Client, char *Nick ));
GLOBAL void Client_SetUser PARAMS(( CLIENT *Client, const char *User, bool Idented )); GLOBAL void Client_SetUser PARAMS(( CLIENT *Client, char *User, bool Idented ));
GLOBAL void Client_SetInfo PARAMS(( CLIENT *Client, const char *Info )); GLOBAL void Client_SetInfo PARAMS(( CLIENT *Client, char *Info ));
GLOBAL void Client_SetPassword PARAMS(( CLIENT *Client, const char *Pwd )); GLOBAL void Client_SetPassword PARAMS(( CLIENT *Client, char *Pwd ));
GLOBAL void Client_SetType PARAMS(( CLIENT *Client, int Type )); GLOBAL void Client_SetType PARAMS(( CLIENT *Client, int Type ));
GLOBAL void Client_SetHops PARAMS(( CLIENT *Client, int Hops )); GLOBAL void Client_SetHops PARAMS(( CLIENT *Client, int Hops ));
GLOBAL void Client_SetToken PARAMS(( CLIENT *Client, int Token )); GLOBAL void Client_SetToken PARAMS(( CLIENT *Client, int Token ));
GLOBAL void Client_SetOperByMe PARAMS(( CLIENT *Client, bool OperByMe )); GLOBAL void Client_SetOperByMe PARAMS(( CLIENT *Client, bool OperByMe ));
GLOBAL void Client_SetModes PARAMS(( CLIENT *Client, const char *Modes )); GLOBAL void Client_SetModes PARAMS(( CLIENT *Client, char *Modes ));
GLOBAL void Client_SetFlags PARAMS(( CLIENT *Client, const char *Flags )); GLOBAL void Client_SetFlags PARAMS(( CLIENT *Client, char *Flags ));
GLOBAL void Client_SetIntroducer PARAMS(( CLIENT *Client, CLIENT *Introducer )); GLOBAL void Client_SetIntroducer PARAMS(( CLIENT *Client, CLIENT *Introducer ));
GLOBAL void Client_SetAway PARAMS(( CLIENT *Client, const char *Txt )); GLOBAL void Client_SetAway PARAMS(( CLIENT *Client, char *Txt ));
GLOBAL bool Client_ModeAdd PARAMS(( CLIENT *Client, char Mode )); GLOBAL bool Client_ModeAdd PARAMS(( CLIENT *Client, char Mode ));
GLOBAL bool Client_ModeDel PARAMS(( CLIENT *Client, char Mode )); GLOBAL bool Client_ModeDel PARAMS(( CLIENT *Client, char Mode ));
@@ -146,8 +149,8 @@ GLOBAL int Client_GetLastWhowasIndex PARAMS(( void ));
GLOBAL void Client_RegisterWhowas PARAMS(( CLIENT *Client )); GLOBAL void Client_RegisterWhowas PARAMS(( CLIENT *Client ));
GLOBAL char * Client_TypeText PARAMS((CLIENT *Client));
#endif #endif
/* -eof- */ /* -eof- */

View File

@@ -1,47 +0,0 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* SSL defines.
*/
#ifndef conf_ssl_h
#define conf_ssl_h
#ifdef HAVE_LIBSSL
#define SSL_SUPPORT
#include <openssl/ssl.h>
#endif
#ifdef HAVE_LIBGNUTLS
#define SSL_SUPPORT
#include <gnutls/gnutls.h>
#ifndef LIBGNUTLS_VERSION_MAJOR
#define gnutls_certificate_credentials_t gnutls_certificate_credentials
#define gnutls_cipher_algorithm_t gnutls_cipher_algorithm
#define gnutls_datum_t gnutls_datum
#define gnutls_dh_params_t gnutls_dh_params
#define gnutls_session_t gnutls_session
#define gnutls_transport_ptr_t gnutls_transport_ptr
#endif
#endif
#ifdef SSL_SUPPORT
struct ConnSSL_State {
#ifdef HAVE_LIBSSL
SSL *ssl;
#endif
#ifdef HAVE_LIBGNUTLS
gnutls_session gnutls_session;
void *cookie; /* pointer to server configuration structure
(for outgoing connections), or NULL. */
#endif
};
bool
ConnSSL_InitLibrary(void);
#else
static inline bool
ConnSSL_InitLibrary(void) { return true; }
#endif /* SSL_SUPPORT */
#endif /* conf_ssl_h */
/* -eof- */

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de) * Copyright (c)2001,2002 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
@@ -14,6 +14,8 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: conf.c,v 1.103 2007/11/23 16:26:04 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
@@ -40,10 +42,8 @@
#include "ngircd.h" #include "ngircd.h"
#include "conn.h" #include "conn.h"
#include "client.h" #include "client.h"
#include "channel.h"
#include "defines.h" #include "defines.h"
#include "log.h" #include "log.h"
#include "match.h"
#include "resolve.h" #include "resolve.h"
#include "tool.h" #include "tool.h"
@@ -55,11 +55,10 @@ static bool Use_Log = true;
static CONF_SERVER New_Server; static CONF_SERVER New_Server;
static int New_Server_Idx; static int New_Server_Idx;
static size_t Conf_Oper_Count;
static size_t Conf_Channel_Count;
static void Set_Defaults PARAMS(( bool InitServers )); static void Set_Defaults PARAMS(( bool InitServers ));
static bool Read_Config PARAMS(( bool ngircd_starting )); static void Read_Config PARAMS(( void ));
static bool Validate_Config PARAMS(( bool TestOnly, bool Rehash )); static void Validate_Config PARAMS(( bool TestOnly, bool Rehash ));
static void Handle_GLOBAL PARAMS(( int Line, char *Var, char *Arg )); static void Handle_GLOBAL PARAMS(( int Line, char *Var, char *Arg ));
static void Handle_OPERATOR PARAMS(( int Line, char *Var, char *Arg )); static void Handle_OPERATOR PARAMS(( int Line, char *Var, char *Arg ));
@@ -73,71 +72,6 @@ static void Config_Error_TooLong PARAMS(( const int LINE, const char *Value ));
static void Init_Server_Struct PARAMS(( CONF_SERVER *Server )); static void Init_Server_Struct PARAMS(( CONF_SERVER *Server ));
#ifdef WANT_IPV6
#define DEFAULT_LISTEN_ADDRSTR "::,0.0.0.0"
#else
#define DEFAULT_LISTEN_ADDRSTR "0.0.0.0"
#endif
#ifdef SSL_SUPPORT
struct SSLOptions Conf_SSLOptions;
static void
ConfSSL_Init(void)
{
free(Conf_SSLOptions.KeyFile);
Conf_SSLOptions.KeyFile = NULL;
free(Conf_SSLOptions.CertFile);
Conf_SSLOptions.CertFile = NULL;
free(Conf_SSLOptions.DHFile);
Conf_SSLOptions.DHFile = NULL;
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
}
static bool
ssl_print_configvar(const char *name, const char *file)
{
FILE *fp;
if (!file) {
printf(" %s =\n", name);
return true;
}
fp = fopen(file, "r");
if (fp)
fclose(fp);
else
fprintf(stderr, "ERROR: %s \"%s\": %s\n",
name, file, strerror(errno));
printf(" %s = %s\n", name, file);
return fp != NULL;
}
static bool
ConfSSL_Puts(void)
{
bool ret;
ret = ssl_print_configvar("SSLKeyFile", Conf_SSLOptions.KeyFile);
if (!ssl_print_configvar("SSLCertFile", Conf_SSLOptions.CertFile))
ret = false;
if (!ssl_print_configvar("SSLDHFile", Conf_SSLOptions.DHFile))
ret = false;
if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
puts(" SSLKeyFilePassword = <secret>");
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
return ret;
}
#endif
static char * static char *
strdup_warn(const char *str) strdup_warn(const char *str)
@@ -181,7 +115,7 @@ ports_parse(array *a, int Line, char *Arg)
ptr = strtok( Arg, "," ); ptr = strtok( Arg, "," );
while (ptr) { while (ptr) {
ngt_TrimStr( ptr ); ngt_TrimStr( ptr );
port = atoi(ptr); port = atol( ptr );
if (port > 0 && port < 0xFFFF) { if (port > 0 && port < 0xFFFF) {
port16 = (UINT16) port; port16 = (UINT16) port;
if (!array_catb(a, (char*)&port16, sizeof port16)) if (!array_catb(a, (char*)&port16, sizeof port16))
@@ -200,68 +134,24 @@ ports_parse(array *a, int Line, char *Arg)
GLOBAL void GLOBAL void
Conf_Init( void ) Conf_Init( void )
{ {
Read_Config( true ); Set_Defaults( true );
Read_Config( );
Validate_Config(false, false); Validate_Config(false, false);
} /* Config_Init */ } /* Config_Init */
GLOBAL bool GLOBAL void
Conf_Rehash( void ) Conf_Rehash( void )
{ {
if (!Read_Config(false)) Set_Defaults( false );
return false; Read_Config( );
Validate_Config(false, true); Validate_Config(false, true);
/* Update CLIENT structure of local server */ /* Update CLIENT structure of local server */
Client_SetInfo(Client_ThisServer(), Conf_ServerInfo); Client_SetInfo(Client_ThisServer(), Conf_ServerInfo);
return true;
} /* Config_Rehash */ } /* Config_Rehash */
static const char*
yesno_to_str(int boolean_value)
{
if (boolean_value)
return "yes";
return "no";
}
static void
opers_free(void)
{
struct Conf_Oper *op;
size_t len;
len = array_length(&Conf_Opers, sizeof(*op));
op = array_start(&Conf_Opers);
while (len--) {
free(op->mask);
op++;
}
array_free(&Conf_Opers);
}
static void
opers_puts(void)
{
struct Conf_Oper *op;
size_t len;
len = array_length(&Conf_Opers, sizeof(*op));
op = array_start(&Conf_Opers);
while (len--) {
assert(op->name[0]);
puts("[OPERATOR]");
printf(" Name = %s\n", op->name);
printf(" Password = %s\n", op->pwd);
printf(" Mask = %s\n\n", op->mask ? op->mask : "");
op++;
}
}
GLOBAL int GLOBAL int
Conf_Test( void ) Conf_Test( void )
{ {
@@ -270,16 +160,13 @@ Conf_Test( void )
struct passwd *pwd; struct passwd *pwd;
struct group *grp; struct group *grp;
unsigned int i; unsigned int i;
bool config_valid; char *topic;
size_t predef_channel_count;
struct Conf_Channel *predef_chan;
Use_Log = false; Use_Log = false;
Set_Defaults( true );
if (! Read_Config(true)) Read_Config( );
return 1; Validate_Config(true, false);
config_valid = Validate_Config(true, false);
/* If stdin and stdout ("you can read our nice message and we can /* If stdin and stdout ("you can read our nice message and we can
* read in your keypress") are valid tty's, wait for a key: */ * read in your keypress") are valid tty's, wait for a key: */
@@ -294,7 +181,6 @@ Conf_Test( void )
printf( " Name = %s\n", Conf_ServerName ); printf( " Name = %s\n", Conf_ServerName );
printf( " Info = %s\n", Conf_ServerInfo ); printf( " Info = %s\n", Conf_ServerInfo );
printf( " Password = %s\n", Conf_ServerPwd ); printf( " Password = %s\n", Conf_ServerPwd );
printf(" WebircPassword = %s\n", Conf_WebircPwd);
printf( " AdminInfo1 = %s\n", Conf_ServerAdmin1 ); printf( " AdminInfo1 = %s\n", Conf_ServerAdmin1 );
printf( " AdminInfo2 = %s\n", Conf_ServerAdmin2 ); printf( " AdminInfo2 = %s\n", Conf_ServerAdmin2 );
printf( " AdminEMail = %s\n", Conf_ServerAdminMail ); printf( " AdminEMail = %s\n", Conf_ServerAdminMail );
@@ -302,46 +188,39 @@ Conf_Test( void )
printf( " MotdPhrase = %s\n", Conf_MotdPhrase ); printf( " MotdPhrase = %s\n", Conf_MotdPhrase );
printf( " ChrootDir = %s\n", Conf_Chroot ); printf( " ChrootDir = %s\n", Conf_Chroot );
printf( " PidFile = %s\n", Conf_PidFile); printf( " PidFile = %s\n", Conf_PidFile);
printf(" Listen = %s\n", Conf_ListenAddress);
fputs(" Ports = ", stdout); fputs(" Ports = ", stdout);
ports_puts(&Conf_ListenPorts);
#ifdef SSL_SUPPORT
fputs(" SSLPorts = ", stdout);
ports_puts(&Conf_SSLOptions.ListenPorts);
if (!ConfSSL_Puts())
config_valid = false;
#endif
ports_puts(&Conf_ListenPorts);
printf( " Listen = %s\n", Conf_ListenAddress );
pwd = getpwuid( Conf_UID ); pwd = getpwuid( Conf_UID );
if (pwd) if( pwd ) printf( " ServerUID = %s\n", pwd->pw_name );
printf(" ServerUID = %s\n", pwd->pw_name); else printf( " ServerUID = %ld\n", (long)Conf_UID );
else
printf(" ServerUID = %ld\n", (long)Conf_UID);
grp = getgrgid( Conf_GID ); grp = getgrgid( Conf_GID );
if (grp) if( grp ) printf( " ServerGID = %s\n", grp->gr_name );
printf(" ServerGID = %s\n", grp->gr_name); else printf( " ServerGID = %ld\n", (long)Conf_GID );
else
printf(" ServerGID = %ld\n", (long)Conf_GID);
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", yesno_to_str(Conf_OperCanMode)); printf( " OperCanUseMode = %s\n", Conf_OperCanMode == true ? "yes" : "no" );
printf(" OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode)); printf( " OperServerMode = %s\n", Conf_OperServerMode == true? "yes" : "no" );
printf(" AllowRemoteOper = %s\n", yesno_to_str(Conf_AllowRemoteOper)); printf( " PredefChannelsOnly = %s\n", Conf_PredefChannelsOnly == true ? "yes" : "no" );
printf(" PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly)); printf( " NoDNS = %s\n", Conf_NoDNS ? "yes" : "no");
printf(" NoDNS = %s\n", yesno_to_str(Conf_NoDNS));
printf(" NoIdent = %s\n", yesno_to_str(Conf_NoIdent));
#ifdef WANT_IPV6
printf(" ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
printf(" ConnectIPv6 = %s\n", yesno_to_str(Conf_ConnectIPv4));
#endif
printf( " MaxConnections = %ld\n", Conf_MaxConnections); printf( " MaxConnections = %ld\n", Conf_MaxConnections);
printf( " MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP); printf( " MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP);
printf( " MaxJoins = %d\n", Conf_MaxJoins>0 ? Conf_MaxJoins : -1); printf( " MaxJoins = %d\n", Conf_MaxJoins>0 ? Conf_MaxJoins : -1);
printf( " MaxNickLength = %u\n\n", Conf_MaxNickLength - 1); printf( " MaxNickLength = %u\n\n", Conf_MaxNickLength - 1);
opers_puts(); for( i = 0; i < Conf_Oper_Count; i++ ) {
if( ! Conf_Oper[i].name[0] ) continue;
/* Valid "Operator" section */
puts( "[OPERATOR]" );
printf( " Name = %s\n", Conf_Oper[i].name );
printf( " Password = %s\n", Conf_Oper[i].pwd );
if ( Conf_Oper[i].mask ) printf( " Mask = %s\n", Conf_Oper[i].mask );
puts( "" );
}
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;
@@ -351,34 +230,27 @@ Conf_Test( void )
printf( " Name = %s\n", Conf_Server[i].name ); printf( " Name = %s\n", Conf_Server[i].name );
printf( " Host = %s\n", Conf_Server[i].host ); printf( " Host = %s\n", Conf_Server[i].host );
printf( " Port = %u\n", (unsigned int)Conf_Server[i].port ); printf( " Port = %u\n", (unsigned int)Conf_Server[i].port );
#ifdef SSL_SUPPORT
printf( " SSLConnect = %s\n", Conf_Server[i].SSLConnect?"yes":"no");
#endif
printf( " MyPassword = %s\n", Conf_Server[i].pwd_in ); printf( " MyPassword = %s\n", Conf_Server[i].pwd_in );
printf( " PeerPassword = %s\n", Conf_Server[i].pwd_out ); printf( " PeerPassword = %s\n", Conf_Server[i].pwd_out );
printf( " ServiceMask = %s\n", Conf_Server[i].svs_mask);
printf( " Group = %d\n", Conf_Server[i].group ); printf( " Group = %d\n", Conf_Server[i].group );
printf( " Passive = %s\n\n", Conf_Server[i].flags & CONF_SFLAG_DISABLED ? "yes" : "no"); printf( " Passive = %s\n\n", Conf_Server[i].flags & CONF_SFLAG_DISABLED ? "yes" : "no");
} }
predef_channel_count = array_length(&Conf_Channels, sizeof(*predef_chan)); for( i = 0; i < Conf_Channel_Count; i++ ) {
predef_chan = array_start(&Conf_Channels); if( ! Conf_Channel[i].name[0] ) continue;
for (i = 0; i < predef_channel_count; i++, predef_chan++) {
if (!predef_chan->name[0])
continue;
/* Valid "Channel" section */ /* Valid "Channel" section */
puts( "[CHANNEL]" ); puts( "[CHANNEL]" );
printf(" Name = %s\n", predef_chan->name); printf( " Name = %s\n", Conf_Channel[i].name );
printf(" Modes = %s\n", predef_chan->modes); printf( " Modes = %s\n", Conf_Channel[i].modes );
printf(" Key = %s\n", predef_chan->key); printf( " Key = %s\n", Conf_Channel[i].key );
printf(" MaxUsers = %lu\n", predef_chan->maxusers); printf( " MaxUsers = %lu\n", Conf_Channel[i].maxusers );
printf(" Topic = %s\n", predef_chan->topic);
printf(" KeyFile = %s\n\n", predef_chan->keyfile); topic = (char*)array_start(&Conf_Channel[i].topic);
printf( " Topic = %s\n\n", topic ? topic : "");
} }
return (config_valid ? 0 : 1); return 0;
} /* Conf_Test */ } /* Conf_Test */
@@ -447,7 +319,7 @@ Conf_GetServer( CONN_ID Idx )
GLOBAL bool GLOBAL bool
Conf_EnableServer( const char *Name, UINT16 Port ) Conf_EnableServer( char *Name, UINT16 Port )
{ {
/* Enable specified server and adjust port */ /* Enable specified server and adjust port */
@@ -460,7 +332,7 @@ Conf_EnableServer( const char *Name, UINT16 Port )
/* Gotcha! Set port and enable server: */ /* Gotcha! Set port and enable server: */
Conf_Server[i].port = Port; Conf_Server[i].port = Port;
Conf_Server[i].flags &= ~CONF_SFLAG_DISABLED; Conf_Server[i].flags &= ~CONF_SFLAG_DISABLED;
return (Conf_Server[i].port && Conf_Server[i].host[0]); return true;
} }
} }
return false; return false;
@@ -486,7 +358,7 @@ Conf_EnablePassiveServer(const char *Name)
GLOBAL bool GLOBAL bool
Conf_DisableServer( const char *Name ) Conf_DisableServer( char *Name )
{ {
/* Enable specified server and adjust port */ /* Enable specified server and adjust port */
@@ -507,7 +379,7 @@ Conf_DisableServer( const char *Name )
GLOBAL bool GLOBAL bool
Conf_AddServer( const char *Name, UINT16 Port, const char *Host, const char *MyPwd, const char *PeerPwd ) Conf_AddServer( char *Name, UINT16 Port, char *Host, char *MyPwd, char *PeerPwd )
{ {
/* Add new server to configuration */ /* Add new server to configuration */
@@ -537,27 +409,15 @@ Conf_AddServer( const char *Name, UINT16 Port, const char *Host, const char *MyP
} /* Conf_AddServer */ } /* Conf_AddServer */
/**
* Check if the given nick name is an service
*/
GLOBAL bool
Conf_IsService(int ConfServer, const char *Nick)
{
return MatchCaseInsensitive(Conf_Server[ConfServer].svs_mask, Nick);
} /* Conf_IsService */
/**
* Initialize configuration settings with their default values.
*/
static void static void
Set_Defaults( bool InitServers ) Set_Defaults( bool InitServers )
{ {
/* Initialize configuration variables with default values. */
int i; int i;
strcpy( Conf_ServerName, "" ); strcpy( Conf_ServerName, "" );
snprintf(Conf_ServerInfo, sizeof Conf_ServerInfo, "%s %s", snprintf( Conf_ServerInfo, sizeof Conf_ServerInfo, "%s %s", PACKAGE_NAME, PACKAGE_VERSION );
PACKAGE_NAME, PACKAGE_VERSION);
strcpy( Conf_ServerPwd, "" ); strcpy( Conf_ServerPwd, "" );
strcpy( Conf_ServerAdmin1, "" ); strcpy( Conf_ServerAdmin1, "" );
@@ -566,31 +426,29 @@ Set_Defaults(bool InitServers)
strlcpy( Conf_MotdFile, SYSCONFDIR, sizeof( Conf_MotdFile )); strlcpy( Conf_MotdFile, SYSCONFDIR, sizeof( Conf_MotdFile ));
strlcat( Conf_MotdFile, MOTD_FILE, sizeof( Conf_MotdFile )); strlcat( Conf_MotdFile, MOTD_FILE, sizeof( Conf_MotdFile ));
strlcpy( Conf_MotdPhrase, MOTD_PHRASE, sizeof( Conf_MotdPhrase )); strlcpy( Conf_MotdPhrase, MOTD_PHRASE, sizeof( Conf_MotdPhrase ));
Conf_UID = Conf_GID = 0;
strlcpy( Conf_Chroot, CHROOT_DIR, sizeof( Conf_Chroot )); strlcpy( Conf_Chroot, CHROOT_DIR, sizeof( Conf_Chroot ));
strlcpy( Conf_PidFile, PID_FILE, sizeof( Conf_PidFile )); strlcpy( Conf_PidFile, PID_FILE, sizeof( Conf_PidFile ));
free(Conf_ListenAddress); strcpy( Conf_ListenAddress, "" );
Conf_ListenAddress = NULL;
Conf_UID = Conf_GID = 0;
Conf_PingTimeout = 120; Conf_PingTimeout = 120;
Conf_PongTimeout = 20; Conf_PongTimeout = 20;
Conf_ConnectRetry = 60; Conf_ConnectRetry = 60;
Conf_NoDNS = false;
Conf_NoIdent = false;
Conf_Oper_Count = 0; Conf_Oper_Count = 0;
Conf_Channel_Count = 0; Conf_Channel_Count = 0;
Conf_OperCanMode = false; Conf_OperCanMode = false;
Conf_OperServerMode = false; Conf_NoDNS = false;
Conf_AllowRemoteOper = false;
Conf_PredefChannelsOnly = false; Conf_PredefChannelsOnly = false;
Conf_OperServerMode = false;
Conf_ConnectIPv4 = true;
Conf_ConnectIPv6 = true;
Conf_MaxConnections = 0; Conf_MaxConnections = 0;
Conf_MaxConnectionsIP = 5; Conf_MaxConnectionsIP = 5;
@@ -598,25 +456,12 @@ Set_Defaults(bool InitServers)
Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT; Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
/* Initialize server configuration structures */ /* Initialize server configuration structures */
if (InitServers) { if( InitServers ) for( i = 0; i < MAX_SERVERS; Init_Server_Struct( &Conf_Server[i++] ));
for (i = 0; i < MAX_SERVERS;
Init_Server_Struct(&Conf_Server[i++]));
}
} /* Set_Defaults */ } /* Set_Defaults */
static bool static void
no_listenports(void) Read_Config( void )
{
size_t cnt = array_bytes(&Conf_ListenPorts);
#ifdef SSL_SUPPORT
cnt += array_bytes(&Conf_SSLOptions.ListenPorts);
#endif
return cnt == 0;
}
static bool
Read_Config( bool ngircd_starting )
{ {
/* Read configuration file. */ /* Read configuration file. */
@@ -631,15 +476,10 @@ Read_Config( bool ngircd_starting )
/* No configuration file found! */ /* No configuration file found! */
Config_Error( LOG_ALERT, "Can't read configuration \"%s\": %s", Config_Error( LOG_ALERT, "Can't read configuration \"%s\": %s",
NGIRCd_ConfFile, strerror( errno )); NGIRCd_ConfFile, strerror( errno ));
if (!ngircd_starting)
return false;
Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME ); Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME );
exit( 1 ); exit( 1 );
} }
opers_free();
Set_Defaults( ngircd_starting );
Config_Error( LOG_INFO, "Reading configuration from \"%s\" ...", NGIRCd_ConfFile ); Config_Error( LOG_INFO, "Reading configuration from \"%s\" ...", NGIRCd_ConfFile );
/* Clean up server configuration structure: mark all already /* Clean up server configuration structure: mark all already
@@ -678,9 +518,7 @@ Read_Config( bool ngircd_starting )
strcpy( section, "" ); strcpy( section, "" );
Init_Server_Struct( &New_Server ); Init_Server_Struct( &New_Server );
New_Server_Idx = NONE; New_Server_Idx = NONE;
#ifdef SSL_SUPPORT
ConfSSL_Init();
#endif
/* Read configuration file */ /* Read configuration file */
while( true ) { while( true ) {
if( ! fgets( str, LINE_LEN, fd )) break; if( ! fgets( str, LINE_LEN, fd )) break;
@@ -696,6 +534,21 @@ Read_Config( bool ngircd_starting )
if( strcasecmp( section, "[GLOBAL]" ) == 0 ) if( strcasecmp( section, "[GLOBAL]" ) == 0 )
continue; continue;
if( strcasecmp( section, "[OPERATOR]" ) == 0 ) {
if( Conf_Oper_Count + 1 > MAX_OPERATORS )
Config_Error( LOG_ERR, "Too many operators configured.");
else {
/* Initialize new operator structure */
Conf_Oper[Conf_Oper_Count].name[0] = '\0';
Conf_Oper[Conf_Oper_Count].pwd[0] = '\0';
if (Conf_Oper[Conf_Oper_Count].mask) {
free(Conf_Oper[Conf_Oper_Count].mask );
Conf_Oper[Conf_Oper_Count].mask = NULL;
}
Conf_Oper_Count++;
}
continue;
}
if( strcasecmp( section, "[SERVER]" ) == 0 ) { if( strcasecmp( section, "[SERVER]" ) == 0 ) {
/* Check if there is already a server to add */ /* Check if there is already a server to add */
if( New_Server.name[0] ) { if( New_Server.name[0] ) {
@@ -721,14 +574,19 @@ Read_Config( bool ngircd_starting )
continue; continue;
} }
if( strcasecmp( section, "[CHANNEL]" ) == 0 ) { if( strcasecmp( section, "[CHANNEL]" ) == 0 ) {
if( Conf_Channel_Count + 1 > MAX_DEFCHANNELS ) {
Config_Error( LOG_ERR, "Too many pre-defined channels configured." );
} else {
/* Initialize new channel structure */
strcpy( Conf_Channel[Conf_Channel_Count].name, "" );
strcpy( Conf_Channel[Conf_Channel_Count].modes, "" );
strcpy( Conf_Channel[Conf_Channel_Count].key, "" );
Conf_Channel[Conf_Channel_Count].maxusers = 0;
array_free(&Conf_Channel[Conf_Channel_Count].topic);
Conf_Channel_Count++; Conf_Channel_Count++;
}
continue; continue;
} }
if (strcasecmp(section, "[OPERATOR]") == 0) {
Conf_Oper_Count++;
continue;
}
Config_Error( LOG_ERR, "%s, line %d: Unknown section \"%s\"!", NGIRCd_ConfFile, line, section ); Config_Error( LOG_ERR, "%s, line %d: Unknown section \"%s\"!", NGIRCd_ConfFile, line, section );
section[0] = 0x1; section[0] = 0x1;
} }
@@ -761,24 +619,13 @@ Read_Config( bool ngircd_starting )
Conf_Server[New_Server_Idx] = New_Server; Conf_Server[New_Server_Idx] = New_Server;
} }
/* not a single listening port? Add default. */ if (0 == array_length(&Conf_ListenPorts, sizeof(UINT16))) {
if (no_listenports() && if (!array_copyb(&Conf_ListenPorts, (char*) &defaultport, sizeof defaultport)) {
!array_copyb(&Conf_ListenPorts, (char*) &defaultport, sizeof defaultport))
{
Config_Error( LOG_ALERT, "Could not add default listening Port %u: %s", Config_Error( LOG_ALERT, "Could not add default listening Port %u: %s",
(unsigned int) defaultport, strerror(errno)); (unsigned int) defaultport, strerror(errno));
exit( 1 ); exit( 1 );
} }
if (!Conf_ListenAddress)
Conf_ListenAddress = strdup_warn(DEFAULT_LISTEN_ADDRSTR);
if (!Conf_ListenAddress) {
Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME);
exit(1);
} }
return true;
} /* Read_Config */ } /* Read_Config */
@@ -846,13 +693,6 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
Config_Error_TooLong( Line, Var ); Config_Error_TooLong( Line, Var );
return; return;
} }
if (strcasecmp(Var, "WebircPassword") == 0) {
/* Password required for WEBIRC command */
len = strlcpy(Conf_WebircPwd, Arg, sizeof(Conf_WebircPwd));
if (len >= sizeof(Conf_WebircPwd))
Config_Error_TooLong(Line, Var);
return;
}
if( strcasecmp( Var, "AdminInfo1" ) == 0 ) { if( strcasecmp( Var, "AdminInfo1" ) == 0 ) {
/* Administrative info #1 */ /* Administrative info #1 */
len = strlcpy( Conf_ServerAdmin1, Arg, sizeof( Conf_ServerAdmin1 )); len = strlcpy( Conf_ServerAdmin1, Arg, sizeof( Conf_ServerAdmin1 ));
@@ -973,33 +813,6 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
Conf_NoDNS = Check_ArgIsTrue( Arg ); Conf_NoDNS = Check_ArgIsTrue( Arg );
return; return;
} }
if (strcasecmp(Var, "NoIdent") == 0) {
/* don't do IDENT lookups when clients connect? */
Conf_NoIdent = Check_ArgIsTrue(Arg);
#ifndef IDENTAUTH
if (!Conf_NoIdent) {
/* user has enabled ident lookups explicitly, but ... */
Config_Error(LOG_WARNING,
"%s: line %d: NoIdent=False, but ngircd was built without IDENT support",
NGIRCd_ConfFile, Line);
}
#endif
return;
}
#ifdef WANT_IPV6
/* the default setting for all the WANT_IPV6 special options is 'true' */
if( strcasecmp( Var, "ConnectIPv6" ) == 0 ) {
/* connect to other hosts using ipv6, if they have an AAAA record? */
Conf_ConnectIPv6 = Check_ArgIsTrue( Arg );
return;
}
if( strcasecmp( Var, "ConnectIPv4" ) == 0 ) {
/* connect to other hosts using ipv4.
* again, this can be used for ipv6-only setups */
Conf_ConnectIPv4 = Check_ArgIsTrue( Arg );
return;
}
#endif
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 );
@@ -1010,11 +823,6 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
Conf_OperServerMode = Check_ArgIsTrue( Arg ); Conf_OperServerMode = Check_ArgIsTrue( Arg );
return; return;
} }
if(strcasecmp(Var, "AllowRemoteOper") == 0) {
/* Are remote IRC operators allowed to control this server? */
Conf_AllowRemoteOper = Check_ArgIsTrue(Arg);
return;
}
if( strcasecmp( Var, "MaxConnections" ) == 0 ) { if( strcasecmp( Var, "MaxConnections" ) == 0 ) {
/* Maximum number of connections. 0 -> "no limit". */ /* Maximum number of connections. 0 -> "no limit". */
#ifdef HAVE_ISDIGIT #ifdef HAVE_ISDIGIT
@@ -1051,53 +859,12 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
if( strcasecmp( Var, "Listen" ) == 0 ) { if( strcasecmp( Var, "Listen" ) == 0 ) {
/* IP-Address to bind sockets */ /* IP-Address to bind sockets */
if (Conf_ListenAddress) { len = strlcpy( Conf_ListenAddress, Arg, sizeof( Conf_ListenAddress ));
Config_Error(LOG_ERR, "Multiple Listen= options, ignoring: %s", Arg); if (len >= sizeof( Conf_ListenAddress ))
return; Config_Error_TooLong( Line, Var );
}
Conf_ListenAddress = strdup_warn(Arg);
/*
* if allocation fails, we're in trouble:
* we cannot ignore the error -- otherwise ngircd
* would listen on all interfaces.
*/
if (!Conf_ListenAddress) {
Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME);
exit(1);
}
return; return;
} }
#ifdef SSL_SUPPORT
if( strcasecmp( Var, "SSLPorts" ) == 0 ) {
ports_parse(&Conf_SSLOptions.ListenPorts, Line, Arg);
return;
}
if( strcasecmp( Var, "SSLKeyFile" ) == 0 ) {
assert(Conf_SSLOptions.KeyFile == NULL );
Conf_SSLOptions.KeyFile = strdup_warn(Arg);
return;
}
if( strcasecmp( Var, "SSLCertFile" ) == 0 ) {
assert(Conf_SSLOptions.CertFile == NULL );
Conf_SSLOptions.CertFile = strdup_warn(Arg);
return;
}
if( strcasecmp( Var, "SSLKeyFilePassword" ) == 0 ) {
assert(array_bytes(&Conf_SSLOptions.KeyFilePassword) == 0);
if (!array_copys(&Conf_SSLOptions.KeyFilePassword, Arg))
Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Could not copy %s: %s!",
NGIRCd_ConfFile, Line, Var, strerror(errno));
return;
}
if( strcasecmp( Var, "SSLDHFile" ) == 0 ) {
assert(Conf_SSLOptions.DHFile == NULL);
Conf_SSLOptions.DHFile = strdup_warn( Arg );
return;
}
#endif
Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!",
NGIRCd_ConfFile, Line, Var ); NGIRCd_ConfFile, Line, Var );
} /* Handle_GLOBAL */ } /* Handle_GLOBAL */
@@ -1106,38 +873,36 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
static void static void
Handle_OPERATOR( int Line, char *Var, char *Arg ) Handle_OPERATOR( int Line, char *Var, char *Arg )
{ {
unsigned int opercount;
size_t len; size_t len;
struct Conf_Oper *op;
assert( Line > 0 ); assert( Line > 0 );
assert( Var != NULL ); assert( Var != NULL );
assert( Arg != NULL ); assert( Arg != NULL );
assert( Conf_Oper_Count > 0 ); assert( Conf_Oper_Count > 0 );
op = array_alloc(&Conf_Opers, sizeof(*op), Conf_Oper_Count - 1); if ( Conf_Oper_Count == 0 )
if (!op) {
Config_Error(LOG_ERR, "Could not allocate memory for operator (%d:%s = %s)", Line, Var, Arg);
return; return;
}
opercount = Conf_Oper_Count - 1;
if( strcasecmp( Var, "Name" ) == 0 ) { if( strcasecmp( Var, "Name" ) == 0 ) {
/* Name of IRC operator */ /* Name of IRC operator */
len = strlcpy(op->name, Arg, sizeof(op->name)); len = strlcpy( Conf_Oper[opercount].name, Arg, sizeof( Conf_Oper[opercount].name ));
if (len >= sizeof(op->name)) if (len >= sizeof( Conf_Oper[opercount].name ))
Config_Error_TooLong( Line, Var ); Config_Error_TooLong( Line, Var );
return; return;
} }
if( strcasecmp( Var, "Password" ) == 0 ) { if( strcasecmp( Var, "Password" ) == 0 ) {
/* Password of IRC operator */ /* Password of IRC operator */
len = strlcpy(op->pwd, Arg, sizeof(op->pwd)); len = strlcpy( Conf_Oper[opercount].pwd, Arg, sizeof( Conf_Oper[opercount].pwd ));
if (len >= sizeof(op->pwd)) if (len >= sizeof( Conf_Oper[opercount].pwd ))
Config_Error_TooLong( Line, Var ); Config_Error_TooLong( Line, Var );
return; return;
} }
if( strcasecmp( Var, "Mask" ) == 0 ) { if( strcasecmp( Var, "Mask" ) == 0 ) {
if (op->mask) if (Conf_Oper[opercount].mask) return; /* Hostname already configured */
return; /* Hostname already configured */
op->mask = strdup_warn( Arg ); Conf_Oper[opercount].mask = strdup_warn( Arg );
return; return;
} }
Config_Error( LOG_ERR, "%s, line %d (section \"Operator\"): Unknown variable \"%s\"!", Config_Error( LOG_ERR, "%s, line %d (section \"Operator\"): Unknown variable \"%s\"!",
@@ -1173,7 +938,7 @@ Handle_SERVER( int Line, char *Var, char *Arg )
return; return;
} }
if (strcasecmp(Var, "Bind") == 0) { if (strcasecmp(Var, "Bind") == 0) {
if (ng_ipaddr_init(&New_Server.bind_addr, Arg, 0)) if (ngt_IPStrToBin(Arg, &New_Server.bind_addr))
return; return;
Config_Error(LOG_ERR, "%s, line %d (section \"Server\"): Can't parse IP address \"%s\"", Config_Error(LOG_ERR, "%s, line %d (section \"Server\"): Can't parse IP address \"%s\"",
@@ -1209,12 +974,6 @@ Handle_SERVER( int Line, char *Var, char *Arg )
NGIRCd_ConfFile, Line, port ); NGIRCd_ConfFile, Line, port );
return; return;
} }
#ifdef SSL_SUPPORT
if( strcasecmp( Var, "SSLConnect" ) == 0 ) {
New_Server.SSLConnect = Check_ArgIsTrue(Arg);
return;
}
#endif
if( strcasecmp( Var, "Group" ) == 0 ) { if( strcasecmp( Var, "Group" ) == 0 ) {
/* Server group */ /* Server group */
#ifdef HAVE_ISDIGIT #ifdef HAVE_ISDIGIT
@@ -1230,13 +989,6 @@ Handle_SERVER( int Line, char *Var, char *Arg )
New_Server.flags |= CONF_SFLAG_DISABLED; New_Server.flags |= CONF_SFLAG_DISABLED;
return; return;
} }
if (strcasecmp(Var, "ServiceMask") == 0) {
len = strlcpy(New_Server.svs_mask, ngt_LowerStr(Arg),
sizeof(New_Server.svs_mask));
if (len >= sizeof(New_Server.svs_mask))
Config_Error_TooLong(Line, Var);
return;
}
Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Unknown variable \"%s\"!", Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Unknown variable \"%s\"!",
NGIRCd_ConfFile, Line, Var ); NGIRCd_ConfFile, Line, Var );
@@ -1244,16 +996,12 @@ Handle_SERVER( int Line, char *Var, char *Arg )
static bool static bool
Handle_Channelname(struct Conf_Channel *new_chan, const char *name) Handle_Channelname(size_t chancount, const char *name)
{ {
size_t size = sizeof(new_chan->name); size_t size = sizeof( Conf_Channel[chancount].name );
char *dest = new_chan->name; char *dest = Conf_Channel[chancount].name;
if (!Channel_IsValidName(name)) { if (*name && *name != '#') {
/*
* maybe user forgot to add a '#'.
* This is only here for user convenience.
*/
*dest = '#'; *dest = '#';
--size; --size;
++dest; ++dest;
@@ -1266,68 +1014,55 @@ static void
Handle_CHANNEL( int Line, char *Var, char *Arg ) Handle_CHANNEL( int Line, char *Var, char *Arg )
{ {
size_t len; size_t len;
size_t chancount; size_t chancount = 0;
struct Conf_Channel *chan;
assert( Line > 0 ); assert( Line > 0 );
assert( Var != NULL ); assert( Var != NULL );
assert( Arg != NULL ); assert( Arg != NULL );
assert(Conf_Channel_Count > 0); if (Conf_Channel_Count > 0)
chancount = Conf_Channel_Count - 1; chancount = Conf_Channel_Count - 1;
chan = array_alloc(&Conf_Channels, sizeof(*chan), chancount);
if (!chan) {
Config_Error(LOG_ERR, "Could not allocate memory for predefined channel (%d:%s = %s)", Line, Var, Arg);
return;
}
if( strcasecmp( Var, "Name" ) == 0 ) { if( strcasecmp( Var, "Name" ) == 0 ) {
if (!Handle_Channelname(chan, Arg)) if (!Handle_Channelname(chancount, Arg))
Config_Error_TooLong( Line, Var ); Config_Error_TooLong( Line, Var );
return; return;
} }
if( strcasecmp( Var, "Modes" ) == 0 ) { if( strcasecmp( Var, "Modes" ) == 0 ) {
/* Initial modes */ /* Initial modes */
len = strlcpy(chan->modes, Arg, sizeof(chan->modes)); len = strlcpy( Conf_Channel[chancount].modes, Arg, sizeof( Conf_Channel[chancount].modes ));
if (len >= sizeof(chan->modes)) if (len >= sizeof( Conf_Channel[chancount].modes ))
Config_Error_TooLong( Line, Var ); Config_Error_TooLong( Line, Var );
return; return;
} }
if( strcasecmp( Var, "Topic" ) == 0 ) { if( strcasecmp( Var, "Topic" ) == 0 ) {
/* Initial topic */ /* Initial topic */
len = strlcpy(chan->topic, Arg, sizeof(chan->topic)); if (!array_copys( &Conf_Channel[chancount].topic, Arg))
if (len >= sizeof(chan->topic))
Config_Error_TooLong( Line, Var ); Config_Error_TooLong( Line, Var );
return; return;
} }
if( strcasecmp( Var, "Key" ) == 0 ) { if( strcasecmp( Var, "Key" ) == 0 ) {
/* Initial Channel Key (mode k) */ /* Initial Channel Key (mode k) */
len = strlcpy(chan->key, Arg, sizeof(chan->key)); len = strlcpy(Conf_Channel[chancount].key, Arg, sizeof(Conf_Channel[chancount].key));
if (len >= sizeof(chan->key)) if (len >= sizeof( Conf_Channel[chancount].key ))
Config_Error_TooLong(Line, Var); Config_Error_TooLong(Line, Var);
return; return;
} }
if( strcasecmp( Var, "MaxUsers" ) == 0 ) { if( strcasecmp( Var, "MaxUsers" ) == 0 ) {
/* maximum user limit, mode l */ /* maximum user limit, mode l */
chan->maxusers = (unsigned long) atol(Arg); Conf_Channel[chancount].maxusers = (unsigned long) atol(Arg);
if (chan->maxusers == 0) if (Conf_Channel[chancount].maxusers == 0)
Config_Error_NaN(Line, Var); Config_Error_NaN(Line, Var);
return; return;
} }
if (strcasecmp(Var, "KeyFile") == 0) {
/* channel keys */
len = strlcpy(chan->keyfile, Arg, sizeof(chan->keyfile));
if (len >= sizeof(chan->keyfile))
Config_Error_TooLong(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 */
static bool static void
Validate_Config(bool Configtest, bool Rehash) Validate_Config(bool Configtest, bool Rehash)
{ {
/* Validate configuration settings. */ /* Validate configuration settings. */
@@ -1335,7 +1070,6 @@ Validate_Config(bool Configtest, bool Rehash)
#ifdef DEBUG #ifdef DEBUG
int i, servers, servers_once; int i, servers, servers_once;
#endif #endif
bool config_valid = true;
char *ptr; char *ptr;
/* Validate configured server name, see RFC 2812 section 2.3.1 */ /* Validate configured server name, see RFC 2812 section 2.3.1 */
@@ -1354,7 +1088,6 @@ Validate_Config(bool Configtest, bool Rehash)
if (!Conf_ServerName[0]) { if (!Conf_ServerName[0]) {
/* No server name configured! */ /* No server name configured! */
config_valid = false;
Config_Error(LOG_ALERT, Config_Error(LOG_ALERT,
"No (valid) server name configured in \"%s\" (section 'Global': 'Name')!", "No (valid) server name configured in \"%s\" (section 'Global': 'Name')!",
NGIRCd_ConfFile); NGIRCd_ConfFile);
@@ -1368,7 +1101,6 @@ Validate_Config(bool Configtest, bool Rehash)
if (Conf_ServerName[0] && !strchr(Conf_ServerName, '.')) { if (Conf_ServerName[0] && !strchr(Conf_ServerName, '.')) {
/* No dot in server name! */ /* No dot in server name! */
config_valid = false;
Config_Error(LOG_ALERT, Config_Error(LOG_ALERT,
"Invalid server name configured in \"%s\" (section 'Global': 'Name'): Dot missing!", "Invalid server name configured in \"%s\" (section 'Global': 'Name'): Dot missing!",
NGIRCd_ConfFile); NGIRCd_ConfFile);
@@ -1383,7 +1115,6 @@ Validate_Config(bool Configtest, bool Rehash)
#ifdef STRICT_RFC #ifdef STRICT_RFC
if (!Conf_ServerAdminMail[0]) { if (!Conf_ServerAdminMail[0]) {
/* No administrative contact configured! */ /* No administrative contact configured! */
config_valid = false;
Config_Error(LOG_ALERT, Config_Error(LOG_ALERT,
"No administrator email address configured in \"%s\" ('AdminEMail')!", "No administrator email address configured in \"%s\" ('AdminEMail')!",
NGIRCd_ConfFile); NGIRCd_ConfFile);
@@ -1416,8 +1147,6 @@ Validate_Config(bool Configtest, bool Rehash)
"Configuration: Operators=%d, Servers=%d[%d], Channels=%d", "Configuration: Operators=%d, Servers=%d[%d], Channels=%d",
Conf_Oper_Count, servers, servers_once, Conf_Channel_Count); Conf_Oper_Count, servers, servers_once, Conf_Channel_Count);
#endif #endif
return config_valid;
} /* Validate_Config */ } /* Validate_Config */
@@ -1484,7 +1213,7 @@ Init_Server_Struct( CONF_SERVER *Server )
Resolve_Init(&Server->res_stat); Resolve_Init(&Server->res_stat);
Server->conn_id = NONE; Server->conn_id = NONE;
memset(&Server->bind_addr, 0, sizeof(&Server->bind_addr)); Server->bind_addr.s_addr = htonl(INADDR_ANY);
} /* Init_Server_Struct */ } /* Init_Server_Struct */

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de) * Copyright (c)2001,2002 by 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,6 +8,8 @@
* (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.47 2007/11/23 16:28:37 fw Exp $
*
* Configuration management (header) * Configuration management (header)
*/ */
@@ -20,17 +22,13 @@
#include "defines.h" #include "defines.h"
#include "array.h" #include "array.h"
#include "portab.h" #include "portab.h"
#include "tool.h"
#include "ng_ipaddr.h"
#include "resolve.h"
#include "conf-ssl.h"
typedef struct _Conf_Oper
struct Conf_Oper { {
char name[CLIENT_PASS_LEN]; /* Name (ID) of IRC operator */ char name[CLIENT_PASS_LEN]; /* Name (ID) of IRC operator */
char pwd[CLIENT_PASS_LEN]; /* Password */ char pwd[CLIENT_PASS_LEN]; /* Password */
char *mask; /* allowed host mask */ char *mask;
}; } CONF_OPER;
typedef struct _Conf_Server typedef struct _Conf_Server
{ {
@@ -44,36 +42,17 @@ typedef struct _Conf_Server
RES_STAT res_stat; /* Status of the resolver */ RES_STAT res_stat; /* Status of the resolver */
int flags; /* Flags */ int flags; /* Flags */
CONN_ID conn_id; /* ID of server connection or NONE */ CONN_ID conn_id; /* ID of server connection or NONE */
ng_ipaddr_t bind_addr; /* source address to use for outgoing struct in_addr bind_addr; /* source address to use for outgoing connections */
connections */
ng_ipaddr_t dst_addr[2]; /* list of addresses to connect to */
#ifdef SSL_SUPPORT
bool SSLConnect; /* connect() using SSL? */
#endif
char svs_mask[CLIENT_ID_LEN]; /* Mask of nick names that are
services */
} CONF_SERVER; } CONF_SERVER;
typedef struct _Conf_Channel
#ifdef SSL_SUPPORT {
struct SSLOptions {
char *KeyFile;
char *CertFile;
char *DHFile;
array ListenPorts;
array KeyFilePassword;
};
#endif
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" ) */ char key[CLIENT_PASS_LEN]; /* Channel key ("password", mode "k" ) */
char topic[COMMAND_LEN]; /* Initial topic */
char keyfile[512]; /* Path and name of channel key file */
unsigned long maxusers; /* maximum usercount for this channel, mode "l" */ unsigned long maxusers; /* maximum usercount for this channel, mode "l" */
}; array topic; /* Initial topic */
} CONF_CHANNEL;
#define CONF_SFLAG_ONCE 1 /* Delete this entry after next disconnect */ #define CONF_SFLAG_ONCE 1 /* Delete this entry after next disconnect */
@@ -104,7 +83,7 @@ GLOBAL char Conf_MotdPhrase[LINE_LEN];
GLOBAL array Conf_ListenPorts; GLOBAL array Conf_ListenPorts;
/* Address to which the socket should be bound or empty (=all) */ /* Address to which the socket should be bound or empty (=all) */
GLOBAL char *Conf_ListenAddress; GLOBAL char Conf_ListenAddress[16];
/* User and group ID the server should run with */ /* User and group ID the server should run with */
GLOBAL uid_t Conf_UID; GLOBAL uid_t Conf_UID;
@@ -124,43 +103,29 @@ GLOBAL int Conf_PongTimeout;
GLOBAL int Conf_ConnectRetry; GLOBAL int Conf_ConnectRetry;
/* Operators */ /* Operators */
GLOBAL array Conf_Opers; GLOBAL CONF_OPER Conf_Oper[MAX_OPERATORS];
GLOBAL unsigned int Conf_Oper_Count;
/* Servers */ /* Servers */
GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS]; GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS];
/* Pre-defined channels */ /* Pre-defined channels */
GLOBAL array Conf_Channels; GLOBAL CONF_CHANNEL Conf_Channel[MAX_DEFCHANNELS];
GLOBAL unsigned int Conf_Channel_Count;
/* Pre-defined channels only */ /* Pre-defined channels only */
GLOBAL bool Conf_PredefChannelsOnly; 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;
/* Disable all DNS functions? */
GLOBAL bool Conf_NoDNS;
/* If an IRC op gives chanop privileges without being a chanop, /* If an IRC op gives chanop privileges without being a chanop,
* ircd2 will ignore the command. This enables a workaround: * ircd2 will ignore the command. This enables a workaround:
* It masks the command as coming from the server */ * It masks the command as coming from the server */
GLOBAL bool Conf_OperServerMode; GLOBAL bool Conf_OperServerMode;
/* Are remote IRC operators allowed to manage this server? */
GLOBAL bool Conf_AllowRemoteOper;
/* Disable all DNS functions? */
GLOBAL bool Conf_NoDNS;
/* Disable IDENT lookups, even when compiled with support for it */
GLOBAL bool Conf_NoIdent;
/*
* try to connect to remote systems using the ipv6 protocol,
* if they have an ipv6 address? (default yes)
*/
GLOBAL bool Conf_ConnectIPv6;
/* same as above, but for ipv4 hosts, default: yes */
GLOBAL bool Conf_ConnectIPv4;
/* Maximum number of connections to this server */ /* Maximum number of connections to this server */
GLOBAL long Conf_MaxConnections; GLOBAL long Conf_MaxConnections;
@@ -174,22 +139,17 @@ GLOBAL int Conf_MaxConnectionsIP;
GLOBAL unsigned int Conf_MaxNickLength; GLOBAL unsigned int Conf_MaxNickLength;
GLOBAL void Conf_Init PARAMS((void)); GLOBAL void Conf_Init PARAMS((void));
GLOBAL bool Conf_Rehash PARAMS((void)); GLOBAL void Conf_Rehash PARAMS((void));
GLOBAL int Conf_Test PARAMS((void)); GLOBAL int Conf_Test PARAMS((void));
GLOBAL void Conf_UnsetServer PARAMS(( CONN_ID Idx )); GLOBAL void Conf_UnsetServer PARAMS(( CONN_ID Idx ));
GLOBAL void Conf_SetServer PARAMS(( int ConfServer, CONN_ID Idx )); GLOBAL void Conf_SetServer PARAMS(( int ConfServer, CONN_ID Idx ));
GLOBAL int Conf_GetServer PARAMS(( CONN_ID Idx )); GLOBAL int Conf_GetServer PARAMS(( CONN_ID Idx ));
GLOBAL bool Conf_EnableServer PARAMS(( const char *Name, UINT16 Port )); GLOBAL bool Conf_EnableServer PARAMS(( char *Name, UINT16 Port ));
GLOBAL bool Conf_EnablePassiveServer PARAMS((const char *Name)); GLOBAL bool Conf_EnablePassiveServer PARAMS((const char *Name));
GLOBAL bool Conf_DisableServer PARAMS(( const char *Name )); GLOBAL bool Conf_DisableServer PARAMS(( char *Name ));
GLOBAL bool Conf_AddServer PARAMS(( const char *Name, UINT16 Port, const char *Host, const char *MyPwd, const char *PeerPwd )); GLOBAL bool Conf_AddServer PARAMS(( char *Name, UINT16 Port, char *Host, char *MyPwd, char *PeerPwd ));
GLOBAL bool Conf_IsService PARAMS((int ConfServer, const char *Nick));
/* Password required by WEBIRC command */
GLOBAL char Conf_WebircPwd[CLIENT_PASS_LEN];
#endif #endif

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de) * Copyright (c)2001,2002 by 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
@@ -16,10 +16,11 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: conn-func.c,v 1.11 2007/10/04 15:03:56 alex Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
#include <string.h> #include <log.h>
#include "log.h"
#include "conn.h" #include "conn.h"
#include "client.h" #include "client.h"
@@ -31,6 +32,8 @@
GLOBAL void GLOBAL void
Conn_UpdateIdle( CONN_ID Idx ) Conn_UpdateIdle( CONN_ID Idx )
{ {
/* Idle-Timer zuruecksetzen */
assert( Idx > NONE ); assert( Idx > NONE );
My_Connections[Idx].lastprivmsg = time( NULL ); My_Connections[Idx].lastprivmsg = time( NULL );
} }
@@ -49,7 +52,8 @@ Conn_GetSignon(CONN_ID Idx)
GLOBAL time_t GLOBAL time_t
Conn_GetIdle( CONN_ID Idx ) Conn_GetIdle( CONN_ID Idx )
{ {
/* Return Idle-Timer of a connetion */ /* Idle-Time einer Verbindung liefern (in Sekunden) */
assert( Idx > NONE ); assert( Idx > NONE );
return time( NULL ) - My_Connections[Idx].lastprivmsg; return time( NULL ) - My_Connections[Idx].lastprivmsg;
} /* Conn_GetIdle */ } /* Conn_GetIdle */
@@ -58,6 +62,8 @@ Conn_GetIdle( CONN_ID Idx )
GLOBAL time_t GLOBAL time_t
Conn_LastPing( CONN_ID Idx ) Conn_LastPing( CONN_ID Idx )
{ {
/* Zeitpunkt des letzten PING liefern */
assert( Idx > NONE ); assert( Idx > NONE );
return My_Connections[Idx].lastping; return My_Connections[Idx].lastping;
} /* Conn_LastPing */ } /* Conn_LastPing */
@@ -66,11 +72,11 @@ Conn_LastPing( CONN_ID Idx )
GLOBAL void GLOBAL void
Conn_SetPenalty( CONN_ID Idx, time_t Seconds ) Conn_SetPenalty( CONN_ID Idx, time_t Seconds )
{ {
/* set Penalty-Delay for a socket. /* Penalty-Delay fuer eine Verbindung (in Sekunden) setzen;
* during the penalty, the socket is ignored completely, no new * waehrend dieser Zeit wird der entsprechende Socket vom Server
* data is read. This function only increases the penalty, it is * bei Lese-Operationen komplett ignoriert. Der Delay kann mit
* not possible to decrease the penalty time. * dieser Funktion nur erhoeht, nicht aber verringert werden. */
*/
time_t t; time_t t;
assert( Idx > NONE ); assert( Idx > NONE );
@@ -98,6 +104,8 @@ Conn_ResetPenalty( CONN_ID Idx )
GLOBAL void GLOBAL void
Conn_ClearFlags( void ) Conn_ClearFlags( void )
{ {
/* Alle Connection auf "nicht-markiert" setzen */
CONN_ID i; CONN_ID i;
for( i = 0; i < Pool_Size; i++ ) My_Connections[i].flag = 0; for( i = 0; i < Pool_Size; i++ ) My_Connections[i].flag = 0;
@@ -107,6 +115,8 @@ Conn_ClearFlags( void )
GLOBAL int GLOBAL int
Conn_Flag( CONN_ID Idx ) Conn_Flag( CONN_ID Idx )
{ {
/* Ist eine Connection markiert (true) oder nicht? */
assert( Idx > NONE ); assert( Idx > NONE );
return My_Connections[Idx].flag; return My_Connections[Idx].flag;
} /* Conn_Flag */ } /* Conn_Flag */
@@ -164,17 +174,6 @@ Conn_Options( CONN_ID Idx )
} /* Conn_Options */ } /* Conn_Options */
/**
* Set connection option.
*/
GLOBAL void
Conn_SetOption(CONN_ID Idx, int Option)
{
assert(Idx > NONE);
Conn_OPTION_ADD(&My_Connections[Idx], Option);
} /* Conn_SetOption */
/** /**
* Get the start time of the connection. * Get the start time of the connection.
* The result is the start time in seconds since 1970-01-01, as reported * The result is the start time in seconds since 1970-01-01, as reported
@@ -195,12 +194,12 @@ Conn_StartTime( CONN_ID Idx )
return 0; return 0;
} /* Conn_StartTime */ } /* Conn_StartTime */
/**
* return number of bytes queued for writing
*/
GLOBAL size_t GLOBAL size_t
Conn_SendQ( CONN_ID Idx ) Conn_SendQ( CONN_ID Idx )
{ {
/* Laenge der Daten im Schreibbuffer liefern */
assert( Idx > NONE ); assert( Idx > NONE );
#ifdef ZLIB #ifdef ZLIB
if( My_Connections[Idx].options & CONN_ZIP ) if( My_Connections[Idx].options & CONN_ZIP )
@@ -211,36 +210,31 @@ Conn_SendQ( CONN_ID Idx )
} /* Conn_SendQ */ } /* Conn_SendQ */
/**
* return number of messages sent on this connection so far
*/
GLOBAL long GLOBAL long
Conn_SendMsg( CONN_ID Idx ) Conn_SendMsg( CONN_ID Idx )
{ {
/* Anzahl gesendeter Nachrichten liefern */
assert( Idx > NONE ); assert( Idx > NONE );
return My_Connections[Idx].msg_out; return My_Connections[Idx].msg_out;
} /* Conn_SendMsg */ } /* Conn_SendMsg */
/**
* return number of (uncompressed) bytes sent
* on this connection so far
*/
GLOBAL long GLOBAL long
Conn_SendBytes( CONN_ID Idx ) Conn_SendBytes( CONN_ID Idx )
{ {
/* Anzahl gesendeter Bytes (unkomprimiert) liefern */
assert( Idx > NONE ); assert( Idx > NONE );
return My_Connections[Idx].bytes_out; return My_Connections[Idx].bytes_out;
} /* Conn_SendBytes */ } /* Conn_SendBytes */
/**
* return number of bytes pending in read buffer
*/
GLOBAL size_t GLOBAL size_t
Conn_RecvQ( CONN_ID Idx ) Conn_RecvQ( CONN_ID Idx )
{ {
/* Laenge der Daten im Lesebuffer liefern */
assert( Idx > NONE ); assert( Idx > NONE );
#ifdef ZLIB #ifdef ZLIB
if( My_Connections[Idx].options & CONN_ZIP ) if( My_Connections[Idx].options & CONN_ZIP )
@@ -251,24 +245,21 @@ Conn_RecvQ( CONN_ID Idx )
} /* Conn_RecvQ */ } /* Conn_RecvQ */
/**
* return number of messages received on this connection so far
*/
GLOBAL long GLOBAL long
Conn_RecvMsg( CONN_ID Idx ) Conn_RecvMsg( CONN_ID Idx )
{ {
/* Anzahl empfangener Nachrichten liefern */
assert( Idx > NONE ); assert( Idx > NONE );
return My_Connections[Idx].msg_in; return My_Connections[Idx].msg_in;
} /* Conn_RecvMsg */ } /* Conn_RecvMsg */
/**
* return number of (uncompressed) bytes received on this
* connection so far
*/
GLOBAL long GLOBAL long
Conn_RecvBytes( CONN_ID Idx ) Conn_RecvBytes( CONN_ID Idx )
{ {
/* Anzahl empfangener Bytes (unkomprimiert) liefern */
assert( Idx > NONE ); assert( Idx > NONE );
return My_Connections[Idx].bytes_in; return My_Connections[Idx].bytes_in;
} /* Conn_RecvBytes */ } /* Conn_RecvBytes */

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de) * Copyright (c)2001,2002 by 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,6 +8,8 @@
* (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.7 2007/10/04 15:03:56 alex Exp $
*
* Connection management: Global functions (header) * Connection management: Global functions (header)
*/ */
@@ -21,10 +23,6 @@
* include this conn-func.h header. */ * include this conn-func.h header. */
#ifndef CONN_MODULE #ifndef CONN_MODULE
# include "conn.h" # include "conn.h"
#else
#define Conn_OPTION_ADD( x, opt ) ( (x)->options |= (opt) )
#define Conn_OPTION_DEL( x, opt ) ( (x)->options &= ~(opt) )
#define Conn_OPTION_ISSET( x, opt ) ( ((x)->options & (opt)) != 0)
#endif #endif
@@ -51,11 +49,14 @@ GLOBAL CONN_ID Conn_First PARAMS(( void ));
GLOBAL CONN_ID Conn_Next PARAMS(( CONN_ID Idx )); GLOBAL CONN_ID Conn_Next PARAMS(( CONN_ID Idx ));
GLOBAL UINT16 Conn_Options PARAMS(( CONN_ID Idx )); GLOBAL UINT16 Conn_Options PARAMS(( CONN_ID Idx ));
GLOBAL void Conn_SetOption PARAMS(( CONN_ID Idx, int Option ));
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_DEL( x, opt ) ( (x)->options &= ~(opt) )
#define Conn_OPTION_ISSET( x, opt ) ( ((x)->options & (opt)) != 0)
#endif #endif

View File

@@ -1,712 +0,0 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
*
* SSL wrapper functions.
* Copyright (c) 2005-2008 Florian Westphal <fw@strlen.de>
*/
#include "portab.h"
#include "imp.h"
#include "conf-ssl.h"
#ifdef SSL_SUPPORT
#include "io.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define CONN_MODULE
#include "conn.h"
#include "conf.h"
#include "conn-func.h"
#include "conn-ssl.h"
#include "log.h"
#include "exp.h"
#include "defines.h"
extern struct SSLOptions Conf_SSLOptions;
#ifdef HAVE_LIBSSL
#include <openssl/err.h>
#include <openssl/rand.h>
static SSL_CTX * ssl_ctx;
static DH *dh_params;
static bool ConnSSL_LoadServerKey_openssl PARAMS(( SSL_CTX *c ));
#endif
#ifdef HAVE_LIBGNUTLS
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <gnutls/x509.h>
#define DH_BITS 1024
static gnutls_certificate_credentials_t x509_cred;
static gnutls_dh_params_t dh_params;
static bool ConnSSL_LoadServerKey_gnutls PARAMS(( void ));
#endif
static bool ConnSSL_Init_SSL PARAMS(( CONNECTION *c ));
static int ConnectAccept PARAMS(( CONNECTION *c, bool connect ));
static int ConnSSL_HandleError PARAMS(( CONNECTION *c, const int code, const char *fname ));
#ifdef HAVE_LIBGNUTLS
static char * openreadclose(const char *name, size_t *len)
{
char *buf = NULL;
struct stat s;
ssize_t br;
int fd = open(name, O_RDONLY);
if (fd < 0) {
Log(LOG_ERR, "Could not open %s: %s", name, strerror(errno));
return NULL;
}
if (fstat(fd, &s)) {
Log(LOG_ERR, "Could not fstat %s: %s", name, strerror(errno));
goto out;
}
if (!S_ISREG(s.st_mode)) {
Log(LOG_ERR, "%s: Not a regular file", name);
goto out;
}
if (s.st_size <= 0) {
Log(LOG_ERR, "%s: invalid file length (size %ld <= 0)", name, (long) s.st_size);
goto out;
}
buf = malloc(s.st_size);
if (!buf) {
Log(LOG_ERR, "Could not malloc %lu bytes for file %s: %s", s.st_size, name, strerror(errno));
goto out;
}
br = read(fd, buf, s.st_size);
if (br != (ssize_t)s.st_size) {
Log(LOG_ERR, "Could not read file %s: read returned %ld, expected %ld: %s",
name, (long) br, (long) s.st_size, br == -1 ? strerror(errno):"short read?!");
memset(buf, 0, s.st_size);
free(buf);
buf = NULL;
} else {
*len = br;
}
out:
close(fd);
return buf;
}
#endif
#ifdef HAVE_LIBSSL
static void
LogOpenSSLError( const char *msg, const char *msg2 )
{
unsigned long err = ERR_get_error();
char * errmsg = err ? ERR_error_string(err, NULL) : "Unable to determine error";
if (!msg) msg = "SSL Error";
if (msg2)
Log( LOG_ERR, "%s: %s: %s", msg, msg2, errmsg);
else
Log( LOG_ERR, "%s: %s", msg, errmsg);
}
static int
pem_passwd_cb(char *buf, int size, int rwflag, void *password)
{
array *pass = password;
int passlen;
(void)rwflag; /* rwflag is unused if DEBUG is not set. */
assert(rwflag == 0); /* 0 -> callback used for decryption.
* See SSL_CTX_set_default_passwd_cb(3) */
passlen = (int) array_bytes(pass);
LogDebug("pem_passwd_cb buf size %d, array size %d", size, passlen);
assert(passlen >= 0);
if (passlen <= 0) {
Log(LOG_ERR, "pem_passwd_cb: password required, but not set");
return 0;
}
size = passlen > size ? size : passlen;
memcpy(buf, (char *)(array_start(pass)), size);
return size;
}
#endif
static bool
Load_DH_params(void)
{
#ifdef HAVE_LIBSSL
FILE *fp;
bool ret = true;
if (!Conf_SSLOptions.DHFile) {
Log(LOG_NOTICE, "Configuration option \"SSLDHFile\" not set!");
return false;
}
fp = fopen(Conf_SSLOptions.DHFile, "r");
if (!fp) {
Log(LOG_ERR, "%s: %s", Conf_SSLOptions.DHFile, strerror(errno));
return false;
}
dh_params = PEM_read_DHparams(fp, NULL, NULL, NULL);
if (!dh_params) {
Log(LOG_ERR, "%s: PEM_read_DHparams failed!",
Conf_SSLOptions.DHFile);
ret = false;
}
fclose(fp);
return ret;
#endif
#ifdef HAVE_LIBGNUTLS
bool need_dhgenerate = true;
int err;
gnutls_dh_params_t tmp_dh_params;
err = gnutls_dh_params_init(&tmp_dh_params);
if (err < 0) {
Log(LOG_ERR, "gnutls_dh_params_init: %s", gnutls_strerror(err));
return false;
}
if (Conf_SSLOptions.DHFile) {
gnutls_datum_t dhparms;
size_t size;
dhparms.data = (unsigned char *) openreadclose(Conf_SSLOptions.DHFile, &size);
if (dhparms.data) {
dhparms.size = size;
err = gnutls_dh_params_import_pkcs3(tmp_dh_params, &dhparms, GNUTLS_X509_FMT_PEM);
if (err == 0)
need_dhgenerate = false;
else
Log(LOG_ERR, "gnutls_dh_params_init: %s", gnutls_strerror(err));
memset(dhparms.data, 0, size);
free(dhparms.data);
}
}
if (need_dhgenerate) {
Log(LOG_WARNING,
"SSLDHFile not set, generating %u bit DH parameters. This may take a while ...",
DH_BITS);
err = gnutls_dh_params_generate2(tmp_dh_params, DH_BITS);
if (err < 0) {
Log(LOG_ERR, "gnutls_dh_params_generate2: %s", gnutls_strerror(err));
return false;
}
}
dh_params = tmp_dh_params;
return true;
#endif
}
void ConnSSL_Free(CONNECTION *c)
{
#ifdef HAVE_LIBSSL
SSL *ssl = c->ssl_state.ssl;
if (ssl) {
SSL_shutdown(ssl);
SSL_free(ssl);
c->ssl_state.ssl = NULL;
}
#endif
#ifdef HAVE_LIBGNUTLS
gnutls_session_t sess = c->ssl_state.gnutls_session;
if (Conn_OPTION_ISSET(c, CONN_SSL)) {
gnutls_bye(sess, GNUTLS_SHUT_RDWR);
gnutls_deinit(sess);
}
#endif
assert(Conn_OPTION_ISSET(c, CONN_SSL));
/* can't just set bitmask to 0 -- there are other, non-ssl related flags, e.g. CONN_ZIP. */
Conn_OPTION_DEL(c, CONN_SSL_FLAGS_ALL);
}
bool
ConnSSL_InitLibrary( void )
{
#ifdef HAVE_LIBSSL
SSL_CTX *newctx;
if (!ssl_ctx) {
SSL_library_init();
SSL_load_error_strings();
}
if (!RAND_status()) {
Log(LOG_ERR, "OpenSSL PRNG not seeded: /dev/urandom missing?");
/*
* it is probably best to fail and let the user install EGD or a similar program if no kernel random device is available.
* According to OpenSSL RAND_egd(3): "The automatic query of /var/run/egd-pool et al was added in OpenSSL 0.9.7";
* so it makes little sense to deal with PRNGD seeding ourselves.
*/
return false;
}
newctx = SSL_CTX_new(SSLv23_method());
if (!newctx) {
LogOpenSSLError("SSL_CTX_new()", NULL);
return false;
}
if (!ConnSSL_LoadServerKey_openssl(newctx))
goto out;
SSL_CTX_set_options(newctx, SSL_OP_SINGLE_DH_USE|SSL_OP_NO_SSLv2);
SSL_CTX_set_mode(newctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
SSL_CTX_free(ssl_ctx);
ssl_ctx = newctx;
Log(LOG_INFO, "%s initialized.", SSLeay_version(SSLEAY_VERSION));
return true;
out:
SSL_CTX_free(newctx);
return false;
#endif
#ifdef HAVE_LIBGNUTLS
int err;
static bool initialized;
if (initialized) /* TODO: cannot reload gnutls keys: can't simply free x509 context -- it may still be in use */
return false;
err = gnutls_global_init();
if (err) {
Log(LOG_ERR, "gnutls_global_init(): %s", gnutls_strerror(err));
return false;
}
if (!ConnSSL_LoadServerKey_gnutls())
return false;
Log(LOG_INFO, "gnutls %s initialized.", gnutls_check_version(NULL));
initialized = true;
return true;
#endif
}
#ifdef HAVE_LIBGNUTLS
static bool
ConnSSL_LoadServerKey_gnutls(void)
{
int err;
const char *cert_file;
err = gnutls_certificate_allocate_credentials(&x509_cred);
if (err < 0) {
Log(LOG_ERR, "gnutls_certificate_allocate_credentials: %s", gnutls_strerror(err));
return false;
}
cert_file = Conf_SSLOptions.CertFile ? Conf_SSLOptions.CertFile:Conf_SSLOptions.KeyFile;
if (!cert_file) {
Log(LOG_NOTICE, "No SSL server key configured, SSL disabled.");
return false;
}
if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
Log(LOG_WARNING,
"Ignoring KeyFilePassword: Not supported by GNUTLS.");
if (!Load_DH_params())
return false;
gnutls_certificate_set_dh_params(x509_cred, dh_params);
err = gnutls_certificate_set_x509_key_file(x509_cred, cert_file, Conf_SSLOptions.KeyFile, GNUTLS_X509_FMT_PEM);
if (err < 0) {
Log(LOG_ERR, "gnutls_certificate_set_x509_key_file (cert %s, key %s): %s",
cert_file, Conf_SSLOptions.KeyFile ? Conf_SSLOptions.KeyFile : "(NULL)", gnutls_strerror(err));
return false;
}
return true;
}
#endif
#ifdef HAVE_LIBSSL
static bool
ConnSSL_LoadServerKey_openssl(SSL_CTX *ctx)
{
char *cert_key;
assert(ctx);
if (!Conf_SSLOptions.KeyFile) {
Log(LOG_NOTICE, "No SSL server key configured, SSL disabled.");
return false;
}
SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
SSL_CTX_set_default_passwd_cb_userdata(ctx, &Conf_SSLOptions.KeyFilePassword);
if (SSL_CTX_use_PrivateKey_file(ctx, Conf_SSLOptions.KeyFile, SSL_FILETYPE_PEM) != 1) {
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
LogOpenSSLError("SSL_CTX_use_PrivateKey_file", Conf_SSLOptions.KeyFile);
return false;
}
cert_key = Conf_SSLOptions.CertFile ? Conf_SSLOptions.CertFile:Conf_SSLOptions.KeyFile;
if (SSL_CTX_use_certificate_chain_file(ctx, cert_key) != 1) {
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
LogOpenSSLError("SSL_CTX_use_certificate_file", cert_key);
return false;
}
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
if (!SSL_CTX_check_private_key(ctx)) {
LogOpenSSLError("Server Private Key does not match certificate", NULL);
return false;
}
if (Load_DH_params()) {
if (SSL_CTX_set_tmp_dh(ctx, dh_params) != 1)
LogOpenSSLError("Error setting DH Parameters", Conf_SSLOptions.DHFile);
/* don't return false here: the non-DH modes will still work */
DH_free(dh_params);
dh_params = NULL;
}
return true;
}
#endif
static bool
ConnSSL_Init_SSL(CONNECTION *c)
{
int ret;
assert(c != NULL);
#ifdef HAVE_LIBSSL
if (!ssl_ctx) /* NULL when library initialization failed */
return false;
assert(c->ssl_state.ssl == NULL);
c->ssl_state.ssl = SSL_new(ssl_ctx);
if (!c->ssl_state.ssl) {
LogOpenSSLError("SSL_new()", NULL);
return false;
}
ret = SSL_set_fd(c->ssl_state.ssl, c->sock);
if (ret != 1) {
LogOpenSSLError("SSL_set_fd()", NULL);
ConnSSL_Free(c);
return false;
}
#endif
#ifdef HAVE_LIBGNUTLS
ret = gnutls_set_default_priority(c->ssl_state.gnutls_session);
if (ret < 0) {
Log(LOG_ERR, "gnutls_set_default_priority: %s", gnutls_strerror(ret));
ConnSSL_Free(c);
return false;
}
/*
* The intermediate (long) cast is here to avoid a warning like:
* "cast to pointer from integer of different size" on 64-bit platforms.
* There doesn't seem to be an alternate GNUTLS API we could use instead, see e.g.
* http://www.mail-archive.com/help-gnutls@gnu.org/msg00286.html
*/
gnutls_transport_set_ptr(c->ssl_state.gnutls_session, (gnutls_transport_ptr_t) (long) c->sock);
ret = gnutls_credentials_set(c->ssl_state.gnutls_session, GNUTLS_CRD_CERTIFICATE, x509_cred);
if (ret < 0) {
Log(LOG_ERR, "gnutls_credentials_set: %s", gnutls_strerror(ret));
ConnSSL_Free(c);
return false;
}
gnutls_dh_set_prime_bits(c->ssl_state.gnutls_session, DH_BITS);
#endif
Conn_OPTION_ADD(c, CONN_SSL);
return true;
}
bool
ConnSSL_PrepareConnect(CONNECTION *c, UNUSED CONF_SERVER *s)
{
bool ret;
#ifdef HAVE_LIBGNUTLS
int err;
err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_CLIENT);
if (err) {
Log(LOG_ERR, "gnutls_init: %s", gnutls_strerror(err));
return false;
}
#endif
ret = ConnSSL_Init_SSL(c);
if (!ret)
return false;
Conn_OPTION_ADD(c, CONN_SSL_CONNECT);
#ifdef HAVE_LIBSSL
assert(c->ssl_state.ssl);
SSL_set_verify(c->ssl_state.ssl, SSL_VERIFY_NONE, NULL);
#endif
return true;
}
/*
Check an Handle Error return code after failed calls to ssl/tls functions.
OpenSSL:
SSL_connect(), SSL_accept(), SSL_do_handshake(), SSL_read(), SSL_peek(), or SSL_write() on ssl.
GNUTLS:
gnutlsssl_read(), gnutls_write() or gnutls_handshake().
Return: -1 on fatal error, 0 if we can try again later.
*/
static int
ConnSSL_HandleError( CONNECTION *c, const int code, const char *fname )
{
#ifdef HAVE_LIBSSL
int ret = SSL_ERROR_SYSCALL;
unsigned long sslerr;
int real_errno = errno;
ret = SSL_get_error(c->ssl_state.ssl, code);
switch (ret) {
case SSL_ERROR_WANT_READ:
io_event_del(c->sock, IO_WANTWRITE);
Conn_OPTION_ADD(c, CONN_SSL_WANT_READ);
return 0; /* try again later */
case SSL_ERROR_WANT_WRITE:
io_event_del(c->sock, IO_WANTREAD);
Conn_OPTION_ADD(c, CONN_SSL_WANT_WRITE); /* fall through */
case SSL_ERROR_NONE:
return 0; /* try again later */
case SSL_ERROR_ZERO_RETURN:
LogDebug("TLS/SSL connection shut down normally");
break;
/*
SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_ACCEPT, SSL_ERROR_WANT_X509_LOOKUP
*/
case SSL_ERROR_SYSCALL:
sslerr = ERR_get_error();
if (sslerr) {
Log( LOG_ERR, "%s: %s", fname, ERR_error_string(sslerr, NULL ));
} else {
switch (code) { /* EOF that violated protocol */
case 0:
Log(LOG_ERR, "%s: Client Disconnected", fname );
break;
case -1: /* low level socket I/O error, check errno */
Log(LOG_ERR, "%s: %s", fname, strerror(real_errno));
}
}
break;
case SSL_ERROR_SSL:
LogOpenSSLError("TLS/SSL Protocol Error", fname);
break;
default:
Log( LOG_ERR, "%s: Unknown error %d!", fname, ret);
}
ConnSSL_Free(c);
return -1;
#endif
#ifdef HAVE_LIBGNUTLS
switch (code) {
case GNUTLS_E_AGAIN:
case GNUTLS_E_INTERRUPTED:
if (gnutls_record_get_direction(c->ssl_state.gnutls_session)) {
Conn_OPTION_ADD(c, CONN_SSL_WANT_WRITE);
io_event_del(c->sock, IO_WANTREAD);
} else {
Conn_OPTION_ADD(c, CONN_SSL_WANT_READ);
io_event_del(c->sock, IO_WANTWRITE);
}
break;
default:
assert(code < 0);
if (gnutls_error_is_fatal(code)) {
Log(LOG_ERR, "%s: %s", fname, gnutls_strerror(code));
ConnSSL_Free(c);
return -1;
}
}
return 0;
#endif
}
static void
ConnSSL_LogCertInfo( CONNECTION *c )
{
#ifdef HAVE_LIBSSL
SSL *ssl = c->ssl_state.ssl;
assert(ssl);
Log(LOG_INFO, "New %s connection using cipher %s on socket %d.",
SSL_get_version(ssl), SSL_get_cipher(ssl), c->sock);
#endif
#ifdef HAVE_LIBGNUTLS
gnutls_session_t sess = c->ssl_state.gnutls_session;
gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(sess);
Log(LOG_INFO, "New %s connection using cipher %s-%s on socket %d.",
gnutls_protocol_get_name(gnutls_protocol_get_version(sess)),
gnutls_cipher_get_name(cipher),
gnutls_mac_get_name(gnutls_mac_get(sess)), c->sock);
#endif
}
/*
Accept incoming SSL connection.
Return Values:
1: SSL Connection established
0: try again
-1: SSL Connection not established due to fatal error.
*/
int
ConnSSL_Accept( CONNECTION *c )
{
assert(c != NULL);
if (!Conn_OPTION_ISSET(c, CONN_SSL)) {
#ifdef HAVE_LIBGNUTLS
int err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_SERVER);
if (err) {
Log(LOG_ERR, "gnutls_init: %s", gnutls_strerror(err));
return false;
}
#endif
LogDebug("ConnSSL_Accept: Initializing SSL data");
if (!ConnSSL_Init_SSL(c))
return -1;
}
return ConnectAccept(c, false );
}
int
ConnSSL_Connect( CONNECTION *c )
{
assert(c != NULL);
#ifdef HAVE_LIBSSL
assert(c->ssl_state.ssl);
#endif
assert(Conn_OPTION_ISSET(c, CONN_SSL));
return ConnectAccept(c, true);
}
/* accept/connect wrapper. if connect is true, connect to peer, otherwise wait for incoming connection */
static int
ConnectAccept( CONNECTION *c, bool connect)
{
int ret;
#ifdef HAVE_LIBSSL
SSL *ssl = c->ssl_state.ssl;
assert(ssl != NULL);
ret = connect ? SSL_connect(ssl) : SSL_accept(ssl);
if (1 != ret)
return ConnSSL_HandleError(c, ret, connect ? "SSL_connect": "SSL_accept");
#endif
#ifdef HAVE_LIBGNUTLS
(void) connect;
ret = gnutls_handshake(c->ssl_state.gnutls_session);
if (ret)
return ConnSSL_HandleError(c, ret, "gnutls_handshake");
#endif /* _GNUTLS */
Conn_OPTION_DEL(c, (CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ|CONN_SSL_CONNECT));
ConnSSL_LogCertInfo(c);
return 1;
}
ssize_t
ConnSSL_Write(CONNECTION *c, const void *buf, size_t count)
{
ssize_t bw;
Conn_OPTION_DEL(c, CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ);
assert(count > 0);
#ifdef HAVE_LIBSSL
bw = (ssize_t) SSL_write(c->ssl_state.ssl, buf, count);
#endif
#ifdef HAVE_LIBGNUTLS
bw = gnutls_write(c->ssl_state.gnutls_session, buf, count);
#endif
if (bw > 0)
return bw;
if (ConnSSL_HandleError( c, bw, "ConnSSL_Write") == 0)
errno = EAGAIN; /* try again */
return -1;
}
ssize_t
ConnSSL_Read(CONNECTION *c, void * buf, size_t count)
{
ssize_t br;
Conn_OPTION_DEL(c, CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ);
#ifdef HAVE_LIBSSL
br = (ssize_t) SSL_read(c->ssl_state.ssl, buf, count);
if (br > 0) /* on EOF we have to call ConnSSL_HandleError(), see SSL_read(3) */
return br;
#endif
#ifdef HAVE_LIBGNUTLS
br = gnutls_read(c->ssl_state.gnutls_session, buf, count);
if (br >= 0) /* on EOF we must _not_ call ConnSSL_HandleError, see gnutls_record_recv(3) */
return br;
#endif
/* error on read: switch ConnSSL_HandleError() return values -> 0 is "try again", so return -1 and set EAGAIN */
if (ConnSSL_HandleError(c, br, "ConnSSL_Read") == 0) {
errno = EAGAIN;
return -1;
}
return 0;
}
bool
ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len)
{
#ifdef HAVE_LIBSSL
char *nl;
SSL *ssl = c->ssl_state.ssl;
if (!ssl)
return false;
*buf = 0;
SSL_CIPHER_description(SSL_get_current_cipher(ssl), buf, len);
nl = strchr(buf, '\n');
if (nl)
*nl = 0;
return true;
#endif
#ifdef HAVE_LIBGNUTLS
if (Conn_OPTION_ISSET(c, CONN_SSL)) {
const char *name_cipher, *name_mac, *name_proto, *name_keyexchange;
unsigned keysize;
gnutls_session_t sess = c->ssl_state.gnutls_session;
gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(sess);
name_cipher = gnutls_cipher_get_name(cipher);
name_mac = gnutls_mac_get_name(gnutls_mac_get(sess));
keysize = gnutls_cipher_get_key_size(cipher) * 8;
name_proto = gnutls_protocol_get_name(gnutls_protocol_get_version(sess));
name_keyexchange = gnutls_kx_get_name(gnutls_kx_get(sess));
return snprintf(buf, len, "%s-%s%15s Kx=%s Enc=%s(%u) Mac=%s",
name_cipher, name_mac, name_proto, name_keyexchange, name_cipher, keysize, name_mac) > 0;
}
return false;
#endif
}
#endif /* SSL_SUPPORT */
/* -eof- */

View File

@@ -1,28 +0,0 @@
/*
* ngIRCd -- The Next Generation IRC Daemon
* SSL wrapper functions. (header)
*/
#ifndef conn_ssl_h
#define conn_ssl_h
#include "conf-ssl.h"
#include "conn.h"
#include "conf.h"
#ifdef SSL_SUPPORT
GLOBAL void ConnSSL_Free PARAMS(( CONNECTION *c ));
GLOBAL bool ConnSSL_PrepareConnect PARAMS(( CONNECTION *c, CONF_SERVER *s ));
GLOBAL int ConnSSL_Accept PARAMS(( CONNECTION *c ));
GLOBAL int ConnSSL_Connect PARAMS(( CONNECTION *c ));
GLOBAL ssize_t ConnSSL_Write PARAMS(( CONNECTION *c, const void *buf, size_t count));
GLOBAL ssize_t ConnSSL_Read PARAMS(( CONNECTION *c, void *buf, size_t count));
GLOBAL bool ConnSSL_GetCipherInfo PARAMS(( CONNECTION *c, char *buf, size_t len ));
#endif /* SSL_SUPPORT */
#endif /* conn_ssl_h */
/* -eof- */

View File

@@ -11,15 +11,19 @@
* Connection compression using ZLIB * Connection compression using ZLIB
*/ */
#include "portab.h" #include "portab.h"
#define CONN_MODULE #define CONN_MODULE
#ifdef ZLIB #ifdef ZLIB
/* 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.16 2007/05/17 23:34:24 alex Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@@ -37,7 +41,7 @@
GLOBAL bool GLOBAL bool
Zip_InitConn( CONN_ID Idx ) Zip_InitConn( CONN_ID Idx )
{ {
/* initialize zlib compression on this link */ /* Kompression fuer Link initialisieren */
assert( Idx > NONE ); assert( Idx > NONE );
@@ -48,7 +52,9 @@ Zip_InitConn( CONN_ID Idx )
My_Connections[Idx].zip.in.zfree = NULL; My_Connections[Idx].zip.in.zfree = NULL;
My_Connections[Idx].zip.in.data_type = Z_ASCII; My_Connections[Idx].zip.in.data_type = Z_ASCII;
if (inflateInit( &My_Connections[Idx].zip.in ) != Z_OK) { if( inflateInit( &My_Connections[Idx].zip.in ) != Z_OK )
{
/* Fehler! */
Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib inflate)!", Idx ); Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib inflate)!", Idx );
return false; return false;
} }
@@ -59,7 +65,9 @@ Zip_InitConn( CONN_ID Idx )
My_Connections[Idx].zip.out.zfree = NULL; My_Connections[Idx].zip.out.zfree = NULL;
My_Connections[Idx].zip.out.data_type = Z_ASCII; My_Connections[Idx].zip.out.data_type = Z_ASCII;
if (deflateInit( &My_Connections[Idx].zip.out, Z_DEFAULT_COMPRESSION ) != Z_OK) { if( deflateInit( &My_Connections[Idx].zip.out, Z_DEFAULT_COMPRESSION ) != Z_OK )
{
/* Fehler! */
Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib deflate)!", Idx ); Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib deflate)!", Idx );
return false; return false;
} }
@@ -80,14 +88,12 @@ Zip_InitConn( CONN_ID Idx )
* compression ratios. * compression ratios.
* If the (pre-)compression buffer is full, we try to flush it ("actually * If the (pre-)compression buffer is full, we try to flush it ("actually
* compress some data") and to add the new (uncompressed) data afterwards. * compress some data") and to add the new (uncompressed) data afterwards.
* This function closes the connection on error.
* @param Idx Connection handle. * @param Idx Connection handle.
* @param Data Pointer to the data. * @param Data Pointer to the data.
* @param Len Length of the data to add. * @param Len Length of the data to add.
* @return true on success, false otherwise. * @return true on success, false otherwise. */
*/
GLOBAL bool GLOBAL bool
Zip_Buffer( CONN_ID Idx, const char *Data, size_t Len ) Zip_Buffer( CONN_ID Idx, char *Data, size_t Len )
{ {
size_t buflen; size_t buflen;
@@ -104,11 +110,9 @@ Zip_Buffer( CONN_ID Idx, const char *Data, size_t Len )
/* check again; if zip buf is still too large do not append data: /* check again; if zip buf is still too large do not append data:
* otherwise the zip wbuf would grow too large */ * otherwise the zip wbuf would grow too large */
buflen = array_bytes(&My_Connections[Idx].zip.wbuf); buflen = array_bytes(&My_Connections[Idx].zip.wbuf);
if (buflen + Len >= WRITEBUFFER_SLINK_LEN) { if (buflen + Len >= WRITEBUFFER_SLINK_LEN)
Log(LOG_ALERT, "Zip Write Buffer overflow: %lu bytes\n", buflen + Len);
Conn_Close(Idx, "Zip Write buffer overflow", NULL, false);
return false; 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 */
@@ -116,9 +120,8 @@ Zip_Buffer( CONN_ID Idx, const char *Data, size_t Len )
/** /**
* Compress data in ZIP buffer and move result to the write buffer of * Compress data in ZIP buffer and move result to the write buffer of
* the connection. * the connection.
* This function closes the connection on error.
* @param Idx Connection handle. * @param Idx Connection handle.
* @return true on success, false otherwise. * @retrun true on success, false otherwise.
*/ */
GLOBAL bool GLOBAL bool
Zip_Flush( CONN_ID Idx ) Zip_Flush( CONN_ID Idx )
@@ -181,17 +184,13 @@ Zip_Flush( CONN_ID Idx )
} /* Zip_Flush */ } /* Zip_Flush */
/**
* uncompress data and copy it to read buffer.
* Returns true if data has been unpacked or no
* compressed data is currently pending in the zread buffer.
* This function closes the connection on error.
* @param Idx Connection handle.
* @return true on success, false otherwise.
*/
GLOBAL bool GLOBAL bool
Unzip_Buffer( CONN_ID Idx ) Unzip_Buffer( CONN_ID Idx )
{ {
/* Daten entpacken und in Lesepuffer kopieren. Bei Fehlern
* wird false geliefert, ansonsten true. Der Fall, dass keine
* Daten mehr zu entpacken sind, ist _kein_ Fehler! */
int result; int result;
unsigned char unzipbuf[READBUFFER_LEN]; unsigned char unzipbuf[READBUFFER_LEN];
int unzipbuf_used = 0; int unzipbuf_used = 0;
@@ -236,11 +235,9 @@ Unzip_Buffer( CONN_ID Idx )
#endif #endif
assert(unzipbuf_used <= READBUFFER_LEN); assert(unzipbuf_used <= READBUFFER_LEN);
if (!array_catb(&My_Connections[Idx].rbuf, (char*) unzipbuf, if (!array_catb(&My_Connections[Idx].rbuf, (char*) unzipbuf,
(size_t)unzipbuf_used)) { (size_t)unzipbuf_used))
Log (LOG_ALERT, "Decompression error: can't copy data!?");
Conn_Close(Idx, "Decompression error!", NULL, false);
return false; return false;
}
if( in->avail_in > 0 ) { if( in->avail_in > 0 ) {
array_moveleft(&My_Connections[Idx].zip.rbuf, 1, in_len ); array_moveleft(&My_Connections[Idx].zip.rbuf, 1, in_len );
} else { } else {
@@ -252,25 +249,21 @@ Unzip_Buffer( CONN_ID Idx )
} /* Unzip_Buffer */ } /* Unzip_Buffer */
/**
* @param Idx Connection handle.
* @return amount of sent (compressed) bytes
*/
GLOBAL long GLOBAL long
Zip_SendBytes( CONN_ID Idx ) Zip_SendBytes( CONN_ID Idx )
{ {
/* Anzahl gesendeter Bytes (komprimiert!) liefern */
assert( Idx > NONE ); assert( Idx > NONE );
return My_Connections[Idx].zip.bytes_out; return My_Connections[Idx].zip.bytes_out;
} /* Zip_SendBytes */ } /* Zip_SendBytes */
/**
* @param Idx Connection handle.
* @return amount of received (compressed) bytes
*/
GLOBAL long GLOBAL long
Zip_RecvBytes( CONN_ID Idx ) Zip_RecvBytes( CONN_ID Idx )
{ {
/* Anzahl gesendeter Bytes (komprimiert!) liefern */
assert( Idx > NONE ); assert( Idx > NONE );
return My_Connections[Idx].zip.bytes_in; return My_Connections[Idx].zip.bytes_in;
} /* Zip_RecvBytes */ } /* Zip_RecvBytes */

View File

@@ -22,7 +22,7 @@
GLOBAL bool Zip_InitConn PARAMS(( CONN_ID Idx )); GLOBAL bool Zip_InitConn PARAMS(( CONN_ID Idx ));
GLOBAL bool Zip_Buffer PARAMS(( CONN_ID Idx, const char *Data, size_t Len )); GLOBAL bool Zip_Buffer PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
GLOBAL bool Zip_Flush PARAMS(( CONN_ID Idx )); GLOBAL bool Zip_Flush PARAMS(( CONN_ID Idx ));
GLOBAL bool Unzip_Buffer PARAMS(( CONN_ID Idx )); GLOBAL bool Unzip_Buffer PARAMS(( CONN_ID Idx ));

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2009 by Alexander Barton (alex@barton.de) * Copyright (c)2001,2002 by 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,6 +8,8 @@
* (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.45 2007/10/04 15:03:56 alex Exp $
*
* Connection management (header) * Connection management (header)
*/ */
@@ -18,30 +20,16 @@
#include <time.h> /* for time_t, see below */ #include <time.h> /* for time_t, see below */
/*
* connection state flags. this is a bitmask -- all values must
* be unique and a power of two.
*
* If you introduce new ones in between, make sure to adjust all
* remaining ones.
*/
#define CONN_ISCLOSING 1 /* Conn_Close() already called */ #define CONN_ISCLOSING 1 /* Conn_Close() already called */
#define CONN_ISCONNECTING 2 /* connect() in progress */ #define CONN_ISCONNECTING 2 /* connect() in progress */
#define CONN_RFC1459 4 /* RFC 1459 compatibility mode */
#ifdef ZLIB #ifdef ZLIB
#define CONN_ZIP 8 /* zlib compressed link */ #define CONN_ZIP 4 /* zlib compressed link */
#endif #endif
#include "conf-ssl.h"
#ifdef SSL_SUPPORT typedef int CONN_ID;
#define CONN_SSL_CONNECT 16 /* wait for ssl connect to finish */
#define CONN_SSL 32 /* this connection is SSL encrypted */
#define CONN_SSL_WANT_WRITE 64 /* SSL/TLS library needs to write protocol data */
#define CONN_SSL_WANT_READ 128 /* SSL/TLS library needs to read protocol data */
#define CONN_SSL_FLAGS_ALL (CONN_SSL_CONNECT|CONN_SSL|CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ)
#endif
typedef long CONN_ID;
#include "client.h" #include "client.h"
@@ -50,8 +38,6 @@ typedef long CONN_ID;
#include "defines.h" #include "defines.h"
#include "resolve.h" #include "resolve.h"
#include "array.h" #include "array.h"
#include "tool.h"
#include "ng_ipaddr.h"
#ifdef ZLIB #ifdef ZLIB
#include <zlib.h> #include <zlib.h>
@@ -68,7 +54,7 @@ typedef struct _ZipData
typedef struct _Connection typedef struct _Connection
{ {
int sock; /* Socket handle */ int sock; /* Socket handle */
ng_ipaddr_t addr; /* Client address */ struct sockaddr_in addr; /* Client address */
RES_STAT res_stat; /* Status of resolver process */ RES_STAT res_stat; /* Status of resolver process */
char host[HOST_LEN]; /* Hostname */ char host[HOST_LEN]; /* Hostname */
array rbuf; /* Read buffer */ array rbuf; /* Read buffer */
@@ -82,14 +68,10 @@ typedef struct _Connection
long msg_in, msg_out; /* Received and sent IRC messages */ long msg_in, msg_out; /* Received and sent IRC messages */
int flag; /* Flag (see "irc-write" module) */ int flag; /* Flag (see "irc-write" module) */
UINT16 options; /* Link options / connection state */ UINT16 options; /* Link options / connection state */
UINT16 bps; /* bytes processed within last second */
CLIENT *client; /* pointer to client structure */ CLIENT *client; /* pointer to client structure */
#ifdef ZLIB #ifdef ZLIB
ZIPDATA zip; /* Compression information */ ZIPDATA zip; /* Compression information */
#endif /* ZLIB */ #endif /* ZLIB */
#ifdef SSL_SUPPORT
struct ConnSSL_State ssl_state; /* SSL/GNUTLS state information */
#endif
} CONNECTION; } CONNECTION;
GLOBAL CONNECTION *My_Connections; GLOBAL CONNECTION *My_Connections;
@@ -109,18 +91,11 @@ GLOBAL void Conn_Handler PARAMS(( void ));
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, const char *LogMsg, const char *FwdMsg, bool InformClient )); GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, char *LogMsg, char *FwdMsg, bool InformClient ));
GLOBAL void Conn_SyncServerStruct PARAMS(( void )); GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
GLOBAL CLIENT* Conn_GetClient PARAMS((CONN_ID i)); GLOBAL CLIENT* Conn_GetClient PARAMS((CONN_ID i));
#ifdef SSL_SUPPORT
GLOBAL bool Conn_GetCipherInfo PARAMS((CONN_ID Idx, char *buf, size_t len));
GLOBAL bool Conn_UsesSSL PARAMS((CONN_ID Idx));
#else
static inline bool Conn_UsesSSL(UNUSED CONN_ID Idx) { return false; }
#endif #endif
#endif
/* -eof- */ /* -eof- */

View File

@@ -1,12 +1,14 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 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
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (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.62 2007/11/21 12:16:36 alex Exp $
*/ */
@@ -28,8 +30,16 @@
#define HOST_LEN 256 /* Max. lenght of fully qualified host #define HOST_LEN 256 /* Max. lenght of fully qualified host
names (e. g. "abc.domain.tld") */ names (e. g. "abc.domain.tld") */
#define MAX_LISTEN_PORTS 16 /* Max. count of listening ports */
#define MAX_OPERATORS 16 /* Max. count of configurable IRC Ops */
#define MAX_SERVERS 16 /* Max. count of configurable servers */ #define MAX_SERVERS 16 /* Max. count of configurable servers */
#define MAX_DEFCHANNELS 16 /* Max. count of predefined channels */
#define MAX_SERVICES 8 /* Max. count of services */
#define MAX_WHOWAS 64 /* Max. number of WHOWAS items */ #define MAX_WHOWAS 64 /* Max. number of WHOWAS items */
#define DEFAULT_WHOWAS 5 /* default count for WHOWAS command */ #define DEFAULT_WHOWAS 5 /* default count for WHOWAS command */
@@ -72,7 +82,7 @@
protocol, see doc/Protocol.txt */ protocol, see doc/Protocol.txt */
#ifdef IRCPLUS #ifdef IRCPLUS
# define IRCPLUSFLAGS "CHLS" /* Standard IRC+ flags */ # define IRCPLUSFLAGS "CHL" /* Standard IRC+ flags */
#endif #endif
#define STARTUP_DELAY 1 /* Delay outgoing connections n seconds #define STARTUP_DELAY 1 /* Delay outgoing connections n seconds
@@ -80,8 +90,8 @@
#define RECONNECT_DELAY 3 /* Time to delay re-connect attempts #define RECONNECT_DELAY 3 /* Time to delay re-connect attempts
in seconds. */ in seconds. */
#define USERMODES "aiorsw" /* Supported user modes. */ #define USERMODES "aios" /* Supported user modes. */
#define CHANMODES "biIklmnoPstvz" /* Supported channel modes. */ #define CHANMODES "biIklmnoPstv" /* Supported channel modes. */
#define CONNECTED true /* Internal status codes. */ #define CONNECTED true /* Internal status codes. */
#define DISCONNECTED false #define DISCONNECTED false

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2009 Alexander Barton (alex@barton.de) * Copyright (c)2001,2002 by 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
@@ -38,8 +38,7 @@ Hash( const char *String )
char buffer[LINE_LEN]; char buffer[LINE_LEN];
strlcpy( buffer, String, sizeof( buffer )); strlcpy( buffer, String, sizeof( buffer ));
return jenkins_hash((UINT8 *)ngt_LowerStr(buffer), return jenkins_hash( (UINT8 *)ngt_LowerStr( buffer ), strlen( buffer ), 42 );
(UINT32)strlen(buffer), 42);
} /* Hash */ } /* Hash */

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de) * Copyright (c)2001,2002 by 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
@@ -14,6 +14,8 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-channel.c,v 1.40.2.2 2008/02/26 12:07:41 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
@@ -24,7 +26,6 @@
#include "conn.h" #include "conn.h"
#include "client.h" #include "client.h"
#include "channel.h" #include "channel.h"
#include "conn-func.h"
#include "lists.h" #include "lists.h"
#include "log.h" #include "log.h"
#include "match.h" #include "match.h"
@@ -39,205 +40,11 @@
#include "irc-channel.h" #include "irc-channel.h"
/*
* RFC 2812, (3.2.1 Join message Command):
* Note that this message
* accepts a special argument ("0"), which is a special request to leave all
* channels the user is currently a member of. The server will process this
* message as if the user had sent a PART command (See Section 3.2.2) for
* each channel he is a member of.
*/
static bool
part_from_all_channels(CLIENT* client, CLIENT *target)
{
CL2CHAN *cl2chan;
CHANNEL *chan;
while ((cl2chan = Channel_FirstChannelOf(target))) {
chan = Channel_GetChannel(cl2chan);
assert( chan != NULL );
Channel_Part(target, client, Channel_Name(chan), Client_ID(target));
}
return CONNECTED;
}
/**
* Check weather a local client is allowed to join an already existing
* channel or not.
* @param Client Client that sent the JOIN command
* @param chan Channel to check
* @param channame Name of the channel
* @param key Provided channel key (or NULL if none has been provided)
* @return true if client is allowed to join channel, false otherwise
*/
static bool
join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
const char *key)
{
bool is_invited, is_banned;
const char *channel_modes;
/* Allow IRC operators to overwrite channel limits */
if (strchr(Client_Modes(Client), 'o'))
return true;
is_banned = Lists_Check(Channel_GetListBans(chan), Client);
is_invited = Lists_Check(Channel_GetListInvites(chan), Client);
if (is_banned && !is_invited) {
/* Client is banned from channel (and not on invite list) */
IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG,
Client_ID(Client), channame);
return false;
}
channel_modes = Channel_Modes(chan);
if (strchr(channel_modes, 'i') && !is_invited) {
/* Channel is "invite-only" and client is not on invite list */
IRC_WriteStrClient(Client, ERR_INVITEONLYCHAN_MSG,
Client_ID(Client), channame);
return false;
}
if (!Channel_CheckKey(chan, Client, key ? key : "")) {
/* Channel is protected by a channel key and the client
* didn't specify the correct one */
IRC_WriteStrClient(Client, ERR_BADCHANNELKEY_MSG,
Client_ID(Client), channame);
return false;
}
if (strchr(channel_modes, 'l') &&
(Channel_MaxUsers(chan) <= Channel_MemberCount(chan))) {
/* There are more clints joined to this channel than allowed */
IRC_WriteStrClient(Client, ERR_CHANNELISFULL_MSG,
Client_ID(Client), channame);
return false;
}
if (strchr(channel_modes, 'z') && !Conn_UsesSSL(Client_Conn(Client))) {
/* Only "secure" clients are allowed, but clients doesn't
* use SSL encryption */
IRC_WriteStrClient(Client, ERR_SECURECHANNEL_MSG,
Client_ID(Client), channame);
return false;
}
return true;
}
static void
join_set_channelmodes(CHANNEL *chan, CLIENT *target, const char *flags)
{
if (flags) {
while (*flags) {
Channel_UserModeAdd(chan, target, *flags);
flags++;
}
}
/* If channel persistent and client is ircop: make client chanop */
if (strchr(Channel_Modes(chan), 'P') && strchr(Client_Modes(target), 'o'))
Channel_UserModeAdd(chan, target, 'o');
}
static void
cb_join_forward(CLIENT *To, CLIENT *Prefix, void *Data)
{
CONN_ID conn;
char str[COMMAND_LEN], *ptr = NULL;
strlcpy(str, (char *)Data, sizeof(str));
conn = Client_Conn(To);
if (Conn_Options(conn) & CONN_RFC1459) {
/* RFC 1459 compatibility mode, appended modes are NOT
* supported, so strip them off! */
ptr = strchr(str, 0x7);
if (ptr)
*ptr++ = '\0';
}
IRC_WriteStrClientPrefix(To, Prefix, "JOIN %s", str);
if (ptr && *ptr)
IRC_WriteStrClientPrefix(To, Prefix, "MODE %s +%s %s", str, ptr,
Client_ID(Prefix));
} /* cb_join_forward */
static void
join_forward(CLIENT *Client, CLIENT *target, CHANNEL *chan,
const char *channame)
{
char modes[CHANNEL_MODE_LEN], str[COMMAND_LEN];
strlcpy(&modes[1], Channel_UserModes(chan, target), sizeof(modes) - 1);
if (modes[1])
modes[0] = 0x7;
else
modes[0] = '\0';
/* forward to other servers (if it is not a local channel) */
if (!Channel_IsLocal(chan)) {
snprintf(str, sizeof(str), "%s%s", channame, modes);
IRC_WriteStrServersPrefixFlag_CB(Client, target, '\0',
cb_join_forward, str);
}
/* tell users in this channel about the new client */
IRC_WriteStrChannelPrefix(Client, chan, target, false,
"JOIN :%s", channame);
/* syncronize channel modes */
if (modes[1]) {
IRC_WriteStrChannelPrefix(Client, chan, target, false,
"MODE %s +%s %s", channame,
&modes[1], Client_ID(target));
}
} /* join_forward */
static bool
join_send_topic(CLIENT *Client, CLIENT *target, CHANNEL *chan,
const char *channame)
{
const char *topic;
if (Client_Type(Client) != CLIENT_USER)
return true;
/* acknowledge join */
if (!IRC_WriteStrClientPrefix(Client, target, "JOIN :%s", channame))
return false;
/* Send topic to client, if any */
topic = Channel_Topic(chan);
assert(topic != NULL);
if (*topic) {
if (!IRC_WriteStrClient(Client, RPL_TOPIC_MSG,
Client_ID(Client), channame, topic))
return false;
#ifndef STRICT_RFC
if (!IRC_WriteStrClient(Client, RPL_TOPICSETBY_MSG,
Client_ID(Client), channame,
Channel_TopicWho(chan),
Channel_TopicTime(chan)))
return false;
#endif
}
/* send list of channel members to client */
if (!IRC_Send_NAMES(Client, chan))
return false;
return IRC_WriteStrClient(Client, RPL_ENDOFNAMES_MSG, Client_ID(Client), Channel_Name(chan));
}
GLOBAL bool GLOBAL bool
IRC_JOIN( CLIENT *Client, REQUEST *Req ) IRC_JOIN( CLIENT *Client, REQUEST *Req )
{ {
char *channame, *key = NULL, *flags, *lastkey = NULL, *lastchan = NULL; char *channame, *channame_ptr, *key, *key_ptr, *flags, *topic, modes[8];
bool is_new_chan, is_invited, is_banned;
CLIENT *target; CLIENT *target;
CHANNEL *chan; CHANNEL *chan;
@@ -250,34 +57,28 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
Client_ID(Client), Req->command); Client_ID(Client), Req->command);
/* Who is the sender? */ /* Who is the sender? */
if (Client_Type(Client) == CLIENT_SERVER) if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
target = Client_Search(Req->prefix); else target = Client;
else if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
target = Client;
if (!target)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix);
/* Is argument "0"? */
if (Req->argc == 1 && !strncmp("0", Req->argv[0], 2))
return part_from_all_channels(Client, target);
/* Are channel keys given? */ /* Are channel keys given? */
if (Req->argc > 1) if (Req->argc > 1) {
key = strtok_r(Req->argv[1], ",", &lastkey); key = Req->argv[1];
key_ptr = strchr(key, ',');
if (key_ptr) *key_ptr = '\0';
}
else
key = key_ptr = NULL;
channame = Req->argv[0]; channame = Req->argv[0];
channame = strtok_r(channame, ",", &lastchan); channame_ptr = strchr(channame, ',');
if (channame_ptr) *channame_ptr = '\0';
/* Make sure that "channame" is not the empty string ("JOIN :") */ /* Channel-Namen durchgehen */
if (! channame) while (channame)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, {
Client_ID(Client), Req->command); chan = NULL; flags = NULL;
while (channame) {
flags = NULL;
/* Did the server include channel-user-modes? */
if (Client_Type(Client) == CLIENT_SERVER) { if (Client_Type(Client) == CLIENT_SERVER) {
flags = strchr( channame, 0x7 ); flags = strchr( channame, 0x7 );
if( flags ) { if( flags ) {
@@ -286,79 +87,175 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
} }
} }
chan = Channel_Search(channame); /* wird der Channel neu angelegt? */
if (!chan && Conf_PredefChannelsOnly) { if( Channel_Search( channame )) {
/* channel must be created, but server does not allow this */ 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 ); IRC_WriteStrClient( Client, ERR_BANNEDFROMCHAN_MSG, Client_ID( Client ), channame );
break; /* Try next name, if any */
channame = strchr(channame, ',');
continue;
}
is_new_chan = true;
} }
/* Local client? */ /* Local client? */
if (Client_Type(Client) == CLIENT_USER) { if( Client_Type( Client ) == CLIENT_USER )
/* Test if the user has reached the channel limit */ {
if ((Conf_MaxJoins > 0) && /* Test if the user has reached his maximum channel count */
(Channel_CountForUser(Client) >= Conf_MaxJoins)) if(( Conf_MaxJoins > 0 ) && ( Channel_CountForUser( Client ) >= Conf_MaxJoins ))
return IRC_WriteStrClient(Client, return IRC_WriteStrClient( Client, ERR_TOOMANYCHANNELS_MSG,
ERR_TOOMANYCHANNELS_MSG,
Client_ID( Client ), channame ); Client_ID( Client ), channame );
if (chan) {
/* Already existing channel: check if the /* Existiert der Channel bereits, oder wird er im Moment neu erzeugt? */
* client is allowed to join */ if( is_new_chan )
if (!join_allowed(Client, chan, channame, key)) {
break; /* Erster User im Channel: Operator-Flag setzen */
} else {
/* New channel: first user will become channel
* operator unless this is a modeless channel */
if (*channame != '+')
flags = "o"; flags = "o";
} }
else
{
/* Existierenden Channel suchen */
chan = Channel_Search( channame );
assert( chan != NULL );
/* Local client: update idle time */ is_banned = Lists_Check(Channel_GetListBans(chan), target );
Conn_UpdateIdle(Client_Conn(Client)); is_invited = Lists_Check(Channel_GetListInvites(chan), target );
} else {
/* Testen, ob Client gebanned ist */
if(( is_banned == true) && ( is_invited == false ))
{
/* Client ist gebanned (und nicht invited): */
IRC_WriteStrClient( Client, ERR_BANNEDFROMCHAN_MSG, Client_ID( Client ), channame );
/* Try next name, if any */
channame = strchr(channame, ',');
continue;
}
/* Ist der Channel "invite-only"? */
if(( strchr( Channel_Modes( chan ), 'i' )) && ( is_invited == false ))
{
/* Channel ist "invite-only" und Client wurde nicht invited: */
IRC_WriteStrClient( Client, ERR_INVITEONLYCHAN_MSG, Client_ID( Client ), channame );
/* Try next name, if any */
channame = strchr(channame, ',');
continue;
}
/* Is the channel protected by a key? */
if(( strchr( Channel_Modes( chan ), 'k' )) && ( strcmp( Channel_Key( chan ), key ? key : "" ) != 0 ))
{
/* Bad channel key! */
IRC_WriteStrClient( Client, ERR_BADCHANNELKEY_MSG, Client_ID( Client ), channame );
/* Try next name, if any */
channame = strchr(channame, ',');
continue;
}
/* Are there already too many members? */
if(( strchr( Channel_Modes( chan ), 'l' )) && ( Channel_MaxUsers( chan ) <= Channel_MemberCount( chan )))
{
/* Bad channel key! */
IRC_WriteStrClient( Client, ERR_CHANNELISFULL_MSG, Client_ID( Client ), channame );
/* Try next name, if any */
channame = strchr(channame, ',');
continue;
}
}
}
else
{
/* Remote server: we don't need to know whether the /* Remote server: we don't need to know whether the
* client is invited or not, but we have to make sure * client is invited or not, but we have to make sure
* that the "one shot" entries (generated by INVITE * that the "one shot" entries (generated by INVITE
* 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. */
if (chan)
(void)Lists_Check(Channel_GetListInvites(chan),
target);
}
/* Join channel (and create channel if it doesn't exist) */
if (!Channel_Join(target, channame))
break;
if (!chan) { /* channel is new; it has been created above */
chan = Channel_Search( channame ); chan = Channel_Search( channame );
assert(chan != NULL); if( chan != NULL ) (void)Lists_Check(Channel_GetListInvites(chan), target);
if (Channel_IsModeless(chan)) {
Channel_ModeAdd(chan, 't'); /* /TOPIC not allowed */
Channel_ModeAdd(chan, 'n'); /* no external msgs */
} }
/* Channel joinen (und ggf. anlegen) */
if( ! Channel_Join( target, channame ))
{
/* naechsten Namen ermitteln */
channame = strchr(channame, ',');
continue;
} }
if( ! chan ) chan = Channel_Search( channame );
assert( chan != NULL ); assert( chan != NULL );
join_set_channelmodes(chan, target, flags); /* Modes setzen (wenn vorhanden) */
while( flags && *flags )
{
Channel_UserModeAdd( chan, target, *flags );
flags++;
}
join_forward(Client, target, chan, channame); /* Wenn persistenter Channel und IRC-Operator: zum Channel-OP machen */
if(( strchr( Channel_Modes( chan ), 'P' )) && ( strchr( Client_Modes( target ), 'o' ))) Channel_UserModeAdd( chan, target, 'o' );
if (!join_send_topic(Client, target, chan, channame)) /* Muessen Modes an andere Server gemeldet werden? */
break; /* write error */ strlcpy( &modes[1], Channel_UserModes( chan, target ), sizeof( modes ) - 1 );
if( modes[1] ) modes[0] = 0x7;
else modes[0] = '\0';
/* An andere Server weiterleiten */
IRC_WriteStrServersPrefix( Client, target, "JOIN :%s%s", channame, modes );
/* im Channel bekannt machen */
IRC_WriteStrChannelPrefix( Client, chan, target, false, "JOIN :%s", channame );
if( modes[1] )
{
/* Modes im Channel bekannt machen */
IRC_WriteStrChannelPrefix( Client, chan, target, false, "MODE %s +%s %s", channame, &modes[1], Client_ID( target ));
}
if( Client_Type( Client ) == CLIENT_USER )
{
/* an Client bestaetigen */
IRC_WriteStrClientPrefix( Client, target, "JOIN :%s", channame );
/* Send topic to client, if any */
topic = Channel_Topic(chan);
if (*topic) {
IRC_WriteStrClient(Client, RPL_TOPIC_MSG,
Client_ID(Client), channame, topic);
#ifndef STRICT_RFC
IRC_WriteStrClient(Client, RPL_TOPICSETBY_MSG,
Client_ID(Client), channame,
Channel_TopicWho(chan),
Channel_TopicTime(chan));
#endif
}
/* Mitglieder an Client Melden */
IRC_Send_NAMES( Client, chan );
IRC_WriteStrClient( Client, RPL_ENDOFNAMES_MSG, Client_ID( Client ), Channel_Name( chan ));
}
/* next channel? */ /* next channel? */
channame = strtok_r(NULL, ",", &lastchan); channame = channame_ptr;
if (channame && key) if (channame) {
key = strtok_r(NULL, ",", &lastkey); channame++;
channame_ptr = strchr(channame, ',');
if (channame_ptr) *channame_ptr = '\0';
if (key_ptr) {
key = ++key_ptr;
key_ptr = strchr(key, ',');
if (key_ptr) *key_ptr = '\0';
}
}
} }
return CONNECTED; return CONNECTED;
} /* IRC_JOIN */ } /* IRC_JOIN */
/**
* Handler for the IRC "PART" command.
*/
GLOBAL bool GLOBAL bool
IRC_PART( CLIENT *Client, REQUEST *Req ) IRC_PART( CLIENT *Client, REQUEST *Req )
{ {
@@ -372,33 +269,18 @@ IRC_PART(CLIENT * Client, REQUEST * Req)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command); Client_ID(Client), Req->command);
/* Get the sender */ /* Wer ist der Absender? */
if (Client_Type(Client) == CLIENT_SERVER) if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
target = Client_Search(Req->prefix); else target = Client;
else if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
target = Client;
if (!target)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
/* Loop over all the given channel names */ /* Channel-Namen durchgehen */
chan = strtok(Req->argv[0], ","); chan = strtok(Req->argv[0], ",");
/* Make sure that "chan" is not the empty string ("PART :") */
if (! chan)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
while (chan) { while (chan) {
Channel_Part(target, Client, chan, Channel_Part(target, Client, chan, Req->argc > 1 ? Req->argv[1] : Client_ID(target));
Req->argc > 1 ? Req->argv[1] : Client_ID(target));
chan = strtok(NULL, ","); chan = strtok(NULL, ",");
} }
/* Update idle time, if local client */
if (Client_Conn(Client) > NONE)
Conn_UpdateIdle(Client_Conn(Client));
return CONNECTED; return CONNECTED;
} /* IRC_PART */ } /* IRC_PART */
@@ -414,8 +296,8 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
if ((Req->argc < 1) || (Req->argc > 2)) /* Falsche Anzahl Parameter? */
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 );
if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix ); if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
else from = Client; else from = Client;
@@ -456,22 +338,16 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
/* Set new topic */ /* Set new topic */
Channel_SetTopic(chan, from, Req->argv[1]); Channel_SetTopic(chan, from, Req->argv[1]);
LogDebug("%s \"%s\" set topic on \"%s\": %s", Log(LOG_DEBUG, "User \"%s\" set topic on \"%s\": %s",
Client_TypeText(from), Client_Mask(from), Channel_Name(chan), Client_Mask(from), Channel_Name(chan),
Req->argv[1][0] ? Req->argv[1] : "<none>"); Req->argv[1][0] ? Req->argv[1] : "<none>");
/* Update channel and forward new topic to other servers */ /* im Channel bekannt machen und an Server weiterleiten */
if (!Channel_IsLocal(chan)) IRC_WriteStrServersPrefix( Client, from, "TOPIC %s :%s", Req->argv[0], Req->argv[1] );
IRC_WriteStrServersPrefix(Client, from, "TOPIC %s :%s", IRC_WriteStrChannelPrefix( Client, chan, from, false, "TOPIC %s :%s", Req->argv[0], Req->argv[1] );
Req->argv[0], Req->argv[1]);
IRC_WriteStrChannelPrefix(Client, chan, from, false, "TOPIC %s :%s",
Req->argv[0], Req->argv[1]);
if (Client_Type(Client) == CLIENT_USER) if( Client_Type( Client ) == CLIENT_USER ) return IRC_WriteStrClientPrefix( Client, Client, "TOPIC %s :%s", Req->argv[0], Req->argv[1] );
return IRC_WriteStrClientPrefix(Client, Client, "TOPIC %s :%s", else return CONNECTED;
Req->argv[0], Req->argv[1]);
else
return CONNECTED;
} /* IRC_TOPIC */ } /* IRC_TOPIC */

File diff suppressed because it is too large Load Diff

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: irc-info.h,v 1.6 2008/02/17 13:26:42 alex Exp $ * $Id: irc-info.h,v 1.4 2007/11/21 12:16:36 alex Exp $
* *
* IRC info commands (header) * IRC info commands (header)
*/ */
@@ -19,18 +19,14 @@
GLOBAL bool IRC_ADMIN PARAMS(( CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_ADMIN PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_INFO PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_ISON PARAMS(( CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_ISON PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_LINKS PARAMS(( CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_LINKS PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_LUSERS PARAMS(( CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_LUSERS PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_MOTD PARAMS(( CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_MOTD PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_NAMES PARAMS(( CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_NAMES PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_STATS PARAMS(( CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_STATS PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_SUMMON PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_TIME PARAMS(( CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_TIME PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_USERHOST PARAMS(( CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_USERHOST PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_USERS PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_SERVLIST PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_VERSION PARAMS(( CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_VERSION PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_WHO PARAMS(( CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_WHO PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_WHOIS PARAMS(( CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_WHOIS PARAMS(( CLIENT *Client, REQUEST *Req ));
@@ -39,6 +35,7 @@ GLOBAL bool IRC_WHOWAS PARAMS(( CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_Send_LUSERS PARAMS(( CLIENT *Client )); GLOBAL bool IRC_Send_LUSERS PARAMS(( CLIENT *Client ));
GLOBAL bool IRC_Send_NAMES PARAMS(( CLIENT *Client, CHANNEL *Chan )); GLOBAL bool IRC_Send_NAMES PARAMS(( CLIENT *Client, CHANNEL *Chan ));
GLOBAL bool IRC_Show_MOTD PARAMS(( CLIENT *Client )); GLOBAL bool IRC_Show_MOTD PARAMS(( CLIENT *Client ));
GLOBAL bool IRC_Send_WHO PARAMS(( CLIENT *Client, CHANNEL *Chan, bool OnlyOps ));
GLOBAL bool IRC_Send_ISUPPORT PARAMS(( CLIENT *Client )); GLOBAL bool IRC_Send_ISUPPORT PARAMS(( CLIENT *Client ));

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de) * Copyright (c)2001,2002 by 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
@@ -14,6 +14,8 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-login.c,v 1.54.2.1 2008/02/05 11:48:37 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
@@ -33,6 +35,7 @@
#include "irc.h" #include "irc.h"
#include "irc-info.h" #include "irc-info.h"
#include "irc-write.h" #include "irc-write.h"
#include "cvs-version.h"
#include "exp.h" #include "exp.h"
#include "irc-login.h" #include "irc-login.h"
@@ -40,9 +43,6 @@
static bool Hello_User PARAMS(( CLIENT *Client )); 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 ));
static void Introduce_Client PARAMS((CLIENT *To, CLIENT *Client, int Type));
static void cb_introduceClient PARAMS((CLIENT *Client, CLIENT *Prefix,
void *i));
/** /**
@@ -67,7 +67,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
/* Not yet registered "unknown" connection, PASS with one /* Not yet registered "unknown" connection, PASS with one
* argument: either a regular client, service, or server * argument: either a regular client, service, or server
* using the old RFC 1459 section 4.1.1 syntax. */ * using the old RFC 1459 section 4.1.1 syntax. */
LogDebug("Connection %d: got PASS command (RFC 1459) ...", LogDebug("Connection %d: got PASS command ...",
Client_Conn(Client)); Client_Conn(Client));
} else if ((Client_Type(Client) == CLIENT_UNKNOWN || } else if ((Client_Type(Client) == CLIENT_UNKNOWN ||
Client_Type(Client) == CLIENT_UNKNOWNSERVER) && Client_Type(Client) == CLIENT_UNKNOWNSERVER) &&
@@ -75,7 +75,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
/* Not yet registered "unknown" connection or outgoing server /* Not yet registered "unknown" connection or outgoing server
* link, PASS with three or four argument: server using the * link, PASS with three or four argument: server using the
* RFC 2813 section 4.1.1 syntax. */ * RFC 2813 section 4.1.1 syntax. */
LogDebug("Connection %d: got PASS command (RFC 2813, new server link) ...", LogDebug("Connection %d: got PASS command (new server link) ...",
Client_Conn(Client)); Client_Conn(Client));
} else if (Client_Type(Client) == CLIENT_UNKNOWN || } else if (Client_Type(Client) == CLIENT_UNKNOWN ||
Client_Type(Client) == CLIENT_UNKNOWNSERVER) { Client_Type(Client) == CLIENT_UNKNOWNSERVER) {
@@ -89,6 +89,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
} }
Client_SetPassword(Client, Req->argv[0]); Client_SetPassword(Client, Req->argv[0]);
Client_SetType(Client, CLIENT_GOTPASS);
/* Protocol version */ /* Protocol version */
if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) { if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) {
@@ -104,12 +105,8 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
Req->argv[1][2] = c2; Req->argv[1][2] = c2;
Req->argv[1][4] = c4; Req->argv[1][4] = c4;
} else
Client_SetType(Client, CLIENT_GOTPASS_2813);
} else {
protohigh = protolow = 0; protohigh = protolow = 0;
Client_SetType(Client, CLIENT_GOTPASS);
}
/* Protocol type, see doc/Protocol.txt */ /* Protocol type, see doc/Protocol.txt */
if (Req->argc >= 2 && strlen(Req->argv[1]) > 4) if (Req->argc >= 2 && strlen(Req->argv[1]) > 4)
@@ -148,6 +145,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
} else { } else {
/* The peer seems to be a server supporting the /* The peer seems to be a server supporting the
* "original" IRC protocol (RFC 2813). */ * "original" IRC protocol (RFC 2813). */
serverver = "";
if (strchr(orig_flags, 'Z')) if (strchr(orig_flags, 'Z'))
flags = "Z"; flags = "Z";
else else
@@ -173,23 +171,27 @@ GLOBAL bool
IRC_NICK( CLIENT *Client, REQUEST *Req ) IRC_NICK( CLIENT *Client, REQUEST *Req )
{ {
CLIENT *intr_c, *target, *c; CLIENT *intr_c, *target, *c;
char *nick, *user, *hostname, *modes, *info; char *modes;
int token, hops;
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
#ifndef STRICT_RFC
/* Some IRC clients, for example BitchX, send the NICK and USER /* Some IRC clients, for example BitchX, send the NICK and USER
* commands in the wrong order ... */ * commands in the wrong order ... */
if( Client_Type( Client ) == CLIENT_UNKNOWN if( Client_Type( Client ) == CLIENT_UNKNOWN
|| Client_Type( Client ) == CLIENT_GOTPASS || Client_Type( Client ) == CLIENT_GOTPASS
|| Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTNICK
#ifndef STRICT_RFC
|| Client_Type( Client ) == CLIENT_GOTUSER || Client_Type( Client ) == CLIENT_GOTUSER
#endif
|| Client_Type( Client ) == CLIENT_USER || Client_Type( Client ) == CLIENT_USER
|| Client_Type(Client) == CLIENT_SERVICE
|| ( Client_Type( Client ) == CLIENT_SERVER && Req->argc == 1 )) || ( Client_Type( Client ) == CLIENT_SERVER && Req->argc == 1 ))
#else
if( Client_Type( Client ) == CLIENT_UNKNOWN
|| Client_Type( Client ) == CLIENT_GOTPASS
|| Client_Type( Client ) == CLIENT_GOTNICK
|| Client_Type( Client ) == CLIENT_USER
|| ( Client_Type( Client ) == CLIENT_SERVER && Req->argc == 1 ))
#endif
{ {
/* User registration or change of nickname */ /* User registration or change of nickname */
@@ -237,11 +239,11 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
return CONNECTED; return CONNECTED;
} }
if (Client_Type(target) != CLIENT_USER && if(( Client_Type( target ) != CLIENT_USER )
Client_Type(target) != CLIENT_SERVICE && && ( Client_Type( target ) != CLIENT_SERVER ))
Client_Type(target) != CLIENT_SERVER) { {
/* New client */ /* New client */
LogDebug("Connection %d: got valid NICK command ...", Log( LOG_DEBUG, "Connection %d: got valid NICK command ...",
Client_Conn( Client )); Client_Conn( Client ));
/* Register new nickname of this client */ /* Register new nickname of this client */
@@ -253,20 +255,23 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
return Hello_User( Client ); return Hello_User( Client );
else else
Client_SetType( Client, CLIENT_GOTNICK ); Client_SetType( Client, CLIENT_GOTNICK );
} else { }
else
{
/* Nickname change */ /* Nickname change */
if (Client_Conn(target) > NONE) { if( Client_Conn( target ) > NONE )
{
/* Local client */ /* Local client */
Log( LOG_INFO, Log( LOG_INFO,
"%s \"%s\" changed nick (connection %d): \"%s\" -> \"%s\".", "User \"%s\" changed nick (connection %d): \"%s\" -> \"%s\".",
Client_TypeText(target), Client_Mask(target), Client_Mask( target ), Client_Conn( target ),
Client_Conn(target), Client_ID(target), Client_ID( target ), Req->argv[0] );
Req->argv[0]); }
Conn_UpdateIdle(Client_Conn(target)); else
} else { {
/* Remote client */ /* Remote client */
LogDebug("%s \"%s\" changed nick: \"%s\" -> \"%s\".", Log( LOG_DEBUG,
Client_TypeText(target), "User \"%s\" changed nick: \"%s\" -> \"%s\".",
Client_Mask( target ), Client_ID( target ), Client_Mask( target ), Client_ID( target ),
Req->argv[0] ); Req->argv[0] );
} }
@@ -292,48 +297,28 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
} }
return CONNECTED; return CONNECTED;
} else if(Client_Type(Client) == CLIENT_SERVER ||
Client_Type(Client) == CLIENT_SERVICE) {
/* Server or service introduces new client */
/* Bad number of parameters? */
if (Req->argc != 2 && Req->argc != 7)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (Req->argc >= 7) {
/* RFC 2813 compatible syntax */
nick = Req->argv[0];
hops = atoi(Req->argv[1]);
user = Req->argv[2];
hostname = Req->argv[3];
token = atoi(Req->argv[4]);
modes = Req->argv[5] + 1;
info = Req->argv[6];
} else {
/* RFC 1459 compatible syntax */
nick = Req->argv[0];
hops = 1;
user = Req->argv[0];
hostname = Client_ID(Client);
token = atoi(Req->argv[1]);
modes = "";
info = Req->argv[0];
} }
else if( Client_Type( Client ) == CLIENT_SERVER )
{
/* Server introduces new client */
c = Client_Search(nick); /* Falsche Anzahl Parameter? */
if(c) { if( Req->argc != 7 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/*
* the new nick is already present on this server: /* Nick ueberpruefen */
* the new and the old one have to be disconnected now. c = Client_Search( Req->argv[0] );
*/ if( c )
{
/* Der neue Nick ist auf diesem Server bereits registriert:
* sowohl der neue, als auch der alte Client muessen nun
* disconnectiert werden. */
Log( LOG_ERR, "Server %s introduces already registered nick \"%s\"!", Client_ID( Client ), Req->argv[0] ); Log( LOG_ERR, "Server %s introduces already registered nick \"%s\"!", Client_ID( Client ), Req->argv[0] );
Kill_Nick( Req->argv[0], "Nick collision" ); Kill_Nick( Req->argv[0], "Nick collision" );
return CONNECTED; return CONNECTED;
} }
/* Find the Server this client is connected to */ /* Server, zu dem der Client connectiert ist, suchen */
intr_c = Client_GetFromToken(Client, token); intr_c = Client_GetFromToken( Client, atoi( Req->argv[4] ));
if( ! intr_c ) if( ! intr_c )
{ {
Log( LOG_ERR, "Server %s introduces nick \"%s\" on unknown server!?", Client_ID( Client ), Req->argv[0] ); Log( LOG_ERR, "Server %s introduces nick \"%s\" on unknown server!?", Client_ID( Client ), Req->argv[0] );
@@ -341,26 +326,24 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
return CONNECTED; return CONNECTED;
} }
c = Client_NewRemoteUser(intr_c, nick, hops, user, hostname, /* Neue Client-Struktur anlegen */
token, modes, info, true); c = Client_NewRemoteUser( intr_c, Req->argv[0], atoi( Req->argv[1] ), Req->argv[2], Req->argv[3], atoi( Req->argv[4] ), Req->argv[5] + 1, Req->argv[6], true);
if( ! c ) if( ! c )
{ {
/* out of memory, need to disconnect client to keep network state consistent */ /* Eine neue Client-Struktur konnte nicht angelegt werden.
* Der Client muss disconnectiert werden, damit der Netz-
* status konsistent bleibt. */
Log( LOG_ALERT, "Can't create client structure! (on connection %d)", Client_Conn( Client )); Log( LOG_ALERT, "Can't create client structure! (on connection %d)", Client_Conn( Client ));
Kill_Nick( Req->argv[0], "Server error" ); Kill_Nick( Req->argv[0], "Server error" );
return CONNECTED; return CONNECTED;
} }
/* RFC 2813: client is now fully registered, inform all the modes = Client_Modes( c );
* other servers about the new user. if( *modes ) Log( LOG_DEBUG, "User \"%s\" (+%s) registered (via %s, on %s, %d hop%s).", Client_Mask( c ), modes, Client_ID( Client ), Client_ID( intr_c ), Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
* RFC 1459: announce the new client only after receiving the else Log( LOG_DEBUG, "User \"%s\" registered (via %s, on %s, %d hop%s).", Client_Mask( c ), Client_ID( Client ), Client_ID( intr_c ), Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
* USER command, first we need more information! */
if (Req->argc < 7) { /* Andere Server, ausser dem Introducer, informieren */
LogDebug("Client \"%s\" is beeing registered (RFC 1459) ...", IRC_WriteStrServersPrefix( Client, Client, "NICK %s %d %s %s %d %s :%s", Req->argv[0], atoi( Req->argv[1] ) + 1, Req->argv[2], Req->argv[3], Client_MyToken( intr_c ), Req->argv[5], Req->argv[6] );
Client_Mask(c));
Client_SetType(c, CLIENT_GOTNICK);
} else
Introduce_Client(Client, c, CLIENT_USER);
return CONNECTED; return CONNECTED;
} }
@@ -368,13 +351,9 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
} /* IRC_NICK */ } /* IRC_NICK */
/**
* Handler for the IRC command "USER".
*/
GLOBAL bool GLOBAL bool
IRC_USER( CLIENT *Client, REQUEST *Req ) IRC_USER( CLIENT *Client, REQUEST *Req )
{ {
CLIENT *c;
#ifdef IDENTAUTH #ifdef IDENTAUTH
char *ptr; char *ptr;
#endif #endif
@@ -382,206 +361,41 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
if (Client_Type(Client) == CLIENT_GOTNICK ||
#ifndef STRICT_RFC #ifndef STRICT_RFC
Client_Type(Client) == CLIENT_UNKNOWN || if( Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTPASS || Client_Type( Client ) == CLIENT_UNKNOWN )
#else
if( Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTPASS )
#endif #endif
Client_Type(Client) == CLIENT_GOTPASS)
{ {
/* New connection */ /* Wrong number of parameters? */
if (Req->argc != 4) if( Req->argc != 4 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
return IRC_WriteStrClient(Client,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client),
Req->command);
/* User name */ /* User name */
#ifdef IDENTAUTH #ifdef IDENTAUTH
ptr = Client_User( Client ); ptr = Client_User( Client );
if (!ptr || !*ptr || *ptr == '~') if( ! ptr || ! *ptr || *ptr == '~' ) Client_SetUser( Client, Req->argv[0], false );
Client_SetUser(Client, Req->argv[0], false);
#else #else
Client_SetUser( Client, Req->argv[0], false ); Client_SetUser( Client, Req->argv[0], false );
#endif #endif
/* "Real name" or user info text: Don't set it to the empty /* "Real name" or user info text: Don't set it to the empty string, the original ircd
* string, the original ircd can't deal with such "real names" * can't deal with such "real names" (e. g. "USER user * * :") ... */
* (e. g. "USER user * * :") ... */ if( *Req->argv[3] ) Client_SetInfo( Client, Req->argv[3] );
if (*Req->argv[3]) else Client_SetInfo( Client, "-" );
Client_SetInfo(Client, Req->argv[3]);
else
Client_SetInfo(Client, "-");
LogDebug("Connection %d: got valid USER command ...", Log( LOG_DEBUG, "Connection %d: got valid USER command ...", Client_Conn( Client ));
Client_Conn(Client)); if( Client_Type( Client ) == CLIENT_GOTNICK ) return Hello_User( Client );
if (Client_Type(Client) == CLIENT_GOTNICK) else Client_SetType( Client, CLIENT_GOTUSER );
return Hello_User(Client);
else
Client_SetType(Client, CLIENT_GOTUSER);
return CONNECTED; return CONNECTED;
} else if (Client_Type(Client) == CLIENT_SERVER ||
Client_Type(Client) == CLIENT_SERVICE) {
/* Server/service updating an user */
if (Req->argc != 4)
return IRC_WriteStrClient(Client,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client),
Req->command);
c = Client_Search(Req->prefix);
if (!c)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client),
Req->prefix);
Client_SetUser(c, Req->argv[0], true);
Client_SetHostname(c, Req->argv[1]);
Client_SetInfo(c, Req->argv[3]);
LogDebug("Connection %d: got valid USER command for \"%s\".",
Client_Conn(Client), Client_Mask(c));
/* RFC 1459 style user registration?
* Introduce client to network: */
if (Client_Type(c) == CLIENT_GOTNICK)
Introduce_Client(Client, c, CLIENT_USER);
return CONNECTED;
} else if (Client_Type(Client) == CLIENT_USER) {
/* Already registered connection */
return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG,
Client_ID(Client));
} else {
/* Unexpected/invalid connection state? */
return IRC_WriteStrClient(Client, ERR_NOTREGISTERED_MSG,
Client_ID(Client));
} }
else if( Client_Type( Client ) == CLIENT_USER || Client_Type( Client ) == CLIENT_SERVER || Client_Type( Client ) == CLIENT_SERVICE )
{
return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
}
else return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
} /* IRC_USER */ } /* IRC_USER */
/**
* Handler for the IRC command "SERVICE".
* This function implements IRC Services registration using the SERVICE command
* defined in RFC 2812 3.1.6 and RFC 2813 4.1.4.
* At the moment ngIRCd doesn't support directly linked services, so this
* function returns ERR_ERRONEUSNICKNAME when the SERVICE command has not been
* received from a peer server.
*/
GLOBAL bool
IRC_SERVICE(CLIENT *Client, REQUEST *Req)
{
CLIENT *c, *intr_c;
char *nick, *user, *host, *info, *modes, *ptr;
int token, hops;
assert(Client != NULL);
assert(Req != NULL);
if (Client_Type(Client) != CLIENT_GOTPASS &&
Client_Type(Client) != CLIENT_SERVER)
return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG,
Client_ID(Client));
if (Req->argc != 6)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (Client_Type(Client) != CLIENT_SERVER)
return IRC_WriteStrClient(Client, ERR_ERRONEUSNICKNAME_MSG,
Client_ID(Client), Req->argv[0]);
/* Bad number of parameters? */
if (Req->argc != 6)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
nick = Req->argv[0];
user = NULL; host = NULL;
token = atoi(Req->argv[1]);
hops = atoi(Req->argv[4]);
info = Req->argv[5];
/* Validate service name ("nick name") */
c = Client_Search(nick);
if(c) {
/* Nick name collission: disconnect (KILL) both clients! */
Log(LOG_ERR, "Server %s introduces already registered service \"%s\"!",
Client_ID(Client), nick);
Kill_Nick(nick, "Nick collision");
return CONNECTED;
}
/* Get the server to which the service is connected */
intr_c = Client_GetFromToken(Client, token);
if (! intr_c) {
Log(LOG_ERR, "Server %s introduces service \"%s\" on unknown server!?",
Client_ID(Client), nick);
Kill_Nick(nick, "Unknown server");
return CONNECTED;
}
/* Get user and host name */
ptr = strchr(nick, '@');
if (ptr) {
*ptr = '\0';
host = ++ptr;
}
if (!host)
host = Client_Hostname(intr_c);
ptr = strchr(nick, '!');
if (ptr) {
*ptr = '\0';
user = ++ptr;
}
if (!user)
user = nick;
/* According to RFC 2812/2813 parameter 4 <type> "is currently reserved
* for future usage"; but we use it to transfer the modes and check
* that the first character is a '+' sign and ignore it otherwise. */
modes = (Req->argv[3][0] == '+') ? ++Req->argv[3] : "";
c = Client_NewRemoteUser(intr_c, nick, hops, user, host,
token, modes, info, true);
if (! c) {
/* Couldn't create client structure, so KILL the service to
* keep network status consistent ... */
Log(LOG_ALERT, "Can't create client structure! (on connection %d)",
Client_Conn(Client));
Kill_Nick(nick, "Server error");
return CONNECTED;
}
Introduce_Client(Client, c, CLIENT_SERVICE);
return CONNECTED;
} /* IRC_SERVICE */
/**
* Handler for the IRC command "WEBIRC".
* Syntax: WEBIRC <password> <username> <real-hostname> <real-IP-address>
*/
GLOBAL bool
IRC_WEBIRC(CLIENT *Client, REQUEST *Req)
{
/* Exactly 4 parameters are requited */
if (Req->argc != 4)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (!Conf_WebircPwd[0] || strcmp(Req->argv[0], Conf_WebircPwd) != 0)
return IRC_WriteStrClient(Client, ERR_PASSWDMISMATCH_MSG,
Client_ID(Client));
LogDebug("Connection %d: got valid WEBIRC command: user=%s, host=%s, ip=%s",
Client_Conn(Client), Req->argv[1], Req->argv[2], Req->argv[3]);
Client_SetUser(Client, Req->argv[1], true);
Client_SetHostname(Client, Req->argv[2]);
return CONNECTED;
} /* IRC_WEBIRC */
GLOBAL bool GLOBAL bool
IRC_QUIT( CLIENT *Client, REQUEST *Req ) IRC_QUIT( CLIENT *Client, REQUEST *Req )
{ {
@@ -604,6 +418,7 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
target = Client_Search( Req->prefix ); target = Client_Search( Req->prefix );
if( ! target ) if( ! target )
{ {
/* Den Client kennen wir nicht (mehr), also nichts zu tun. */
Log( LOG_WARNING, "Got QUIT from %s for unknown client!?", Client_ID( Client )); Log( LOG_WARNING, "Got QUIT from %s for unknown client!?", Client_ID( Client ));
return CONNECTED; return CONNECTED;
} }
@@ -621,7 +436,7 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
strlcat(quitmsg, "\"", sizeof quitmsg ); strlcat(quitmsg, "\"", sizeof quitmsg );
} }
/* User, Service, or not yet registered */ /* User, Service, oder noch nicht registriert */
Conn_Close( Client_Conn( Client ), "Got QUIT command.", Req->argc == 1 ? quitmsg : NULL, true); Conn_Close( Client_Conn( Client ), "Got QUIT command.", Req->argc == 1 ? quitmsg : NULL, true);
return DISCONNECTED; return DISCONNECTED;
@@ -637,6 +452,7 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
assert(Client != NULL); assert(Client != NULL);
assert(Req != NULL); assert(Req != NULL);
/* Wrong number of arguments? */
if (Req->argc < 1) if (Req->argc < 1)
return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG, return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG,
Client_ID(Client)); Client_ID(Client));
@@ -742,7 +558,7 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
/* The connection timestamp has already been updated when the data has /* The connection timestamp has already been updated when the data has
* been read from so socket, so we don't need to update it here. */ * been read from so socket, so we don't need to update it here. */
#ifdef DEBUG
if (Client_Conn(Client) > NONE) if (Client_Conn(Client) > NONE)
Log(LOG_DEBUG, Log(LOG_DEBUG,
"Connection %d: received PONG. Lag: %ld seconds.", "Connection %d: received PONG. Lag: %ld seconds.",
@@ -751,7 +567,7 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
else else
Log(LOG_DEBUG, Log(LOG_DEBUG,
"Connection %d: received PONG.", Client_Conn(Client)); "Connection %d: received PONG.", Client_Conn(Client));
#endif
return CONNECTED; return CONNECTED;
} /* IRC_PONG */ } /* IRC_PONG */
@@ -759,46 +575,56 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
static bool static bool
Hello_User( CLIENT *Client ) Hello_User( CLIENT *Client )
{ {
#ifdef CVSDATE
char ver[12], vertxt[30];
#endif
assert( Client != NULL ); assert( Client != NULL );
/* Check password ... */ /* Check password ... */
if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) { if( strcmp( Client_Password( Client ), Conf_ServerPwd ) != 0 )
{
/* Bad password! */ /* Bad password! */
Log(LOG_ERR, Log( LOG_ERR, "User \"%s\" rejected (connection %d): Bad password!", Client_Mask( Client ), Client_Conn( Client ));
"Client \"%s\" rejected (connection %d): Bad password!",
Client_Mask(Client), Client_Conn(Client));
Conn_Close( Client_Conn( Client ), NULL, "Bad password", true); Conn_Close( Client_Conn( Client ), NULL, "Bad password", true);
return DISCONNECTED; return DISCONNECTED;
} }
Introduce_Client(NULL, Client, CLIENT_USER); Log( LOG_NOTICE, "User \"%s\" registered (connection %d).", Client_Mask( Client ), Client_Conn( Client ));
if (!IRC_WriteStrClient /* Inform other servers */
(Client, RPL_WELCOME_MSG, Client_ID(Client), Client_Mask(Client))) IRC_WriteStrServers( NULL, "NICK %s 1 %s %s 1 +%s :%s", Client_ID( Client ), Client_User( Client ), Client_Hostname( Client ), Client_Modes( Client ), Client_Info( Client ));
return false;
if (!IRC_WriteStrClient /* Welcome :-) */
(Client, RPL_YOURHOST_MSG, Client_ID(Client), if( ! IRC_WriteStrClient( Client, RPL_WELCOME_MSG, Client_ID( Client ), Client_Mask( Client ))) return false;
Client_ID(Client_ThisServer()), PACKAGE_VERSION, TARGET_CPU,
TARGET_VENDOR, TARGET_OS)) /* Version and system type */
return false; #ifdef CVSDATE
if (!IRC_WriteStrClient strlcpy( ver, CVSDATE, sizeof( ver ));
(Client, RPL_CREATED_MSG, Client_ID(Client), NGIRCd_StartStr)) memmove( ver + 4, ver + 5, 2 );
return false; memmove( ver + 6, ver + 8, 3 );
if (!IRC_WriteStrClient snprintf( vertxt, sizeof( vertxt ), "%s(%s)", PACKAGE_VERSION, ver );
(Client, RPL_MYINFO_MSG, Client_ID(Client), if( ! IRC_WriteStrClient( Client, RPL_YOURHOST_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), vertxt, TARGET_CPU, TARGET_VENDOR, TARGET_OS )) return false;
Client_ID(Client_ThisServer()), PACKAGE_VERSION, USERMODES, #else
CHANMODES)) if( ! IRC_WriteStrClient( Client, RPL_YOURHOST_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), PACKAGE_VERSION, TARGET_CPU, TARGET_VENDOR, TARGET_OS )) return false;
return false; #endif
if( ! IRC_WriteStrClient( Client, RPL_CREATED_MSG, Client_ID( Client ), NGIRCd_StartStr )) return false;
#ifdef CVSDATE
if( ! IRC_WriteStrClient( Client, RPL_MYINFO_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), vertxt, USERMODES, CHANMODES )) return false;
#else
if( ! IRC_WriteStrClient( Client, RPL_MYINFO_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), PACKAGE_VERSION, USERMODES, CHANMODES )) return false;
#endif
/* Features supported by this server (005 numeric, ISUPPORT), /* Features supported by this server (005 numeric, ISUPPORT),
* see <http://www.irc.org/tech_docs/005.html> for details. */ * see <http://www.irc.org/tech_docs/005.html> for details. */
if (! IRC_Send_ISUPPORT(Client)) if (! IRC_Send_ISUPPORT(Client))
return DISCONNECTED; return DISCONNECTED;
if (!IRC_Send_LUSERS(Client)) Client_SetType( Client, CLIENT_USER );
return DISCONNECTED;
if (!IRC_Show_MOTD(Client)) if( ! IRC_Send_LUSERS( Client )) return DISCONNECTED;
return DISCONNECTED; if( ! IRC_Show_MOTD( Client )) return DISCONNECTED;
/* Suspend the client for a second ... */ /* Suspend the client for a second ... */
IRC_SetPenalty( Client, 1 ); IRC_SetPenalty( Client, 1 );
@@ -825,74 +651,4 @@ Kill_Nick( char *Nick, char *Reason )
} /* Kill_Nick */ } /* Kill_Nick */
static void
Introduce_Client(CLIENT *From, CLIENT *Client, int Type)
{
/* Set client type (user or service) */
Client_SetType(Client, Type);
if (From) {
if (Conf_IsService(Conf_GetServer(Client_Conn(From)),
Client_ID(Client)))
Client_SetType(Client, CLIENT_SERVICE);
LogDebug("%s \"%s\" (+%s) registered (via %s, on %s, %d hop%s).",
Client_TypeText(Client), Client_Mask(Client),
Client_Modes(Client), Client_ID(From),
Client_ID(Client_Introducer(Client)),
Client_Hops(Client), Client_Hops(Client) > 1 ? "s": "");
} else
Log(LOG_NOTICE, "%s \"%s\" registered (connection %d).",
Client_TypeText(Client), Client_Mask(Client),
Client_Conn(Client));
/* Inform other servers */
IRC_WriteStrServersPrefixFlag_CB(From,
From != NULL ? From : Client_ThisServer(),
'\0', cb_introduceClient, (void *)Client);
} /* Introduce_Client */
static void
cb_introduceClient(CLIENT *To, CLIENT *Prefix, void *data)
{
CLIENT *c = (CLIENT *)data;
CONN_ID conn;
char *modes, *user, *host;
modes = Client_Modes(c);
user = Client_User(c) ? Client_User(c) : "-";
host = Client_Hostname(c) ? Client_Hostname(c) : "-";
conn = Client_Conn(To);
if (Conn_Options(conn) & CONN_RFC1459) {
/* RFC 1459 mode: separate NICK and USER commands */
Conn_WriteStr(conn, "NICK %s :%d", Client_ID(c),
Client_Hops(c) + 1);
Conn_WriteStr(conn, ":%s USER %s %s %s :%s",
Client_ID(c), user, host,
Client_ID(Client_Introducer(c)), Client_Info(c));
if (modes[0])
Conn_WriteStr(conn, ":%s MODE %s +%s",
Client_ID(c), Client_ID(c), modes);
} else {
/* RFC 2813 mode: one combined NICK or SERVICE command */
if (Client_Type(c) == CLIENT_SERVICE
&& strchr(Client_Flags(To), 'S'))
IRC_WriteStrClientPrefix(To, Prefix,
"SERVICE %s %d * +%s %d :%s",
Client_Mask(c),
Client_MyToken(Client_Introducer(c)),
Client_Modes(c), Client_Hops(c) + 1,
Client_Info(c));
else
IRC_WriteStrClientPrefix(To, Prefix,
"NICK %s %d %s %s %d +%s :%s",
Client_ID(c), Client_Hops(c) + 1,
user, host,
Client_MyToken(Client_Introducer(c)),
modes, Client_Info(c));
}
} /* cb_introduceClient */
/* -eof- */ /* -eof- */

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de) * Copyright (c)2001,2002 by 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,6 +8,8 @@
* (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: irc-login.h,v 1.6 2005/03/19 18:43:48 fw Exp $
*
* Login and logout (header) * Login and logout (header)
*/ */
@@ -15,15 +17,15 @@
#ifndef __irc_login_h__ #ifndef __irc_login_h__
#define __irc_login_h__ #define __irc_login_h__
GLOBAL bool IRC_PASS PARAMS((CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_PASS PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_NICK PARAMS((CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_NICK PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_USER PARAMS((CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_USER PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_SERVICE PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_WEBIRC PARAMS((CLIENT *Client, REQUEST *Req));
GLOBAL bool IRC_PING PARAMS((CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_PING PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_PONG PARAMS((CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_PONG PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_QUIT PARAMS((CLIENT *Client, REQUEST *Req )); GLOBAL bool IRC_QUIT PARAMS((CLIENT *Client, REQUEST *Req ));
#endif #endif

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2010 Alexander Barton (alex@barton.de) * Copyright (c)2001-2005 Alexander Barton (alex@barton.de)
* *
* This program is free software; you can redistribute it and/or modify * 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
@@ -14,6 +14,8 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-mode.c,v 1.50.2.1 2008/02/16 11:26:12 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
@@ -39,10 +41,13 @@
static bool Client_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )); static bool Client_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ));
static bool Channel_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )); static bool Channel_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ));
static bool Add_Ban_Invite PARAMS((int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Pattern)); static bool Add_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
static bool Del_Ban_Invite PARAMS((int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Pattern)); static bool Add_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
static bool Send_ListChange PARAMS(( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Mask )); static bool Del_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
static bool Del_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern ));
static bool Send_ListChange PARAMS(( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Mask ));
GLOBAL bool GLOBAL bool
@@ -229,9 +234,7 @@ client_exit:
ok = IRC_WriteStrClientPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes ); ok = IRC_WriteStrClientPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes );
IRC_WriteStrServersPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes ); IRC_WriteStrServersPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes );
} }
LogDebug("%s \"%s\": Mode change, now \"%s\".", Log( LOG_DEBUG, "User \"%s\": Mode change, now \"%s\".", Client_Mask( Target ), Client_Modes( Target ));
Client_TypeText(Target), Client_Mask(Target),
Client_Modes(Target));
} }
IRC_SetPenalty( Client, 1 ); IRC_SetPenalty( Client, 1 );
@@ -240,23 +243,31 @@ client_exit:
static bool static bool
Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel) Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
{ {
char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], argadd[CLIENT_PASS_LEN]; /* Handle channel and channel-user modes */
const char *mode_ptr;
char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2], argadd[CLIENT_PASS_LEN], *mode_ptr;
bool ok, set, modeok = false, skiponce, use_servermode = false;
int mode_arg, arg_arg;
CLIENT *client;
long l;
size_t len;
/* Mode request: let's answer it :-) */
if( Req->argc == 1 )
{
/* Member or not? -- That's the question! */ /* Member or not? -- That's the question! */
if (!Channel_IsMemberOf(Channel, Origin)) if( ! Channel_IsMemberOf( Channel, Origin )) return IRC_WriteStrClient( Origin, RPL_CHANNELMODEIS_MSG, Client_ID( Origin ), Channel_Name( Channel ), Channel_Modes( Channel ));
return IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG,
Client_ID(Origin), Channel_Name(Channel), Channel_Modes(Channel));
/* The sender is a member: generate extended reply */ /* The sender is a member: generate extended reply */
strlcpy( the_modes, Channel_Modes( Channel ), sizeof( the_modes )); strlcpy( the_modes, Channel_Modes( Channel ), sizeof( the_modes ));
mode_ptr = the_modes; mode_ptr = the_modes;
the_args[0] = '\0'; the_args[0] = '\0';
while( *mode_ptr )
while(*mode_ptr) { {
switch(*mode_ptr) { switch( *mode_ptr )
{
case 'l': case 'l':
snprintf( argadd, sizeof( argadd ), " %lu", 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 ));
@@ -268,401 +279,331 @@ Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel)
} }
mode_ptr++; mode_ptr++;
} }
if (the_args[0]) if( the_args[0] ) strlcat( the_modes, the_args, sizeof( the_modes ));
strlcat(the_modes, the_args, sizeof(the_modes));
return IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG, return IRC_WriteStrClient( Origin, RPL_CHANNELMODEIS_MSG, Client_ID( Origin ), Channel_Name( Channel ), the_modes );
Client_ID(Origin), Channel_Name(Channel), the_modes);
} }
/**
* Handle channel mode and channel-user mode changes
*/
static bool
Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
{
char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2],
argadd[CLIENT_PASS_LEN], *mode_ptr;
bool connected, set, modeok = true, skiponce, use_servermode = false, retval;
int mode_arg, arg_arg;
CLIENT *client;
long l;
size_t len;
if (Channel_IsModeless(Channel))
return IRC_WriteStrClient(Client, ERR_NOCHANMODES_MSG,
Client_ID(Client), Channel_Name(Channel));
/* Mode request: let's answer it :-) */
if (Req->argc <= 1)
return Channel_Mode_Answer_Request(Origin, Channel);
/* Is the user allowed to change modes? */ /* Is the user allowed to change modes? */
if (Client_Type(Client) == CLIENT_USER) { if( Client_Type( Client ) == CLIENT_USER )
{
/* Is the originating user on that channel? */ /* Is the originating user on that channel? */
if (!Channel_IsMemberOf(Channel, Origin)) if( ! Channel_IsMemberOf( Channel, Origin )) return IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG, Client_ID( Origin ), Channel_Name( Channel ));
return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG,
Client_ID(Origin), Channel_Name(Channel)); /* Is he channel operator? */
modeok = false; if( strchr( Channel_UserModes( Channel, Origin ), 'o' )) modeok = true;
/* channel operator? */ else if( Conf_OperCanMode )
if (strchr(Channel_UserModes(Channel, Origin), 'o')) {
modeok = true;
else if (Conf_OperCanMode) {
/* IRC-Operators can use MODE as well */ /* IRC-Operators can use MODE as well */
if( Client_OperByMe( Origin )) { if( Client_OperByMe( Origin )) {
modeok = true; modeok = true;
if (Conf_OperServerMode) if ( Conf_OperServerMode ) use_servermode = true; /* Change Origin to Server */
use_servermode = true; /* Change Origin to Server */
} }
} }
} }
else modeok = true;
mode_arg = 1; mode_arg = 1;
mode_ptr = Req->argv[mode_arg]; mode_ptr = Req->argv[mode_arg];
if (Req->argc > mode_arg + 1) if( Req->argc > mode_arg + 1 ) arg_arg = mode_arg + 1;
arg_arg = mode_arg + 1; else arg_arg = -1;
else
arg_arg = -1;
/* Initial state: set or unset modes? */ /* Initial state: set or unset modes? */
skiponce = false; skiponce = false;
switch (*mode_ptr) { if( *mode_ptr == '-' ) set = false;
case '-': else if( *mode_ptr == '+' ) set = true;
set = false; else set = skiponce = true;
break;
case '+':
set = true;
break;
default:
set = true;
skiponce = true;
}
/* Prepare reply string */ /* Prepare reply string */
strcpy(the_modes, set ? "+" : "-"); if( set ) strcpy( the_modes, "+" );
else strcpy( the_modes, "-" );
the_args[0] = '\0'; the_args[0] = '\0';
x[1] = '\0'; x[1] = '\0';
connected = CONNECTED; ok = CONNECTED;
while (mode_ptr) { while( mode_ptr )
if (!skiponce) {
mode_ptr++; if( ! skiponce ) mode_ptr++;
if (!*mode_ptr) { if( ! *mode_ptr )
{
/* Try next argument if there's any */ /* Try next argument if there's any */
if (arg_arg > mode_arg) if( arg_arg > mode_arg ) mode_arg = arg_arg;
mode_arg = arg_arg; else mode_arg++;
else if( mode_arg < Req->argc ) mode_ptr = Req->argv[mode_arg];
mode_arg++; else break;
if( Req->argc > mode_arg + 1 ) arg_arg = mode_arg + 1;
if (mode_arg >= Req->argc) else arg_arg = -1;
break;
mode_ptr = Req->argv[mode_arg];
if (Req->argc > mode_arg + 1)
arg_arg = mode_arg + 1;
else
arg_arg = -1;
} }
skiponce = false; skiponce = false;
switch (*mode_ptr) { switch( *mode_ptr )
{
case '+': case '+':
case '-': case '-':
if (((*mode_ptr == '+') && !set) if((( *mode_ptr == '+' ) && ( ! set )) || (( *mode_ptr == '-' ) && ( set )))
|| ((*mode_ptr == '-') && set)) { {
/* Action modifier ("+"/"-") must be changed ... */ /* Action modifier ("+"/"-") must be changed ... */
len = strlen( the_modes ) - 1; len = strlen( the_modes ) - 1;
if (the_modes[len] == '+' || the_modes[len] == '-') { if(( the_modes[len] == '+' ) || ( the_modes[len] == '-' ))
{
/* Adjust last action modifier in result */ /* Adjust last action modifier in result */
the_modes[len] = *mode_ptr; the_modes[len] = *mode_ptr;
} else { }
else
{
/* Append modifier character to result string */ /* Append modifier character to result string */
x[0] = *mode_ptr; x[0] = *mode_ptr;
strlcat( the_modes, x, sizeof( the_modes )); strlcat( the_modes, x, sizeof( the_modes ));
} }
set = *mode_ptr == '+'; if( *mode_ptr == '+' ) set = true;
else set = false;
} }
continue; continue;
} }
/* Are there arguments left? */ /* Are there arguments left? */
if (arg_arg >= Req->argc) if( arg_arg >= Req->argc ) arg_arg = -1;
arg_arg = -1;
/* Validate modes */ /* Validate modes */
x[0] = '\0'; x[0] = '\0';
argadd[0] = '\0'; argadd[0] = '\0';
client = NULL; client = NULL;
switch (*mode_ptr) { switch( *mode_ptr )
{
/* --- Channel modes --- */ /* --- Channel modes --- */
case 'i': /* Invite only */ case 'i': /* Invite only */
case 'm': /* Moderated */ case 'm': /* Moderated */
case 'n': /* Only members can write */ case 'n': /* Only members can write */
case 's': /* Secret channel */ case 's': /* Secret channel */
case 't': /* Topic locked */ case 't': /* Topic locked */
case 'z': /* Secure connections only */ if( modeok ) x[0] = *mode_ptr;
if (modeok) else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
x[0] = *mode_ptr;
else
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin), Channel_Name(Channel));
break; break;
case 'k': /* Channel key */ case 'k': /* Channel key */
if (!set) { if( ! set )
if (modeok) {
x[0] = *mode_ptr; if( modeok ) x[0] = *mode_ptr;
else else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
break; break;
} }
if (arg_arg > mode_arg) { if( arg_arg > mode_arg )
if (modeok) { {
if( modeok )
{
Channel_ModeDel( Channel, 'k' ); Channel_ModeDel( Channel, 'k' );
Channel_SetKey(Channel, Channel_SetKey( Channel, Req->argv[arg_arg] );
Req->argv[arg_arg]); strlcpy( argadd, Channel_Key( Channel ), sizeof( argadd ));
strlcpy(argadd, Channel_Key(Channel),
sizeof(argadd));
x[0] = *mode_ptr; x[0] = *mode_ptr;
} else {
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
} }
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
Req->argv[arg_arg][0] = '\0'; Req->argv[arg_arg][0] = '\0';
arg_arg++; arg_arg++;
} else {
connected = IRC_WriteStrClient(Origin,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Origin), Req->command);
goto chan_exit;
} }
else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command );
break; break;
case 'l': /* Member limit */ case 'l': /* Member limit */
if (!set) { if( ! set )
if (modeok) {
x[0] = *mode_ptr; if( modeok ) x[0] = *mode_ptr;
else else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
break; break;
} }
if (arg_arg > mode_arg) { if( arg_arg > mode_arg )
if (modeok) { {
if( modeok )
{
l = atol( Req->argv[arg_arg] ); l = atol( Req->argv[arg_arg] );
if (l > 0 && l < 0xFFFF) { if( l > 0 && l < 0xFFFF )
{
Channel_ModeDel( Channel, 'l' ); Channel_ModeDel( Channel, 'l' );
Channel_SetMaxUsers( Channel, l ); Channel_SetMaxUsers( Channel, l );
snprintf(argadd, sizeof(argadd), snprintf( argadd, sizeof( argadd ), "%ld", l );
"%ld", l);
x[0] = *mode_ptr; x[0] = *mode_ptr;
} }
} else {
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
} }
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
Req->argv[arg_arg][0] = '\0'; Req->argv[arg_arg][0] = '\0';
arg_arg++; arg_arg++;
} else {
connected = IRC_WriteStrClient(Origin,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Origin), Req->command);
goto chan_exit;
} }
else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command );
break; break;
case 'P': /* Persistent channel */ case 'P': /* Persistent channel */
if (modeok) { if (modeok) {
/* Only IRC operators are allowed to /* Only IRC operators are allowed to
* set the 'P' channel mode! */ * set the 'P' channel mode! */
if (set && ! (Client_OperByMe(Client) if (set && ! (Client_OperByMe(Client)
|| Client_Type(Client) == CLIENT_SERVER)) || Client_Type(Client) == CLIENT_SERVER)) {
connected = IRC_WriteStrClient(Origin, ok = IRC_WriteStrClient(Origin,
ERR_NOPRIVILEGES_MSG, ERR_NOPRIVILEGES_MSG,
Client_ID(Origin)); Client_ID(Origin));
else } else
x[0] = 'P'; x[0] = 'P';
} else } else
connected = IRC_WriteStrClient(Origin, ok = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG, ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin), Client_ID(Origin),
Channel_Name(Channel)); Channel_Name(Channel));
break; break;
/* --- Channel user modes --- */ /* --- Channel user modes --- */
case 'o': /* Channel operator */ case 'o': /* Channel operator */
case 'v': /* Voice */ case 'v': /* Voice */
if (arg_arg > mode_arg) { if( arg_arg > mode_arg )
if (modeok) { {
if( modeok )
{
client = Client_Search( Req->argv[arg_arg] ); client = Client_Search( Req->argv[arg_arg] );
if (client) if( client ) x[0] = *mode_ptr;
x[0] = *mode_ptr; else ok = IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[arg_arg] );
else
connected = IRC_WriteStrClient(Client,
ERR_NOSUCHNICK_MSG,
Client_ID(Client),
Req->argv[arg_arg]);
} else {
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
} }
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
Req->argv[arg_arg][0] = '\0'; Req->argv[arg_arg][0] = '\0';
arg_arg++; arg_arg++;
} else {
connected = IRC_WriteStrClient(Origin,
ERR_NEEDMOREPARAMS_MSG,
Client_ID(Origin), Req->command);
goto chan_exit;
} }
else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command );
break; break;
/* --- Channel lists --- */ /* --- Channel lists --- */
case 'I': /* Invite lists */ case 'I': /* Invite lists */
case 'b': /* Ban lists */ if( arg_arg > mode_arg )
if (arg_arg > mode_arg) { {
/* modify list */ /* modify list */
if (modeok) { if( modeok )
connected = set {
? Add_Ban_Invite(*mode_ptr, Origin, if( set ) Add_Invite( Origin, Client, Channel, Req->argv[arg_arg] );
Client, Channel, else Del_Invite( Origin, Client, Channel, Req->argv[arg_arg] );
Req->argv[arg_arg])
: Del_Ban_Invite(*mode_ptr, Origin,
Client, Channel,
Req->argv[arg_arg]);
} else {
connected = IRC_WriteStrClient(Origin,
ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(Origin),
Channel_Name(Channel));
} }
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
Req->argv[arg_arg][0] = '\0'; Req->argv[arg_arg][0] = '\0';
arg_arg++; arg_arg++;
} else {
if (*mode_ptr == 'I')
Channel_ShowInvites(Origin, Channel);
else
Channel_ShowBans(Origin, Channel);
} }
else Channel_ShowInvites( Origin, Channel );
break; break;
case 'b': /* Ban lists */
if( arg_arg > mode_arg )
{
/* modify list */
if( modeok )
{
if( set ) Add_Ban( Origin, Client, Channel, Req->argv[arg_arg] );
else Del_Ban( Origin, Client, Channel, Req->argv[arg_arg] );
}
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
Req->argv[arg_arg][0] = '\0';
arg_arg++;
}
else Channel_ShowBans( Origin, Channel );
break;
default: default:
Log(LOG_DEBUG, Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\" on %s!?", set ? '+' : '-', *mode_ptr, Client_ID( Origin ), Channel_Name( Channel ));
"Unknown mode \"%c%c\" from \"%s\" on %s!?", if( Client_Type( Client ) != CLIENT_SERVER ) ok = IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Origin ), set ? '+' : '-', *mode_ptr );
set ? '+' : '-', *mode_ptr, Client_ID(Origin),
Channel_Name(Channel));
if (Client_Type(Client) != CLIENT_SERVER)
connected = IRC_WriteStrClient(Origin,
ERR_UMODEUNKNOWNFLAG2_MSG,
Client_ID(Origin),
set ? '+' : '-', *mode_ptr);
x[0] = '\0'; x[0] = '\0';
goto chan_exit; goto chan_exit;
} /* switch() */ }
if( ! ok ) break;
if (!connected)
break;
/* Is there a valid mode change? */ /* Is there a valid mode change? */
if (!x[0]) if( ! x[0] ) continue;
continue;
/* Validate target client */ /* Validate target client */
if (client && (!Channel_IsMemberOf(Channel, client))) { if( client && ( ! Channel_IsMemberOf( Channel, client )))
if (!IRC_WriteStrClient {
(Origin, ERR_USERNOTINCHANNEL_MSG, if( ! IRC_WriteStrClient( Origin, ERR_USERNOTINCHANNEL_MSG, Client_ID( Origin ), Client_ID( client ), Channel_Name( Channel ))) break;
Client_ID(Origin), Client_ID(client),
Channel_Name(Channel)))
break;
continue; continue;
} }
if (client) { if( set )
{
/* Set mode */
if( client )
{
/* Channel-User-Mode */ /* Channel-User-Mode */
retval = set if( Channel_UserModeAdd( Channel, client, x[0] ))
? Channel_UserModeAdd(Channel, client, x[0]) {
: Channel_UserModeDel(Channel, client, x[0]);
if (retval) {
strlcat( the_args, " ", sizeof( the_args )); strlcat( the_args, " ", sizeof( the_args ));
strlcat(the_args, Client_ID(client), strlcat( the_args, Client_ID( client ), sizeof( the_args ));
sizeof(the_args));
strlcat( the_modes, x, sizeof( the_modes )); strlcat( the_modes, x, sizeof( the_modes ));
LogDebug Log( LOG_DEBUG, "User \"%s\": Mode change on %s, now \"%s\"", Client_Mask( client ), Channel_Name( Channel ), Channel_UserModes( Channel, client ));
("User \"%s\": Mode change on %s, now \"%s\"",
Client_Mask(client), Channel_Name(Channel),
Channel_UserModes(Channel, client));
} }
} else { }
else
{
/* Channel-Mode */ /* Channel-Mode */
retval = set if( Channel_ModeAdd( Channel, x[0] ))
? Channel_ModeAdd(Channel, x[0]) {
: Channel_ModeDel(Channel, x[0]);
if (retval) {
strlcat( the_modes, x, sizeof( the_modes )); strlcat( the_modes, x, sizeof( the_modes ));
LogDebug("Channel %s: Mode change, now \"%s\".", Log( LOG_DEBUG, "Channel %s: Mode change, now \"%s\".", Channel_Name( Channel ), Channel_Modes( Channel ));
Channel_Name(Channel), }
Channel_Modes(Channel)); }
}
else
{
/* Unset mode */
if( client )
{
/* Channel-User-Mode */
if( Channel_UserModeDel( Channel, client, x[0] ))
{
strlcat( the_args, " ", sizeof( the_args ));
strlcat( the_args, Client_ID( client ), sizeof( the_args ));
strlcat( the_modes, x, sizeof( the_modes ));
Log( LOG_DEBUG, "User \"%s\": Mode change on %s, now \"%s\"", Client_Mask( client ), Channel_Name( Channel ), Channel_UserModes( Channel, client ));
}
}
else
{
/* Channel-Mode */
if( Channel_ModeDel( Channel, x[0] ))
{
strlcat( the_modes, x, sizeof( the_modes ));
Log( LOG_DEBUG, "Channel %s: Mode change, now \"%s\".", Channel_Name( Channel ), Channel_Modes( Channel ));
}
} }
} }
/* Are there additional arguments to add? */ /* Are there additional arguments to add? */
if (argadd[0]) { if( argadd[0] )
{
strlcat( the_args, " ", sizeof( the_args )); strlcat( the_args, " ", sizeof( the_args ));
strlcat( the_args, argadd, sizeof( the_args )); strlcat( the_args, argadd, sizeof( the_args ));
} }
} }
chan_exit: chan_exit:
/* Are there changed modes? */ /* Are there changed modes? */
if (the_modes[1]) { if( the_modes[1] )
{
/* Clean up mode string */ /* Clean up mode string */
len = strlen( the_modes ) - 1; len = strlen( the_modes ) - 1;
if ((the_modes[len] == '+') || (the_modes[len] == '-')) if(( the_modes[len] == '+' ) || ( the_modes[len] == '-' )) the_modes[len] = '\0';
the_modes[len] = '\0';
if (Client_Type(Client) == CLIENT_SERVER) { if( Client_Type( Client ) == CLIENT_SERVER )
/* MODE requests for local channels from other servers {
* are definitely invalid! */ /* Forward mode changes to channel users and other servers */
if (Channel_IsLocal(Channel)) { IRC_WriteStrServersPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
Log(LOG_ALERT, "Got remote MODE command for local channel!? Ignored."); IRC_WriteStrChannelPrefix( Client, Channel, Origin, false, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
return CONNECTED;
} }
else
{
if ( use_servermode ) Origin = Client_ThisServer();
/* Forward mode changes to channel users and all the
* other remote servers: */
IRC_WriteStrServersPrefix(Client, Origin,
"MODE %s %s%s", Channel_Name(Channel),
the_modes, the_args);
IRC_WriteStrChannelPrefix(Client, Channel, Origin,
false, "MODE %s %s%s", Channel_Name(Channel),
the_modes, the_args);
} else {
if (use_servermode)
Origin = Client_ThisServer();
/* Send reply to client and inform other servers and channel users */ /* Send reply to client and inform other servers and channel users */
connected = IRC_WriteStrClientPrefix(Client, Origin, ok = IRC_WriteStrClientPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
"MODE %s %s%s", Channel_Name(Channel), IRC_WriteStrServersPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
the_modes, the_args); IRC_WriteStrChannelPrefix( Client, Channel, Origin, false, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
/* Only forward requests for non-local channels */
if (!Channel_IsLocal(Channel))
IRC_WriteStrServersPrefix(Client, Origin,
"MODE %s %s%s", Channel_Name(Channel),
the_modes, the_args);
IRC_WriteStrChannelPrefix(Client, Channel, Origin,
false, "MODE %s %s%s", Channel_Name(Channel),
the_modes, the_args);
} }
} }
IRC_SetPenalty( Client, 1 ); IRC_SetPenalty( Client, 1 );
return connected; return CONNECTED;
} /* Channel_Mode */ } /* Channel_Mode */
@@ -672,10 +613,12 @@ IRC_AWAY( CLIENT *Client, REQUEST *Req )
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
/* Falsche Anzahl Parameter? */
if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if(( Req->argc == 1 ) && (Req->argv[0][0] )) if(( Req->argc == 1 ) && (Req->argv[0][0] ))
{ {
/* AWAY setzen */
Client_SetAway( Client, Req->argv[0] ); Client_SetAway( Client, Req->argv[0] );
Client_ModeAdd( Client, 'a' ); Client_ModeAdd( Client, 'a' );
IRC_WriteStrServersPrefix( Client, Client, "MODE %s :+a", Client_ID( Client )); IRC_WriteStrServersPrefix( Client, Client, "MODE %s :+a", Client_ID( Client ));
@@ -683,6 +626,7 @@ IRC_AWAY( CLIENT *Client, REQUEST *Req )
} }
else else
{ {
/* AWAY loeschen */
Client_ModeDel( Client, 'a' ); Client_ModeDel( Client, 'a' );
IRC_WriteStrServersPrefix( Client, Client, "MODE %s :-a", Client_ID( Client )); IRC_WriteStrServersPrefix( Client, Client, "MODE %s :-a", Client_ID( Client ));
return IRC_WriteStrClient( Client, RPL_UNAWAY_MSG, Client_ID( Client )); return IRC_WriteStrClient( Client, RPL_UNAWAY_MSG, Client_ID( Client ));
@@ -691,78 +635,101 @@ IRC_AWAY( CLIENT *Client, REQUEST *Req )
static bool static bool
Add_Ban_Invite(int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Pattern) Add_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
{ {
const char *mask; char *mask;
bool already; bool already;
bool ret;
assert( Client != NULL ); assert( Client != NULL );
assert( Channel != NULL ); assert( Channel != NULL );
assert( Pattern != NULL ); assert( Pattern != NULL );
assert(what == 'I' || what == 'b');
mask = Lists_MakeMask( Pattern ); mask = Lists_MakeMask( Pattern );
already = Lists_CheckDupeMask(Channel_GetListInvites(Channel), mask ); already = Lists_CheckDupeMask(Channel_GetListInvites(Channel), mask );
if (!already) { if (!already) {
if (what == 'I') if( ! Channel_AddInvite(Channel, mask, false ))
ret = Channel_AddInvite(Channel, mask, false);
else
ret = Channel_AddBan(Channel, mask);
if (!ret)
return CONNECTED; return CONNECTED;
} }
if ( already && ( Client_Type( Prefix ) == CLIENT_SERVER )) if ( already && ( Client_Type( Prefix ) == CLIENT_SERVER ))
return CONNECTED; return CONNECTED;
if (what == 'I')
return Send_ListChange( "+I", Prefix, Client, Channel, mask ); return Send_ListChange( "+I", Prefix, Client, Channel, mask );
return Send_ListChange("+b", Prefix, Client, Channel, mask); } /* Add_Invite */
}
static bool static bool
Del_Ban_Invite(int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Pattern) Add_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
{ {
const char *mask; char *mask;
struct list_head *list; bool already;
assert( Client != NULL ); assert( Client != NULL );
assert( Channel != NULL ); assert( Channel != NULL );
assert( Pattern != NULL ); assert( Pattern != NULL );
assert(what == 'I' || what == 'b');
mask = Lists_MakeMask( Pattern ); mask = Lists_MakeMask( Pattern );
if (what == 'I') already = Lists_CheckDupeMask(Channel_GetListBans(Channel), mask );
list = Channel_GetListInvites(Channel); if (!already) {
else if( ! Channel_AddBan(Channel, mask))
list = Channel_GetListBans(Channel); return CONNECTED;
Lists_Del(list, mask);
if (what == 'I')
return Send_ListChange( "-I", Prefix, Client, Channel, mask );
return Send_ListChange( "-b", Prefix, Client, Channel, mask );
} }
if ( already && ( Client_Type( Prefix ) == CLIENT_SERVER ))
return CONNECTED;
return Send_ListChange( "+b", Prefix, Client, Channel, mask );
} /* Add_Ban */
static bool static bool
Send_ListChange( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Mask ) Del_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
{ {
char *mask;
assert( Client != NULL );
assert( Channel != NULL );
assert( Pattern != NULL );
mask = Lists_MakeMask( Pattern );
Lists_Del(Channel_GetListInvites(Channel), mask);
return Send_ListChange( "-I", Prefix, Client, Channel, mask );
} /* Del_Invite */
static bool
Del_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
{
char *mask;
assert( Client != NULL );
assert( Channel != NULL );
assert( Pattern != NULL );
mask = Lists_MakeMask( Pattern );
Lists_Del(Channel_GetListBans(Channel), mask);
return Send_ListChange( "-b", Prefix, Client, Channel, mask );
} /* Del_Ban */
static bool
Send_ListChange( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Mask )
{
/* Bestaetigung an Client schicken & andere Server sowie Channel-User informieren */
bool ok; bool ok;
if( Client_Type( Client ) == CLIENT_USER ) if( Client_Type( Client ) == CLIENT_USER )
{ {
/* send confirmation to client */ /* Bestaetigung an Client */
ok = IRC_WriteStrClientPrefix( Client, Prefix, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask ); ok = IRC_WriteStrClientPrefix( Client, Prefix, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
} }
else ok = true; else ok = true;
/* to other servers */ /* an andere Server */
IRC_WriteStrServersPrefix( Client, Prefix, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask ); IRC_WriteStrServersPrefix( Client, Prefix, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
/* and local users in channel */ /* und lokale User im Channel */
IRC_WriteStrChannelPrefix( Client, Channel, Prefix, false, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask ); IRC_WriteStrChannelPrefix( Client, Channel, Prefix, false, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
return ok; return ok;

View File

@@ -14,6 +14,8 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-op.c,v 1.17 2006/12/07 17:57:20 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@@ -33,98 +35,27 @@
#include "irc-op.h" #include "irc-op.h"
static bool
try_kick(CLIENT *peer, CLIENT* from, const char *nick, const char *channel,
const char *reason)
{
CLIENT *target = Client_Search(nick);
if (!target)
return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG, Client_ID(from), nick);
Channel_Kick(peer, target, from, channel, reason);
return true;
}
GLOBAL bool GLOBAL bool
IRC_KICK( CLIENT *Client, REQUEST *Req ) IRC_KICK( CLIENT *Client, REQUEST *Req )
{ {
CLIENT *from; CLIENT *target, *from;
char *itemList = Req->argv[0];
const char* currentNick, *currentChannel, *reason;
unsigned int channelCount = 1;
unsigned int nickCount = 1;
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
if ((Req->argc < 2) || (Req->argc > 3)) /* Falsche Anzahl Parameter? */
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, if(( Req->argc < 2) || ( Req->argc > 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
Client_ID(Client), Req->command);
while (*itemList) { if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
if (*itemList == ',') { else from = Client;
*itemList = '\0'; if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
channelCount++;
}
itemList++;
}
itemList = Req->argv[1]; /* Ziel-User suchen */
while (*itemList) { target = Client_Search( Req->argv[1] );
if (*itemList == ',') { if( ! target ) return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( from ), Req->argv[1] );
*itemList = '\0';
nickCount++;
}
itemList++;
}
if (Client_Type(Client) == CLIENT_SERVER) Channel_Kick( target, from, Req->argv[0], Req->argc == 3 ? Req->argv[2] : Client_ID( from ));
from = Client_Search(Req->prefix); return CONNECTED;
else
from = Client;
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
reason = Req->argc == 3 ? Req->argv[2] : Client_ID(from);
currentNick = Req->argv[1];
currentChannel = Req->argv[0];
if (channelCount == 1) {
while (nickCount > 0) {
if (!try_kick(Client, from, currentNick,
currentChannel, reason))
return false;
while (*currentNick)
currentNick++;
currentNick++;
nickCount--;
}
} else if (channelCount == nickCount) {
while (nickCount > 0) {
if (!try_kick(Client, from, currentNick,
currentChannel, reason))
return false;
while (*currentNick)
currentNick++;
while (*currentChannel)
currentChannel++;
currentNick++;
currentChannel++;
nickCount--;
}
} else {
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
return true;
} /* IRC_KICK */ } /* IRC_KICK */
@@ -133,53 +64,42 @@ IRC_INVITE(CLIENT *Client, REQUEST *Req)
{ {
CHANNEL *chan; CHANNEL *chan;
CLIENT *target, *from; CLIENT *target, *from;
const char *colon_if_necessary;
bool remember = false; bool remember = false;
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
if (Req->argc != 2) /* Wrong number of parameters? */
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
Client_ID(Client), Req->command);
if (Client_Type(Client) == CLIENT_SERVER) if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
from = Client_Search(Req->prefix); else from = Client;
else if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
from = Client;
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
/* Search user */ /* Search user */
target = Client_Search( Req->argv[0] ); target = Client_Search( Req->argv[0] );
if (!target || (Client_Type(target) != CLIENT_USER)) if(( ! target ) || ( Client_Type( target ) != CLIENT_USER )) return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] );
return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->argv[0]);
chan = Channel_Search( Req->argv[1] ); chan = Channel_Search( Req->argv[1] );
if (chan) {
if( chan )
{
/* Channel exists. Is the user a valid member of the channel? */ /* Channel exists. Is the user a valid member of the channel? */
if (!Channel_IsMemberOf(chan, from)) if( ! Channel_IsMemberOf( chan, from )) return IRC_WriteStrClient( from, ERR_NOTONCHANNEL_MSG, Client_ID( Client ), Req->argv[1] );
return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG, Client_ID(Client), Req->argv[1]);
/* Is the channel "invite-only"? */ /* Is the channel "invite-only"? */
if (strchr(Channel_Modes(chan), 'i')) { if( strchr( Channel_Modes( chan ), 'i' ))
{
/* Yes. The user must be channel operator! */ /* Yes. The user must be channel operator! */
if (!strchr(Channel_UserModes(chan, from), 'o')) if( ! strchr( Channel_UserModes( chan, from ), 'o' )) return IRC_WriteStrClient( from, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( from ), Channel_Name( chan ));
return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
Client_ID(from), Channel_Name(chan));
remember = true; remember = true;
} }
/* Is the target user already member of the channel? */ /* Is the target user already member of the channel? */
if (Channel_IsMemberOf(chan, target)) if( Channel_IsMemberOf( chan, target )) return IRC_WriteStrClient( from, ERR_USERONCHANNEL_MSG, Client_ID( from ), Req->argv[0], Req->argv[1] );
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_Check(Channel_GetListBans(chan), target)) if( Lists_Check(Channel_GetListBans(chan), target )) remember = true;
remember = true;
if (remember) { if (remember) {
/* We must remember this invite */ /* We must remember this invite */
@@ -190,30 +110,15 @@ IRC_INVITE(CLIENT *Client, REQUEST *Req)
LogDebug("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]);
/*
* RFC 2812 says:
* 'There is no requirement that the channel [..] must exist or be a valid channel'
* The problem with this is that this allows the "channel" to contain spaces,
* in which case we must prefix its name with a colon to make it clear that
* it is only a single argument.
*/
colon_if_necessary = strchr(Req->argv[1], ' ') ? ":":"";
/* Inform target client */ /* Inform target client */
IRC_WriteStrClientPrefix(target, from, "INVITE %s %s%s", Req->argv[0], IRC_WriteStrClientPrefix( target, from, "INVITE %s %s", Req->argv[0], Req->argv[1] );
colon_if_necessary, Req->argv[1]);
if (Client_Conn(target) > NONE) { if( Client_Conn( target ) > NONE )
{
/* The target user is local, so we have to send the status code */ /* The target user is local, so we have to send the status code */
if (!IRC_WriteStrClientPrefix(from, target, RPL_INVITING_MSG, if( ! IRC_WriteStrClientPrefix( from, target, RPL_INVITING_MSG, Client_ID( from ), Req->argv[0], Req->argv[1] )) return DISCONNECTED;
Client_ID(from), Req->argv[0], colon_if_necessary, Req->argv[1]))
return DISCONNECTED;
if (strchr(Client_Modes(target), 'a') &&
!IRC_WriteStrClient(from, RPL_AWAY_MSG, Client_ID(from),
Client_ID(target), Client_Away(target)))
return DISCONNECTED;
} }
return CONNECTED; return CONNECTED;
} /* IRC_INVITE */ } /* IRC_INVITE */

View File

@@ -1,6 +1,6 @@
/* /*
* ngIRCd -- The Next Generation IRC Daemon * ngIRCd -- The Next Generation IRC Daemon
* Copyright (c)2001-2008 Alexander Barton (alex@barton.de) * Copyright (c)2001,2002 by 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
@@ -14,9 +14,10 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-oper.c,v 1.29 2007/08/02 10:14:26 fw Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -31,53 +32,51 @@
#include "match.h" #include "match.h"
#include "messages.h" #include "messages.h"
#include "parse.h" #include "parse.h"
#include "op.h"
#include <exp.h> #include <exp.h>
#include "irc-oper.h" #include "irc-oper.h"
/**
* Handle invalid received OPER command.
* Log OPER attempt and send error message to client.
*/
static bool static bool
Bad_OperPass(CLIENT *Client, char *errtoken, char *errmsg) Bad_OperPass(CLIENT *Client, char *errtoken, char *errmsg)
{ {
Log(LOG_WARNING, "Got invalid OPER from \"%s\": \"%s\" -- %s", Log( LOG_WARNING, "Got invalid OPER from \"%s\": \"%s\" -- %s", Client_Mask( Client ),
Client_Mask(Client), errtoken, errmsg); errtoken, errmsg);
IRC_SetPenalty(Client, 3); IRC_SetPenalty(Client, 3);
return IRC_WriteStrClient(Client, ERR_PASSWDMISMATCH_MSG, return IRC_WriteStrClient( Client, ERR_PASSWDMISMATCH_MSG, Client_ID( Client ));
Client_ID(Client)); }
} /* Bad_OperPass */
GLOBAL bool GLOBAL bool
IRC_OPER( CLIENT *Client, REQUEST *Req ) IRC_OPER( CLIENT *Client, REQUEST *Req )
{ {
struct Conf_Oper *op; unsigned int i;
size_t len, i;
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
/* Falsche Anzahl Parameter? */
if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
len = array_length(&Conf_Opers, sizeof(*op)); /* Operator suchen */
op = array_start(&Conf_Opers); for( i = 0; i < Conf_Oper_Count; i++)
for (i = 0; i < len && strcmp(op[i].name, Req->argv[0]); i++) {
; if( Conf_Oper[i].name[0] && Conf_Oper[i].pwd[0] && ( strcmp( Conf_Oper[i].name, Req->argv[0] ) == 0 )) break;
if (i >= len) }
if( i >= Conf_Oper_Count )
return Bad_OperPass(Client, Req->argv[0], "not configured"); return Bad_OperPass(Client, Req->argv[0], "not configured");
if (strcmp(op[i].pwd, Req->argv[1]) != 0) /* Stimmt das Passwort? */
return Bad_OperPass(Client, op[i].name, "bad password"); if( strcmp( Conf_Oper[i].pwd, Req->argv[1] ) != 0 )
return Bad_OperPass(Client, Conf_Oper[i].name, "Bad password");
if (op[i].mask && (!Match(op[i].mask, Client_Mask(Client)))) /* Authorized Mask? */
return Bad_OperPass(Client, op[i].mask, "hostmask check failed"); if( Conf_Oper[i].mask && (! Match( Conf_Oper[i].mask, Client_Mask( Client ) )))
return Bad_OperPass(Client, Conf_Oper[i].mask, "hostmask check failed" );
if( ! Client_HasMode( Client, 'o' )) if( ! Client_HasMode( Client, 'o' ))
{ {
/* noch kein o-Mode gesetzt */
Client_ModeAdd( Client, 'o' ); Client_ModeAdd( Client, 'o' );
if( ! IRC_WriteStrClient( Client, "MODE %s :+o", Client_ID( Client ))) return DISCONNECTED; if( ! IRC_WriteStrClient( Client, "MODE %s :+o", Client_ID( Client ))) return DISCONNECTED;
IRC_WriteStrServersPrefix( NULL, Client, "MODE %s :+o", Client_ID( Client )); IRC_WriteStrServersPrefix( NULL, Client, "MODE %s :+o", Client_ID( Client ));
@@ -101,8 +100,10 @@ IRC_DIE(CLIENT * Client, REQUEST * Req)
assert(Client != NULL); assert(Client != NULL);
assert(Req != NULL); assert(Req != NULL);
if (!Op_Check(Client, Req)) /* Not a local IRC operator? */
return Op_NoPrivileges(Client, Req); if ((!Client_HasMode(Client, 'o')) || (!Client_OperByMe(Client)))
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
Client_ID(Client));
/* Bad number of parameters? */ /* Bad number of parameters? */
#ifdef STRICT_RFC #ifdef STRICT_RFC
@@ -141,8 +142,8 @@ IRC_REHASH( CLIENT *Client, REQUEST *Req )
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
if (!Op_Check(Client, Req)) /* Not a local IRC operator? */
return Op_NoPrivileges(Client, Req); if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
/* Bad number of parameters? */ /* Bad number of parameters? */
if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
@@ -162,8 +163,8 @@ IRC_RESTART( CLIENT *Client, REQUEST *Req )
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
if (!Op_Check(Client, Req)) /* Not a local IRC operator? */
return Op_NoPrivileges(Client, Req); if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
/* Bad number of parameters? */ /* Bad number of parameters? */
if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
@@ -180,18 +181,17 @@ IRC_RESTART( CLIENT *Client, REQUEST *Req )
GLOBAL bool GLOBAL bool
IRC_CONNECT(CLIENT * Client, REQUEST * Req) IRC_CONNECT(CLIENT * Client, REQUEST * Req)
{ {
CLIENT *from, *target;
assert(Client != NULL); assert(Client != NULL);
assert(Req != NULL); assert(Req != NULL);
if (Client_Type(Client) != CLIENT_SERVER /* Not a local IRC operator? */
&& !Client_HasMode(Client, 'o')) if ((!Client_HasMode(Client, 'o')) || (!Client_OperByMe(Client)))
return Op_NoPrivileges(Client, Req); return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
Client_ID(Client));
/* Bad number of parameters? */ /* Bad number of parameters? */
if (Req->argc != 1 && Req->argc != 2 && Req->argc != 3 && if ((Req->argc != 1) && (Req->argc != 2) && (Req->argc != 5))
Req->argc != 5 && Req->argc != 6)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command); Client_ID(Client), Req->command);
@@ -200,55 +200,23 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command); Client_ID(Client), Req->command);
from = Client; Log(LOG_NOTICE | LOG_snotice,
target = Client_ThisServer(); "Got CONNECT command from \"%s\" for \"%s\".", Client_Mask(Client),
Req->argv[0]);
if (Req->argc == 3 || Req->argc == 6) {
/* This CONNECT has a target parameter */
if (Client_Type(Client) == CLIENT_SERVER && Req->prefix)
from = Client_Search(Req->prefix);
if (! from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
target = (Req->argc == 3) ? Client_Search(Req->argv[2])
: Client_Search(Req->argv[5]);
if (! target || Client_Type(target) != CLIENT_SERVER)
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
Client_ID(from), Req->argv[0]);
}
if (target != Client_ThisServer()) {
/* Forward CONNECT command ... */
if (Req->argc == 3)
IRC_WriteStrClientPrefix(target, from,
"CONNECT %s %s :%s", Req->argv[0],
Req->argv[1], Req->argv[2]);
else
IRC_WriteStrClientPrefix(target, from,
"CONNECT %s %s %s %s %s :%s", Req->argv[0],
Req->argv[1], Req->argv[2], Req->argv[3],
Req->argv[4], Req->argv[5]);
return CONNECTED;
}
if (!Op_Check(from, Req))
return Op_NoPrivileges(Client, Req);
switch (Req->argc) { switch (Req->argc) {
case 1: case 1:
if (!Conf_EnablePassiveServer(Req->argv[0])) if (!Conf_EnablePassiveServer(Req->argv[0]))
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG, return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(from), Client_ID(Client),
Req->argv[0]); Req->argv[0]);
break; break;
case 2: case 2:
case 3:
/* Connect configured server */ /* Connect configured server */
if (!Conf_EnableServer if (!Conf_EnableServer
(Req->argv[0], (UINT16) atoi(Req->argv[1]))) (Req->argv[0], (UINT16) atoi(Req->argv[1])))
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG, return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(from), Client_ID(Client),
Req->argv[0]); Req->argv[0]);
break; break;
default: default:
@@ -256,69 +224,50 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
if (!Conf_AddServer if (!Conf_AddServer
(Req->argv[0], (UINT16) atoi(Req->argv[1]), Req->argv[2], (Req->argv[0], (UINT16) atoi(Req->argv[1]), Req->argv[2],
Req->argv[3], Req->argv[4])) Req->argv[3], Req->argv[4]))
return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG, return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(from), Client_ID(Client),
Req->argv[0]); Req->argv[0]);
} }
Log(LOG_NOTICE | LOG_snotice,
"Got CONNECT command from \"%s\" for \"%s\".", Client_Mask(from),
Req->argv[0]);
IRC_SendWallops(Client_ThisServer(), Client_ThisServer(),
"Received CONNECT %s from %s",
Req->argv[0], Client_ID(from));
return CONNECTED; return CONNECTED;
} /* IRC_CONNECT */ } /* IRC_CONNECT */
/**
* Disconnect (and disable) configured server.
*/
GLOBAL bool GLOBAL bool
IRC_DISCONNECT(CLIENT *Client, REQUEST *Req ) IRC_DISCONNECT(CLIENT *Client, REQUEST *Req )
{ {
/* Disconnect and disable configured server */
CONN_ID my_conn; CONN_ID my_conn;
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
if (!Op_Check(Client, Req)) /* Not a local IRC operator? */
return Op_NoPrivileges(Client, Req); if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
/* Bad number of parameters? */ /* Bad number of parameters? */
if (Req->argc != 1) if( Req->argc != 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
IRC_SendWallops(Client_ThisServer(), Client_ThisServer(), Log( LOG_NOTICE|LOG_snotice, "Got DISCONNECT command from \"%s\" for0 \"%s\".", Client_Mask( Client ), Req->argv[0]);
"Received DISCONNECT %s from %s",
Req->argv[0], Client_ID(Client));
Log(LOG_NOTICE | LOG_snotice,
"Got DISCONNECT command from \"%s\" for \"%s\".",
Client_Mask(Client), Req->argv[0]);
/* Save ID of this connection */ /* Save ID of this connection */
my_conn = Client_Conn( Client ); my_conn = Client_Conn( Client );
/* Disconnect configured server */ /* Connect configured server */
if (!Conf_DisableServer(Req->argv[0])) if( ! Conf_DisableServer( Req->argv[0] )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] );
return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
Client_ID(Client), Req->argv[0]);
/* Are we still connected or were we killed, too? */ /* Are we still connected or were we killed, too? */
if (Conn_GetClient(my_conn)) if( Conn_GetClient( my_conn )) return CONNECTED;
return CONNECTED; else return DISCONNECTED;
else } /* IRC_CONNECT */
return DISCONNECTED;
} /* IRC_DISCONNECT */
GLOBAL bool GLOBAL bool
IRC_WALLOPS( CLIENT *Client, REQUEST *Req ) IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
{ {
CLIENT *from; CLIENT *to, *from;
int client_type;
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
@@ -326,7 +275,8 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
if (Req->argc != 1) if (Req->argc != 1)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
switch (Client_Type(Client)) { client_type = Client_Type(Client);
switch (client_type) {
case CLIENT_USER: case CLIENT_USER:
if (!Client_OperByMe(Client)) if (!Client_OperByMe(Client))
return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG, Client_ID(Client)); return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG, Client_ID(Client));
@@ -342,9 +292,25 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
if (!from) if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix); return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix);
IRC_SendWallops(Client, from, "%s", Req->argv[0]); for (to=Client_First(); to != NULL; to=Client_Next(to)) {
if (Client_Conn(to) < 0) /* no local connection or WALLOPS origin */
continue;
client_type = Client_Type(to);
switch (client_type) {
case CLIENT_USER:
if (Client_HasMode(to, 'w'))
IRC_WriteStrClientPrefix(to, from, "WALLOPS :%s", Req->argv[0]);
break;
case CLIENT_SERVER:
if (to != Client)
IRC_WriteStrClientPrefix(to, from, "WALLOPS :%s", Req->argv[0]);
break;
}
}
return CONNECTED; return CONNECTED;
} /* IRC_WALLOPS */ }
/* -eof- */ /* -eof- */

View File

@@ -14,6 +14,8 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: irc-server.c,v 1.46 2007/11/21 12:16:36 alex Exp $";
#include "imp.h" #include "imp.h"
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
@@ -24,7 +26,6 @@
#include "defines.h" #include "defines.h"
#include "resolve.h" #include "resolve.h"
#include "conn.h" #include "conn.h"
#include "conn-func.h"
#include "conn-zip.h" #include "conn-zip.h"
#include "conf.h" #include "conf.h"
#include "client.h" #include "client.h"
@@ -37,7 +38,6 @@
#include "numeric.h" #include "numeric.h"
#include "ngircd.h" #include "ngircd.h"
#include "irc-info.h" #include "irc-info.h"
#include "op.h"
#include "exp.h" #include "exp.h"
#include "irc-server.h" #include "irc-server.h"
@@ -50,8 +50,9 @@
GLOBAL bool GLOBAL bool
IRC_SERVER( CLIENT *Client, REQUEST *Req ) IRC_SERVER( CLIENT *Client, REQUEST *Req )
{ {
char str[LINE_LEN]; char str[LINE_LEN], *ptr;
CLIENT *from, *c; CLIENT *from, *c;
bool ok;
int i; int i;
CONN_ID con; CONN_ID con;
@@ -63,82 +64,80 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG, return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG,
Client_ID(Client), Req->command); Client_ID(Client), Req->command);
if (Client_Type(Client) == CLIENT_GOTPASS || if (Client_Type(Client) == CLIENT_GOTPASS) {
Client_Type(Client) == CLIENT_GOTPASS_2813) {
/* We got a PASS command from the peer, and now a SERVER /* We got a PASS command from the peer, and now a SERVER
* command: the peer tries to register itself as a server. */ * command: the peer tries to register itself as a server. */
LogDebug("Connection %d: got SERVER command (new server link) ...", LogDebug("Connection %d: got SERVER command (new server link) ...",
Client_Conn(Client)); Client_Conn(Client));
/* 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 );
/* Ist this server configured on out side? */ /* Ist dieser Server bei uns konfiguriert? */
for( i = 0; i < MAX_SERVERS; i++ ) if( strcasecmp( Req->argv[0], Conf_Server[i].name ) == 0 ) break; for( i = 0; i < MAX_SERVERS; i++ ) if( strcasecmp( Req->argv[0], Conf_Server[i].name ) == 0 ) break;
if( i >= MAX_SERVERS ) if( i >= MAX_SERVERS )
{ {
/* Server ist nicht konfiguriert! */
Log( LOG_ERR, "Connection %d: Server \"%s\" not configured here!", Client_Conn( Client ), Req->argv[0] ); Log( LOG_ERR, "Connection %d: Server \"%s\" not configured here!", Client_Conn( Client ), Req->argv[0] );
Conn_Close( Client_Conn( Client ), NULL, "Server not configured here", true); Conn_Close( Client_Conn( Client ), NULL, "Server not configured here", true);
return DISCONNECTED; return DISCONNECTED;
} }
if( strcmp( Client_Password( Client ), Conf_Server[i].pwd_in ) != 0 ) if( strcmp( Client_Password( Client ), Conf_Server[i].pwd_in ) != 0 )
{ {
/* wrong password */ /* Falsches Passwort */
Log( LOG_ERR, "Connection %d: Got bad password from server \"%s\"!", Client_Conn( Client ), Req->argv[0] ); Log( LOG_ERR, "Connection %d: Got bad password from server \"%s\"!", Client_Conn( Client ), Req->argv[0] );
Conn_Close( Client_Conn( Client ), NULL, "Bad password", true); Conn_Close( Client_Conn( Client ), NULL, "Bad password", true);
return DISCONNECTED; return DISCONNECTED;
} }
/* Is there a registered server with this ID? */ /* Ist ein Server mit dieser ID bereits registriert? */
if( ! Client_CheckID( Client, Req->argv[0] )) return DISCONNECTED; if( ! Client_CheckID( Client, Req->argv[0] )) return DISCONNECTED;
/* Server-Strukturen fuellen ;-) */
Client_SetID( Client, Req->argv[0] ); Client_SetID( Client, Req->argv[0] );
Client_SetHops( Client, 1 ); Client_SetHops( Client, 1 );
Client_SetInfo( Client, Req->argv[Req->argc - 1] ); Client_SetInfo( Client, Req->argv[Req->argc - 1] );
/* Is this server registering on our side, or are we connecting to /* Meldet sich der Server bei uns an (d.h., bauen nicht wir
* a remote server? */ * selber die Verbindung zu einem anderen Server auf)? */
con = Client_Conn( Client ); con = Client_Conn( Client );
if (Client_Token(Client) != TOKEN_OUTBOUND) { if( Client_Token( Client ) != TOKEN_OUTBOUND )
/* Incoming connection, send user/pass */ {
if (!IRC_WriteStrClient(Client, "PASS %s %s", /* Eingehende Verbindung: Unseren SERVER- und PASS-Befehl senden */
Conf_Server[i].pwd_out, ok = true;
NGIRCd_ProtoID) if( ! IRC_WriteStrClient( Client, "PASS %s %s", Conf_Server[i].pwd_out, NGIRCd_ProtoID )) ok = false;
|| !IRC_WriteStrClient(Client, "SERVER %s 1 :%s", else ok = IRC_WriteStrClient( Client, "SERVER %s 1 :%s", Conf_ServerName, Conf_ServerInfo );
Conf_ServerName, if( ! ok )
Conf_ServerInfo)) { {
Conn_Close(con, "Unexpected server behavior!", Conn_Close( con, "Unexpected server behavior!", NULL, false );
NULL, false);
return DISCONNECTED; return DISCONNECTED;
} }
Client_SetIntroducer( Client, Client ); Client_SetIntroducer( Client, Client );
Client_SetToken( Client, 1 ); Client_SetToken( Client, 1 );
} else { }
/* outgoing connect, we already sent a SERVER and PASS else
* command to the peer */ {
/* Ausgehende verbindung, SERVER und PASS wurden von uns bereits
* an die Gegenseite uerbermittelt */
Client_SetToken( Client, atoi( Req->argv[1] )); Client_SetToken( Client, atoi( Req->argv[1] ));
} }
/* Mark this connection as belonging to an configured server */ /* Mark this connection as belonging to an configured server */
Conf_SetServer(i, con); Conf_SetServer(i, con);
/* Check protocol level */
if (Client_Type(Client) == CLIENT_GOTPASS) {
/* We got a "simple" PASS command, so the peer is
* using the protocol as defined in RFC 1459. */
if (! (Conn_Options(con) & CONN_RFC1459))
Log(LOG_INFO,
"Switching connection %d (\"%s\") to RFC 1459 compatibility mode.",
con, Client_ID(Client));
Conn_SetOption(con, CONN_RFC1459);
}
Client_SetType(Client, CLIENT_UNKNOWNSERVER); Client_SetType(Client, CLIENT_UNKNOWNSERVER);
#ifdef ZLIB #ifdef ZLIB
if (strchr(Client_Flags(Client), 'Z') && !Zip_InitConn(con)) { /* Kompression initialisieren, wenn erforderlich */
if( strchr( Client_Flags( Client ), 'Z' ))
{
if( ! Zip_InitConn( con ))
{
/* Fehler! */
Conn_Close( con, "Can't inizialize compression (zlib)!", NULL, false ); Conn_Close( con, "Can't inizialize compression (zlib)!", NULL, false );
return DISCONNECTED; return DISCONNECTED;
} }
}
#endif #endif
#ifdef IRCPLUS #ifdef IRCPLUS
@@ -161,34 +160,43 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
} }
else if( Client_Type( Client ) == CLIENT_SERVER ) else if( Client_Type( Client ) == CLIENT_SERVER )
{ {
/* New server is being introduced to the network */ /* Neuer Server wird im Netz angekuendigt */
/* Falsche Anzahl Parameter? */
if( Req->argc != 4 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); if( Req->argc != 4 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* check for existing server with same ID */ /* Ist ein Server mit dieser ID bereits registriert? */
if( ! Client_CheckID( Client, Req->argv[0] )) return DISCONNECTED; if( ! Client_CheckID( Client, Req->argv[0] )) return DISCONNECTED;
/* Ueberfluessige Hostnamen aus Info-Text entfernen */
ptr = strchr( Req->argv[3] + 2, '[' );
if( ! ptr ) ptr = Req->argv[3];
from = Client_Search( Req->prefix ); from = Client_Search( Req->prefix );
if( ! from ) if( ! from )
{ {
/* Uh, Server, that introduced the new server is unknown?! */ /* Hm, Server, der diesen einfuehrt, ist nicht bekannt!? */
Log( LOG_ALERT, "Unknown ID in prefix of SERVER: \"%s\"! (on connection %d)", Req->prefix, Client_Conn( Client )); Log( LOG_ALERT, "Unknown ID in prefix of SERVER: \"%s\"! (on connection %d)", Req->prefix, Client_Conn( Client ));
Conn_Close( Client_Conn( Client ), NULL, "Unknown ID in prefix of SERVER", true); Conn_Close( Client_Conn( Client ), NULL, "Unknown ID in prefix of SERVER", true);
return DISCONNECTED; return DISCONNECTED;
} }
c = Client_NewRemoteServer(Client, Req->argv[0], from, atoi(Req->argv[1]), atoi(Req->argv[2]), Req->argv[3], true); /* Neue Client-Struktur anlegen */
if (!c) { c = Client_NewRemoteServer( Client, Req->argv[0], from, atoi( Req->argv[1] ), atoi( Req->argv[2] ), ptr, true);
if( ! c )
{
/* Neue Client-Struktur konnte nicht angelegt werden */
Log( LOG_ALERT, "Can't create client structure for server! (on connection %d)", Client_Conn( Client )); Log( LOG_ALERT, "Can't create client structure for server! (on connection %d)", Client_Conn( Client ));
Conn_Close( Client_Conn( Client ), NULL, "Can't allocate client structure for remote server", true); Conn_Close( Client_Conn( Client ), NULL, "Can't allocate client structure for remote server", true);
return DISCONNECTED; return DISCONNECTED;
} }
/* Log-Meldung zusammenbauen und ausgeben */
if(( Client_Hops( c ) > 1 ) && ( Req->prefix[0] )) snprintf( str, sizeof( str ), "connected to %s, ", Client_ID( from )); if(( Client_Hops( c ) > 1 ) && ( Req->prefix[0] )) snprintf( str, sizeof( str ), "connected to %s, ", Client_ID( from ));
else strcpy( str, "" ); else strcpy( str, "" );
Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" registered (via %s, %s%d hop%s).", Client_ID( c ), Client_ID( Client ), str, Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" ); Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" registered (via %s, %s%d hop%s).", Client_ID( c ), Client_ID( Client ), str, Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
/* notify other servers */ /* Andere Server informieren */
IRC_WriteStrServersPrefix( Client, from, "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c )); IRC_WriteStrServersPrefix( Client, from, "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ));
return CONNECTED; return CONNECTED;
@@ -209,6 +217,7 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
/* Falsche Anzahl Parameter? */
if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
strlcpy( nick_in, Req->argv[1], sizeof( nick_in )); strlcpy( nick_in, Req->argv[1], sizeof( nick_in ));
@@ -220,7 +229,7 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
{ {
is_op = is_voiced = false; is_op = is_voiced = false;
/* cut off prefixes */ /* Prefixe abschneiden */
while(( *ptr == '@' ) || ( *ptr == '+' )) while(( *ptr == '@' ) || ( *ptr == '+' ))
{ {
if( *ptr == '@' ) is_op = true; if( *ptr == '@' ) is_op = true;
@@ -238,14 +247,14 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
if( is_op ) Channel_UserModeAdd( chan, c, 'o' ); if( is_op ) Channel_UserModeAdd( chan, c, 'o' );
if( is_voiced ) Channel_UserModeAdd( chan, c, 'v' ); if( is_voiced ) Channel_UserModeAdd( chan, c, 'v' );
/* announce to channel... */ /* im Channel bekannt machen */
IRC_WriteStrChannelPrefix( Client, chan, c, false, "JOIN :%s", channame ); IRC_WriteStrChannelPrefix( Client, chan, c, false, "JOIN :%s", channame );
/* set Channel-User-Modes */ /* Channel-User-Modes setzen */
strlcpy( modes, Channel_UserModes( chan, c ), sizeof( modes )); strlcpy( modes, Channel_UserModes( chan, c ), sizeof( modes ));
if( modes[0] ) if( modes[0] )
{ {
/* send modes to channel */ /* Modes im Channel bekannt machen */
IRC_WriteStrChannelPrefix( Client, chan, Client, false, "MODE %s +%s %s", channame, modes, Client_ID( c )); IRC_WriteStrChannelPrefix( Client, chan, Client, false, "MODE %s +%s %s", channame, modes, Client_ID( c ));
} }
@@ -256,110 +265,60 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
} }
else Log( LOG_ERR, "Got NJOIN for unknown nick \"%s\" for channel \"%s\"!", ptr, channame ); else Log( LOG_ERR, "Got NJOIN for unknown nick \"%s\" for channel \"%s\"!", ptr, channame );
/* search for next Nick */ /* naechsten Nick suchen */
ptr = strtok( NULL, "," ); ptr = strtok( NULL, "," );
} }
/* forward to other servers */ /* an andere Server weiterleiten */
if( nick_out[0] != '\0' ) IRC_WriteStrServersPrefix( Client, Client_ThisServer( ), "NJOIN %s :%s", Req->argv[0], nick_out ); if( nick_out[0] != '\0' ) IRC_WriteStrServersPrefix( Client, Client_ThisServer( ), "NJOIN %s :%s", Req->argv[0], nick_out );
return CONNECTED; return CONNECTED;
} /* IRC_NJOIN */ } /* IRC_NJOIN */
/**
* Handler for the IRC command "SQUIT".
* See RFC 2813 section 4.1.2 and RFC 2812 section 3.1.8.
*/
GLOBAL bool GLOBAL bool
IRC_SQUIT( CLIENT *Client, REQUEST *Req ) IRC_SQUIT( CLIENT *Client, REQUEST *Req )
{ {
char msg[COMMAND_LEN], logmsg[COMMAND_LEN]; CLIENT *target;
CLIENT *from, *target; char msg[LINE_LEN + 64];
CONN_ID con;
assert( Client != NULL ); assert( Client != NULL );
assert( Req != NULL ); assert( Req != NULL );
if (Client_Type(Client) != CLIENT_SERVER /* Falsche Anzahl Parameter? */
&& !Client_HasMode(Client, 'o')) if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
return Op_NoPrivileges(Client, Req);
/* Bad number of arguments? */ Log( LOG_DEBUG, "Got SQUIT from %s for \"%s\": \"%s\" ...", Client_ID( Client ), Req->argv[0], Req->argv[1] );
if (Req->argc != 2)
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
if (Client_Type(Client) == CLIENT_SERVER && Req->prefix) {
from = Client_Search(Req->prefix);
if (Client_Type(from) != CLIENT_SERVER
&& !Op_Check(Client, Req))
return Op_NoPrivileges(Client, Req);
} else
from = Client;
if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
Log(LOG_DEBUG, "Got SQUIT from %s for \"%s\": \"%s\" ...",
Client_ID(from), Req->argv[0], Req->argv[1]);
target = Client_Search( Req->argv[0] ); target = Client_Search( Req->argv[0] );
if (Client_Type(Client) != CLIENT_SERVER && if( ! target )
target == Client_ThisServer()) {
return Op_NoPrivileges(Client, Req); /* Den Server kennen wir nicht (mehr), also nichts zu tun. */
if (!target) { Log( LOG_WARNING, "Got SQUIT from %s for unknown server \"%s\"!?", Client_ID( Client ), Req->argv[0] );
/* The server is (already) unknown */
Log(LOG_WARNING,
"Got SQUIT from %s for unknown server \"%s\"!?",
Client_ID(Client), Req->argv[0]);
return CONNECTED; return CONNECTED;
} }
con = Client_Conn(target);
if( Req->argv[1][0] ) if( Req->argv[1][0] )
if (Client_NextHop(from) != Client || con > NONE) {
snprintf(msg, sizeof(msg), "%s (SQUIT from %s)", if( strlen( Req->argv[1] ) > LINE_LEN ) Req->argv[1][LINE_LEN] = '\0';
Req->argv[1], Client_ID(from)); snprintf( msg, sizeof( msg ), "%s (SQUIT from %s).", Req->argv[1], Client_ID( Client ));
else }
strlcpy(msg, Req->argv[1], sizeof(msg)); else snprintf( msg, sizeof( msg ), "Got SQUIT from %s.", Client_ID( Client ));
else
snprintf(msg, sizeof(msg), "Got SQUIT from %s",
Client_ID(from));
if (con > NONE) { if( Client_Conn( target ) > NONE )
/* We are directly connected to the target server, so we {
* have to tear down the connection and to inform all the /* dieser Server hat die Connection */
* other remaining servers in the network */ if( Req->argv[1][0] ) Conn_Close( Client_Conn( target ), msg, Req->argv[1], true);
IRC_SendWallops(Client_ThisServer(), Client_ThisServer(), else Conn_Close( Client_Conn( target ), msg, NULL, true);
"Received SQUIT %s from %s: %s",
Req->argv[0], Client_ID(from),
Req->argv[1][0] ? Req->argv[1] : "-");
Conn_Close(con, NULL, msg, true);
if (con == Client_Conn(Client))
return DISCONNECTED; return DISCONNECTED;
} else {
/* This server is not directly connected, so the SQUIT must
* be forwarded ... */
if (Client_Type(from) != CLIENT_SERVER) {
/* The origin is not an IRC server, so don't evaluate
* this SQUIT but simply forward it */
IRC_WriteStrClientPrefix(Client_NextHop(target),
from, "SQUIT %s :%s", Req->argv[0], Req->argv[1]);
} else {
/* SQUIT has been generated by another server, so
* remove the target server from the network! */
logmsg[0] = '\0';
if (!strchr(msg, '('))
snprintf(logmsg, sizeof(logmsg),
"%s (SQUIT from %s)", Req->argv[1],
Client_ID(from));
Client_Destroy(target, logmsg[0] ? logmsg : msg,
msg, false);
}
} }
else
{
/* Verbindung hielt anderer Server */
Client_Destroy( target, msg, Req->argv[1], false );
return CONNECTED; return CONNECTED;
}
} /* IRC_SQUIT */ } /* IRC_SQUIT */
/* -eof- */ /* -eof- */

Some files were not shown because too many files have changed in this diff Show More