about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--AUTHORS4
-rw-r--r--ChangeLog83
-rw-r--r--INSTALL.md8
-rw-r--r--Makefile.am18
-rw-r--r--NEWS41
-rw-r--r--contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj23
-rwxr-xr-xcontrib/nglog.sh10
-rw-r--r--doc/Makefile.am6
-rw-r--r--src/ngircd/client.c8
-rw-r--r--src/ngircd/conf.c171
-rw-r--r--src/ngircd/conn-func.c2
-rw-r--r--src/ngircd/conn.c58
-rw-r--r--src/ngircd/conn.h14
-rw-r--r--src/ngircd/irc-oper.c9
-rw-r--r--src/ngircd/ngircd.c1
-rw-r--r--src/portab/portab.h4
17 files changed, 250 insertions, 211 deletions
diff --git a/.travis.yml b/.travis.yml
index 3b82280a..3131cbb6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,4 @@
 language: c
-sudo: false
 addons:
   apt:
     packages:
diff --git a/AUTHORS b/AUTHORS
index 4c555dbc..7af0c1e7 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -40,6 +40,7 @@ Dana Dahlstrom <dana+ngIRCd@cs.ucsd.edu>
 David Kingston <deathking1337@aim.com>
 DNS <dns@rbose.org>
 Eric Grunow <egrunow@ucsd.edu>
+Fabrice Fontaine <fontaine.fabrice@gmail.com>
 Federico G. Schwindt <fgsch@lodoss.net>
 Gabor Adam Toth <tg@tgbit.net>
 Götz Hoffart <goetz@hoffart.de>
@@ -48,8 +49,10 @@ Ilja Osthoff <i.osthoff@gmx.net>
 ItsOnlyBinary <ItsOnlyBinary@users.noreply.github.com>
 James Lu <james@overdrivenetworks.com>
 Jari Aalto <jari.aalto@cante.net>
+JRMU <jrmu@lecturify.com>
 LucentW <lucent@zebes.info>
 Mantas Mikulėnas <grawity@gmail.com>
+Michi <michi+ngircd@dataswamp.org>
 Neale Pickett <neale@woozle.org>
 Peter Powell <petpow@saberuk.com>
 Rolf Eike Beer <eike@sf-mail.de>
@@ -63,6 +66,7 @@ Tassilo Schweyer <dev@welterde.de>
 Tom Ryder <tom@sanctum.geek.nz>
 Unit 193 <unit193@ubuntu.com>
 William Pitcock <nenolod@dereferenced.org>
+Windree <57554809+Windree@users.noreply.github.com>
 xor <xorboy@gmail.com>
 Yecheng Fu <cofyc.jackson@gmail.com>
 
diff --git a/ChangeLog b/ChangeLog
index 06dc4f83..83a4bc5c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,6 +8,89 @@
 
                                -- ChangeLog --
 
+ngIRCd 26
+
+  ngIRCd 26~rc1
+  - Remove deprecated legacy configuration options and related functions that
+    have been marked for removal for quite some time:
+    - PredefChannelsOnly (v22)
+    - NoticeAuth (v24)
+    - NoXXX (v19)
+    - Old '[GLOBAL]' section handling (v19)
+    Thanks to Michi <michi+ngircd@dataswamp.org> for the patch!
+  - Increase read buffer size for server connections: This applies the same
+    logic we have for write buffers to distinguish between server and client
+    connections and sets the maximum buffer size accordingly. As a result
+    peering with servers with many GLINE/KLINEs does not kill the connecting
+    server connection anymore. Thanks to Michi <michi+ngircd@dataswamp.org>!
+  - Fix recursion bug on write errors: Depending on the stack size, too many
+    clients on the same channel quitting at the same time would trigger a crash
+    due to too many recursive calls to Conn_Close(). Thanks to Michi
+    <michi+ngircd@dataswamp.org> for the patch!
+  - Fix builds using GCC option -fno-common, which is the default starting with
+    GCC 10. Thanks to Michi <michi+ngircd@dataswamp.org> for the patch!
+    Closes #266.
+  - Convert INSTALL and README files to Markdown.
+  - Allow setting arbitrary channel modes in the configuration file by handling
+    them like in MODE commands, and allow multiple "Modes =" lines per [Channel]
+    section. Thanks to Michi <michi+ngircd@dataswamp.org>!
+    Closes #55.
+  - Add "FNC" (forced nick changes) to ISUPPORT(005) numeric. Most probably
+    this doesn't make any difference to any client, but it seems correct.
+    See <http://www.irc.org/tech_docs/005.html> for details.
+  - Reuse old SSL key if loading a new one failed.
+  - Remove outdated OpenBSD/NetBSD systrace.policy.
+  - Enhance handling of command line errors, and return with exit code 0 ("no
+    error") when "--help" or "--version" is used (which resulted in exit code 1,
+    "error" before). Exit with code 2 ("command line error") for all other
+    invalid command line options, and show the error message itself on stderr
+    (instead of stdout and exit code 1, "generic error", as before).
+    This new behaviour is more in line with the GNU "coding standards",
+    see <https://www.gnu.org/prep/standards/html_node/_002d_002dhelp.html>.
+  - Fix and update Xcode project: Reference correct contrib/Makefile.am file,
+    correctly sort contrib/nglog.sh and add "ORGANIZATIONNAME" setting.
+  - contrib/ngindent.sh: Add more GNU indent options for better results, and
+    add the ".sh" suffix to bring this script in line with the others in the
+    contrib/ folder.
+  - Add ./contrib/nglog.sh: This script parses the log output of ngircd(8),
+    and colorizes the messages according to their log level. Example usage:
+    ngircd -f $PWD/doc/sample-ngircd.conf -np | ./contrib/nglog.sh
+  - Log received signals with their names using strsignal(3), when available.
+  - Make test suite compatible with Haiku OS.
+  - Fix host mask cloaking bug, don't cloak multiple times: Previously, each
+    server would cloak every user's host mask. The problem is that if a network
+    has more than one server, then a user's host mask would get cloaked twice.
+    This patch ensures that a server only cloaks the host mask if it has not yet
+    been cloaked (the period indicates it's still an IP address). Thanks to
+    JRMU <jrmu@lecturify.com> for the patch!
+    Closes #228.
+  - Enlarge buffers of info texts to 128 bytes. This includes:
+    - "Real name" of a client (4th filed of the USER command).
+    - Server info text ("Info" configuration option).
+    - Admin info texts and email address ("AdminInfo1", "AdminInfo2" and
+      "AdminEmail" configuration options).
+    - Network name ("Network" configuration option).
+    The limit was 64 bytes before ...
+    Closes #258.
+  - Streamline handling of invalid and unset server name: Don't exit during
+    runtime (REHASH command, HUP signal), because the server name can't be
+    changed in this case anyway and the new invalid name will be ignored.
+  - Fix and extend documentation: Fix some typos, fix syntax of LINKS and LIST
+    commands, whitespace and spelling fixes, update dependencies and add some
+    more information about IRCv3 support.
+    Thanks to Thanks Windree, Étienne Mollier <etienne.mollier@mailoo.org> and
+    Christoph Biedl <debian.axhn@manchmal.in-ulm.de>.
+    Closes #264.
+  - Slightly reorder startup steps, and enhance logging:
+    - Show name of configuration file at the beginning of start up.
+    - Add a message when ngIRCd is ready, including its host name.
+    - Show name of configuration file on REHASH (SIGHUP), too.
+    - Change level of "done message" to NOTICE, like "starting" & "ready".
+    - Initialize IO functions before channels, connections, clients, ...
+  - configure.ng: OpenSSL can depends on lz or latomic so use pkg-config to
+    find those dependencies and fallback to existing mechanism.
+    Closes #256.
+  - ngircd.conf.5: Fix wording as suggested by lintian.
 
 ngIRCd 25 (2019-01-23)
 
diff --git a/INSTALL.md b/INSTALL.md
index 7a7712af..5d521b55 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -14,6 +14,14 @@ configure ngIRCd.
 
 Differences to version 25
 
+- **Attention**:
+  All already deprecated legacy options (besides the newly deprecated *Key* and
+  *MaxUsers* settings, see below) were removed in ngIRCd 26, so make sure to
+  update your configuration before upgrading, if you haven't done so already
+  (you got a warning on daemon startup when using deprecated options): you can
+  check your configuration using `ngircd --configtest` -- which is a good idea
+  anyway ;-)
+
 - Setting modes for predefined channels in *[Channel]* sections has been
   enhanced: now you can set *all* modes, like in IRC "MODE" commands, and have
   this setting multiple times per *[Channel]* block. Modifying lists (ban list,
diff --git a/Makefile.am b/Makefile.am
index 5ac537f6..ec9c4447 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,13 +23,13 @@ maintainer-clean-local:
 	rm -f config.log debian
 
 testsuite:
-	cd src/testsuite && make check
+	cd src/testsuite && ${MAKE} check
 
 lint:
-	cd src/ngircd && make lint
+	cd src/ngircd && ${MAKE} lint
 
 srcdoc:
-	cd doc && make srcdoc
+	cd doc && ${MAKE} srcdoc
 
 have-xcodebuild:
 	@xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -list \
@@ -64,7 +64,7 @@ osxpkg: have-packagemaker osxpkg-dest
 	 --out ../../$(distdir).mpkg
 	rm -f $(distdir).mpkg.zip
 	zip -ro9 $(distdir).mpkg.zip $(distdir).mpkg
-	make osxpkg-clean
+	${MAKE} osxpkg-clean
 
 osxpkg-clean:
 	[ ! -r ngircd.dest ] || sudo -n rm -rf ngircd.dest
@@ -72,12 +72,12 @@ osxpkg-clean:
 
 osxpkg-dest: have-xcodebuild osxpkg-clean clean
 	./configure --prefix=/opt/ngircd
-	make xcode
-	make -C contrib/MacOSX de.barton.ngircd.plist
+	${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
+	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
diff --git a/NEWS b/NEWS
index 91f7cc69..2d6e4ce6 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,47 @@
 
                                   -- NEWS --
 
+ngIRCd 26
+
+  ngIRCd 26~rc1
+  - Allow setting arbitrary channel modes in the configuration file by handling
+    them like in MODE commands, and allow multiple "Modes =" lines per [Channel]
+    section. Thanks to Michi <michi+ngircd@dataswamp.org>!
+    Closes #55.
+  - Add "FNC" (forced nick changes) to ISUPPORT(005) numeric. Most probably
+    this doesn't make any difference to any client, but it seems correct.
+    See <http://www.irc.org/tech_docs/005.html> for details.
+  - Enhance handling of command line errors, and return with exit code 0 ("no
+    error") when "--help" or "--version" is used (which resulted in exit code 1,
+    "error" before). Exit with code 2 ("command line error") for all other
+    invalid command line options, and show the error message itself on stderr
+    (instead of stdout and exit code 1, "generic error", as before).
+    This new behaviour is more in line with the GNU "coding standards",
+    see <https://www.gnu.org/prep/standards/html_node/_002d_002dhelp.html>.
+  - Add ./contrib/nglog.sh: This script parses the log output of ngircd(8),
+    and colorizes the messages according to their log level. Example usage:
+    ngircd -f $PWD/doc/sample-ngircd.conf -np | ./contrib/nglog.sh
+  - Enlarge buffers of info texts to 128 bytes. This includes:
+    - "Real name" of a client (4th filed of the USER command).
+    - Server info text ("Info" configuration option).
+    - Admin info texts and email address ("AdminInfo1", "AdminInfo2" and
+      "AdminEmail" configuration options).
+    - Network name ("Network" configuration option).
+    The limit was 64 bytes before ...
+    Closes #258.
+  - Streamline handling of invalid and unset server name: Don't exit during
+    runtime (REHASH command, HUP signal), because the server name can't be
+    changed in this case anyway and the new invalid name will be ignored.
+  - Slightly reorder startup steps, and enhance logging:
+    - Show name of configuration file at the beginning of start up.
+    - Add a message when ngIRCd is ready, including its host name.
+    - Show name of configuration file on REHASH (SIGHUP), too.
+    - Change level of "done message" to NOTICE, like "starting" & "ready".
+    - Initialize IO functions before channels, connections, clients, ...
+  - configure.ng: OpenSSL can depends on lz or latomic so use pkg-config to
+    find those dependencies and fallback to existing mechanism.
+    Closes #256.
+
 ngIRCd 25 (2019-01-23)
 
   - Implement new configuration option "MaxPenaltyTime", which configures the
diff --git a/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj b/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj
index 2fe59a9d..989a002b 100644
--- a/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj
+++ b/contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj
@@ -628,7 +628,7 @@
 		08FB7793FE84155DC02AAC07 /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastUpgradeCheck = 1130;
+				LastUpgradeCheck = 1140;
 				ORGANIZATIONNAME = "ngIRCd Development Team";
 			};
 			buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "ngIRCd" */;
@@ -707,6 +707,7 @@
 		1DEB928708733DD80010E9CD /* Default */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				CLANG_ENABLE_OBJC_WEAK = YES;
 			};
 			name = Default;
 		};
@@ -715,14 +716,22 @@
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				CLANG_WARN_ASSIGN_ENUM = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
 				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
 				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
 				CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
 				CLANG_WARN_STRICT_PROTOTYPES = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
 				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
@@ -733,6 +742,7 @@
 				GCC_WARN_PEDANTIC = YES;
 				GCC_WARN_SHADOW = YES;
 				GCC_WARN_SIGN_COMPARE = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
 				GCC_WARN_UNINITIALIZED_AUTOS = YES;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_LABEL = YES;
@@ -748,14 +758,23 @@
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
 				CLANG_WARN_ASSIGN_ENUM = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
 				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
 				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
 				CLANG_WARN_EMPTY_BODY = YES;
 				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
 				CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES;
 				CLANG_WARN_STRICT_PROTOTYPES = YES;
 				CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_NO_COMMON_BLOCKS = YES;
 				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 				GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
 				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
@@ -766,6 +785,7 @@
 				GCC_WARN_PEDANTIC = YES;
 				GCC_WARN_SHADOW = YES;
 				GCC_WARN_SIGN_COMPARE = YES;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
 				GCC_WARN_UNINITIALIZED_AUTOS = YES;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_LABEL = YES;
@@ -782,6 +802,7 @@
 		FAB0570D105D917F006AF9E2 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
+				CLANG_ENABLE_OBJC_WEAK = YES;
 			};
 			name = Debug;
 		};
diff --git a/contrib/nglog.sh b/contrib/nglog.sh
index c96f993a..852ee93c 100755
--- a/contrib/nglog.sh
+++ b/contrib/nglog.sh
@@ -1,7 +1,7 @@
-#!/bin/sh
+#!/bin/bash
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2019 Alexander Barton (alex@barton.de) and Contributors
+# Copyright (c)2001-2020 Alexander Barton (alex@barton.de) and Contributors
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@
 # ./src/ngircd/ngircd -f $PWD/doc/sample-ngircd.conf -np | ./contrib/nglog.sh
 #
 
-awk '
+gawk '
   /^\[[[:digit:]]+:0 / {print "\033[1;95m" $0 "\033[0m"}
   /^\[[[:digit:]]+:1 / {print "\033[1;35m" $0 "\033[0m"}
   /^\[[[:digit:]]+:2 / {print "\033[1;91m" $0 "\033[0m"}
@@ -23,4 +23,6 @@ awk '
   /^\[[[:digit:]]+:5 / {print "\033[1m" $0 "\033[0m"}
   /^\[[[:digit:]]+:6 / {print $0}
   /^\[[[:digit:]]+:7 / {print "\033[90m" $0 "\033[0m"}
-'
+' </dev/stdin &
+
+wait
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 5c8a5d85..4ce26f06 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -55,7 +55,7 @@ all: $(generated_docs)
 install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
 	$(MKDIR_P) -m 755 $(DESTDIR)$(sysconfdir)
 	@if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
-	  make install-config; \
+	  ${MAKE} install-config; \
 	 fi
 	$(MKDIR_P) -m 755 $(DESTDIR)$(docdir)
 	for f in $(static_docs) $(toplevel_docs); do \
@@ -75,7 +75,7 @@ install-config:
 uninstall-hook:
 	rm -rf $(DESTDIR)$(docdir)
 	@if cmp --silent sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; then \
-	  make uninstall-config; \
+	  ${MAKE} uninstall-config; \
 	 else \
 	  echo; \
 	  echo " ** NOTE: Not uninstalling changed configuration file:"; \
@@ -87,7 +87,7 @@ uninstall-config:
 	rm -f $(DESTDIR)$(sysconfdir)/ngircd.conf
 
 srcdoc:
-	make -C src srcdoc
+	${MAKE} -C src srcdoc
 
 .PHONY: install-config uninstall-config srcdoc
 
diff --git a/src/ngircd/client.c b/src/ngircd/client.c
index a453312c..67c02604 100644
--- a/src/ngircd/client.c
+++ b/src/ngircd/client.c
@@ -337,9 +337,11 @@ Client_SetHostname( CLIENT *Client, const char *Hostname )
 	assert(Client != NULL);
 	assert(Hostname != NULL);
 
-	/* Only cloak the hostmask if it has not yet been cloaked (the period
-	 * indicates it's still an IP address). */
-	if (Conf_CloakHost[0] && strchr(Client->host, '.')) {
+	/* Only cloak the hostmask if it has not yet been cloaked.
+	 * The period or colon indicates it's still an IP address.
+	 * An empty string means a rDNS lookup did not happen (yet). */
+	if (Conf_CloakHost[0] && (!Client->host[0] || strchr(Client->host, '.')
+				  || strchr(Client->host, ':'))) {
 		char cloak[GETID_LEN];
 
 		strlcpy(cloak, Hostname, GETID_LEN);
diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c
index 02ed1f39..a58ac26e 100644
--- a/src/ngircd/conf.c
+++ b/src/ngircd/conf.c
@@ -903,7 +903,7 @@ Read_Config(bool TestOnly, bool IsStarting)
 	FILE *fd;
 	DIR *dh;
 
-	Log(LOG_INFO, "Using configuration file \"%s\" ...", NGIRCd_ConfFile);
+	Config_Error(LOG_INFO, "Using configuration file \"%s\" ...", NGIRCd_ConfFile);
 
 	/* Open configuration file */
 	fd = fopen( NGIRCd_ConfFile, "r" );
@@ -1290,116 +1290,6 @@ WarnPAM(const char UNUSED *File, int UNUSED Line)
 #endif
 }
 
-/**
- * Handle legacy "NoXXX" options in [GLOBAL] section.
- *
- * TODO: This function and support for "NoXXX" could be removed starting
- * with ngIRCd release 19 (one release after marking it "deprecated").
- *
- * @param Var	Variable name.
- * @param Arg	Argument string.
- * @returns	true if a NoXXX option has been processed; false otherwise.
- */
-static bool
-CheckLegacyNoOption(const char *Var, const char *Arg)
-{
-	if(strcasecmp(Var, "NoDNS") == 0) {
-		Conf_DNS = !Check_ArgIsTrue( Arg );
-		return true;
-	}
-	if (strcasecmp(Var, "NoIdent") == 0) {
-		Conf_Ident = !Check_ArgIsTrue(Arg);
-		return true;
-	}
-	if(strcasecmp(Var, "NoPAM") == 0) {
-		Conf_PAM = !Check_ArgIsTrue(Arg);
-		return true;
-	}
-	return false;
-}
-
-/**
- * Handle deprecated legacy options in [GLOBAL] section.
- *
- * TODO: This function and support for these options in the [Global] section
- * could be removed starting with ngIRCd release 19 (one release after
- * marking it "deprecated").
- *
- * @param Var	Variable name.
- * @param Arg	Argument string.
- * @returns	true if a legacy option has been processed; false otherwise.
- */
-static const char*
-CheckLegacyGlobalOption(const char *File, int Line, char *Var, char *Arg)
-{
-	if (strcasecmp(Var, "AllowRemoteOper") == 0
-	    || strcasecmp(Var, "ChrootDir") == 0
-	    || strcasecmp(Var, "ConnectIPv4") == 0
-	    || strcasecmp(Var, "ConnectIPv6") == 0
-	    || strcasecmp(Var, "OperCanUseMode") == 0
-	    || strcasecmp(Var, "OperChanPAutoOp") == 0
-	    || strcasecmp(Var, "OperServerMode") == 0
-	    || strcasecmp(Var, "PredefChannelsOnly") == 0
-	    || strcasecmp(Var, "SyslogFacility") == 0
-	    || strcasecmp(Var, "WebircPassword") == 0) {
-		Handle_OPTIONS(File, Line, Var, Arg);
-		return "[Options]";
-	}
-	if (strcasecmp(Var, "ConnectRetry") == 0
-	    || strcasecmp(Var, "IdleTimeout") == 0
-	    || strcasecmp(Var, "MaxConnections") == 0
-	    || strcasecmp(Var, "MaxConnectionsIP") == 0
-	    || strcasecmp(Var, "MaxJoins") == 0
-	    || strcasecmp(Var, "MaxNickLength") == 0
-	    || strcasecmp(Var, "PingTimeout") == 0
-	    || strcasecmp(Var, "PongTimeout") == 0) {
-		Handle_LIMITS(File, Line, Var, Arg);
-		return "[Limits]";
-	}
-#ifdef SSL_SUPPORT
-	if (strcasecmp(Var, "SSLCertFile") == 0
-	    || strcasecmp(Var, "SSLDHFile") == 0
-	    || strcasecmp(Var, "SSLKeyFile") == 0
-	    || strcasecmp(Var, "SSLKeyFilePassword") == 0
-	    || strcasecmp(Var, "SSLPorts") == 0) {
-		Handle_SSL(File, Line, Var + 3, Arg);
-		return "[SSL]";
-	}
-#endif
-
-	return NULL;
-}
-
-/**
- * Strip "no" prefix of a string.
- *
- * TODO: This function and support for "NoXXX" should be removed starting
- * with ngIRCd release 19! (One release after marking it "deprecated").
- *
- * @param str	Pointer to input string starting with "no".
- * @returns	New pointer to string without "no" prefix.
- */
-static const char *
-NoNo(const char *str)
-{
-	assert(strncasecmp("no", str, 2) == 0 && str[2]);
-	return str + 2;
-}
-
-/**
- * Invert "boolean" string.
- *
- * TODO: This function and support for "NoXXX" should be removed starting
- * with ngIRCd release 19! (One release after marking it "deprecated").
- *
- * @param arg	"Boolean" input string.
- * @returns	Pointer to inverted "boolean string".
- */
-static const char *
-InvertArg(const char *arg)
-{
-	return yesno_to_str(!Check_ArgIsTrue(arg));
-}
 
 /**
  * Handle variable in [Global] configuration section.
@@ -1414,7 +1304,6 @@ Handle_GLOBAL(const char *File, int Line, char *Var, char *Arg )
 	struct passwd *pwd;
 	struct group *grp;
 	size_t len;
-	const char *section;
 	char *ptr;
 
 	assert(File != NULL);
@@ -1554,36 +1443,6 @@ Handle_GLOBAL(const char *File, int Line, char *Var, char *Arg )
 		return;
 	}
 
-	if (CheckLegacyNoOption(Var, Arg)) {
-		/* TODO: This function and support for "NoXXX" could be
-		 * be removed starting with ngIRCd release 19 (one release
-		 * after marking it "deprecated"). */
-		Config_Error(LOG_WARNING,
-			     "%s, line %d (section \"Global\"): \"No\"-Prefix is deprecated, use \"%s = %s\" in [Options] section!",
-			     File, Line, NoNo(Var), InvertArg(Arg));
-		if (strcasecmp(Var, "NoIdent") == 0)
-			WarnIdent(File, Line);
-		else if (strcasecmp(Var, "NoPam") == 0)
-			WarnPAM(File, Line);
-		return;
-	}
-	if ((section = CheckLegacyGlobalOption(File, Line, Var, Arg))) {
-		/** TODO: This function and support for these options in the
-		 * [Global] section could be removed starting with ngIRCd
-		 * release 19 (one release after marking it "deprecated"). */
-		if (strncasecmp(Var, "SSL", 3) == 0) {
-			Config_Error(LOG_WARNING,
-				     "%s, line %d (section \"Global\"): \"%s\" is deprecated here, move it to %s and rename to \"%s\"!",
-				     File, Line, Var, section,
-				     Var + 3);
-		} else {
-			Config_Error(LOG_WARNING,
-				     "%s, line %d (section \"Global\"): \"%s\" is deprecated here, move it to %s!",
-				     File, Line, Var, section);
-		}
-		return;
-	}
-
 	Config_Error_Section(File, Line, Var, "Global");
 }
 
@@ -1808,18 +1667,6 @@ Handle_OPTIONS(const char *File, int Line, char *Var, char *Arg)
 		Conf_MorePrivacy = Check_ArgIsTrue(Arg);
 		return;
 	}
-	if (strcasecmp(Var, "NoticeAuth") == 0) {
-		/*
-		 * TODO: This section and support for "NoticeAuth" variable
-		 * could be removed starting with ngIRCd release 24 (one
-		 * release after marking it "deprecated") ...
-		 */
-		Config_Error(LOG_WARNING,
-			     "%s, line %d (section \"Options\"): \"%s\" is deprecated, please use \"NoticeBeforeRegistration\"!",
-			     File, Line, Var);
-		Conf_NoticeBeforeRegistration = Check_ArgIsTrue(Arg);
-		return;
-	}
 	if (strcasecmp(Var, "NoticeBeforeRegistration") == 0) {
 		Conf_NoticeBeforeRegistration = Check_ArgIsTrue(Arg);
 		return;
@@ -1851,22 +1698,6 @@ Handle_OPTIONS(const char *File, int Line, char *Var, char *Arg)
 			Config_Error_TooLong(File, Line, Var);
 		return;
 	}
-	if (strcasecmp(Var, "PredefChannelsOnly") == 0) {
-		/*
-		 * TODO: This section and support for "PredefChannelsOnly"
-		 * could be removed starting with ngIRCd release 22 (one
-		 * release after marking it "deprecated") ...
-		 */
-		Config_Error(LOG_WARNING,
-			     "%s, line %d (section \"Options\"): \"%s\" is deprecated, please use \"AllowedChannelTypes\"!",
-			     File, Line, Var);
-		if (Check_ArgIsTrue(Arg))
-			Conf_AllowedChannelTypes[0] = '\0';
-		else
-			strlcpy(Conf_AllowedChannelTypes, CHANTYPES,
-				sizeof(Conf_AllowedChannelTypes));
-		return;
-	}
 #ifndef STRICT_RFC
 	if (strcasecmp(Var, "RequireAuthPing") == 0) {
 		Conf_AuthPing = Check_ArgIsTrue(Arg);
diff --git a/src/ngircd/conn-func.c b/src/ngircd/conn-func.c
index 72d38b86..4a2d32d6 100644
--- a/src/ngircd/conn-func.c
+++ b/src/ngircd/conn-func.c
@@ -51,7 +51,7 @@ GLOBAL void
 Conn_UpdatePing(CONN_ID Idx)
 {
 	assert(Idx > NONE);
-	My_Connections[Idx].lastping = time(NULL);
+	My_Connections[Idx].lastping = My_Connections[Idx].lastdata = time(NULL);
 }
 
 /*
diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c
index f62e9675..c304fdb5 100644
--- a/src/ngircd/conn.c
+++ b/src/ngircd/conn.c
@@ -10,6 +10,7 @@
  */
 
 #define CONN_MODULE
+#define CONN_MODULE_GLOBAL_INIT
 
 #include "portab.h"
 
@@ -659,12 +660,14 @@ Conn_Handler(void)
 	size_t wdatalen;
 	struct timeval tv;
 	time_t t;
+	bool command_available;
 
 	Log(LOG_NOTICE, "Server \"%s\" (on \"%s\") ready.",
 	    Client_ID(Client_ThisServer()), Client_Hostname(Client_ThisServer()));
 
 	while (!NGIRCd_SignalQuit && !NGIRCd_SignalRestart) {
 		t = time(NULL);
+		command_available = false;
 
 		/* Check configured servers and established links */
 		Check_Servers();
@@ -733,16 +736,31 @@ Conn_Handler(void)
 				continue;
 			}
 
+			if (array_bytes(&My_Connections[i].rbuf) >= COMMAND_LEN) {
+				/* There is still more data in the read buffer
+				 * than a single valid command can get long:
+				 * so either there is a complete command, or
+				 * invalid data. Therefore don't try to read in
+				 * even more data from the network but wait for
+				 * this command(s) to be handled first! */
+				io_event_del(My_Connections[i].sock,
+					     IO_WANTREAD);
+				command_available = true;
+				continue;
+			}
+
 			io_event_add(My_Connections[i].sock, IO_WANTREAD);
 		}
 
-		/* Set the timeout for reading from the network to 1 second,
-		 * which is the granularity with witch we handle "penalty
-		 * times" for example.
+		/* Don't wait for data when there is still at least one command
+		 * available in a read buffer which can be handled immediately;
+		 * set the timeout for reading from the network to 1 second
+		 * otherwise, which is the granularity with witch we handle
+		 * "penalty times" for example.
 		 * Note: tv_sec/usec are undefined(!) after io_dispatch()
 		 * returns, so we have to set it before each call to it! */
 		tv.tv_usec = 0;
-		tv.tv_sec = 1;
+		tv.tv_sec = command_available ? 0 : 1;
 
 		/* Wait for activity ... */
 		i = io_dispatch(&tv);
@@ -1271,6 +1289,9 @@ Handle_Write( CONN_ID Idx )
 		if (errno == EAGAIN || errno == EINTR)
 			return true;
 
+		/* Log write errors but do not close the connection yet.
+		 * Calling Conn_Close() now could result in too many recursive calls.
+		 */
 		if (!Conn_OPTION_ISSET(&My_Connections[Idx], CONN_ISCLOSING))
 			Log(LOG_ERR,
 			    "Write error on connection %d (socket %d): %s!",
@@ -1278,7 +1299,7 @@ Handle_Write( CONN_ID Idx )
 		else
 			LogDebug("Recursive write error on connection %d (socket %d): %s!",
 				 Idx, My_Connections[Idx].sock, strerror(errno));
-		Conn_Close(Idx, "Write error", NULL, false);
+
 		return false;
 	}
 
@@ -1539,16 +1560,21 @@ Socket2Index( int Sock )
  * @param Idx	Connection index.
  */
 static void
-Read_Request( CONN_ID Idx )
+Read_Request(CONN_ID Idx)
 {
 	ssize_t len;
 	static const unsigned int maxbps = COMMAND_LEN / 2;
 	char readbuf[READBUFFER_LEN];
 	time_t t;
 	CLIENT *c;
-	assert( Idx > NONE );
-	assert( My_Connections[Idx].sock > NONE );
 
+	assert(Idx > NONE);
+	assert(My_Connections[Idx].sock > NONE);
+
+	/* Check if the read buffer is "full". Basically this shouldn't happen
+	 * here, because as long as there possibly are commands in the read
+	 * buffer (buffer usage > COMMAND_LEN), the socket shouldn't be
+	 * scheduled for reading in Conn_Handler() at all ... */
 #ifdef ZLIB
 	if ((array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN) ||
 		(array_bytes(&My_Connections[Idx].zip.rbuf) >= READBUFFER_LEN))
@@ -1556,7 +1582,6 @@ Read_Request( CONN_ID Idx )
 	if (array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN)
 #endif
 	{
-		/* Read buffer is full */
 		Log(LOG_ERR,
 		    "Receive buffer space exhausted (connection %d): %d/%d bytes",
 		    Idx, array_bytes(&My_Connections[Idx].rbuf), READBUFFER_LEN);
@@ -1564,12 +1589,14 @@ Read_Request( CONN_ID Idx )
 		return;
 	}
 
+	/* Now read new data from the network, up to READBUFFER_LEN bytes ... */
 #ifdef SSL_SUPPORT
 	if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_SSL))
-		len = ConnSSL_Read( &My_Connections[Idx], readbuf, sizeof(readbuf));
+		len = ConnSSL_Read(&My_Connections[Idx], readbuf, sizeof(readbuf));
 	else
 #endif
-	len = read(My_Connections[Idx].sock, readbuf, sizeof(readbuf));
+		len = read(My_Connections[Idx].sock, readbuf, sizeof(readbuf));
+
 	if (len == 0) {
 		LogDebug("Client \"%s:%u\" is closing connection %d ...",
 			 My_Connections[Idx].host,
@@ -1579,13 +1606,20 @@ Read_Request( CONN_ID Idx )
 	}
 
 	if (len < 0) {
-		if( errno == EAGAIN ) return;
+		if (errno == EAGAIN)
+			return;
+
 		Log(LOG_ERR, "Read error on connection %d (socket %d): %s!",
 		    Idx, My_Connections[Idx].sock, strerror(errno));
 		Conn_Close(Idx, "Read error", "Client closed connection",
 			   false);
 		return;
 	}
+
+	/* Now append the newly received data to the connection buffer.
+	 * NOTE: This can lead to connection read buffers being bigger(!) than
+	 * READBUFFER_LEN bytes, as we add up to READBUFFER_LEN new bytes to a
+	 * buffer possibly being "almost" READBUFFER_LEN bytes already! */
 #ifdef ZLIB
 	if (Conn_OPTION_ISSET(&My_Connections[Idx], CONN_ZIP)) {
 		if (!array_catb(&My_Connections[Idx].zip.rbuf, readbuf,
diff --git a/src/ngircd/conn.h b/src/ngircd/conn.h
index c642541f..869477f0 100644
--- a/src/ngircd/conn.h
+++ b/src/ngircd/conn.h
@@ -105,9 +105,17 @@ typedef struct _Connection
 #endif
 } CONNECTION;
 
-GLOBAL CONNECTION *My_Connections;
-GLOBAL CONN_ID Pool_Size;
-GLOBAL long WCounter;
+
+#ifdef CONN_MODULE_GLOBAL_INIT
+CONNECTION *My_Connections;
+CONN_ID Pool_Size;
+long WCounter;
+#else
+extern CONNECTION *My_Connections;
+extern CONN_ID Pool_Size;
+extern long WCounter;
+#endif
+
 
 #define CONNECTION2ID(x) (long)(x - My_Connections)
 
diff --git a/src/ngircd/irc-oper.c b/src/ngircd/irc-oper.c
index e877213e..ae333b10 100644
--- a/src/ngircd/irc-oper.c
+++ b/src/ngircd/irc-oper.c
@@ -447,10 +447,11 @@ IRC_xLINE(CLIENT *Client, REQUEST *Req)
 		if (Class_AddMask(class, Req->argv[0],
 				  timeout,
 				  Req->argv[2])) {
-			Log(LOG_NOTICE|LOG_snotice,
-			    "\"%s\" added \"%s\" to %c-Line list: \"%s\" (%ld seconds).",
-			    Client_Mask(from), Req->argv[0], class_c,
-			    Req->argv[2], atol(Req->argv[1]));
+			if (Client_Type(from) != CLIENT_SERVER)
+				Log(LOG_NOTICE|LOG_snotice,
+				    "\"%s\" added \"%s\" to %c-Line list: \"%s\" (%ld seconds).",
+				    Client_Mask(from), Req->argv[0], class_c,
+				    Req->argv[2], atol(Req->argv[1]));
 			if (class == CLASS_GLINE) {
 				/* Inform other servers */
 				IRC_WriteStrServersPrefix(Client, from,
diff --git a/src/ngircd/ngircd.c b/src/ngircd/ngircd.c
index 7166640b..41255ca0 100644
--- a/src/ngircd/ngircd.c
+++ b/src/ngircd/ngircd.c
@@ -9,6 +9,7 @@
  * Please read the file COPYING, README and AUTHORS for more information.
  */
 
+#define GLOBAL_INIT
 #include "portab.h"
 
 /**
diff --git a/src/portab/portab.h b/src/portab/portab.h
index 70d5ed3e..43f2f907 100644
--- a/src/portab/portab.h
+++ b/src/portab/portab.h
@@ -102,7 +102,11 @@ typedef unsigned char bool;
 #endif
 
 #undef GLOBAL
+#ifdef GLOBAL_INIT
 #define GLOBAL
+#else
+#define GLOBAL extern
+#endif
 
 /* SPLint */