Browse Source

Import upstream version 23

Alexander Barton 8 years ago
parent
commit
ddad8dfe96
64 changed files with 620 additions and 374 deletions
  1. 4 0
      .clang_complete
  2. 11 1
      .mailmap
  3. 13 3
      AUTHORS
  4. 91 12
      ChangeLog
  5. 12 4
      INSTALL
  6. 2 2
      Makefile.am
  7. 2 2
      Makefile.in
  8. 46 7
      NEWS
  9. 7 7
      README
  10. 3 3
      autogen.sh
  11. 16 13
      configure
  12. 2 2
      configure.ac
  13. 2 2
      configure.ng
  14. 12 0
      contrib/Debian/changelog
  15. 2 2
      contrib/Debian/ngircd.init
  16. 4 6
      contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj
  17. 1 1
      contrib/README
  18. 11 0
      contrib/ngircd.service
  19. 1 1
      contrib/ngircd.spec
  20. 1 1
      contrib/platformtest.sh
  21. 2 2
      doc/Capabilities.txt
  22. 2 2
      doc/Commands.txt
  23. 8 2
      doc/Contributing.txt
  24. 4 4
      doc/FAQ.txt
  25. 0 65
      doc/GIT.txt
  26. 1 0
      doc/HowToRelease.txt
  27. 1 2
      doc/Makefile.am
  28. 1 2
      doc/Makefile.in
  29. 4 2
      doc/Modes.txt
  30. 4 4
      doc/Platforms.txt
  31. 2 2
      doc/sample-ngircd.conf.tmpl
  32. 7 6
      man/ngircd.conf.5.tmpl
  33. 3 0
      src/config.h.in
  34. 17 10
      src/ngircd/channel.c
  35. 3 3
      src/ngircd/channel.h
  36. 1 1
      src/ngircd/class.c
  37. 6 6
      src/ngircd/client.c
  38. 16 4
      src/ngircd/conf.c
  39. 2 2
      src/ngircd/conf.h
  40. 2 2
      src/ngircd/conn-func.c
  41. 2 3
      src/ngircd/conn-ssl.c
  42. 2 2
      src/ngircd/conn-zip.c
  43. 16 16
      src/ngircd/conn.c
  44. 1 1
      src/ngircd/defines.h
  45. 5 3
      src/ngircd/irc-channel.c
  46. 46 36
      src/ngircd/irc-info.c
  47. 32 5
      src/ngircd/irc-login.c
  48. 20 4
      src/ngircd/irc-macros.h
  49. 4 1
      src/ngircd/irc-metadata.c
  50. 39 30
      src/ngircd/irc-mode.c
  51. 9 1
      src/ngircd/irc-op.c
  52. 3 1
      src/ngircd/irc-oper.c
  53. 3 3
      src/ngircd/irc.c
  54. 20 5
      src/ngircd/lists.c
  55. 3 1
      src/ngircd/lists.h
  56. 1 1
      src/ngircd/login.c
  57. 10 8
      src/ngircd/match.c
  58. 6 3
      src/ngircd/messages.h
  59. 7 2
      src/ngircd/ngircd.c
  60. 2 2
      src/ngircd/numeric.c
  61. 7 7
      src/ngircd/parse.c
  62. 6 2
      src/ngircd/sighandlers.c
  63. 1 1
      src/portab/portabtest.c
  64. 46 46
      src/portab/vsnprintf.c

+ 4 - 0
.clang_complete

@@ -0,0 +1,4 @@
+-I./src
+-I./src/ipaddr
+-I./src/portab
+-I./src/tool

+ 11 - 1
.mailmap

@@ -1,4 +1,14 @@
 # mailmap file for git-[short]log and git-blame
+# use "git shortlog -se" to see the list of all authors.
+
+Alexander Barton <alex@barton.de> <anonymous>
+Alexander Barton <alex@barton.de> <alex@kfreebsd.barton.de>
 
-Alexander Barton <anonymous>
 Ali Shemiran <ashemira@ucsd.edu>
+
+Dana Dahlstrom <dana+ngIRCd@cs.ucsd.edu> <dana@cs.ucsd.edu>
+Dana Dahlstrom <dana+ngIRCd@cs.ucsd.edu> <dana+70@cs.ucsd.edu>
+
+DNS <dns@rbose.org>
+
+LucentW <lucent@zebes.info> <LucentW@users.noreply.github.com>

+ 13 - 3
AUTHORS

@@ -9,9 +9,11 @@
                        -- AUTHORS and CONTRIBUTORS --
 
 
-Note: If you have critics, patches or something else, please feel free to
-post a mail to the ngIRCd mailing list: <ngircd-ml@arthur.barton.de> (please
-see <http://ngircd.barton.de/#ml> for details).
+Note:
+If you have comments, patches or something else, please feel free to post
+a mail to the ngIRCd mailing list: <ngircd-ml@ngircd.barton.de> (please see
+<http://ngircd.barton.de/support.php> for details) or join the ngIRCd IRC
+channel: <irc://irc.barton.de/ngircd>.
 
 Don't mail the people listed here directly, if possible!
 
@@ -39,15 +41,23 @@ Eric Grunow <egrunow@ucsd.edu>
 Federico G. Schwindt <fgsch@lodoss.net>
 Gabor Adam Toth <tg@tgbit.net>
 Goetz Hoffart <goetz@hoffart.de>
+Ian Chard <ian@chard.org>
 Ilja Osthoff <i.osthoff@gmx.net>
 Jari Aalto <jari.aalto@cante.net>
+LucentW <lucent@zebes.info>
+Mantas Mikulėnas <grawity@gmail.com>
 Neale Pickett <neale@woozle.org>
+Peter Powell <petpow@saberuk.com>
 Rolf Eike Beer <eike@sf-mail.de>
+Roy Sindre Norangshol <roy.sindre@norangshol.no>
 Scott Perry <scperry@ucsd.edu>
 Sean Reifschneider <jafo-rpms@tummy.com>
 Sebastian Köhler <sebkoehler@whoami.org.uk>
 Tassilo Schweyer <dev@welterde.de>
+Tom Ryder <tom@sanctum.geek.nz>
+Unit 193 <unit193@ubuntu.com>
 William Pitcock <nenolod@dereferenced.org>
+Yecheng Fu <cofyc.jackson@gmail.com>
 xor <xorboy@gmail.com>
 
 

+ 91 - 12
ChangeLog

@@ -9,6 +9,85 @@
                                -- ChangeLog --
 
 
+ngIRCd 23 (2015-11-16)
+
+  - Explicitly cast time_t to long when printing it out: this prevents
+    wrong sized data types on platforms where time_t doesn't equal a
+    long any more, for example on OpenBSD (which would result in garbled
+    output on those platforms).
+  - contrib/Debian/changelog: Fix email address.
+  - Documentation: Spelling fixes; update doc/Platforms.txt.
+
+  ngIRCd 23~rc1 (2015-09-06)
+  - Add ".clang_complete" file, which is used by the "linter-clang" package
+    of the Atom editor, for example.
+  - Make server-to-server protocol more robust: ngIRCd now catches more
+    errors on the server-to-server (S2S) protocol that could crash the
+    daemon before. This hasn't been a real problem because the IRC S2S
+    protocol is "trusted" by design, but the behavior is much better now.
+    Thanks to wowaname on #ngircd for pointing this out!
+  - Make platformtest.sh, autogen.sh, and ngircd.init more portable.
+  - Enables "reproducible builds" for ngIRCd: Use the optional BIRTHTIME
+    constant while building ngIRCd, which contains a time stamp for the
+    "Birth Date" information, in seconds since the epoch.
+    See <https://wiki.debian.org/ReproducibleBuilds>.
+  - Update "contrib/ngircd.service" file for systemd.
+  - INSTALL: Add deprecation notice for "PredefChannelsOnly" variable.
+  - Use "NOTICE *" before registration instead of "NOTICE AUTH". "AUTH" is
+    a valid nickname so sending notices to it is probably not a good idea.
+    Use "*" as the target instead as done with numerics when the nick is not
+    available. This mimics the behavior in Charybdis, IRCD-Hybrid, InspIRCd
+    2.2, Plexus 4, etc. Closes #217.
+    The "NoticeAuth" configuration variable (ngircd.conf) has been renamed
+    to "NoticeBeforeRegistration" accordingly, but the old name is still
+    supported for compatibility reasons.
+  - Implement new channel mode "N" (regular users can't change their nick
+    name while on this channel). Closes #214.
+  - README, AUTHORS: Update mailing list and issue tracker URLs.
+  - Remove doc/GIT.txt (it is outdated), update doc/Contributing.txt:
+    ngIRCd uses GitHub, and Git itself is quite common today. So don't
+    include an own Git "mini HowTo" any longer.
+  - Specify session context for OpenSSL clients. This enables some OpenSSL
+    clients, including Pidgin and stunnel 5.06, to reuse a session.
+    Patch by Tom Ryder <tom@sanctum.geek.nz>, thanks! Closes #182.
+  - Keep track of who placed bans, invites, and excepts.
+    Idea and implementation by LucentW, Thanks! Closes #203.
+  - Make setgroups(3) function optional: For example, Interix is missing
+    this function, which prevented ngIRCd to build on this platform. When
+    setgroups(3) isn't available, a warning message is issued on startup.
+  - Implement numeric RPL_LISTSTART(321). lightIRC and other clients
+    expecting RPL_LISTSTART should now behave correctly.
+    Idea and implementation by LucentW, Thanks! Closes #207.
+  - Update ngircd.conf.5: "CloakUserToNick" hides user _and_ real name.
+    This closes #208.
+  - Fix case insensitive pattern matching: Up to now, only the the input
+    string became lowercased and was then compared to the pattern -- which
+    failed when the pattern itself wasn't all lowercase!
+  - Streamline the effect of "MorePrivacy" option: Update documentation
+    in ngircd.conf(5); don't hide channels for IRC Ops on LIST and don't
+    hide IP addresses/hostnames on WHOIS when "MorePrivacy" is in effect.
+    This closes #198.
+  - IRC operators now can kick anyone when "OperCanMode" is set.
+    Idea and implementation by LucentW, Thanks! Closes #202.
+  - Implement user mode "I": Hide channels on WHOIS: this mode prevents
+    ngIRCd from showing channels on WHOIS (IRC Operators can always see
+    the channel list).
+    Idea and implementation by LucentW, Thanks! Closes #197.
+  - INVITE command: Implement ERR_USERNOTONSERV(504) numeric and make sure
+    that the target user is on the same server when inviting other users
+    to local ("&") channels.
+    Idea by Cahata, thanks! Closes #183.
+  - INVITE command: Enforce 1 second penalty time, which prevents flooding
+    of the target client.
+    This closes #186. Reported by Cahata, thanks!
+  - MODE command: Always report channel creation time. Up to now when
+    receiving a MODE command, ngIRCd only reported the channel creation
+    time to clients that were members of the channel. This patch reports
+    the channel creation time to all clients, regardless if they are joined
+    to that channel or not. At least ircd-seven behaves like this.
+    This closes #188. Reported by Cahata, thanks!
+  - Update Xcode project for latest Xcode version (6.3).
+
 ngIRCd 22.1 (2015-04-06)
 
   - Update doc/Platforms.txt and doc/FAQ.txt.
@@ -558,7 +637,7 @@ ngIRCd 19.2 (2012-06-19)
     "CC=xxx MAKE=yyy ./platformtest.sh" calling convention.
   - Add instructions for setting up Atheme IRC services.
   - Implement support for IRC capability handling, the new "CAP" command,
-    and capablity "multi-prefix" which allows both the NAME and	WHO command
+    and capability "multi-prefix" which allows both the NAME and WHO command
     handlers to return more than one "class prefix" to the client.
   - Update Xcode project files: reference missing documentation files.
   - Fix: Don't ignore "permission denied" errors when enabling chroot.
@@ -858,7 +937,7 @@ ngIRCd 17 (2010-11-07)
   - contrib/platformtest.sh: make command name quoting consistent
 
   ngIRCd 17~rc3 (2010-10-27)
-  - Xcode builds: detect version number correctly, updateed project file
+  - Xcode builds: detect version number correctly, updated project file
     to use the Mac OS X 10.5.x SDK, disable pam_fail_delay() because it
     is only available starting with Mac OS X 10.6, and generate a default
     PAM configuration for the Mac OS X Installer.app package of ngIRCd.
@@ -870,7 +949,7 @@ ngIRCd 17 (2010-11-07)
   ngIRCd 17~rc2 (2010-10-25)
   - ZeroConf: include header files missing since commit a988bbc86a.
   - Generate ngIRCd version number from GIT tag.
-  - Make sourcecode compatible with ansi2knr again. This allows to compile
+  - Make source code compatible with ansi2knr again. This allows to compile
     ngIRCd using a pre-ANSI K&R C compiler again.
   - ./configure: check if C compiler can compile ISO Standard C.
   - ./configure: check support for C prototypes again.
@@ -886,7 +965,7 @@ ngIRCd 17 (2010-11-07)
     Howl, Avahi or on Mac OS X).
   - New configuration option "SyslogFacility" to define the syslog "facility"
     (the "target"), to which ngIRCd should send its log messages.
-    Possible values are system dependant, but most probably "auth", "daemon",
+    Possible values are system dependent, but most probably "auth", "daemon",
     "user" and "local1" through "local7" are possible values; see syslog(3).
     Default is "local5" for historical reasons.
   - Dump the "internal server state" (configured servers, established
@@ -907,7 +986,7 @@ ngIRCd 17 (2010-11-07)
   - Make configure switch "--docdir" work (closes: #108).
   - Reformat and update FAQ.txt a little bit.
   - INSTALL: mention SSL, IPv6, and changed handling of MotdFile.
-  - Change MOTD file handling: ngIRCd now caches the contens of the MOTD
+  - Change MOTD file handling: ngIRCd now caches the contents of the MOTD
     file, so the daemon now requires a HUP signal or REHASH command to
     re-read the MOTD file when its content changed.
   - Startup: open /dev/null before chroot'ing the daemon.
@@ -943,14 +1022,14 @@ ngIRCd 16 (2010-05-02)
   - Include netinet/{in.h, in_systm.h} when checking for netinet/ip.h
   - Only include <netinet/in_systm.h> if it exists
   - Updated doc/Platforms.txt
-  - Enhace connection statistics counters: display total number of served
+  - Enhance connection statistics counters: display total number of served
     connections on daemon shutdown and when a new client connects using
     the new numeric RPL_STATSCONN (250).
 
   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
+  - Updated 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
@@ -978,7 +1057,7 @@ ngIRCd 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
+  - Enable IRC operators to use the IRC command SQUIT (instead 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
@@ -1032,7 +1111,7 @@ ngIRCd 14 (2009-04-20)
   - 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)
+    (closes bug #93, reported by Gonosz Csiga)
 
 ngIRCd 13 (2008-12-25)
 
@@ -1262,7 +1341,7 @@ ngIRCd 0.9.0 (2005-07-24)
   - Fixed ./configure test for TCP Wrappers: now it runs on Mac OS X as well.
   - Enhanced configure script: now you can pass an (optional) search path
     to all --with-XXX parameters, e. g. "--with-ident=/opt/ident".
-  - Removed typedefs for the native C datatypes.
+  - Removed typedefs for the native C data types.
     Use stdbool.h / inttypes.h if available.
   - New configuration option "OperServerMode" to enable a workaround needed
     when running an network with ircd2 servers and "OperCanUseMode" enabled
@@ -1443,7 +1522,7 @@ ngIRCd 0.7.0 (2003-05-01)
     to add a new server (ngIRCd tries to connect new servers only once!).
   - Added DISCONNECT command ("DISCONNECT <name>") to disable servers.
   - Restructured the documentation: Now the main language is English. The
-    german documentation has been removed (until there is a maintainer).
+    German documentation has been removed (until there is a maintainer).
   - Enhanced killing of users caused by a nickname collision.
   - Better error detection for status code ("numerics") forwarding.
   - Moved tool functions to own library: "libngtool".
@@ -1484,7 +1563,7 @@ ngIRCd 0.6.1 (2003-01-21)
     member when changing his channel user modes which could crash ngIRCd.
 
 
-Older changes (sorry, only available in german language):
+Older changes (sorry, only available in German language):
 
 ngIRCd 0.6.0, 24.12.2002
 

+ 12 - 4
INSTALL

@@ -14,6 +14,10 @@ I. Upgrade Information
 
 Differences to version 22.x
 
+- The "NoticeAuth" ngircd.conf configuration variable has been renamed to
+  "NoticeBeforeRegistration". The old "NoticeAuth" variable still works but
+  is deprecated now.
+
 - The default value of the SSL "CipherList" variable has been changed to
   "HIGH:!aNULL:@STRENGTH:!SSLv3" (OpenSSL) and "SECURE128:-VERS-SSL3.0"
   (GnuTLS) to disable the old SSLv3 protocol by default.
@@ -32,6 +36,10 @@ Differences to version 20.x
   the new mask will be KILL'ed. This was not the case with earlier versions
   that only added the mask but didn't kill already connected users.
 
+- The "PredefChannelsOnly" configuration variable has been superseded by the
+  new "AllowedChannelTypes" variable. It is still supported and translated to
+  the appropriate "AllowedChannelTypes" setting but is deprecated now.
+
 Differences to version 19.x
 
 - Starting with ngIRCd 20, users can "cloak" their hostname only when the
@@ -40,7 +48,7 @@ Differences to version 19.x
   set mode +x. This prevents regular users from changing their hostmask to
   the name of the IRC server itself, which confused quite a few people ;-)
 
-Differences to version 17
+Differences to version 17.x
 
 - Support for ZeroConf/Bonjour/Rendezvous service registration has been
   removed. The configuration option "NoZeroconf" is no longer available.
@@ -77,7 +85,7 @@ Differences to version 17
   You should adjust your ngircd.conf and run "ngircd --configtest" to make
   sure that your settings are correct and up to date!
 
-Differences to version 16
+Differences to version 16.x
 
 - Changes to the "MotdFile" specified in ngircd.conf now require a ngircd
   configuration reload to take effect (HUP signal, REHASH command).
@@ -154,7 +162,7 @@ If you are using one of the "big" operating systems or Linux distributions,
 you can use the following commands to install all the required packages to
 build the sources including all optional features and to run the test suite:
 
-* RedHat / Fedora based distributions:
+* Red Hat / Fedora based distributions:
 
   yum install \
     autoconf automake expect gcc glibc-devel gnutls-devel \
@@ -178,7 +186,7 @@ This step is therefore only interesting for developers.
 autogen.sh produces the Makefile.in's, which are necessary for the configure
 script itself, and some more files for make. To run autogen.sh you'll need
 GNU autoconf and GNU automake: at least autoconf 2.61 and automake 1.10 are
-requird, newer is better. But don't use automake 1.12 or newer for creating
+required, newer is better. But don't use automake 1.12 or newer for creating
 distribution archives: it will work but lack "de-ANSI-fication" support in the
 generated Makefile's! Stick with automake 1.11.x for this purpose ...
 So automake 1.11.x and autoconf 2.67+ is recommended.

+ 2 - 2
Makefile.am

@@ -1,6 +1,6 @@
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors
+# Copyright (c)2001-2015 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
@@ -13,7 +13,7 @@ AUTOMAKE_OPTIONS = gnu
 
 SUBDIRS = doc src man contrib
 
-EXTRA_DIST = autogen.sh configure.ng .mailmap
+EXTRA_DIST = autogen.sh configure.ng .clang_complete .mailmap
 
 clean-local: osxpkg-clean
 	rm -f build-stamp*

+ 2 - 2
Makefile.in

@@ -17,7 +17,7 @@
 
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors
+# Copyright (c)2001-2015 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
@@ -246,7 +246,7 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 AUTOMAKE_OPTIONS = gnu
 SUBDIRS = doc src man contrib
-EXTRA_DIST = autogen.sh configure.ng .mailmap
+EXTRA_DIST = autogen.sh configure.ng .clang_complete .mailmap
 all: all-recursive
 
 .SUFFIXES:

+ 46 - 7
NEWS

@@ -9,6 +9,45 @@
                                   -- NEWS --
 
 
+ngIRCd 23 (2015-11-16)
+
+  ngIRCd 23~rc1 (2015-09-06)
+  - Use "NOTICE *" before registration instead of "NOTICE AUTH". "AUTH" is
+    a valid nickname so sending notices to it is probably not a good idea.
+    Use "*" as the target instead as done with numerics when the nick is not
+    available. This mimics the behavior in Charybdis, IRCD-Hybrid, InspIRCd
+    2.2, Plexus 4, etc. Closes #217.
+    The "NoticeAuth" configuration variable (ngircd.conf) has been renamed
+    to "NoticeBeforeRegistration" accordingly, but the old name is still
+    supported for compatibility reasons.
+  - Implement new channel mode "N" (regular users can't change their nick
+    name while on this channel). Closes #214.
+  - Keep track of who placed bans, invites, and excepts.
+    Idea and implementation by LucentW, Thanks! Closes #203.
+  - Implement numeric RPL_LISTSTART(321). lightIRC and other clients
+    expecting RPL_LISTSTART should now behave correctly.
+    Idea and implementation by LucentW, Thanks! Closes #207.
+  - Streamline the effect of "MorePrivacy" option: Update documentation
+    in ngircd.conf(5); don't hide channels for IRC Ops on LIST and don't
+    hide IP addresses/hostnames on WHOIS when "MorePrivacy" is in effect.
+    This closes #198.
+  - IRC operators now can kick anyone when "OperCanMode" is set.
+    Idea and implementation by LucentW, Thanks! Closes #202.
+  - Implement user mode "I": Hide channels on WHOIS: this mode prevents
+    ngIRCd from showing channels on WHOIS (IRC Operators can always see
+    the channel list).
+    Idea and implementation by LucentW, Thanks! Closes #197.
+  - INVITE command: Implement ERR_USERNOTONSERV(504) numeric and make sure
+    that the target user is on the same server when inviting other users
+    to local ("&") channels.
+    Idea by Cahata, thanks! Closes #183.
+  - MODE command: Always report channel creation time. Up to now when
+    receiving a MODE command, ngIRCd only reported the channel creation
+    time to clients that were members of the channel. This patch reports
+    the channel creation time to all clients, regardless if they are joined
+    to that channel or not. At least ircd-seven behaves like this.
+    This closes #188. Reported by Cahata, thanks!
+
 ngIRCd 22.1 (2015-04-06)
 
   - Update "CipherList" to not enable SSLv3 by default. Idea, initial patch,
@@ -285,7 +324,7 @@ ngIRCd 19.2 (2012-06-19)
     which still is the default when "CloakHostModeX" isn't set.
   - Add instructions for setting up Atheme IRC services.
   - Implement support for IRC capability handling, the new "CAP" command,
-    and capablity "multi-prefix" which allows both the NAME and	WHO command
+    and capability "multi-prefix" which allows both the NAME and WHO command
     handlers to return more than one "class prefix" to the client.
 
 ngIRCd 19.1 (2012-03-19)
@@ -448,7 +487,7 @@ ngIRCd 17 (2010-11-07)
 
   ngIRCd 17~rc2 (2010-10-25)
   - Generate ngIRCd version number from GIT tag.
-  - Make sourcecode compatible with ansi2knr again. This allows to compile
+  - Make source code compatible with ansi2knr again. This allows to compile
     ngIRCd using a pre-ANSI K&R C compiler again.
 
   ngIRCd 17~rc1 (2010-10-11)
@@ -457,7 +496,7 @@ ngIRCd 17 (2010-11-07)
     Howl, Avahi or on Mac OS X).
   - New configuration option "SyslogFacility" to define the syslog "facility"
     (the "target"), to which ngIRCd should send its log messages.
-    Possible values are system dependant, but most probably "auth", "daemon",
+    Possible values are system dependent, but most probably "auth", "daemon",
     "user" and "local1" through "local7" are possible values; see syslog(3).
     Default is "local5" for historical reasons.
   - Dump the "internal server state" (configured servers, established
@@ -467,7 +506,7 @@ ngIRCd 17 (2010-11-07)
     signal SIGUSR1, when debug code is compiled in, not only on startup
     using the command line parameters.
   - Implement user mode "x": host name cloaking (closes: #102).
-  - Change MOTD file handling: ngIRCd now caches the contens of the MOTD
+  - Change MOTD file handling: ngIRCd now caches the contents of the MOTD
     file, so the daemon now requires a HUP signal or REHASH command to
     re-read the MOTD file when its content changed.
   - Allow IRC ops to change channel modes even without OperServerMode set.
@@ -483,7 +522,7 @@ ngIRCd 17 (2010-11-07)
 ngIRCd 16 (2010-05-02)
 
   ngIRCd 16~rc2 (2010-04-25)
-  - Enhace connection statistics counters: display total number of served
+  - Enhance connection statistics counters: display total number of served
     connections on daemon shutdown and when a new client connects using
     the new numeric RPL_STATSCONN (250).
 
@@ -505,7 +544,7 @@ ngIRCd 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
+  - Enable IRC operators to use the IRC command SQUIT (instead 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
@@ -688,7 +727,7 @@ ngIRCd 0.7.0 (2003-05-01)
   - Documentation is now installed in $(datadir)/doc/ngircd.
 
 
-Older news (sorry, only available in german language):
+Older news (sorry, only available in German language):
 
 ngIRCd 0.6.0, 24.12.2002
 

+ 7 - 7
README

@@ -28,7 +28,7 @@ Please see the INSTALL document for installation and upgrade information!
 II. Status
 ~~~~~~~~~~~
 
-It is not the goal of ngIRCd to implement all the nasty behaviours of the
+It is not the goal of ngIRCd to implement all the nasty behaviors of the
 original ircd, but to implement most of the useful commands and semantics
 specified by the RFCs.
 
@@ -74,7 +74,7 @@ releases there.
 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
 the file "doc/GIT.txt" which describes the use of GIT, the version control
-system used by ngIRCd (homepage: http://git-scm.com/).
+system used by ngIRCd (homepage: <http://git-scm.com/>).
 
 
 VI. Bugs
@@ -83,11 +83,11 @@ VI. Bugs
 If you find bugs in the ngIRCd (which might be there :-), please report
 them at the following URL:
 
-<http://ngircd.barton.de/bugtracker.php>
+<https://github.com/ngircd/ngircd/issues>
 
 There you can read about known bugs and limitations, too.
 
-If you have critics, patches or something else, please feel free to post a
-mail to the ngIRCd mailing list: <ngircd-ml@arthur.barton.de> (please see
-<http://ngircd.barton.de/support.php#ml> for details) or join the ngIRCd
-IRC channel: <irc://irc.barton.de/ngircd>.
+If you have comments, patches or something else, please feel free to post
+a mail to the ngIRCd mailing list: <ngircd-ml@ngircd.barton.de> (please see
+<http://ngircd.barton.de/support.php> for details) or join the ngIRCd IRC
+channel: <irc://irc.barton.de/ngircd>.

+ 3 - 3
autogen.sh

@@ -109,8 +109,8 @@ Notfound()
 
 Run()
 {
-	[ "$VERBOSE" = "1" ] && echo " - running \"$@\" ..."
-	$@
+	[ "$VERBOSE" = "1" ] && echo " - running \"$*\" ..."
+	"$@"
 }
 
 # Reset locale settings to suppress warning messages of Perl
@@ -157,7 +157,7 @@ AUTOMAKE_VERSION=`echo $AUTOMAKE | cut -d'-' -f2-`
 	&& export AUTOMAKE_VERSION || unset AUTOMAKE_VERSION
 [ "$VERBOSE" = "1" ] && echo " - AUTOMAKE_VERSION=$AUTOMAKE_VERSION"
 
-[ $# -gt 0 ] && CONFIGURE_ARGS=" $@" || CONFIGURE_ARGS=""
+[ $# -gt 0 ] && CONFIGURE_ARGS=" $*" || CONFIGURE_ARGS=""
 [ -z "$GO" -a -n "$CONFIGURE_ARGS" ] && GO=1
 
 # Verify that all tools have been found

+ 16 - 13
configure

@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for ngIRCd 22.1.
+# Generated by GNU Autoconf 2.69 for ngIRCd 23.
 #
 # Report bugs to <ngircd-ml@ngircd.barton.de>.
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='ngIRCd'
 PACKAGE_TARNAME='ngircd'
-PACKAGE_VERSION='22.1'
-PACKAGE_STRING='ngIRCd 22.1'
+PACKAGE_VERSION='23'
+PACKAGE_STRING='ngIRCd 23'
 PACKAGE_BUGREPORT='ngircd-ml@ngircd.barton.de'
 PACKAGE_URL='http://ngircd.barton.de/'
 
@@ -1300,7 +1300,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures ngIRCd 22.1 to adapt to many kinds of systems.
+\`configure' configures ngIRCd 23 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1370,7 +1370,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of ngIRCd 22.1:";;
+     short | recursive ) echo "Configuration of ngIRCd 23:";;
    esac
   cat <<\_ACEOF
 
@@ -1483,7 +1483,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-ngIRCd configure 22.1
+ngIRCd configure 23
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2017,7 +2017,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by ngIRCd $as_me 22.1, which was
+It was created by ngIRCd $as_me 23, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2311,16 +2311,17 @@ as_fn_append ac_func_list " arc4random_stir"
 as_fn_append ac_func_list " gai_strerror"
 as_fn_append ac_func_list " getnameinfo"
 as_fn_append ac_func_list " inet_aton"
+as_fn_append ac_func_list " setgroups"
 as_fn_append ac_func_list " sigaction"
 as_fn_append ac_func_list " sigprocmask"
 as_fn_append ac_func_list " snprintf"
-as_fn_append ac_func_list " vsnprintf"
 as_fn_append ac_func_list " strdup"
-as_fn_append ac_func_list " strndup"
-as_fn_append ac_func_list " strlcpy"
 as_fn_append ac_func_list " strlcat"
+as_fn_append ac_func_list " strlcpy"
+as_fn_append ac_func_list " strndup"
 as_fn_append ac_func_list " strtok_r"
 as_fn_append ac_func_list " unsetenv"
+as_fn_append ac_func_list " vsnprintf"
 as_fn_append ac_func_list " waitpid"
 # Check that the precious variables saved in the cache have kept the same
 # value.
@@ -2933,7 +2934,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='ngircd'
- VERSION='22.1'
+ VERSION='23'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -6199,6 +6200,8 @@ done
 
 
 
+
+
 	for ac_func in getaddrinfo
 do :
   ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo"
@@ -8095,7 +8098,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by ngIRCd $as_me 22.1, which was
+This file was extended by ngIRCd $as_me 23, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -8162,7 +8165,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-ngIRCd config.status 22.1
+ngIRCd config.status 23
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 

+ 2 - 2
configure.ac

@@ -221,8 +221,8 @@ AC_CHECK_FUNCS([ \
 # Optional functions
 AC_CHECK_FUNCS_ONCE([
 	arc4random arc4random_stir gai_strerror getnameinfo inet_aton \
-	sigaction sigprocmask snprintf vsnprintf strdup strndup strlcpy strlcat \
-	strtok_r unsetenv waitpid])
+	setgroups sigaction sigprocmask snprintf strdup strlcat strlcpy \
+	strndup strtok_r unsetenv vsnprintf waitpid])
 
 WORKING_GETADDRINFO
 

+ 2 - 2
configure.ng

@@ -221,8 +221,8 @@ AC_CHECK_FUNCS([ \
 # Optional functions
 AC_CHECK_FUNCS_ONCE([
 	arc4random arc4random_stir gai_strerror getnameinfo inet_aton \
-	sigaction sigprocmask snprintf vsnprintf strdup strndup strlcpy strlcat \
-	strtok_r unsetenv waitpid])
+	setgroups sigaction sigprocmask snprintf strdup strlcat strlcpy \
+	strndup strtok_r unsetenv vsnprintf waitpid])
 
 WORKING_GETADDRINFO
 

+ 12 - 0
contrib/Debian/changelog

@@ -1,3 +1,15 @@
+ngircd (23-0ab1) unstable; urgency=low
+
+  * New "upstream" release: ngIRCd 23.
+
+ -- Alexander Barton <alex@barton.de>  Mon, 16 Nov 2015 21:27:03 +0100
+
+ngircd (23~rc1-0ab1) unstable; urgency=low
+
+  * New "upstream" release candidate 1 for ngIRCd Release 23.
+
+ -- Alexander Barton <alex@barton.de>  Sun, 06 Sep 2015 16:55:23 +0200
+
 ngircd (22.1-0ab1) unstable; urgency=low
 
   * New "upstream" release: ngIRCd 22.1.

+ 2 - 2
contrib/Debian/ngircd.init

@@ -1,7 +1,7 @@
 #!/bin/sh
 #
 # ngIRCd start and stop script for Debian-based systems
-# Copyright 2008-2013 Alexander Barton <alex@barton.de>
+# Copyright 2008-2015 Alexander Barton <alex@barton.de>
 #
 
 ### BEGIN INIT INFO
@@ -37,7 +37,7 @@ log_daemon_msg() {
 	echo -n "$*"
 }
 log_end_msg() {
-	[ "$1" == "0" ] && echo "." || echo " failed!"
+	[ "$1" = "0" ] && echo "." || echo " failed!"
 }
 log_failure_msg() {
 	echo "$*"

+ 4 - 6
contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj

@@ -84,7 +84,7 @@
 		FA2D564811EA158B00D37A35 /* pam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pam.h; sourceTree = "<group>"; };
 		FA2D564911EA158B00D37A35 /* pam.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pam.c; sourceTree = "<group>"; };
 		FA2D567A11EA1AB300D37A35 /* libpam.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpam.dylib; path = usr/lib/libpam.dylib; sourceTree = SDKROOT; };
-		FA322BBA0CEF72E4001761B3 /* ngIRCd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = ngIRCd; path = ngircd; sourceTree = BUILT_PRODUCTS_DIR; };
+		FA322BBA0CEF72E4001761B3 /* ngircd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ngircd; sourceTree = BUILT_PRODUCTS_DIR; };
 		FA322CD60CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; 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>"; };
@@ -310,7 +310,7 @@
 		1AB674ADFE9D54B511CA2CBB /* Products */ = {
 			isa = PBXGroup;
 			children = (
-				FA322BBA0CEF72E4001761B3 /* ngIRCd */,
+				FA322BBA0CEF72E4001761B3 /* ngircd */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -626,7 +626,7 @@
 			name = ngIRCd;
 			productInstallPath = "$(HOME)/bin";
 			productName = ngIRCd;
-			productReference = FA322BBA0CEF72E4001761B3 /* ngIRCd */;
+			productReference = FA322BBA0CEF72E4001761B3 /* ngircd */;
 			productType = "com.apple.product-type.tool";
 		};
 /* End PBXNativeTarget section */
@@ -635,7 +635,7 @@
 		08FB7793FE84155DC02AAC07 /* Project object */ = {
 			isa = PBXProject;
 			attributes = {
-				LastUpgradeCheck = 0430;
+				LastUpgradeCheck = 0630;
 			};
 			buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "ngIRCd" */;
 			compatibilityVersion = "Xcode 3.2";
@@ -742,7 +742,6 @@
 		1DEB928B08733DD80010E9CD /* Default */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
 				CODE_SIGN_IDENTITY = "";
 				GCC_VERSION = "";
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
@@ -755,7 +754,6 @@
 		FAB0570C105D917F006AF9E2 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				ARCHS = "$(NATIVE_ARCH_ACTUAL)";
 				GCC_DEBUGGING_SYMBOLS = full;
 				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_VERSION = "";

+ 1 - 1
contrib/README

@@ -12,7 +12,7 @@
 Debian/
  - Various files for building Debian GNU/Linux packages (".deb's").
 	- ngircd.init; ngircd.default: init script for Debian-based systems.
-	- ngircd.pam: example PAM configuraton.
+	- ngircd.pam: example PAM configuration.
 
 MacOSX/
  - Project files for XCode, the "project builder" of Apple Mac OS X.

+ 11 - 0
contrib/ngircd.service

@@ -4,8 +4,19 @@ After=network.target
 
 [Service]
 Type=forking
+User=irc
+Group=irc
+CapabilityBoundingSet=CAP_SETUID CAP_SETGID CAP_SYS_CHROOT CAP_NET_BIND_SERVICE
+PrivateTmp=yes
+PrivateDevices=yes
+ProtectSystem=full
+ProtectHome=true
+NoNewPrivileges=true
+RuntimeDirectory=ircd
+RuntimeDirectoryMode=750
 ExecStart=/usr/sbin/ngircd
 ExecReload=/bin/kill -HUP $MAINPID
+Restart=on-failure
 
 [Install]
 WantedBy=multi-user.target

+ 1 - 1
contrib/ngircd.spec

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

+ 1 - 1
contrib/platformtest.sh

@@ -161,7 +161,7 @@ if [ -r "Makefile" ]; then
 fi
 
 # Get ngIRCd version information
-eval $(grep "^VERSION = " Makefile | sed -e 's/ //g')
+eval "$(grep "^VERSION = " Makefile | sed -e 's/ //g')"
 case "$VERSION" in
 	*~*-*)
 		VERSION=`echo "$VERSION" | cut -b1-10`

+ 2 - 2
doc/Capabilities.txt

@@ -13,7 +13,7 @@ This document lists and describes the "IRC capabilities" that ngIRCd supports
 and can be requested by a IRC/IRCv3 client that supports the "CAP" command.
 
 ngIRCd implements the "IRC Client Capabilities Extension" as described here:
-<http://www.leeh.co.uk/draft-mitchell-irc-capabilities-02.html>
+<http://ircv3.net/specs/core/capability-negotiation-3.1.html>
 
 
 I. Supported Capabilities
@@ -25,4 +25,4 @@ I. Supported Capabilities
    server to send all possible prefixes which apply to a user in NAMES and
    WHO output.
 
-   See <http://ircv3.atheme.org/extensions/multi-prefix-3.1>.
+   See <http://ircv3.net/specs/extensions/multi-prefix-3.1.html>.

+ 2 - 2
doc/Commands.txt

@@ -78,7 +78,7 @@ Connection Handling Commands
 	like this: "CAP REQ :capability1 capability2 capability3" for example.
 
 	References:
-	 - <http://ircv3.atheme.org/specification/capability-negotiation-3.1>
+	 - <http://ircv3.net/specs/core/capability-negotiation-3.1.html>
 	 - <http://ngircd.barton.de/doc/Capabilities.txt>
 	 - doc/Capabilities.txt
 
@@ -380,7 +380,7 @@ Status and Informational Commands
 
 	Please note that "all" IRC daemons even parse separate nicknames in
 	a single parameter (like ":nick1 nick2"), and therefore ngIRCd
-	implements this behaviour, too.
+	implements this behavior, too.
 
 	References:
 	 - RFC 2812, 4.9 "Ison message"

+ 8 - 2
doc/Contributing.txt

@@ -2,7 +2,7 @@
                      ngIRCd - Next Generation IRC Server
                            http://ngircd.barton.de/
 
-               (c)2001-2011 Alexander Barton and Contributors.
+               (c)2001-2015 Alexander Barton and Contributors.
                ngIRCd is free software and published under the
                    terms of the GNU General Public License.
 
@@ -15,7 +15,7 @@ get an idea of how to do it the best :-)
  - Use GIT
 
    The source code of ngIRCd is maintained using GIT, see doc/GIT.txt. So if
-   remotely possible, use GIT for your work, too. It makes your and our lifes
+   remotely possible, use GIT for your work, too. It makes your and our lives
    much easier ;-)
 
  - Don't forget to include documentation
@@ -52,3 +52,9 @@ get an idea of how to do it the best :-)
 
    And this is open source, your work must not be 100% finished and perfect,
    work in progress is interesting, too: "release early, release often"!
+
+- Use GitHub to create "Pull Requests"
+
+  ngIRCd is hosted on GitHub (<https://github.com/ngircd>), so please use the
+  tools available there and open issues (comment!) and create pull requests!
+  See <https://help.github.com/articles/using-pull-requests/> for details.

+ 4 - 4
doc/FAQ.txt

@@ -99,11 +99,11 @@ IV. Bugs!?
 ~~~~~~~~~~
 
 Q: Is there a list of known bugs and desired feature enhancements?
-A: Yes. Have a look at the bug tracking system (Bugzilla) for ngIRCd located
-   at <http://ngircd.barton.de/bugzilla/index.cgi>. There you can file bug
+A: Yes. Have a look at the bug tracking system (GitHub issues) for ngIRCd located
+   at <https://github.com/ngircd/ngircd/issues>. There you can file bug
    reports and feature requests as well as search the bug database.
 
 Q: What should I do if I found a bug?
-A: Please file a bug report at <http://ngircd.barton.de/bugzilla/index.cgi>!
-   The author of the particular component will be notified automagically :-)
+A: Please file a bug report at <https://github.com/ngircd/ngircd/issues/new>!
+   The author will be notified automagically :-)
 

+ 0 - 65
doc/GIT.txt

@@ -1,65 +0,0 @@
-
-                     ngIRCd - Next Generation IRC Server
-                           http://ngircd.barton.de/
-
-               (c)2001-2011 Alexander Barton and Contributors.
-               ngIRCd is free software and published under the
-                   terms of the GNU General Public License.
-
-                                 -- GIT.txt --
-
-
-The source code of ngIRCd is maintained using GIT, an distributed version
-control system. Homepage including documentation: <http://git-scm.com/>.
-
-
-I. Viewing the source code online
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ngIRCd "GITweb" interface allows you to browse the GIT repository and
-to see all individual files, tags, branches, commits etc.:
-
- <http://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd.git>
-
-
-II. Getting the source code
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To access (copy, clone) the source tree repository 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. Please see the
-file INSTALL for details!
-
-To update the local GIT repository:
-
- $ git pull
-
-This retrieves all changes and merges them into the current branch.
-
-
-III. 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>.
-
-
-IV. 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>.

+ 1 - 0
doc/HowToRelease.txt

@@ -37,6 +37,7 @@ II. How to prepare a new ngIRCd release?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 a) Make sure the source tree is in a releasable state ;-)
+    - is the AUTHORS file up to date?
 
 b) Make sure you have working versions of GNU autoconf and GNU automake
    installed on the system you use for generating the release:

+ 1 - 2
doc/Makefile.am

@@ -1,6 +1,6 @@
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors
+# Copyright (c)2001-2015 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
@@ -23,7 +23,6 @@ static_docs = \
 	Commands.txt \
 	Contributing.txt \
 	FAQ.txt \
-	GIT.txt \
 	HowToRelease.txt \
 	Modes.txt \
 	PAM.txt \

+ 1 - 2
doc/Makefile.in

@@ -17,7 +17,7 @@
 
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors
+# Copyright (c)2001-2015 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
@@ -232,7 +232,6 @@ static_docs = \
 	Commands.txt \
 	Contributing.txt \
 	FAQ.txt \
-	GIT.txt \
 	HowToRelease.txt \
 	Modes.txt \
 	PAM.txt \

+ 4 - 2
doc/Modes.txt

@@ -2,7 +2,7 @@
                      ngIRCd - Next Generation IRC Server
                            http://ngircd.barton.de/
 
-               (c)2001-2014 Alexander Barton and Contributors.
+               (c)2001-2015 Alexander Barton and Contributors.
                ngIRCd is free software and published under the
                    terms of the GNU General Public License.
 
@@ -28,6 +28,7 @@ channels he is using at the moment.
   C	19	Only users that share a channel are allowed to send messages.
   F	22	Relaxed flood protection (only settable by IRC Operators).
   i	0.0.1	User is "invisible".
+  I	23	No channels are shown on WHOIS (IRC Ops can always see those).
   o	0.0.1	User is IRC operator.
   q	20	User is protected, can not be kicked from a channel.
   r	0.0.1	User is restricted.
@@ -55,6 +56,7 @@ users to lists (e.g. "invite list", "ban list"), others have parameters
   m	0.3.0	Channel is moderated, only "voiced" users can send messages.
   M	20	Only registered users (and IRC Ops) can send messages.
   n	0.3.0	Channel doesn't allow messages of users not being members.
+  N     23      Users can't change their nickname while on this channel.
   O	18	Only IRC operators are allowed to join this channel.
   P	0.5.0	Channel is "persistent".
   Q	20	Nobody can be kicked from the channel.
@@ -86,4 +88,4 @@ Notes
 ~~~~~
 
 (1) This mode is not set by ngIRCd itself but by services. ngIRCd handles
-    the mode transparently and possibly adjusts its behaviour.
+    the mode transparently and possibly adjusts its behavior.

+ 4 - 4
doc/Platforms.txt

@@ -89,7 +89,7 @@ sparc/unknown/openbsd5.5    gcc 4.2.1    21.1       14-05-03 goetz    Y Y Y Y 3
 x86_64/apple/darwin10.8.0   gcc 4.2.1    21~rc2     13-10-30 alex     Y Y Y Y 3
 x86_64/apple/darwin12.3.0   gcc 4.2.1    20.2       13-04-01 alex     Y Y Y Y 3
 x86_64/apple/darwin13.0.0   A-clang 5.0  21         14-01-02 alex     Y Y Y Y 3
-x86_64/apple/darwin14.0.0   A-clang 6.0  22~rc1-3   14-10-10 alex     Y Y Y Y 3
+x86_64/apple/darwin14.5.0   A-clang 6.1  23~rc1     15-09-06 alex     Y Y Y Y 3
 x86_64/unknown/dragonfly3.4 gcc 4.7.2    21         13-11-12 goetz    Y Y N Y 3
 x86_64/unknown/freebsd8.4   gcc 4.2.1    22~rc1-3   14-10-10 alex     Y Y y Y 3
 x86_64/unknown/freebsd9.2   gcc 4.2.1    22~rc1-3   14-10-10 alex     Y Y Y Y 3
@@ -97,10 +97,10 @@ x86_64/unknown/freebsd10.0  F-clang 3.3  22~rc1-3   14-10-10 alex     Y Y Y Y 3
 x86_64/unkn./freebsd8.1-gnu gcc 4.4.5    19         12-02-26 alex     Y Y Y Y 3
 x86_64/unknown/linux-gnu    clang 3.3    21         14-01-07 alex     Y Y Y Y 1
 x86_64/unknown/linux-gnu    clang 3.4    22~rc1-3   14-10-11 alex     Y Y Y Y 1
-x86_64/unknown/linux-gnu    gcc 4.4.5    22~rc1-3   14-10-10 alex     Y Y Y Y 1
-x86_64/unknown/linux-gnu    gcc 4.7.2    22~rc1-3   14-10-10 alex     Y Y Y Y 1
+x86_64/unknown/linux-gnu    gcc 4.4.5    23~rc1-3   15-11-15 alex     Y Y Y Y 1
+x86_64/unknown/linux-gnu    gcc 4.7.2    23~rc1-3   15-11-15 alex     Y Y Y Y 1
 x86_64/unknown/linux-gnu    gcc 4.8.2    21         13-12-29 alex     Y Y Y Y 1
-x86_64/unknown/linux-gnu    gcc 4.9.1    22~rc1-3   14-10-10 alex     Y Y Y Y 1
+x86_64/unknown/linux-gnu    gcc 4.9.2    23~rc1-3   15-11-15 alex     Y Y Y Y 1
 x86_64/unknown/linux-gnu    nwcc 0.8.2   21         13-12-01 goetz    Y Y Y Y 1
 x86_64/unknown/linux-gnu    Open64       21.1       14-03-27 goetz    Y Y Y Y 1
 x86_64/unknown/linux-gnu    Sun C 5.12   21.1       14-03-27 goetz    Y Y Y Y 1

+ 2 - 2
doc/sample-ngircd.conf.tmpl

@@ -193,9 +193,9 @@
 	;MorePrivacy = no
 
 	# Normally ngIRCd doesn't send any messages to a client until it is
-	# registered. Enable this option to let the daemon send "NOTICE AUTH"
+	# registered. Enable this option to let the daemon send "NOTICE *"
 	# messages to clients while connecting.
-	;NoticeAuth = no
+	;NoticeBeforeRegistration = no
 
 	# Should IRC Operators be allowed to use the MODE command even if
 	# they are not(!) channel-operators?

+ 7 - 6
man/ngircd.conf.5.tmpl

@@ -252,8 +252,8 @@ The Salt for cloaked hostname hashing. When undefined a random hash is
 generated after each server start.
 .TP
 \fBCloakUserToNick\fR (boolean)
-Set every clients' user name to their nickname and hide the one supplied
-by the IRC client. Default: no.
+Set every clients' user name and real name to their nickname and hide the one
+supplied by the IRC client. Default: no.
 .TP
 \fBConnectIPv4\fR (boolean)
 Set this to no if you do not want ngIRCd to connect to other IRC servers using
@@ -291,16 +291,17 @@ Default: none.
 .TP
 \fBMorePrivacy\fR (boolean)
 This will cause ngIRCd to censor user idle time, logon time as well as the
-part/quit messages (that are sometimes used to inform everyone about which
-client software is being used). WHOWAS requests are also silently ignored.
+PART/QUIT messages (that are sometimes used to inform everyone about which
+client software is being used). WHOWAS requests are also silently ignored,
+and NAMES output doesn't list any clients for non-members.
 This option is most useful when ngIRCd is being used together with
 anonymizing software such as TOR or I2P and one does not wish to make it
 too easy to collect statistics on the users.
 Default: no.
 .TP
-\fBNoticeAuth\fR (boolean)
+\fBNoticeBeforeRegistration\fR (boolean)
 Normally ngIRCd doesn't send any messages to a client until it is registered.
-Enable this option to let the daemon send "NOTICE AUTH" messages to clients
+Enable this option to let the daemon send "NOTICE *" messages to clients
 while connecting. Default: no.
 .TP
 \fBOperCanUseMode\fR (boolean)

+ 3 - 0
src/config.h.in

@@ -150,6 +150,9 @@
 /* Define to 1 if you have the `select' function. */
 #undef HAVE_SELECT
 
+/* Define to 1 if you have the `setgroups' function. */
+#undef HAVE_SETGROUPS
+
 /* Define to 1 if you have the `setsid' function. */
 #undef HAVE_SETSID
 

+ 17 - 10
src/ngircd/channel.c

@@ -352,14 +352,19 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
 		    !Channel_UserHasMode(chan, Target, 'q') &&
 		    !Channel_UserHasMode(chan, Target, 'a'))
 			can_kick = true;
-			
-		/* Half Op can't kick owner | admin | op */ 
+
+		/* Half Op can't kick owner | admin | op */
 		else if (Channel_UserHasMode(chan, Peer, 'h') &&
 		    !Channel_UserHasMode(chan, Target, 'q') &&
 		    !Channel_UserHasMode(chan, Target, 'a') &&
 		    !Channel_UserHasMode(chan, Target, 'o'))
 			can_kick = true;
 
+		/* IRC operators & IRCd with OperCanMode enabled
+		 * can kick anyways regardless of privilege */
+		else if(Client_HasMode(Origin, 'o') && Conf_OperCanMode)
+		    can_kick = true;
+
 		if(!can_kick) {
 			IRC_WriteErrClient(Origin, ERR_CHANOPPRIVTOOLOW_MSG,
 					   Client_ID(Origin), Name);
@@ -1039,7 +1044,7 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch
 	switch( Type )
 	{
 		case REMOVE_QUIT:
-			/* QUIT: other servers have already been notified, 
+			/* QUIT: other servers have already been notified,
 			 * see Client_Destroy(); so only inform other clients
 			 * in same channel. */
 			assert( InformServer == false );
@@ -1093,29 +1098,29 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const ch
 
 
 GLOBAL bool
-Channel_AddBan(CHANNEL *c, const char *mask )
+Channel_AddBan(CHANNEL *c, const char *mask, const char *who )
 {
 	struct list_head *h = Channel_GetListBans(c);
 	LogDebug("Adding \"%s\" to \"%s\" ban list", mask, Channel_Name(c));
-	return Lists_Add(h, mask, false, NULL);
+	return Lists_Add(h, mask, time(NULL), who, false);
 }
 
 
 GLOBAL bool
-Channel_AddExcept(CHANNEL *c, const char *mask )
+Channel_AddExcept(CHANNEL *c, const char *mask, const char *who )
 {
 	struct list_head *h = Channel_GetListExcepts(c);
 	LogDebug("Adding \"%s\" to \"%s\" exception list", mask, Channel_Name(c));
-	return Lists_Add(h, mask, false, NULL);
+	return Lists_Add(h, mask, time(NULL), who, false);
 }
 
 
 GLOBAL bool
-Channel_AddInvite(CHANNEL *c, const char *mask, bool onlyonce)
+Channel_AddInvite(CHANNEL *c, const char *mask, bool onlyonce, const char *who )
 {
 	struct list_head *h = Channel_GetListInvites(c);
 	LogDebug("Adding \"%s\" to \"%s\" invite list", mask, Channel_Name(c));
-	return Lists_Add(h, mask, onlyonce, NULL);
+	return Lists_Add(h, mask, time(NULL), who, onlyonce);
 }
 
 
@@ -1132,7 +1137,9 @@ ShowChannelList(struct list_head *head, CLIENT *Client, CHANNEL *Channel,
 	while (e) {
 		if (!IRC_WriteStrClient(Client, msg, Client_ID(Client),
 					Channel_Name(Channel),
-					Lists_GetMask(e)))
+					Lists_GetMask(e),
+					Lists_GetReason(e),
+					Lists_GetValidity(e)))
 			return DISCONNECTED;
 		e = Lists_GetNext(e);
 	}

+ 3 - 3
src/ngircd/channel.h

@@ -127,10 +127,10 @@ GLOBAL char *Channel_TopicWho PARAMS(( CHANNEL *Chan ));
 GLOBAL unsigned int Channel_CreationTime PARAMS(( CHANNEL *Chan ));
 #endif
 
-GLOBAL bool Channel_AddBan PARAMS((CHANNEL *c, const char *Mask));
-GLOBAL bool Channel_AddExcept PARAMS((CHANNEL *c, const char *Mask));
+GLOBAL bool Channel_AddBan PARAMS((CHANNEL *c, const char *Mask, const char *who));
+GLOBAL bool Channel_AddExcept PARAMS((CHANNEL *c, const char *Mask, const char *who));
 GLOBAL bool Channel_AddInvite PARAMS((CHANNEL *c, const char *Mask,
-				      bool OnlyOnce));
+				      bool OnlyOnce, const char *who));
 
 GLOBAL bool Channel_ShowBans PARAMS((CLIENT *client, CHANNEL *c));
 GLOBAL bool Channel_ShowExcepts PARAMS((CLIENT *client, CHANNEL *c));

+ 1 - 1
src/ngircd/class.c

@@ -105,7 +105,7 @@ Class_AddMask(const int Class, const char *Pattern, time_t ValidUntil,
 
 	Lists_MakeMask(Pattern, mask, sizeof(mask));
 	return Lists_Add(&My_Classes[Class], mask,
-			 ValidUntil, Reason);
+			 ValidUntil, Reason, false);
 }
 
 GLOBAL void

+ 6 - 6
src/ngircd/client.c

@@ -72,7 +72,7 @@ GLOBAL void
 Client_Init( void )
 {
 	struct hostent *h;
-	
+
 	This_Server = New_Client_Struct( );
 	if( ! This_Server )
 	{
@@ -98,7 +98,7 @@ Client_Init( void )
 	Client_SetInfo( This_Server, Conf_ServerInfo );
 
 	My_Clients = This_Server;
-	
+
 	memset( &My_Whowas, 0, sizeof( My_Whowas ));
 } /* Client_Init */
 
@@ -111,7 +111,7 @@ Client_Exit( void )
 
 	if( NGIRCd_SignalRestart ) Client_Destroy( This_Server, "Server going down (restarting).", NULL, false );
 	else Client_Destroy( This_Server, "Server going down.", NULL, false );
-	
+
 	cnt = 0;
 	c = My_Clients;
 	while(c) {
@@ -228,7 +228,7 @@ GLOBAL void
 Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool SendQuit )
 {
 	/* remove a client */
-	
+
 	CLIENT *last, *c;
 	char msg[COMMAND_LEN];
 	const char *txt;
@@ -381,7 +381,7 @@ Client_SetID( CLIENT *Client, const char *ID )
 {
 	assert( Client != NULL );
 	assert( ID != NULL );
-	
+
 	strlcpy( Client->id, ID, sizeof( Client->id ));
 
 	if (Conf_CloakUserToNick) {
@@ -698,7 +698,7 @@ Client_ID( CLIENT *Client )
 	if(Client->type == CLIENT_USER)
 		assert(strlen(Client->id) < Conf_MaxNickLength);
 #endif
-						   
+
 	if( Client->id[0] ) return Client->id;
 	else return "*";
 } /* Client_ID */

+ 16 - 4
src/ngircd/conf.c

@@ -364,7 +364,7 @@ Conf_Test( void )
 		       ? (const char*) array_start(&Conf_Motd) : "");
 	}
 	printf("  Network = %s\n", Conf_Network);
-	if (!Conf_PAM) 
+	if (!Conf_PAM)
 		printf("  Password = %s\n", Conf_ServerPwd);
 	printf("  PidFile = %s\n", Conf_PidFile);
 	printf("  Ports = ");
@@ -412,7 +412,7 @@ Conf_Test( void )
 #endif
 	printf("  IncludeDir = %s\n", Conf_IncludeDir);
 	printf("  MorePrivacy = %s\n", yesno_to_str(Conf_MorePrivacy));
-	printf("  NoticeAuth = %s\n", yesno_to_str(Conf_NoticeAuth));
+	printf("  NoticeBeforeRegistration = %s\n", yesno_to_str(Conf_NoticeBeforeRegistration));
 	printf("  OperCanUseMode = %s\n", yesno_to_str(Conf_OperCanMode));
 	printf("  OperChanPAutoOp = %s\n", yesno_to_str(Conf_OperChanPAutoOp));
 	printf("  OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode));
@@ -797,7 +797,7 @@ Set_Defaults(bool InitServers)
 #endif
 	strcpy(Conf_IncludeDir, "");
 	Conf_MorePrivacy = false;
-	Conf_NoticeAuth = false;
+	Conf_NoticeBeforeRegistration = false;
 	Conf_OperCanMode = false;
 	Conf_OperChanPAutoOp = true;
 	Conf_OperServerMode = false;
@@ -1797,7 +1797,19 @@ Handle_OPTIONS(const char *File, int Line, char *Var, char *Arg)
 		return;
 	}
 	if (strcasecmp(Var, "NoticeAuth") == 0) {
-		Conf_NoticeAuth = Check_ArgIsTrue(Arg);
+		/*
+		 * 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;
 	}
 	if (strcasecmp(Var, "OperCanUseMode") == 0) {

+ 2 - 2
src/ngircd/conf.h

@@ -194,8 +194,8 @@ GLOBAL bool Conf_Ident;
 /** Enable "more privacy" mode and "censor" some user-related information */
 GLOBAL bool Conf_MorePrivacy;
 
-/** Enable NOTICE AUTH messages on connect */
-GLOBAL bool Conf_NoticeAuth;
+/** Enable "NOTICE *" messages on connect */
+GLOBAL bool Conf_NoticeBeforeRegistration;
 
 /** Enable all usage of PAM, even when compiled with support for it */
 GLOBAL bool Conf_PAM;

+ 2 - 2
src/ngircd/conn-func.c

@@ -138,7 +138,7 @@ GLOBAL CONN_ID
 Conn_First( void )
 {
 	CONN_ID i;
-	
+
 	for( i = 0; i < Pool_Size; i++ )
 	{
 		if( My_Connections[i].sock != NONE ) return i;
@@ -152,7 +152,7 @@ Conn_Next( CONN_ID Idx )
 	CONN_ID i = NONE;
 
 	assert( Idx > NONE );
-	
+
 	for( i = Idx + 1; i < Pool_Size; i++ )
 	{
 		if( My_Connections[i].sock != NONE ) return i;

+ 2 - 3
src/ngircd/conn-ssl.c

@@ -317,6 +317,7 @@ ConnSSL_InitLibrary( void )
 		goto out;
 	}
 
+	SSL_CTX_set_session_id_context(newctx, (unsigned char *)"ngircd", 6);
 	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_set_verify(newctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE,
@@ -744,7 +745,7 @@ ConnSSL_InitCertFp( CONNECTION *c )
 		gnutls_x509_crt_deinit(cert);
 		return 0;
 	}
-	
+
 	if (gnutls_x509_crt_import(cert, &cert_list[0],
 				   GNUTLS_X509_FMT_DER) != GNUTLS_E_SUCCESS) {
 		gnutls_x509_crt_deinit(cert);
@@ -911,5 +912,3 @@ ConnSSL_InitLibrary(void)
 
 #endif /* SSL_SUPPORT */
 /* -eof- */
-
-

+ 2 - 2
src/ngircd/conn-zip.c

@@ -175,7 +175,7 @@ Zip_Flush( CONN_ID Idx )
 	}
 
 	My_Connections[Idx].bytes_out += zipbuf_used;
-	My_Connections[Idx].zip.bytes_out += array_bytes(&My_Connections[Idx].zip.wbuf); 
+	My_Connections[Idx].zip.bytes_out += array_bytes(&My_Connections[Idx].zip.wbuf);
 	array_trunc(&My_Connections[Idx].zip.wbuf);
 
 	return true;
@@ -198,7 +198,7 @@ Unzip_Buffer( CONN_ID Idx )
 	int unzipbuf_used = 0;
 	unsigned int z_rdatalen;
 	unsigned int in_len;
-	
+
 	z_stream *in;
 
 	assert( Idx > NONE );

+ 16 - 16
src/ngircd/conn.c

@@ -328,7 +328,7 @@ Conn_Init( void )
 		array_bytes(&My_ConnArray));
 
 	assert(array_length(&My_ConnArray, sizeof(CONNECTION)) >= (size_t)Pool_Size);
-	
+
 	array_free( &My_Listeners );
 
 	for (i = 0; i < Pool_Size; i++)
@@ -796,7 +796,7 @@ Conn_Handler(void)
 GLOBAL bool
 Conn_WriteStr(CONN_ID Idx, const char *Format, ...)
 #else
-GLOBAL bool 
+GLOBAL bool
 Conn_WriteStr(Idx, Format, va_alist)
 CONN_ID Idx;
 const char *Format;
@@ -829,7 +829,7 @@ va_dcl
 		 * IRC_WriteXXX() functions when the prefix of this server had
 		 * to be added to an already "quite long" command line which
 		 * has been received from a regular IRC client, for example.
-		 * 
+		 *
 		 * We are not allowed to send such "oversized" messages to
 		 * other servers and clients, see RFC 2812 2.3 and 2813 3.3
 		 * ("these messages SHALL NOT exceed 512 characters in length,
@@ -1487,16 +1487,16 @@ Conn_StartLogin(CONN_ID Idx)
 		ident_sock = My_Connections[Idx].sock;
 #endif
 
-	if (Conf_NoticeAuth) {
-		/* Send "NOTICE AUTH" messages to the client */
+	if (Conf_NoticeBeforeRegistration) {
+		/* Send "NOTICE *" messages to the client */
 #ifdef IDENTAUTH
 		if (Conf_Ident)
 			(void)Conn_WriteStr(Idx,
-				"NOTICE AUTH :*** Looking up your hostname and checking ident");
+				"NOTICE * :*** Looking up your hostname and checking ident");
 		else
 #endif
 			(void)Conn_WriteStr(Idx,
-				"NOTICE AUTH :*** Looking up your hostname");
+				"NOTICE * :*** Looking up your hostname");
 		/* Send buffered data to the client, but break on errors
 		 * because Handle_Write() would have closed the connection
 		 * again in this case! */
@@ -1583,7 +1583,7 @@ Read_Request( CONN_ID Idx )
 	if (len == 0) {
 		LogDebug("Client \"%s:%u\" is closing connection %d ...",
 			 My_Connections[Idx].host,
-			 ng_ipaddr_tostr(&My_Connections[Idx].addr), Idx);
+			 ng_ipaddr_getport(&My_Connections[Idx].addr), Idx);
 		Conn_Close(Idx, NULL, "Client closed connection", false);
 		return;
 	}
@@ -2265,9 +2265,9 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 		strlcpy(My_Connections[i].host, readbuf,
 			sizeof(My_Connections[i].host));
 		Client_SetHostname(c, readbuf);
-		if (Conf_NoticeAuth)
+		if (Conf_NoticeBeforeRegistration)
 			(void)Conn_WriteStr(i,
-					"NOTICE AUTH :*** Found your hostname: %s",
+					"NOTICE * :*** Found your hostname: %s",
 					My_Connections[i].host);
 #ifdef IDENTAUTH
 		++identptr;
@@ -2291,22 +2291,22 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 				    i, identptr);
 				Client_SetUser(c, identptr, true);
 			}
-			if (Conf_NoticeAuth) {
+			if (Conf_NoticeBeforeRegistration) {
 				(void)Conn_WriteStr(i,
-					"NOTICE AUTH :*** Got %sident response%s%s",
+					"NOTICE * :*** Got %sident response%s%s",
 					*ptr ? "invalid " : "",
 					*ptr ? "" : ": ",
 					*ptr ? "" : identptr);
 			}
 		} else if(Conf_Ident) {
 			Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
-			if (Conf_NoticeAuth)
+			if (Conf_NoticeBeforeRegistration)
 				(void)Conn_WriteStr(i,
-					"NOTICE AUTH :*** No ident response");
+					"NOTICE * :*** No ident response");
 		}
 #endif
 
-		if (Conf_NoticeAuth) {
+		if (Conf_NoticeBeforeRegistration) {
 			/* Send buffered data to the client, but break on
 			 * errors because Handle_Write() would have closed
 			 * the connection again in this case! */
@@ -2364,7 +2364,7 @@ Simple_Message(int Sock, const char *Msg)
  * @returns	Pointer to CLIENT structure.
  */
 GLOBAL CLIENT *
-Conn_GetClient( CONN_ID Idx ) 
+Conn_GetClient( CONN_ID Idx )
 {
 	CONNECTION *c;
 

+ 1 - 1
src/ngircd/defines.h

@@ -177,7 +177,7 @@
 #endif
 
 /** Supported user modes. */
-#define USERMODES "abBcCFioqrRswx"
+#define USERMODES "abBcCFiIoqrRswx"
 
 /** Supported channel modes. */
 #define CHANMODES "abehiIklmMnoOPqQrRstvVz"

+ 5 - 3
src/ngircd/irc-channel.c

@@ -597,6 +597,10 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
 		}
 	}
 
+	/* Send list head */
+	if (!IRC_WriteStrClient(from, RPL_LISTSTART_MSG, Client_ID(from)))
+		return DISCONNECTED;
+
 	while (pattern) {
 		/* Loop through all the channels */
 		if (Req->argc > 0)
@@ -608,9 +612,7 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
 				/* Gotcha! */
 				if (!Channel_HasMode(chan, 's')
 				    || Channel_IsMemberOf(chan, from)
-				    || (!Conf_MorePrivacy
-					&& Client_HasMode(Client, 'o')
-					&& Client_Conn(Client) > NONE))
+				    || Client_HasMode(from, 'o'))
 				{
 					if ((Conf_MaxListSize > 0)
 					    && IRC_CheckListTooBig(from, count,

+ 46 - 36
src/ngircd/irc-info.c

@@ -313,48 +313,50 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
 				Client_Info(Client_Introducer(c))))
 		return DISCONNECTED;
 
-	/* Channels */
-	snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG,
-		 Client_ID(from), Client_ID(c));
-	cl2chan = Channel_FirstChannelOf(c);
-	while (cl2chan) {
-		chan = Channel_GetChannel(cl2chan);
-		assert(chan != NULL);
-
-		/* next */
-		cl2chan = Channel_NextChannelOf(c, cl2chan);
-
-		/* Secret channel? */
-		if (Channel_HasMode(chan, 's')
-		    && !Channel_IsMemberOf(chan, Client))
-			continue;
+	/* Channels, show only if client has no +I or if from is oper */
+	if(!(Client_HasMode(c, 'I')) || Client_HasMode(from, 'o'))  {
+		snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG,
+			 Client_ID(from), Client_ID(c));
+		cl2chan = Channel_FirstChannelOf(c);
+		while (cl2chan) {
+			chan = Channel_GetChannel(cl2chan);
+			assert(chan != NULL);
+
+			/* next */
+			cl2chan = Channel_NextChannelOf(c, cl2chan);
+
+			/* Secret channel? */
+			if (Channel_HasMode(chan, 's')
+			    && !Channel_IsMemberOf(chan, Client))
+				continue;
 
-		/* Local channel and request is not from a user? */
-		if (Client_Type(Client) == CLIENT_SERVER
-		    && Channel_IsLocal(chan))
-			continue;
+			/* Local channel and request is not from a user? */
+			if (Client_Type(Client) == CLIENT_SERVER
+			    && Channel_IsLocal(chan))
+				continue;
 
-		/* Concatenate channel names */
-		if (str[strlen(str) - 1] != ':')
-			strlcat(str, " ", sizeof(str));
+			/* Concatenate channel names */
+			if (str[strlen(str) - 1] != ':')
+				strlcat(str, " ", sizeof(str));
 
-		who_flags_qualifier(Client, Channel_UserModes(chan, c),
-				    str, sizeof(str));
-		strlcat(str, Channel_Name(chan), sizeof(str));
+			who_flags_qualifier(Client, Channel_UserModes(chan, c),
+			                    str, sizeof(str));
+			strlcat(str, Channel_Name(chan), sizeof(str));
 
-		if (strlen(str) > (COMMAND_LEN - CHANNEL_NAME_LEN - 4)) {
-			/* Line becomes too long: send it! */
+			if (strlen(str) > (COMMAND_LEN - CHANNEL_NAME_LEN - 4)) {
+				/* Line becomes too long: send it! */
+				if (!IRC_WriteStrClient(Client, "%s", str))
+					return DISCONNECTED;
+				snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG,
+					 Client_ID(from), Client_ID(c));
+			}
+		}
+		if(str[strlen(str) - 1] != ':') {
+			/* There is data left to send: */
 			if (!IRC_WriteStrClient(Client, "%s", str))
 				return DISCONNECTED;
-			snprintf(str, sizeof(str), RPL_WHOISCHANNELS_MSG,
-				 Client_ID(from), Client_ID(c));
 		}
 	}
-	if(str[strlen(str) - 1] != ':') {
-		/* There is data left to send: */
-		if (!IRC_WriteStrClient(Client, "%s", str))
-			return DISCONNECTED;
-	}
 
 	/* IRC-Services? */
 	if (Client_Type(c) == CLIENT_SERVICE &&
@@ -405,7 +407,7 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
 
 	/* Local client and requester is the user itself or an IRC Op? */
 	if (Client_Conn(c) > NONE &&
-	    (from == c || (!Conf_MorePrivacy && Client_HasMode(from, 'o')))) {
+	    (from == c || Client_HasMode(from, 'o'))) {
 		/* Client hostname */
 		if (!IRC_WriteStrClient(from, RPL_WHOISHOST_MSG,
 					Client_ID(from), Client_ID(c),
@@ -556,7 +558,15 @@ IRC_INFO(CLIENT * Client, REQUEST * Req)
 				NGIRCd_Version))
 		return DISCONNECTED;
 
-#if defined(__DATE__) && defined(__TIME__)
+#if defined(BIRTHDATE)
+	char t_str[60];
+	time_t t = BIRTHDATE;
+	(void)strftime(t_str, sizeof(t_str), "%a %b %d %Y at %H:%M:%S (%Z)",
+			localtime(&t));
+	snprintf(msg, sizeof(msg), "Birth Date: %s", t_str);
+	if (!IRC_WriteStrClient(Client, RPL_INFO_MSG, Client_ID(prefix), msg))
+		return DISCONNECTED;
+#elif defined(__DATE__) && defined(__TIME__)
 	snprintf(msg, sizeof(msg), "Birth Date: %s at %s", __DATE__, __TIME__);
 	if (!IRC_WriteStrClient(Client, RPL_INFO_MSG, Client_ID(prefix), msg))
 		return DISCONNECTED;

+ 32 - 5
src/ngircd/irc-login.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2015 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
@@ -172,6 +172,7 @@ GLOBAL bool
 IRC_NICK( CLIENT *Client, REQUEST *Req )
 {
 	CLIENT *intr_c, *target, *c;
+	CHANNEL *chan;
 	char *nick, *user, *hostname, *modes, *info;
 	int token, hops;
 
@@ -195,6 +196,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
 
 		/* Search "target" client */
 		if (Client_Type(Client) == CLIENT_SERVER) {
+			_IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
 			target = Client_Search(Req->prefix);
 			if (!target)
 				return IRC_WriteErrClient(Client,
@@ -259,6 +261,22 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
 				Client_SetType( Client, CLIENT_GOTNICK );
 		} else {
 			/* Nickname change */
+
+			/* Check that the user isn't on any channels set +N */
+			if(Client_Type(Client) == CLIENT_USER &&
+			   !Client_HasMode(Client, 'o')) {
+				chan = Channel_First();
+				while (chan) {
+					if(Channel_HasMode(chan, 'N') &&
+					   Channel_IsMemberOf(chan, Client))
+						return IRC_WriteErrClient(Client,
+									  ERR_NONICKCHANGE_MSG,
+									  Client_ID(Client),
+									  Channel_Name(chan));
+					chan = Channel_Next(chan);
+				}
+			}
+
 			Change_Nick(Client, target, Req->argv[0],
 				    Client_Type(Client) == CLIENT_USER ? true : false);
 			IRC_SetPenalty(target, 2);
@@ -362,6 +380,8 @@ IRC_SVSNICK(CLIENT *Client, REQUEST *Req)
 	assert(Client != NULL);
 	assert(Req != NULL);
 
+	_IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
+
 	/* Search the originator */
 	from = Client_Search(Req->prefix);
 	if (!from)
@@ -464,6 +484,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
 		   Client_Type(Client) == CLIENT_SERVICE) {
 		/* Server/service updating an user */
 		_IRC_ARGC_EQ_OR_RETURN_(Client, Req, 4)
+		_IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
 
 		c = Client_Search(Req->prefix);
 		if (!c)
@@ -636,6 +657,8 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
 
 	if (Client_Type(Client) == CLIENT_SERVER) {
 		/* Server */
+		_IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
+
 		target = Client_Search(Req->prefix);
 		if (!target) {
 			Log(LOG_WARNING,
@@ -724,9 +747,10 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
 
 		if (target != Client_ThisServer()) {
 			/* Ok, we have to forward the PING */
-			if (Client_Type(Client) == CLIENT_SERVER)
+			if (Client_Type(Client) == CLIENT_SERVER) {
+				_IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
 				from = Client_Search(Req->prefix);
-			else
+			} else
 				from = Client;
 			if (!from)
 				return IRC_WriteErrClient(Client,
@@ -798,6 +822,8 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
 
 	/* Forward? */
 	if (Req->argc == 2 && Client_Type(Client) == CLIENT_SERVER) {
+		_IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
+
 		target = Client_Search(Req->argv[0]);
 		if (!target)
 			return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG,
@@ -847,13 +873,14 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
 	if (Client_Type(Client) == CLIENT_SERVER && Conn_LastPing(conn) == 0) {
 		Log(LOG_INFO,
 		    "Synchronization with \"%s\" done (connection %d): %ld second%s [%ld users, %ld channels].",
-		    Client_ID(Client), conn, time(NULL) - Conn_GetSignon(conn),
+		    Client_ID(Client), conn,
+		    (long)(time(NULL) - Conn_GetSignon(conn)),
 		    time(NULL) - Conn_GetSignon(conn) == 1 ? "" : "s",
 		    Client_UserCount(), Channel_CountVisible(NULL));
 		Conn_UpdatePing(conn);
 	} else
 		LogDebug("Connection %d: received PONG. Lag: %ld seconds.",
-			 conn, time(NULL) - Conn_LastPing(conn));
+			 conn, (long)(time(NULL) - Conn_LastPing(conn)));
 
 	return CONNECTED;
 } /* IRC_PONG */

+ 20 - 4
src/ngircd/irc-macros.h

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2015 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
@@ -66,6 +66,18 @@ if (Req->argc < Min || Req->argc > Max) { \
 }
 
 /**
+ * Make sure that the command has a prefix.
+ *
+ * If there is no prefix, send an error to the client and return from
+ * the function.
+ */
+#define _IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req) \
+if (!Req->prefix) { \
+	return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG, \
+				  Client_ID(Client), Req->command); \
+}
+
+/**
  * Get sender of an IRC command.
  *
  * The sender is either stored in the prefix if the command has been
@@ -73,13 +85,17 @@ if (Req->argc < Min || Req->argc > Max) { \
  * send an error to the client and return from the function.
  */
 #define _IRC_GET_SENDER_OR_RETURN_(Sender, Req, Client) \
-	if (Client_Type(Client) == CLIENT_SERVER) \
+	if (Client_Type(Client) == CLIENT_SERVER) { \
+		if (!Req->prefix) \
+			return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG, \
+						  Client_ID(Client), Req->command); \
 		Sender = Client_Search(Req->prefix); \
-	else \
+	} else \
 		Sender = Client; \
 	if (!Sender) \
 		return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG, \
-					  Client_ID(Client), Req->prefix);
+					  Client_ID(Client), \
+					  Req->prefix ? Req->prefix : "(none)");
 
 /**
  * Get target of an IRC command and make sure that it is a server.

+ 4 - 1
src/ngircd/irc-metadata.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2015 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
@@ -24,6 +24,7 @@
 
 #include "conn-func.h"
 #include "channel.h"
+#include "irc-macros.h"
 #include "irc-write.h"
 #include "log.h"
 #include "messages.h"
@@ -47,6 +48,8 @@ IRC_METADATA(CLIENT *Client, REQUEST *Req)
 	assert(Client != NULL);
 	assert(Req != NULL);
 
+	_IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
+
 	prefix = Client_Search(Req->prefix);
 	if (!prefix)
 		return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,

+ 39 - 30
src/ngircd/irc-mode.c

@@ -206,6 +206,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 		case 'b': /* Block private msgs */
 		case 'C': /* Only messages from clients sharing a channel */
 		case 'i': /* Invisible */
+		case 'I': /* Hide channel list from WHOIS */
 		case 's': /* Server messages */
 		case 'w': /* Wallops messages */
 			x[0] = *mode_ptr;
@@ -378,37 +379,44 @@ Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel)
 	char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], argadd[CLIENT_PASS_LEN];
 	const char *mode_ptr;
 
-	/* Member or not? -- That's the question! */
-	if (!Channel_IsMemberOf(Channel, Origin))
-		return IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG,
-			Client_ID(Origin), Channel_Name(Channel), Channel_Modes(Channel));
-
-	/* The sender is a member: generate extended reply */
-	strlcpy(the_modes, Channel_Modes(Channel), sizeof(the_modes));
-	mode_ptr = the_modes;
-	the_args[0] = '\0';
-
-	while(*mode_ptr) {
-		switch(*mode_ptr) {
-		case 'l':
-			snprintf(argadd, sizeof(argadd), " %lu", Channel_MaxUsers(Channel));
-			strlcat(the_args, argadd, sizeof(the_args));
-			break;
-		case 'k':
-			strlcat(the_args, " ", sizeof(the_args));
-			strlcat(the_args, Channel_Key(Channel), sizeof(the_args));
-			break;
+	if (!Channel_IsMemberOf(Channel, Origin)) {
+		/* Not a member: "simple" mode reply */
+		if (!IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG,
+					Client_ID(Origin), Channel_Name(Channel),
+					Channel_Modes(Channel)))
+			return DISCONNECTED;
+	} else {
+		/* The sender is a member: generate extended reply */
+		strlcpy(the_modes, Channel_Modes(Channel), sizeof(the_modes));
+		mode_ptr = the_modes;
+		the_args[0] = '\0';
+
+		while(*mode_ptr) {
+			switch(*mode_ptr) {
+			case 'l':
+				snprintf(argadd, sizeof(argadd), " %lu",
+					 Channel_MaxUsers(Channel));
+				strlcat(the_args, argadd, sizeof(the_args));
+				break;
+			case 'k':
+				strlcat(the_args, " ", sizeof(the_args));
+				strlcat(the_args, Channel_Key(Channel),
+					sizeof(the_args));
+				break;
+			}
+			mode_ptr++;
 		}
-		mode_ptr++;
+		if (the_args[0])
+			strlcat(the_modes, the_args, sizeof(the_modes));
+
+		if (!IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG,
+					Client_ID(Origin), Channel_Name(Channel),
+					the_modes))
+			return DISCONNECTED;
 	}
-	if (the_args[0])
-		strlcat(the_modes, the_args, sizeof(the_modes));
 
-	if (!IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG,
-				Client_ID(Origin), Channel_Name(Channel),
-				the_modes))
-		return DISCONNECTED;
 #ifndef STRICT_RFC
+	/* Channel creation time */
 	if (!IRC_WriteStrClient(Origin, RPL_CREATIONTIME_MSG,
 				  Client_ID(Origin), Channel_Name(Channel),
 				  Channel_CreationTime(Channel)))
@@ -572,6 +580,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 		case 'M': /* Only identified nicks can write */
 		case 'm': /* Moderated */
 		case 'n': /* Only members can write */
+		case 'N': /* Can't change nick while on this channel */
 		case 'Q': /* No kicks */
 		case 't': /* Topic locked */
 			if(is_oper || is_machine || is_owner ||
@@ -1009,15 +1018,15 @@ Add_To_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
 
 	switch (what) {
 		case 'I':
-			if (!Channel_AddInvite(Channel, mask, false))
+			if (!Channel_AddInvite(Channel, mask, false, Client_ID(Client)))
 				return CONNECTED;
 			break;
 		case 'b':
-			if (!Channel_AddBan(Channel, mask))
+			if (!Channel_AddBan(Channel, mask, Client_ID(Client)))
 				return CONNECTED;
 			break;
 		case 'e':
-			if (!Channel_AddExcept(Channel, mask))
+			if (!Channel_AddExcept(Channel, mask, Client_ID(Client)))
 				return CONNECTED;
 			break;
 	}

+ 9 - 1
src/ngircd/irc-op.c

@@ -150,6 +150,14 @@ IRC_INVITE(CLIENT *Client, REQUEST *Req)
 		return IRC_WriteErrClient(from, ERR_NOSUCHNICK_MSG,
 					  Client_ID(Client), Req->argv[0]);
 
+	if (Req->argv[1][0] == '&') {
+		/* Local channel. Make sure the target user is on this server! */
+		if (Client_Conn(target) == NONE)
+			return IRC_WriteErrClient(from, ERR_USERNOTONSERV_MSG,
+						  Client_ID(Client),
+						  Req->argv[0]);
+	}
+
 	chan = Channel_Search(Req->argv[1]);
 	if (chan) {
 		/* Channel exists. Is the user a valid member of the channel? */
@@ -192,7 +200,7 @@ IRC_INVITE(CLIENT *Client, REQUEST *Req)
 		if (remember) {
 			/* We must remember this invite */
 			if (!Channel_AddInvite(chan, Client_MaskCloaked(target),
-						true))
+						true, Client_ID(from)))
 				return CONNECTED;
 		}
 	}

+ 3 - 1
src/ngircd/irc-oper.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2015 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
@@ -30,6 +30,7 @@
 #include "class.h"
 #include "parse.h"
 #include "irc.h"
+#include "irc-macros.h"
 #include "irc-write.h"
 #include "lists.h"
 #include "log.h"
@@ -358,6 +359,7 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
 		from = Client;
 		break;
 	case CLIENT_SERVER:
+		_IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
 		from = Client_Search(Req->prefix);
 		break;
 	default:

+ 3 - 3
src/ngircd/irc.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2015 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
@@ -240,7 +240,7 @@ IRC_TRACE(CLIENT *Client, REQUEST *Req)
 					PACKAGE_VERSION, Client_ID(target),
 					Client_ID(Client_NextHop(target)),
 					Option_String(idx2),
-					time(NULL) - Conn_StartTime(idx2),
+					(long)(time(NULL) - Conn_StartTime(idx2)),
 					Conn_SendQ(idx), Conn_SendQ(idx2)))
 			return DISCONNECTED;
 
@@ -526,7 +526,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 					  Client_ID(Client), Req->command);
 	}
 
-	if (Client_Type(Client) == CLIENT_SERVER)
+	if (Client_Type(Client) == CLIENT_SERVER && Req->prefix)
 		from = Client_Search(Req->prefix);
 	else
 		from = Client;

+ 20 - 5
src/ngircd/lists.c

@@ -32,7 +32,8 @@ struct list_elem {
 	struct list_elem *next;	/** pointer to next list element */
 	char mask[MASK_LEN];	/** IRC mask */
 	char *reason;		/** Optional "reason" text */
-	time_t valid_until;	/** 0: unlimited; 1: once; t(>1): until t */
+	time_t valid_until;	/** 0: unlimited; t(>0): until t */
+	bool onlyonce;
 };
 
 /**
@@ -65,7 +66,7 @@ Lists_GetReason(const struct list_elem *e)
  * Get "validity" value stored in list element.
  *
  * @param list_elem List element.
- * @return Validity: 0=unlimited, 1=once, >1 until this time stamp.
+ * @return Validity: 0=unlimited, >0 until this time stamp.
  */
 GLOBAL time_t
 Lists_GetValidity(const struct list_elem *e)
@@ -75,6 +76,19 @@ Lists_GetValidity(const struct list_elem *e)
 }
 
 /**
+ * Get "onlyonce" value stored in list element.
+ *
+ * @param list_elem List element.
+ * @return True if the element was stored for single use, false otherwise.
+ */
+GLOBAL bool
+Lists_GetOnlyOnce(const struct list_elem *e)
+{
+	assert(e != NULL);
+	return e->onlyonce;
+}
+
+/**
  * Get first list element of a list.
  *
  * @param h List head.
@@ -111,7 +125,7 @@ Lists_GetNext(const struct list_elem *e)
  */
 bool
 Lists_Add(struct list_head *h, const char *Mask, time_t ValidUntil,
-	  const char *Reason)
+	  const char *Reason, bool OnlyOnce)
 {
 	struct list_elem *e, *newelem;
 
@@ -148,6 +162,7 @@ Lists_Add(struct list_head *h, const char *Mask, time_t ValidUntil,
 	else
 		newelem->reason = NULL;
 	newelem->valid_until = ValidUntil;
+	newelem->onlyonce = OnlyOnce;
 	newelem->next = e;
 	h->first = newelem;
 
@@ -329,7 +344,7 @@ Lists_CheckReason(struct list_head *h, CLIENT *Client, char *reason, size_t len)
 		if (MatchCaseInsensitive(e->mask, Client_MaskCloaked(Client))) {
 			if (len && e->reason)
 				strlcpy(reason, e->reason, len);
-			if (e->valid_until == 1) {
+			if (e->onlyonce) {
 				/* Entry is valid only once, delete it */
 				LogDebug("Deleted \"%s\" from list (used).",
 					 e->mask);
@@ -363,7 +378,7 @@ Lists_Expire(struct list_head *h, const char *ListName)
 
 	while (e) {
 		next = e->next;
-		if (e->valid_until > 1 && e->valid_until < now) {
+		if (e->valid_until > 0 && e->valid_until < now) {
 			/* Entry is expired, delete it */
 			if (e->reason)
 				Log(LOG_INFO,

+ 3 - 1
src/ngircd/lists.h

@@ -36,7 +36,8 @@ GLOBAL struct list_elem *Lists_CheckDupeMask PARAMS((const struct list_head *hea
 					const char *mask));
 
 GLOBAL bool Lists_Add PARAMS((struct list_head *h, const char *Mask,
-			      time_t ValidUntil, const char *Reason));
+			      time_t ValidUntil, const char *Reason,
+			      bool OnlyOnce));
 GLOBAL void Lists_Del PARAMS((struct list_head *head, const char *Mask));
 GLOBAL unsigned long Lists_Count PARAMS((struct list_head *h));
 
@@ -46,6 +47,7 @@ GLOBAL void Lists_MakeMask PARAMS((const char *Pattern, char *mask, size_t len))
 GLOBAL const char *Lists_GetMask PARAMS((const struct list_elem *e));
 GLOBAL const char *Lists_GetReason PARAMS((const struct list_elem *e));
 GLOBAL time_t Lists_GetValidity PARAMS((const struct list_elem *e));
+GLOBAL bool Lists_GetOnlyOnce PARAMS((const struct list_elem *e));
 
 GLOBAL void Lists_Expire PARAMS((struct list_head *h, const char *ListName));
 

+ 1 - 1
src/ngircd/login.c

@@ -92,7 +92,7 @@ Login_User(CLIENT * Client)
 		/* Don't do any PAM authentication at all if PAM is not
 		 * enabled, instead emulate the behavior of the daemon
 		 * compiled without PAM support. */
-		if (strcmp(Conn_Password(conn), Conf_ServerPwd) == 0) 
+		if (strcmp(Conn_Password(conn), Conf_ServerPwd) == 0)
 			return Login_User_PostAuth(Client);
 		Client_Reject(Client, "Bad server password", false);
 		return DISCONNECTED;

+ 10 - 8
src/ngircd/match.c

@@ -50,8 +50,10 @@ static int Matche_After_Star PARAMS(( const char *p, const char *t ));
 GLOBAL bool
 Match( const char *Pattern, const char *String )
 {
-	if( Matche( Pattern, String ) == MATCH_VALID ) return true;
-	else return false;
+	if (Matche(Pattern, String) == MATCH_VALID)
+		return true;
+	else
+		return false;
 } /* Match */
 
 /**
@@ -64,10 +66,12 @@ Match( const char *Pattern, const char *String )
 GLOBAL bool
 MatchCaseInsensitive(const char *Pattern, const char *String)
 {
-	char haystack[COMMAND_LEN];
+	char needle[COMMAND_LEN], haystack[COMMAND_LEN];
 
+	strlcpy(needle, Pattern, sizeof(needle));
 	strlcpy(haystack, String, sizeof(haystack));
-	return Match(Pattern, ngt_LowerStr(haystack));
+
+	return Match(ngt_LowerStr(needle), ngt_LowerStr(haystack));
 } /* MatchCaseInsensitive */
 
 /**
@@ -82,16 +86,14 @@ GLOBAL bool
 MatchCaseInsensitiveList(const char *Pattern, const char *String,
 		     const char *Separator)
 {
-	char tmp_pattern[COMMAND_LEN], haystack[COMMAND_LEN], *ptr;
+	char tmp_pattern[COMMAND_LEN], *ptr;
 
 	strlcpy(tmp_pattern, Pattern, sizeof(tmp_pattern));
-	strlcpy(haystack, String, sizeof(haystack));
-	ngt_LowerStr(haystack);
 
 	ptr = strtok(tmp_pattern, Separator);
 	while (ptr) {
 		ngt_TrimStr(ptr);
-		if (Match(ptr, haystack))
+		if (MatchCaseInsensitive(ptr, String))
 			return true;
 		ptr = strtok(NULL, Separator);
 	}

+ 6 - 3
src/ngircd/messages.h

@@ -67,6 +67,7 @@
 #define RPL_WHOISIDLE_MSG		"317 %s %s %lu %lu :seconds idle, signon time"
 #define RPL_ENDOFWHOIS_MSG		"318 %s %s :End of WHOIS list"
 #define RPL_WHOISCHANNELS_MSG		"319 %s %s :"
+#define RPL_LISTSTART_MSG		"321 %s Channel :Users  Name"
 #define RPL_LIST_MSG			"322 %s %s %ld :%s"
 #define RPL_LISTEND_MSG			"323 %s :End of LIST"
 #define RPL_CHANNELMODEIS_MSG		"324 %s %s +%s"
@@ -77,9 +78,9 @@
 #define RPL_TOPICSETBY_MSG		"333 %s %s %s %u"
 #define RPL_WHOISBOT_MSG		"335 %s %s :is an IRC Bot"
 #define RPL_INVITING_MSG		"341 %s %s %s%s"
-#define RPL_INVITELIST_MSG		"346 %s %s %s"
+#define RPL_INVITELIST_MSG		"346 %s %s %s %s %d"
 #define RPL_ENDOFINVITELIST_MSG		"347 %s %s :End of channel invite list"
-#define RPL_EXCEPTLIST_MSG		"348 %s %s %s"
+#define RPL_EXCEPTLIST_MSG		"348 %s %s %s %s %d"
 #define RPL_ENDOFEXCEPTLIST_MSG		"349 %s %s :End of channel exception list"
 #define RPL_VERSION_MSG			"351 %s %s-%s.%s %s :%s"
 #define RPL_WHOREPLY_MSG		"352 %s %s %s %s %s %s %s :%d %s"
@@ -87,7 +88,7 @@
 #define RPL_LINKS_MSG			"364 %s %s %s :%d %s"
 #define RPL_ENDOFLINKS_MSG		"365 %s %s :End of LINKS list"
 #define RPL_ENDOFNAMES_MSG		"366 %s %s :End of NAMES list"
-#define RPL_BANLIST_MSG			"367 %s %s %s"
+#define RPL_BANLIST_MSG			"367 %s %s %s %s %d"
 #define RPL_ENDOFBANLIST_MSG		"368 %s %s :End of channel ban list"
 #define RPL_ENDOFWHOWAS_MSG		"369 %s %s :End of WHOWAS list"
 #define RPL_INFO_MSG    		"371 %s :%s"
@@ -126,6 +127,7 @@
 #define ERR_USERONCHANNEL_MSG		"443 %s %s %s :is already on channel"
 #define ERR_SUMMONDISABLED_MSG		"445 %s :SUMMON has been disabled"
 #define ERR_USERSDISABLED_MSG		"446 %s :USERS has been disabled"
+#define ERR_NONICKCHANGE_MSG		"447 %s :Cannot change nickname while on %s(+N)"
 #define ERR_NOTREGISTERED_MSG		"451 %s :Connection not registered"
 #define ERR_NOTREGISTEREDSERVER_MSG	"451 %s :Connection not registered as server link"
 #define ERR_NEEDMOREPARAMS_MSG		"461 %s %s :Syntax error"
@@ -156,6 +158,7 @@
 #define ERR_UMODEUNKNOWNFLAG_MSG	"501 %s :Unknown mode"
 #define ERR_UMODEUNKNOWNFLAG2_MSG	"501 %s :Unknown mode \"%c%c\""
 #define ERR_USERSDONTMATCH_MSG		"502 %s :Can't set/get mode for other users"
+#define ERR_USERNOTONSERV_MSG		"504 %s %s :User is not on this server"
 #define ERR_NOINVITE_MSG		"518 %s :Cannot invite to %s (+V)"
 
 #ifdef ZLIB

+ 7 - 2
src/ngircd/ngircd.c

@@ -530,7 +530,7 @@ Pidfile_Create(pid_t pid)
 		close(pidfd);
 		return;
 	}
-	
+
 	if (write(pidfd, pidbuf, (size_t)len) != (ssize_t)len)
 		Log(LOG_ERR, "Can't write PID file (%s): %s!", Conf_PidFile,
 		    strerror(errno));
@@ -721,9 +721,10 @@ NGIRCd_Init(bool NGIRCd_NoDaemon)
 			Log(LOG_ERR, "Can't change group ID to %s(%u): %s!",
 			    grp ? grp->gr_name : "?", Conf_GID,
 			    strerror(real_errno));
-			if (real_errno != EPERM) 
+			if (real_errno != EPERM)
 				goto out;
 		}
+#ifdef HAVE_SETGROUPS
 		if (setgroups(0, NULL) != 0) {
 			real_errno = errno;
 			Log(LOG_ERR, "Can't drop supplementary group IDs: %s!",
@@ -731,6 +732,10 @@ NGIRCd_Init(bool NGIRCd_NoDaemon)
 			if (real_errno != EPERM)
 				goto out;
 		}
+#else
+		Log(LOG_WARNING,
+		    "Can't drop supplementary group IDs: setgroups(3) missing!");
+#endif
 	}
 #endif
 

+ 2 - 2
src/ngircd/numeric.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2015 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
@@ -185,7 +185,7 @@ Synchronize_Lists(CLIENT * Client)
 	while (elem) {
 		if (!IRC_WriteStrClient(Client, "GLINE %s %ld :%s",
 					Lists_GetMask(elem),
-					Lists_GetValidity(elem) - time(NULL),
+					(long)(Lists_GetValidity(elem) - time(NULL)),
 					Lists_GetReason(elem)))
 			return DISCONNECTED;
 		elem = Lists_GetNext(elem);

+ 7 - 7
src/ngircd/parse.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2015 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
@@ -70,7 +70,7 @@ static COMMAND My_Commands[] =
 	_CMD("GLINE", IRC_xLINE, CLIENT_USER|CLIENT_SERVER, 0, -1, 0),
 	_CMD("HELP", IRC_HELP, CLIENT_USER, 0, 1, 2),
 	_CMD("INFO", IRC_INFO, CLIENT_USER|CLIENT_SERVER, 0, 1, 2),
-	_CMD("INVITE", IRC_INVITE, CLIENT_USER|CLIENT_SERVER, 2, 2, 0),
+	_CMD("INVITE", IRC_INVITE, CLIENT_USER|CLIENT_SERVER, 2, 2, 1),
 	_CMD("ISON", IRC_ISON, CLIENT_USER, 1, -1, 0),
 	_CMD("JOIN", IRC_JOIN, CLIENT_USER|CLIENT_SERVER, 1, 2, 0),
 	_CMD("KICK", IRC_KICK, CLIENT_USER|CLIENT_SERVER, 2, 3, 0),
@@ -156,7 +156,7 @@ Parse_GetCommandStruct( void )
 
 /**
  * Parse a command ("request") received from a client.
- * 
+ *
  * This function is called after the connection layer received a valid CR+LF
  * terminated line of text: we assume that this is a valid IRC command and
  * try to do something useful with it :-)
@@ -461,10 +461,10 @@ Handle_Numeric(CLIENT *client, REQUEST *Req)
 	}
 
 	/* Determine source */
-	if (! Req->prefix[0]) {
-		/* Oops, no prefix!? */
-		Log(LOG_WARNING, "Got status code %s from \"%s\" without prefix!?",
-						Req->command, Client_ID(client));
+	if (!Req->prefix) {
+		Log(LOG_WARNING,
+		    "Got status code %s from \"%s\" without prefix!?",
+		    Req->command, Client_ID(client));
 		return true;
 	}
 

+ 6 - 2
src/ngircd/sighandlers.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2015 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
@@ -48,7 +48,11 @@ Dump_State(void)
 {
 	Log(LOG_DEBUG, "--- Internal server state: %s ---",
 	    Client_ID(Client_ThisServer()));
-	Log(LOG_DEBUG, "time()=%ld", time(NULL));
+#ifdef HAVE_LONG_LONG
+	Log(LOG_DEBUG, "time()=%llu", (unsigned long long)time(NULL));
+#else
+	Log(LOG_DEBUG, "time()=%lu", (unsigned long)time(NULL));
+#endif
 	Conf_DebugDump();
 	Conn_DebugDump();
 	Client_DebugDump();

+ 1 - 1
src/portab/portabtest.c

@@ -196,7 +196,7 @@ main(void)
 	Check_strlcat();
 	Check_strtok_r();
 	Check_vsnprintf(2+10, "%s%s", "ab", "1234567890");
-	
+
 	return 0;
 }
 

+ 46 - 46
src/portab/vsnprintf.c

@@ -50,9 +50,9 @@
  *  original. Also, there is now a builtin-test, just compile with:
  *    gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
  *  and run snprintf for results.
- * 
+ *
  * Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
- *  The PGP code was using unsigned hexadecimal formats. 
+ *  The PGP code was using unsigned hexadecimal formats.
  *  Unfortunately, unsigned formats simply didn't work.
  *
  * Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
@@ -165,21 +165,21 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args)
 	int flags;
 	int cflags;
 	size_t currlen;
-	
+
 	state = DP_S_DEFAULT;
 	currlen = flags = cflags = min = 0;
 	max = -1;
 	ch = *format++;
-	
+
 	while (state != DP_S_DONE) {
-		if (ch == '\0') 
+		if (ch == '\0')
 			state = DP_S_DONE;
 
 		switch(state) {
 		case DP_S_DEFAULT:
-			if (ch == '%') 
+			if (ch == '%')
 				state = DP_S_FLAGS;
-			else 
+			else
 				dopr_outch (buffer, &currlen, maxlen, ch);
 			ch = *format++;
 			break;
@@ -226,7 +226,7 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args)
 			if (ch == '.') {
 				state = DP_S_MAX;
 				ch = *format++;
-			} else { 
+			} else {
 				state = DP_S_MOD;
 			}
 			break;
@@ -271,7 +271,7 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args)
 			switch (ch) {
 			case 'd':
 			case 'i':
-				if (cflags == DP_C_SHORT) 
+				if (cflags == DP_C_SHORT)
 					value = va_arg (args, int);
 				else if (cflags == DP_C_LONG)
 					value = va_arg (args, long int);
@@ -401,12 +401,12 @@ dopr(char *buffer, size_t maxlen, const char *format, va_list args)
 		}
 	}
 	if (maxlen != 0) {
-		if (currlen < maxlen - 1) 
+		if (currlen < maxlen - 1)
 			buffer[currlen] = '\0';
-		else if (maxlen > 0) 
+		else if (maxlen > 0)
 			buffer[maxlen - 1] = '\0';
 	}
-	
+
 	return currlen;
 }
 
@@ -426,11 +426,11 @@ fmtstr(char *buffer, size_t *currlen, size_t maxlen, char *value, int flags,
 
 	for (strln = 0; value[strln]; ++strln); /* strlen */
 	padlen = min - strln;
-	if (padlen < 0) 
+	if (padlen < 0)
 		padlen = 0;
-	if (flags & DP_F_MINUS) 
+	if (flags & DP_F_MINUS)
 		padlen = -padlen; /* Left Justify */
-	
+
 	while ((padlen > 0) && (cnt < max)) {
 		dopr_outch (buffer, currlen, maxlen, ' ');
 		--padlen;
@@ -460,12 +460,12 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base,
 	int spadlen = 0; /* amount to space pad */
 	int zpadlen = 0; /* amount to zero pad */
 	int caps = 0;
-	
+
 	if (max < 0)
 		max = 0;
-	
+
 	uvalue = value;
-	
+
 	if(!(flags & DP_F_UNSIGNED)) {
 		if( value < 0 ) {
 			signvalue = '-';
@@ -477,7 +477,7 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base,
 				signvalue = ' ';
 		}
 	}
-  
+
 	if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
 
 	do {
@@ -497,7 +497,7 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base,
 		zpadlen = MAX(zpadlen, spadlen);
 		spadlen = 0;
 	}
-	if (flags & DP_F_MINUS) 
+	if (flags & DP_F_MINUS)
 		spadlen = -spadlen; /* Left Justifty */
 
 #ifdef DEBUG_SNPRINTF
@@ -512,7 +512,7 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base,
 	}
 
 	/* Sign */
-	if (signvalue) 
+	if (signvalue)
 		dopr_outch (buffer, currlen, maxlen, signvalue);
 
 	/* Zeros */
@@ -524,9 +524,9 @@ fmtint(char *buffer, size_t *currlen, size_t maxlen, long value, int base,
 	}
 
 	/* Digits */
-	while (place > 0) 
+	while (place > 0)
 		dopr_outch (buffer, currlen, maxlen, convert[--place]);
-  
+
 	/* Left Justified spaces */
 	while (spadlen < 0) {
 		dopr_outch (buffer, currlen, maxlen, ' ');
@@ -541,7 +541,7 @@ abs_val(LDOUBLE value)
 
 	if (value < 0)
 		result = -value;
-	
+
 	return result;
 }
 
@@ -549,12 +549,12 @@ static LDOUBLE
 POW10(int exp)
 {
 	LDOUBLE result = 1;
-	
+
 	while (exp) {
 		result *= 10;
 		exp--;
 	}
-  
+
 	return result;
 }
 
@@ -566,7 +566,7 @@ ROUND(LDOUBLE value)
 	intpart = (LLONG)value;
 	value = value - intpart;
 	if (value >= 0.5) intpart++;
-	
+
 	return intpart;
 }
 
@@ -600,7 +600,7 @@ my_modf(double x0, double *iptr)
 		ret = my_modf(x0-l*f, &i2);
 		(*iptr) = l*f + i2;
 		return ret;
-	} 
+	}
 
 	(*iptr) = l;
 	return x - (*iptr);
@@ -618,14 +618,14 @@ fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue,
 	int iplace = 0;
 	int fplace = 0;
 	int padlen = 0; /* amount to pad */
-	int zpadlen = 0; 
+	int zpadlen = 0;
 	int caps = 0;
 	int index;
 	double intpart;
 	double fracpart;
 	double temp;
-  
-	/* 
+
+	/*
 	 * AIX manpage says the default is 0, but Solaris says the default
 	 * is 6, and sprintf on AIX defaults to 6
 	 */
@@ -645,8 +645,8 @@ fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue,
 		}
 	}
 
-	/* 
-	 * Sorry, we only support 16 digits past the decimal because of our 
+	/*
+	 * Sorry, we only support 16 digits past the decimal because of our
 	 * conversion method
 	 */
 	if (max > 16)
@@ -660,7 +660,7 @@ fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue,
 	my_modf(temp, &intpart);
 
 	fracpart = ROUND((POW10(max)) * (ufvalue - intpart));
-	
+
 	if (fracpart >= POW10(max)) {
 		intpart++;
 		fracpart -= POW10(max);
@@ -697,16 +697,16 @@ fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue,
 		if (fplace == 311) fplace--;
 	}
 	fconvert[fplace] = 0;
-  
+
 	/* -1 for decimal point, another -1 if we are printing a sign */
-	padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 
+	padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
 	zpadlen = max - fplace;
 	if (zpadlen < 0) zpadlen = 0;
-	if (padlen < 0) 
+	if (padlen < 0)
 		padlen = 0;
-	if (flags & DP_F_MINUS) 
+	if (flags & DP_F_MINUS)
 		padlen = -padlen; /* Left Justifty */
-	
+
 	if ((flags & DP_F_ZERO) && (padlen > 0)) {
 		if (signvalue) {
 			dopr_outch (buffer, currlen, maxlen, signvalue);
@@ -722,10 +722,10 @@ fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue,
 		dopr_outch (buffer, currlen, maxlen, ' ');
 		--padlen;
 	}
-	if (signvalue) 
+	if (signvalue)
 		dopr_outch (buffer, currlen, maxlen, signvalue);
-	
-	while (iplace > 0) 
+
+	while (iplace > 0)
 		dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
 
 #ifdef DEBUG_SNPRINTF
@@ -738,11 +738,11 @@ fmtfp (char *buffer, size_t *currlen, size_t maxlen, LDOUBLE fvalue,
 	 */
 	if (max > 0) {
 		dopr_outch (buffer, currlen, maxlen, '.');
-		
-		while (fplace > 0) 
+
+		while (fplace > 0)
 			dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
 	}
-	
+
 	while (zpadlen > 0) {
 		dopr_outch (buffer, currlen, maxlen, '0');
 		--zpadlen;
@@ -786,7 +786,7 @@ va_dcl
 {
 	size_t ret;
 	va_list ap;
-    
+
 	va_start(ap, fmt);
 	ret = vsnprintf(str, count, fmt, ap);
 	va_end(ap);