Browse Source

Import upstream version 20

Alexander Barton 11 years ago
parent
commit
3610f8bac1
100 changed files with 4344 additions and 3814 deletions
  1. 4 0
      .mailmap
  2. 165 6
      ChangeLog
  3. 16 4
      INSTALL
  4. 8 6
      Makefile.am
  5. 9 13
      Makefile.in
  6. 90 5
      NEWS
  7. 9 6
      README
  8. 0 12
      aclocal.m4
  9. 214 0
      autogen.sh
  10. 12 5
      config.guess
  11. 18 5
      config.sub
  12. 695 397
      configure
  13. 156 85
      configure.in
  14. 722 0
      configure.ng
  15. 0 495
      contrib/Anope/0001-Revert-Removed-ngircd.patch
  16. 0 59
      contrib/Anope/0002-ngircd-whitespace-fixes.patch
  17. 0 127
      contrib/Anope/0003-Update-ngIRCd-protocol-module-for-current-Anope-1.9.patch
  18. 0 92
      contrib/Anope/0004-ngircd-Do-PING-PONG-on-server-burst-to-sync-servers.patch
  19. 0 28
      contrib/Anope/0005-ngircd-always-prefix-modes-in-CHANINFO-with.patch
  20. 0 46
      contrib/Anope/0006-ngircd-support-user-mode-R-and-channel-mode-R.patch
  21. 0 95
      contrib/Anope/0007-ngircd-Fix-handling-of-JOIN-commands.patch
  22. 0 37
      contrib/Anope/0008-ngircd-Allow-setting-modes-by-clients-on-burst.patch
  23. 0 142
      contrib/Anope/0009-ngircd-Update-protocol-module-for-current-Anope-1.9.patch
  24. 0 56
      contrib/Anope/0010-ngircd-Add-ProtongIRCd.patch
  25. 0 28
      contrib/Anope/0011-ngircd-Update-protocol-module-for-current-Anope-1.9.patch
  26. 0 24
      contrib/Anope/0012-ngircd-Channel-mode-r-is-supported-now.patch
  27. 0 27
      contrib/Anope/0013-ngircd-Update-copyright-notice.patch
  28. 0 34
      contrib/Anope/0014-ngircd-set-unset-GLINE-s-on-AKILL-commands.patch
  29. 0 26
      contrib/Anope/0015-ngircd-ngIRCd-supports-channel-mode-e-now.patch
  30. 0 34
      contrib/Anope/0016-ngircd-support-SQUERY-command.patch
  31. 0 34
      contrib/Anope/Makefile.am
  32. 0 375
      contrib/Anope/Makefile.in
  33. 0 35
      contrib/Anope/README
  34. 1 6
      contrib/Debian/Makefile.in
  35. 18 0
      contrib/Debian/changelog
  36. 16 16
      contrib/Debian/control
  37. 5 3
      contrib/Debian/rules
  38. 1 6
      contrib/MacOSX/Makefile.in
  39. 10 2
      contrib/MacOSX/config.h
  40. 1 6
      contrib/MacOSX/ngIRCd.pmdoc/Makefile.in
  41. 1 6
      contrib/MacOSX/ngIRCd.xcodeproj/Makefile.in
  42. 36 11
      contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj
  43. 11 4
      contrib/Makefile.am
  44. 12 10
      contrib/Makefile.in
  45. 0 3
      contrib/README
  46. 11 0
      contrib/ngircd.service
  47. 6 6
      contrib/ngircd.spec
  48. 6 6
      contrib/platformtest.sh
  49. 54 0
      doc/Contributing.txt
  50. 1 1
      doc/HowToRelease.txt
  51. 24 3
      doc/Makefile.am
  52. 25 9
      doc/Makefile.in
  53. 12 1
      doc/Modes.txt
  54. 8 5
      doc/Platforms.txt
  55. 75 4
      doc/Protocol.txt
  56. 60 39
      doc/Services.txt
  57. 22 12
      doc/sample-ngircd.conf.tmpl
  58. 1 6
      doc/src/Makefile.in
  59. 1 1
      man/Makefile.am
  60. 2 7
      man/Makefile.in
  61. 17 12
      man/ngircd.8.tmpl
  62. 24 23
      man/ngircd.conf.5.tmpl
  63. 1 6
      src/Makefile.in
  64. 89 34
      src/config.h.in
  65. 10 3
      src/ipaddr/Makefile.am
  66. 25 29
      src/ipaddr/Makefile.in
  67. 21 0
      src/ipaddr/Makefile.ng
  68. 0 36
      src/ipaddr/ansi2knr.1
  69. 0 739
      src/ipaddr/ansi2knr.c
  70. 12 4
      src/ngircd/Makefile.am
  71. 49 23
      src/ngircd/Makefile.in
  72. 152 0
      src/ngircd/Makefile.ng
  73. 89 77
      src/ngircd/channel.c
  74. 95 36
      src/ngircd/client.c
  75. 8 5
      src/ngircd/client.h
  76. 4 8
      src/ngircd/conf-ssl.h
  77. 84 18
      src/ngircd/conf.c
  78. 17 7
      src/ngircd/conf.h
  79. 192 0
      src/ngircd/conn-encoding.c
  80. 30 0
      src/ngircd/conn-encoding.h
  81. 23 5
      src/ngircd/conn-ssl.c
  82. 110 34
      src/ngircd/conn.c
  83. 18 1
      src/ngircd/conn.h
  84. 15 11
      src/ngircd/defines.h
  85. 14 0
      src/ngircd/io.c
  86. 2 2
      src/ngircd/irc-cap.c
  87. 30 17
      src/ngircd/irc-channel.c
  88. 68 0
      src/ngircd/irc-encoding.c
  89. 24 0
      src/ngircd/irc-encoding.h
  90. 87 45
      src/ngircd/irc-info.c
  91. 107 45
      src/ngircd/irc-login.c
  92. 2 1
      src/ngircd/irc-login.h
  93. 109 0
      src/ngircd/irc-metadata.c
  94. 24 0
      src/ngircd/irc-metadata.h
  95. 149 40
      src/ngircd/irc-mode.c
  96. 10 2
      src/ngircd/irc-op.c
  97. 2 0
      src/ngircd/irc-oper.c
  98. 61 34
      src/ngircd/irc-server.c
  99. 32 6
      src/ngircd/irc.c
  100. 0 0
      src/ngircd/lists.c

+ 4 - 0
.mailmap

@@ -0,0 +1,4 @@
+# mailmap file for git-[short]log and git-blame
+
+Alexander Barton <anonymous>
+Ali Shemiran <ashemira@ucsd.edu>

+ 165 - 6
ChangeLog

@@ -9,6 +9,165 @@
                                -- ChangeLog --
                                -- ChangeLog --
 
 
 
 
+ngIRCd 20 (2012-12-17)
+
+  - Allow user names ("INDENT") up to 20 characters when ngIRCd has not
+    been configured for "strict RFC mode". This is useful if you are using
+    external (PAM) authenticaion mechanisms that require longer user names.
+    Patch suggested by Brett Smith <brett@w3.org>, see
+    <http://arthur.barton.de/pipermail/ngircd-ml/2012-October/000579.html>.
+
+  ngIRCd 20~rc2 (2012-12-02)
+  - Rework cloaked hostname handling and implement the "METADATA cloakhost"
+    subcommand: Now ngIRCd uses two fields internally, one to store the
+    "real" hostname and one to save the "cloaked" hostname. This allows
+    "foreign servers" (aka "IRC services") to alter the real and cloaked
+    hostnames of clients without problems, even when the user itself issues
+    additional "MODE +x" and "MODE -x" commands.
+  - RPL_UMODEIS: send correct target name, even on server links.
+  - Update platformtest.sh to follow autoconf changes and only generate
+    the "configure" script when it is missing.
+  - Fix the test suite to correctly execute test scripts even when stdout
+    is redirected.
+  - Fix some compiler warnings on NetBSD and OpenBSD.
+
+  ngIRCd 20~rc1 (2012-11-11)
+  - Update doc/Services.txt: describe the upcoming version of Anope 1.9.8,
+    then including a protocol module for ngIRCd. And remove our own patches
+    in ./contrib/Anope because they aren't supported any more ...
+  - Implement new "METADATA" command which can be used by remote servers
+    and IRC services to update client metadata like the client info text
+    ("real name"), user name, and hostname, and use this command to
+    configure an cloaked hostname (user mode "+x") on remote servers:
+    This prevents "double cloaking" of hostnames and even cloaked
+    hostnames are in sync on all servers supporting "METADATA" now.
+  - Fix error message when trying to join non-predefined channels and the
+    "PredefChannelsOnly" configuration option is set.
+  - Implement new IRC "SVSNICK" command to allow remote servers (and IRC
+    services) to change nicknames of already registered users. The SVSNICK
+    command itself doesn't change the nickname, but it becomes forwarded
+    to the server to which the user is connected to. And then this server
+    initiates the real nickname changing using regular NICK commands.
+    This allows to run mixed networks with old servers not supporting the
+    SVSNICK command, because SVSNICK commands for nicknames on such servers
+    are silently ignored and don't cause a desynchronization of the network.
+  - Make server reconnect time a little bit more random, so that two
+    servers trying to connect to each other asynchronously don't try this
+    in exactly the same time periods and kick each other off ...
+  - Don't accept connections for servers already being linked: there was a
+    time frame that could result in one connection overwriting the other,
+    e. g. the incoming connection overwriting the status of the outgoing
+    one. And this could lead to all kind of weirdness (even crashes!) later
+    on: now such incoming connections are dropped.
+  - New configuration option "MaxListSize" to configure the maximum number
+    of channels returned by a LIST command. The default is 100, as before.
+  - Implement user mode "b", "block messages": when a user has set mode "b",
+    all private messages and notices to this user are blocked if they don't
+    originate from a registered user, an IRC Op, server or service. The
+    originator gets an error numeric sent back in this case,
+    ERR_NONONREG_MSG (486), which is used by UnrealIRCd, too. (Closes #144)
+  - WHOIS: Not only show RPL_WHOISHOST_MSG to local IRC operators, but show
+    it to all IRC operators in the network. And don't show it to anybody if
+    the "more privacy" configuration option is enabled. (Closes #134)
+  - Test suite: make expect scripts more verbose displaying dots for each
+    reply of the server that it is waiting for.
+  - WHOIS: Implement numeric RPL_WHOISMODES_MSG (379) and show user modes in
+    the reply of the WHOIS command for the user himself or, if MorePrivacy
+    isn't set, for request initiated by an IRC operator. (Closes #129)
+  - Implement channel mode "V" (invite disallow): If the new channel mode
+    "V" is set, the INVITE command becomes invalid and all clients get the
+    new ERR_NOINVITE_MSG (518) reply. (Closes #143)
+  - KICK-protect IRC services.
+  - Implement channel mode "Q" and user mode "q": Both modes protect users
+    from channel kicks: only IRC operators and servers can kick users having
+    mode "q" or in channels with mode "Q". (Closes #141)
+  - Debian: require "telnet" or "telnet-ssl" for building and enable
+    CHARCONV in ngircd-full[-dbg] variants.
+  - Send RPL_REHASHING (382) numeric if a REHASH command was accepted.
+  - Fix spelling and variable names in some log messages.
+  - Allow users to "cloak" their hostname only when the configuration
+    variable "CloakHostModeX" (introduced in 19.2) is set. Otherwise, only
+    IRC operators, other servers, and services are allowed to set the user
+    mode "+x": this prevents regular users from changing their hostmask to
+    the name of the IRC server itself, which confused quite a few people ;-)
+    (Closes #133)
+  - New configuration option "OperChanPAutoOp": If disabled, IRC operators
+    don't become channel operators in persistent channels when joining.
+    Enabled by default, which has been the behavior of ngIRCd up to this
+    patch. (Closes #135)
+  - Allow IRC operators to see secret (+s) channels in LIST command as long
+    as the "MorePrivacy" configuration option isn't enabled in the
+    configuration file. (Closes #136)
+  - Enhance build system: Support new (>=1.12) and old (<=1.11) GNU automake
+    versions, update checks for required and optional features, enable
+    colored test output of automake (if available), rename configure.in to
+    more modern configure.ac, include .mailmap and all build-system files in
+    distribution archives and no longer require a GIT tree to detect the
+    correct version string.
+  - Update documentation: add doc/Contributing.txt and include version
+    numbers in doc/Modes.txt.
+  - Free all listen ports on initialization: now listen ports can be
+    reconfigured on runtime using a configuration reload.
+  - Initialize SSL when needed only, and disable SSL on errors.
+  - Implement new (optional) IRC+ "CHARCONV" command to set a client
+    character set that the server translates all messages to/from UTF-8.
+    This feature requires the "libiconv" library and must be enabled using
+    the new "--with-iconv" option of the ./configure script. See
+    doc/Protocol.txt for details. (Closes #109)
+  - Allow limited punctuation in usernames, for better PAM integration.
+  - Correctly re-initialize signal handlers on RESTART commands.
+  - Show a warning on startup if the configuration file is not a full path:
+    ngIRCd is a long-running process and changes its working directory to
+    "/" to not block mounted filesystems and the like when running as daemon
+    ("not in the foreground"); therefore the path to the configuration file
+    must be relative to "/" (or the chroot() directory), which basically is
+    "not relative", to ensure that "kill -HUP" and the "REHASH" command work
+    as expected later on. (Closes #127)
+  - Make the "&SERVER" channel definable in a [Channel] configuration block,
+    which enables server operators to overwrite the built-in topic and
+    channel modes. (Closes #131)
+  - Don't limit list size of "WHO #channel" commands, because it makes no
+    sense to not return all the users in that channel, so I removed the
+    check. But if there are more than MAX_RPL_WHO(25) replies, the client
+    requesting the list will be "penalized" one second more, then 2 in
+    total. (Closes #125)
+  - Make ngIRCd buildable using the kqueue() IO interface on FreeBSD 4.x.
+  - Fix the "NoticeAuth" configuration option when using SSL connections and
+    enhance the message to show the hostname and IDENT reply of the client.
+  - Introduce numeric RPL_HOSTHIDDEN_MSG (396): This numeric is sent to the
+    client each time it changes its displayed hostname using "MODE +/-x",
+    and if "CloakHost" is set right after the MOTD has been sent.
+  - Fix USERHOST not displaying the correctly cloaked hostname.
+  - Implement user mode "B" ("Bot flag"): it is settable and unsettable by
+    every (non-restricted) client. This is how Unreal and InspIRCd do
+    behave, and so do we :-)
+  - Dynamically allocate memory for connection passwords: This a) saves
+    memory for clients not using passwords at all and b) allows for
+    "arbitrarily" long passwords.
+  - Implement channel mode "M": Only the server, identified users and IRC
+    operators are able to talk in such a channel.
+  - Block nicknames that are reserved for services and are defined using the
+    configuration variable "ServiceMask" in "Server" blocks; And this
+    variable now can handle more than one mask separated by commas.
+  - Now "make uninstall" removes the installed "ngircd.conf" file, if it is
+    still equal to our "sample-ngircd.conf" file and therefore hasn't been
+    modified by the user. If it has been modified, it isn't removed and a
+    notice is displayed to the user. And "make install" now displays a
+    message when no ngircd.conf file exists and the "sample-ngircd.conf"
+    file will be installed as a starting point.
+  - Add contrib/ngircd.service, a systemd service file for ngircd.
+  - Implemented XOP channel user modes: "Half Op" ("+h", prefix "%") can set
+    the channel modes +imntvIbek and kick all +v and normal users; "Admin"
+    ("+a", prefix "&") can set channel modes +imntvIbekoRsz and kick all +o,
+    +h, +v and normal users; and "Owner" ("+q", prefix "~") can set channel
+    modes +imntvIbekoRsz and kick all +a, +o, +h, +v and normal users.
+  - Implement hashed cloaked hostnames for both the "CloakHost" and
+    "CloakHostModeX" configuration options: now the admin can use the new
+    '%x' placeholder to insert a hashed version of the clients hostname,
+    and the new configuration option "CloakHostSalt" defines the salt for
+    the hash function. When "CloakHostSalt" is not set (the default), a
+    random salt will be generated after each server restart. (Closes #133)
+
 ngIRCd Release 19.2 (2012-06-19)
 ngIRCd Release 19.2 (2012-06-19)
 
 
   - doc/Capabilities.txt: document "multi-prefix" capability
   - doc/Capabilities.txt: document "multi-prefix" capability
@@ -82,7 +241,7 @@ ngIRCd Release 19 (2012-02-29)
     and receiver are on the same channel. This prevents private flooding
     and receiver are on the same channel. This prevents private flooding
     by completely unknown clients.
     by completely unknown clients.
   - New RPL_WHOISREGNICK_MSG(307) numeric in WHOIS command replies: it
   - New RPL_WHOISREGNICK_MSG(307) numeric in WHOIS command replies: it
-    indicates if a nick name is registered (if user mode 'R' set).
+    indicates if a nickname is registered (if user mode 'R' set).
   - Limit channel invite, ban, and exception lists to 50 entries and fix
   - Limit channel invite, ban, and exception lists to 50 entries and fix
     duplicate check and error messages when adding already listed entries
     duplicate check and error messages when adding already listed entries
     or deleting no (longer) existing ones.
     or deleting no (longer) existing ones.
@@ -123,7 +282,7 @@ ngIRCd Release 19 (2012-02-29)
     limit reached), but report an error and continue. And don't check
     limit reached), but report an error and continue. And don't check
     the channel limit and don't report with "too many channels" when
     the channel limit and don't report with "too many channels" when
     trying to join a channel that the client already is a member of.
     trying to join a channel that the client already is a member of.
-  - ISON command: reply with the correct upper-/lowercase nick names.
+  - ISON command: reply with the correct upper-/lowercase nicknames.
   - New configuration option "PAMIsOptional": when set, clients not
   - New configuration option "PAMIsOptional": when set, clients not
     sending a password are still allowed to connect: they won't become
     sending a password are still allowed to connect: they won't become
     "identified" and keep the "~" character prepended to their supplied
     "identified" and keep the "~" character prepended to their supplied
@@ -170,7 +329,7 @@ ngIRCd Release 19 (2012-02-29)
     The bug has been introduced starting with ngIRCd 17 ... :-(
     The bug has been introduced starting with ngIRCd 17 ... :-(
     (commit ID 6ebb31ab35e)
     (commit ID 6ebb31ab35e)
   - Added doc/Modes.txt: document modes supported by ngIRCd.
   - Added doc/Modes.txt: document modes supported by ngIRCd.
-  - Implement user mode "R": indicates that the nick name of this user
+  - Implement user mode "R": indicates that the nickname of this user
     is "registered". This mode isn't handled by ngIRCd itself, but must
     is "registered". This mode isn't handled by ngIRCd itself, but must
     be set and unset by IRC services like Anope.
     be set and unset by IRC services like Anope.
   - Implement channel mode "R": only registered users (having the user
   - Implement channel mode "R": only registered users (having the user
@@ -188,7 +347,7 @@ ngIRCd Release 19 (2012-02-29)
   - Handle channel user modes 'a', 'h', and 'q' from remote servers.
   - Handle channel user modes 'a', 'h', and 'q' from remote servers.
     These channel user modes aren't used for anything at the moment,
     These channel user modes aren't used for anything at the moment,
     but ngIRCd knows that these three modes are "channel user modes"
     but ngIRCd knows that these three modes are "channel user modes"
-    and not "channel modes", that is that these modes take an "nick name"
+    and not "channel modes", that is that these modes take an "nickname"
     argument. Like unknown user and channel modes, these modes are saved
     argument. Like unknown user and channel modes, these modes are saved
     and forwarded to other servers, but ignored otherwise.
     and forwarded to other servers, but ignored otherwise.
   - Correctly inform clients when other servers change their user modes.
   - Correctly inform clients when other servers change their user modes.
@@ -275,7 +434,7 @@ ngIRCd Release 18 (2011-07-10)
   - New configuration option "CloakHost": when set, this host name is used for
   - New configuration option "CloakHost": when set, this host name is used for
     every client instead of the real DNS host name (or IP address).
     every client instead of the real DNS host name (or IP address).
   - New configuration option "CloakUserToNick": when enabled, ngIRCd sets
   - New configuration option "CloakUserToNick": when enabled, ngIRCd sets
-    every clients' user name to their nick name and hides the user name
+    every clients' user name to their nickname and hides the user name
     supplied by the IRC client.
     supplied by the IRC client.
   - doc/Protocol.txt: Update description of the CHANINFO and WEBIRC commands.
   - doc/Protocol.txt: Update description of the CHANINFO and WEBIRC commands.
   - Doxygen'ify (document) much more source files; code cleanup ...
   - Doxygen'ify (document) much more source files; code cleanup ...
@@ -607,7 +766,7 @@ ngIRCd 0.11.0 (2008-01-15)
   - New [Server] configuration Option "Bind" allows to specify
   - New [Server] configuration Option "Bind" allows to specify
     the source IP address to use when connecting to remote server.
     the source IP address to use when connecting to remote server.
   - New configuration option "MaxNickLength" to specify the allowed maximum
   - New configuration option "MaxNickLength" to specify the allowed maximum
-    length of user nick names. Note: must be unique in an IRC network!
+    length of user nicknames. Note: must be unique in an IRC network!
   - Enhanced the IRC+ protocol to support an enhanced "server handshake" and
   - Enhanced the IRC+ protocol to support an enhanced "server handshake" and
     enable server to recognize numeric 005 (ISUPPORT) and 376 (ENDOFMOTD).
     enable server to recognize numeric 005 (ISUPPORT) and 376 (ENDOFMOTD).
     See doc/Protocol.txt for details.
     See doc/Protocol.txt for details.

+ 16 - 4
INSTALL

@@ -12,6 +12,14 @@
 I. Upgrade Information
 I. Upgrade Information
 ~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~
 
 
+Differences to version 19.x
+
+- Starting with ngIRCd 20, users can "cloak" their hostname only when the
+  configuration variable "CloakHostModeX" (introduced in 19.2) is set.
+  Otherwise, only IRC opertators, other servers, and services are allowed to
+  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
 
 
 - Support for ZeroConf/Bonjour/Rendezvous service registration has been
 - Support for ZeroConf/Bonjour/Rendezvous service registration has been
@@ -149,10 +157,14 @@ This step is therefore only interesting for developers.
 
 
 autogen.sh produces the Makefile.in's, which are necessary for the configure
 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
 script itself, and some more files for make. To run autogen.sh you'll need
-GNU autoconf and GNU automake (use recent versions! autoconf 2.53 and
-automake 1.6.1 are known to work).
-
-Again: "end users" do not need this step!
+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
+distribution archives: it will work but lack "de-ANSI-fucation" 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.
+
+Again: "end users" do not need this step and neither need GNU autoconf nor GNU
+automake at all!
 
 
 
 
 2): "./configure"
 2): "./configure"

+ 8 - 6
Makefile.am

@@ -1,6 +1,6 @@
 #
 #
 # ngIRCd -- The Next Generation IRC Daemon
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
+# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 #
 #
 # This program is free software; you can redistribute it and/or modify
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
@@ -13,24 +13,26 @@ AUTOMAKE_OPTIONS = gnu
 
 
 SUBDIRS = doc src man contrib
 SUBDIRS = doc src man contrib
 
 
+EXTRA_DIST = autogen.sh configure.ng .mailmap
+
 clean-local:
 clean-local:
 	rm -f build-stamp*
 	rm -f build-stamp*
 	rm -rf ngircd.dest
 	rm -rf ngircd.dest
 
 
 maintainer-clean-local:
 maintainer-clean-local:
 	rm -rf autom4te.cache
 	rm -rf autom4te.cache
-	rm -f Makefile.in Makefile aclocal.m4 configure
-	rm -f mkinstalldirs missing depcomp install-sh
+	rm -f Makefile.in Makefile aclocal.m4 configure configure.ac
+	rm -f ar-lib mkinstalldirs missing depcomp install-sh
 	rm -f config.log debian
 	rm -f config.log debian
 
 
 testsuite:
 testsuite:
-	make -C src/testsuite check
+	cd src/testsuite && make check
 
 
 lint:
 lint:
-	make -C src/ngircd lint
+	cd src/ngircd && make lint
 
 
 srcdoc:
 srcdoc:
-	make -C doc srcdoc
+	cd doc && make srcdoc
 
 
 have-xcodebuild:
 have-xcodebuild:
 	@xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -list \
 	@xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -list \

+ 9 - 13
Makefile.in

@@ -17,7 +17,7 @@
 
 
 #
 #
 # ngIRCd -- The Next Generation IRC Daemon
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
+# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 #
 #
 # This program is free software; you can redistribute it and/or modify
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
@@ -44,14 +44,13 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 build_triplet = @build@
 host_triplet = @host@
 host_triplet = @host@
-target_triplet = @target@
 subdir = .
 subdir = .
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \
 	$(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \
 	ChangeLog INSTALL NEWS config.guess config.sub depcomp \
 	ChangeLog INSTALL NEWS config.guess config.sub depcomp \
 	install-sh missing
 	install-sh missing
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 	$(ACLOCAL_M4)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
@@ -213,16 +212,13 @@ sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 sysconfdir = @sysconfdir@
-target = @target@
 target_alias = @target_alias@
 target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 top_srcdir = @top_srcdir@
 AUTOMAKE_OPTIONS = gnu
 AUTOMAKE_OPTIONS = gnu
 SUBDIRS = doc src man contrib
 SUBDIRS = doc src man contrib
+EXTRA_DIST = autogen.sh configure.ng .mailmap
 all: all-recursive
 all: all-recursive
 
 
 .SUFFIXES:
 .SUFFIXES:
@@ -516,7 +512,7 @@ distcheck: dist
 	*.zip*) \
 	*.zip*) \
 	  unzip $(distdir).zip ;;\
 	  unzip $(distdir).zip ;;\
 	esac
 	esac
-	chmod -R a-w $(distdir); chmod a+w $(distdir)
+	chmod -R a-w $(distdir); chmod u+w $(distdir)
 	mkdir $(distdir)/_build
 	mkdir $(distdir)/_build
 	mkdir $(distdir)/_inst
 	mkdir $(distdir)/_inst
 	chmod a-w $(distdir)
 	chmod a-w $(distdir)
@@ -697,18 +693,18 @@ clean-local:
 
 
 maintainer-clean-local:
 maintainer-clean-local:
 	rm -rf autom4te.cache
 	rm -rf autom4te.cache
-	rm -f Makefile.in Makefile aclocal.m4 configure
-	rm -f mkinstalldirs missing depcomp install-sh
+	rm -f Makefile.in Makefile aclocal.m4 configure configure.ac
+	rm -f ar-lib mkinstalldirs missing depcomp install-sh
 	rm -f config.log debian
 	rm -f config.log debian
 
 
 testsuite:
 testsuite:
-	make -C src/testsuite check
+	cd src/testsuite && make check
 
 
 lint:
 lint:
-	make -C src/ngircd lint
+	cd src/ngircd && make lint
 
 
 srcdoc:
 srcdoc:
-	make -C doc srcdoc
+	cd doc && make srcdoc
 
 
 have-xcodebuild:
 have-xcodebuild:
 	@xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -list \
 	@xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -list \

+ 90 - 5
NEWS

@@ -9,6 +9,91 @@
                                   -- NEWS --
                                   -- NEWS --
 
 
 
 
+ngIRCd 20 (2012-12-17)
+
+  - Allow user names ("INDENT") up to 20 characters when ngIRCd has not
+    been configured for "strict RFC mode". This is useful if you are using
+    external (PAM) authenticaion mechanisms that require longer user names.
+    Patch suggested by Brett Smith <brett@w3.org>, see
+    <http://arthur.barton.de/pipermail/ngircd-ml/2012-October/000579.html>.
+
+  ngIRCd 20~rc2 (2012-12-02)
+  - Rework cloaked hostname handling and implement the "METADATA cloakhost"
+    subcommand: Now ngIRCd uses two fields internally, one to store the
+    "real" hostname and one to save the "cloaked" hostname. This allows
+    "foreign servers" (aka "IRC services") to alter the real and cloaked
+    hostnames of clients without problems, even when the user itself issues
+    additional "MODE +x" and "MODE -x" commands.
+
+  ngIRCd 20~rc1 (2012-11-11)
+  - Update doc/Services.txt: describe the upcoming version of Anope 1.9.8,
+    then including a protocol module for ngIRCd. And remove our own patches
+    in ./contrib/Anope because they aren't supported any more ...
+  - Implement new "METADATA" command which can be used by remote servers
+    and IRC services to update client metadata like the client info text
+    ("real name"), user name, and hostname, and use this command to
+    configure an cloaked hostname (user mode "+x") on remote servers:
+    This prevents "double cloaking" of hostnames and even cloaked
+    hostnames are in sync on all servers supporting "METADATA" now.
+  - Implement new IRC "SVSNICK" command to allow remote servers (and IRC
+    services) to change nicknames of already registered users. The SVSNICK
+    command itself doesn't change the nickname, but it becomes forwarded
+    to the server to which the user is connected to. And then this server
+    initiates the real nickname changing using regular NICK commands.
+    This allows to run mixed networks with old servers not supporting the
+    SVSNICK command, because SVSNICK commands for nicknames on such servers
+    are silently ignored and don't cause a desynchronization of the network.
+  - New configuration option "MaxListSize" to configure the maximum number
+    of channels returned by a LIST command. The default is 100, as before.
+  - Implement user mode "b", "block messages": when a user has set mode "b",
+    all private messages and notices to this user are blocked if they don't
+    originate from a registered user, an IRC Op, server or service. The
+    originator gets an error numeric sent back in this case,
+    ERR_NONONREG_MSG (486), which is used by UnrealIRCd, too. (Closes #144)
+  - Implement channel mode "V" (invite disallow): If the new channel mode
+    "V" is set, the INVITE command becomes invalid and all clients get the
+    new ERR_NOINVITE_MSG (518) reply. (Closes #143)
+  - Implement channel mode "Q" and user mode "q": Both modes protect users
+    from channel kicks: only IRC operators and servers can kick users having
+    mode "q" or in channels with mode "Q". (Closes #141)
+  - Allow users to "cloak" their hostname only when the configuration
+    variable "CloakHostModeX" (introduced in 19.2) is set. Otherwise, only
+    IRC operators, other servers, and services are allowed to set the user
+    mode "+x": this prevents regular users from changing their hostmask to
+    the name of the IRC server itself, which confused quite a few people ;-)
+    (Closes #133)
+  - New configuration option "OperChanPAutoOp": If disabled, IRC operators
+    don't become channel operators in persistent channels when joining.
+    Enabled by default, which has been the behavior of ngIRCd up to this
+    patch. (Closes #135)
+  - Allow IRC operators to see secret (+s) channels in LIST command as long
+    as the "MorePrivacy" configuration option isn't enabled in the
+    configuration file. (Closes #136)
+  - Implement new (optional) IRC+ "CHARCONV" command to set a client
+    character set that the server translates all messages to/from UTF-8.
+    This feature requires the "libiconv" library and must be enabled using
+    the new "--with-iconv" option of the ./configure script. See
+    doc/Protocol.txt for details. (Closes #109)
+  - Implement user mode "B" ("Bot flag"): it is settable and unsettable by
+    every (non-restricted) client. This is how Unreal and InspIRCd do
+    behave, and so do we :-)
+  - Implement channel mode "M": Only the server, identified users and IRC
+    operators are able to talk in such a channel.
+  - Block nicknames that are reserved for services and are defined using the
+    configuration variable "ServiceMask" in "Server" blocks; And this
+    variable now can handle more than one mask separated by commas.
+  - Implemented XOP channel user modes: "Half Op" ("+h", prefix "%") can set
+    the channel modes +imntvIbek and kick all +v and normal users; "Admin"
+    ("+a", prefix "&") can set channel modes +imntvIbekoRsz and kick all +o,
+    +h, +v and normal users; and "Owner" ("+q", prefix "~") can set channel
+    modes +imntvIbekoRsz and kick all +a, +o, +h, +v and normal users.
+  - Implement hashed cloaked hostnames for both the "CloakHost" and
+    "CloakHostModeX" configuration options: now the admin can use the new
+    '%x' placeholder to insert a hashed version of the clients hostname,
+    and the new configuration option "CloakHostSalt" defines the salt for
+    the hash function. When "CloakHostSalt" is not set (the default), a
+    random salt will be generated after each server restart.
+
 ngIRCd Release 19.2 (2012-06-19)
 ngIRCd Release 19.2 (2012-06-19)
 
 
   ngIRCd 19.2~rc1 (2012-06-13)
   ngIRCd 19.2~rc1 (2012-06-13)
@@ -43,7 +128,7 @@ ngIRCd Release 19 (2012-02-29)
     and receiver are on the same channel. This prevents private flooding
     and receiver are on the same channel. This prevents private flooding
     by completely unknown clients.
     by completely unknown clients.
   - New RPL_WHOISREGNICK_MSG(307) numeric in WHOIS command replies: it
   - New RPL_WHOISREGNICK_MSG(307) numeric in WHOIS command replies: it
-    indicates if a nick name is registered (if user mode 'R' set).
+    indicates if a nickname is registered (if user mode 'R' set).
   - Limit channel invite, ban, and exception lists to 50 entries and fix
   - Limit channel invite, ban, and exception lists to 50 entries and fix
     duplicate check and error messages when adding already listed entries
     duplicate check and error messages when adding already listed entries
     or deleting no (longer) existing ones.
     or deleting no (longer) existing ones.
@@ -79,7 +164,7 @@ ngIRCd Release 19 (2012-02-29)
     NICK, and USER commands have been processed) and before the child
     NICK, and USER commands have been processed) and before the child
     processes for authentication are forked, so resource usage is smaller.
     processes for authentication are forked, so resource usage is smaller.
   - Added doc/Modes.txt: document modes supported by ngIRCd.
   - Added doc/Modes.txt: document modes supported by ngIRCd.
-  - Implement user mode "R": indicates that the nick name of this user
+  - Implement user mode "R": indicates that the nickname of this user
     is "registered". This mode isn't handled by ngIRCd itself, but must
     is "registered". This mode isn't handled by ngIRCd itself, but must
     be set and unset by IRC services like Anope.
     be set and unset by IRC services like Anope.
   - Implement channel mode "R": only registered users (having the user
   - Implement channel mode "R": only registered users (having the user
@@ -90,7 +175,7 @@ ngIRCd Release 19 (2012-02-29)
   - Handle channel user modes 'a', 'h', and 'q' from remote servers.
   - Handle channel user modes 'a', 'h', and 'q' from remote servers.
     These channel user modes aren't used for anything at the moment,
     These channel user modes aren't used for anything at the moment,
     but ngIRCd knows that these three modes are "channel user modes"
     but ngIRCd knows that these three modes are "channel user modes"
-    and not "channel modes", that is that these modes take an "nick name"
+    and not "channel modes", that is that these modes take an "nickname"
     argument. Like unknown user and channel modes, these modes are saved
     argument. Like unknown user and channel modes, these modes are saved
     and forwarded to other servers, but ignored otherwise.
     and forwarded to other servers, but ignored otherwise.
 
 
@@ -149,7 +234,7 @@ ngIRCd Release 18 (2011-07-10)
   - New configuration option "CloakHost": when set, this host name is used for
   - New configuration option "CloakHost": when set, this host name is used for
     every client instead of the real DNS host name (or IP address).
     every client instead of the real DNS host name (or IP address).
   - New configuration option "CloakUserToNick": when enabled, ngIRCd sets
   - New configuration option "CloakUserToNick": when enabled, ngIRCd sets
-    every clients' user name to their nick name and hides the user name
+    every clients' user name to their nickname and hides the user name
     supplied by the IRC client.
     supplied by the IRC client.
   - Make write buffers bigger, but flush early. Before this change, a client
   - Make write buffers bigger, but flush early. Before this change, a client
     got disconnected if the buffer flushing at 4k failed, now regular clients
     got disconnected if the buffer flushing at 4k failed, now regular clients
@@ -317,7 +402,7 @@ ngIRCd 0.11.0 (2008-01-15)
   - New [Server] configuration Option "Bind" allows to specify
   - New [Server] configuration Option "Bind" allows to specify
     the source IP address to use when connecting to remote server.
     the source IP address to use when connecting to remote server.
   - New configuration option "MaxNickLength" to specify the allowed maximum
   - New configuration option "MaxNickLength" to specify the allowed maximum
-    length of user nick names. Note: must be unique in an IRC network!
+    length of user nicknames. Note: must be unique in an IRC network!
   - Numeric 317: implemented "signon time" (displayed in WHOIS result).
   - Numeric 317: implemented "signon time" (displayed in WHOIS result).
   - Added new server configuration option "Passive" for "Server" blocks to
   - Added new server configuration option "Passive" for "Server" blocks to
     disable automatic outgoing connections (similar to -p option to ngircd,
     disable automatic outgoing connections (similar to -p option to ngircd,

+ 9 - 6
README

@@ -12,12 +12,15 @@
 I. Introduction
 I. Introduction
 ~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~
 
 
-ngIRCd is an Open Source server for the Internet Relay Chat (IRC), which
-is developed and published under the terms of the GNU General Public
-Licence, see the file COPYING for details. ngIRCd means "next generation
-IRC daemon" (which is a little bit exaggerated, "lightweight Internet Relay
-Chat server" would be better), it's written from scratch and not deduced
-from the "grandfather of IRC daemons", the daemon of the IRCNet.
+ngIRCd is a free, portable and lightweight Internet Relay Chat server for
+small or private networks, developed under the GNU General Public License
+(GPL; please see the file COPYING for details). It is simple to configure,
+can cope with dynamic IP addresses, and supports IPv6 as well as SSL. It is
+written from scratch and not based on the original IRCd.
+
+The name ngIRCd means next generation IRC daemon, which is a little bit
+exaggerated: lightweight Internet Relay Chat server most probably would be a
+better name :-)
 
 
 Please see the INSTALL document for installation and upgrade information!
 Please see the INSTALL document for installation and upgrade information!
 
 

+ 0 - 12
aclocal.m4

@@ -406,18 +406,6 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
      [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
      [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
 ])
 ])
 
 
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 8
-
-# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
-AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
-
 # Do all the work for Automake.                             -*- Autoconf -*-
 # Do all the work for Automake.                             -*- Autoconf -*-
 
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,

+ 214 - 0
autogen.sh

@@ -0,0 +1,214 @@
+#!/bin/sh
+#
+# ngIRCd -- The Next Generation IRC Daemon
+# Copyright (c)2001-2012 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# Please read the file COPYING, README and AUTHORS for more information.
+#
+# Usage:
+#   [VAR=<value>] ./autogen.sh [<configure-args>]
+#
+# This script generates the ./configure script using GNU automake and
+# GNU autoconf. It tries to be smart in finding the correct/usable/available
+# installed versions of these tools on your system.
+#
+# In addition, it enables or disables the "de-ANSI-fication" support of GNU
+# automake, which is supported up to autoconf 1.11.x an has been removed
+# in automake 1.12 -- make sure to use a version of automake supporting it
+# when generating distribution archives!
+#
+# The following strategy is used for each of aclocal, autoheader, automake,
+# and autoconf: first, "tool" (the regular name of the tool, e. g. "autoconf"
+# or "automake") is checked. If this fails, "tool<major><minor>" (for example
+# "automake16") and "tool-<major>.<minor>" (e. g. "autoconf-2.54") are tried
+# with <major> being 2 for tool of GNU autoconf and 1 for tools of automake;
+# <minor> is tried from 99 to 0. The first occurrence will be used.
+#
+# When you pass <configure-args> to autogen.sh it will call the generated
+# ./configure script on success and pass these parameters to it.
+#
+# You can tweak the behaviour using these environment variables:
+#
+# - ACLOCAL=<cmd>, AUTOHEADER=<cmd>, AUTOMAKE=<cmd>, AUTOCONF=<cmd>
+#   Name and optionally path to the particular tool.
+# - PREFIX=<path>
+#   Search the GNU autoconf and GNU automake tools in <path> first. If the
+#   generated ./configure script will be called, pass "--prefix=<path>" to it.
+# - EXIST=<tool>
+#   Use <tool> to test for aclocal, autoheader etc. pp. ...
+#   When not specified, either "type" or "which" is used.
+# - VERBOSE=1
+#   Output the detected names of the GNU automake and GNU autoconf tools.
+# - GO=1
+#   Call ./configure even if no arguments have been passed to autogen.sh.
+#
+# Examples:
+#
+# - ./autogen.sh
+#   Generates the ./configure script.
+# - GO=1 ./autogen.sh
+#   Generates the ./configure script and runs it as "./configure".
+# - VERBOSE=1 ./autogen.sh --with-ident
+#   Show tool names, generates the ./configure script, and runs it with
+#   these arguments: "./configure --with-ident".
+# - ACLOCAL=aclocal-1.6 GO=1 PREFIX=$HOME ./autogen.sh
+#   Uses "aclocal-1.6" as aclocal tool, generates the ./configure script,
+#   and runs it with these arguments: "./configure --prefix=$HOME".
+#
+
+Search()
+{
+	[ $# -eq 2 ] || exit 1
+
+	searchlist="$1"
+	major="$2"
+	minor=99
+
+	[ -n "$PREFIX" ] && searchlist="${PREFIX}/$1 ${PREFIX}/bin/$1 $searchlist"
+
+	for name in $searchlist; do
+		$EXIST "${name}" >/dev/null 2>&1
+		if [ $? -eq 0 ]; then
+			echo "${name}"
+			return 0
+		fi
+	done
+
+	while [ $minor -ge 0 ]; do
+		for name in $searchlist; do
+			$EXIST "${name}${major}${minor}" >/dev/null 2>&1
+			if [ $? -eq 0 ]; then
+				echo "${name}${major}${minor}"
+				return 0
+			fi
+			$EXIST "${name}-${major}.${minor}" >/dev/null 2>&1
+			if [ $? -eq 0 ]; then
+				echo "${name}-${major}.${minor}"
+				return 0
+			fi
+		done
+		minor=`expr $minor - 1`
+	done
+	return 1
+}
+
+Notfound()
+{
+	echo "Error: $* not found!"
+	echo "Please install recent versions of GNU autoconf and GNU automake."
+	exit 1
+}
+
+Run()
+{
+	[ "$VERBOSE" = "1" ] && echo " - running \"$@\" ..."
+	$@
+}
+
+# Reset locale settings to suppress warning messages of Perl
+unset LC_ALL
+unset LANG
+
+# Which command should be used to detect the automake/autoconf tools?
+[ -z "$EXIST" ] && existlist="type which" || existlist="$EXIST"
+EXIST=""
+for t in $existlist; do
+	$t /bin/ls >/dev/null 2>&1
+	if [ $? -eq 0 ]; then
+		rm -f /tmp/test.$$
+		$t /tmp/test.$$ >/dev/null 2>&1
+		[ $? -ne 0 ] && EXIST="$t"
+	fi
+	[ -n "$EXIST" ] && break
+done
+if [ -z "$EXIST" ]; then
+	echo "Didn't detect a working command to test for the autoconf/automake tools!"
+	echo "Searchlist: $existlist"
+	exit 1
+fi
+[ "$VERBOSE" = "1" ] && echo "Using \"$EXIST\" to test for tools."
+
+# Try to detect the needed tools when no environment variable already
+# specifies one:
+echo "Searching for required tools ..."
+[ -z "$ACLOCAL" ] && ACLOCAL=`Search aclocal 1`
+[ "$VERBOSE" = "1" ] && echo " - ACLOCAL=$ACLOCAL"
+[ -z "$AUTOHEADER" ] && AUTOHEADER=`Search autoheader 2`
+[ "$VERBOSE" = "1" ] && echo " - AUTOHEADER=$AUTOHEADER"
+[ -z "$AUTOMAKE" ] && AUTOMAKE=`Search automake 1`
+[ "$VERBOSE" = "1" ] && echo " - AUTOMAKE=$AUTOMAKE"
+[ -z "$AUTOCONF" ] && AUTOCONF=`Search autoconf 2`
+[ "$VERBOSE" = "1" ] && echo " - AUTOCONF=$AUTOCONF"
+
+[ $# -gt 0 ] && CONFIGURE_ARGS=" $@" || CONFIGURE_ARGS=""
+[ -z "$GO" -a -n "$CONFIGURE_ARGS" ] && GO=1
+
+# Verify that all tools have been found
+[ -z "$ACLOCAL" ] && Notfound aclocal
+[ -z "$AUTOHEADER" ] && Notfound autoheader
+[ -z "$AUTOMAKE" ] && Notfound automake
+[ -z "$AUTOCONF" ] && Notfound autoconf
+
+AM_VERSION=`$AUTOMAKE --version|head -n 1|egrep -o "([1-9]\.[0-9]+(\.[0-9]+)*)"`
+ifs=$IFS; IFS="."; set $AM_VERSION; IFS=$ifs
+AM_MAJOR="$1"; AM_MINOR="$2"; AM_PATCHLEVEL="$3"
+
+AM_MAKEFILES="src/ipaddr/Makefile.ng src/ngircd/Makefile.ng src/testsuite/Makefile.ng src/tool/Makefile.ng"
+
+if [ "$AM_MAJOR" -eq "1" -a "$AM_MINOR" -lt "12" ]; then
+	# automake < 1.12 => automatic de-ANSI-fication support available
+	echo "Enabling de-ANSI-fication support (automake $AM_VERSION) ..."
+	sed -e "s|^__ng_PROTOTYPES__|AM_C_PROTOTYPES|g" configure.ng >configure.ac
+	DEANSI_START=""
+	DEANSI_END=""
+else
+	# automake >= 1.12 => no de-ANSI-fication support available
+	echo "Disabling de-ANSI-fication support (automake $AM_VERSION) ..."
+	sed -e "s|^__ng_PROTOTYPES__|AC_C_PROTOTYPES|g" configure.ng >configure.ac
+	DEANSI_START="#"
+	DEANSI_END="	# disabled by ./autogen.sh script"
+fi
+sed -e "s|^__ng_Makefile_am_template__|${DEANSI_START}AUTOMAKE_OPTIONS = ansi2knr${DEANSI_END}|g" \
+	src/portab/Makefile.ng >src/portab/Makefile.am
+for makefile_ng in $AM_MAKEFILES; do
+	makefile_am=`echo "$makefile_ng" | sed -e "s|\.ng\$|\.am|g"`
+	sed -e "s|^__ng_Makefile_am_template__|${DEANSI_START}AUTOMAKE_OPTIONS = ../portab/ansi2knr${DEANSI_END}|g" \
+		$makefile_ng >$makefile_am
+done
+
+export ACLOCAL AUTOHEADER AUTOMAKE AUTOCONF
+
+# Generate files
+echo "Generating files using GNU $AUTOCONF and $AUTOMAKE ..."
+Run $ACLOCAL && \
+	Run $AUTOCONF && \
+	Run $AUTOHEADER && \
+	Run $AUTOMAKE --add-missing --no-force
+
+if [ $? -eq 0 -a -x ./configure ]; then
+	# Success: if we got some parameters we call ./configure and pass
+	# all of them to it.
+	NAME=`grep PACKAGE_STRING= configure | cut -d"'" -f2`
+	if [ "$GO" = "1" ]; then
+		[ -n "$PREFIX" ] && p=" --prefix=$PREFIX" || p=""
+		c="./configure${p}${CONFIGURE_ARGS}"
+		echo "Okay, autogen.sh for $NAME done."
+		echo "Calling \"$c\" ..."
+		$c
+		exit $?
+	else
+		echo "Okay, autogen.sh for $NAME done."
+		echo "Now run the \"./configure\" script."
+		exit 0
+	fi
+else
+	# Failure!?
+	echo "Error! Check your installation of GNU automake and autoconf!"
+	exit 1
+fi
+
+# -eof-

+ 12 - 5
config.guess

@@ -4,7 +4,7 @@
 #   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
 #   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
 #   2011, 2012 Free Software Foundation, Inc.
 #   2011, 2012 Free Software Foundation, Inc.
 
 
-timestamp='2012-02-10'
+timestamp='2012-08-14'
 
 
 # This file is free software; you can redistribute it and/or modify it
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
 # under the terms of the GNU General Public License as published by
@@ -200,6 +200,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
 	echo "${machine}-${os}${release}"
 	echo "${machine}-${os}${release}"
 	exit ;;
 	exit ;;
+    *:Bitrig:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+	exit ;;
     *:OpenBSD:*:*)
     *:OpenBSD:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
 	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
 	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
 	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
@@ -801,6 +805,9 @@ EOF
     i*:CYGWIN*:*)
     i*:CYGWIN*:*)
 	echo ${UNAME_MACHINE}-pc-cygwin
 	echo ${UNAME_MACHINE}-pc-cygwin
 	exit ;;
 	exit ;;
+    *:MINGW64*:*)
+	echo ${UNAME_MACHINE}-pc-mingw64
+	exit ;;
     *:MINGW*:*)
     *:MINGW*:*)
 	echo ${UNAME_MACHINE}-pc-mingw32
 	echo ${UNAME_MACHINE}-pc-mingw32
 	exit ;;
 	exit ;;
@@ -1201,6 +1208,9 @@ EOF
     BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
     BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
 	echo i586-pc-haiku
 	echo i586-pc-haiku
 	exit ;;
 	exit ;;
+    x86_64:Haiku:*:*)
+	echo x86_64-unknown-haiku
+	exit ;;
     SX-4:SUPER-UX:*:*)
     SX-4:SUPER-UX:*:*)
 	echo sx4-nec-superux${UNAME_RELEASE}
 	echo sx4-nec-superux${UNAME_RELEASE}
 	exit ;;
 	exit ;;
@@ -1256,7 +1266,7 @@ EOF
     NEO-?:NONSTOP_KERNEL:*:*)
     NEO-?:NONSTOP_KERNEL:*:*)
 	echo neo-tandem-nsk${UNAME_RELEASE}
 	echo neo-tandem-nsk${UNAME_RELEASE}
 	exit ;;
 	exit ;;
-    NSE-?:NONSTOP_KERNEL:*:*)
+    NSE-*:NONSTOP_KERNEL:*:*)
 	echo nse-tandem-nsk${UNAME_RELEASE}
 	echo nse-tandem-nsk${UNAME_RELEASE}
 	exit ;;
 	exit ;;
     NSR-?:NONSTOP_KERNEL:*:*)
     NSR-?:NONSTOP_KERNEL:*:*)
@@ -1330,9 +1340,6 @@ EOF
 	exit ;;
 	exit ;;
 esac
 esac
 
 
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
 eval $set_cc_for_build
 eval $set_cc_for_build
 cat >$dummy.c <<EOF
 cat >$dummy.c <<EOF
 #ifdef _SEQUENT_
 #ifdef _SEQUENT_

+ 18 - 5
config.sub

@@ -4,7 +4,7 @@
 #   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
 #   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
 #   2011, 2012 Free Software Foundation, Inc.
 #   2011, 2012 Free Software Foundation, Inc.
 
 
-timestamp='2012-02-10'
+timestamp='2012-08-18'
 
 
 # This file is (in principle) common to ALL GNU software.
 # This file is (in principle) common to ALL GNU software.
 # The presence of a machine in this file suggests that SOME GNU software
 # The presence of a machine in this file suggests that SOME GNU software
@@ -123,7 +123,7 @@ esac
 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
 case $maybe_os in
   nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
   nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
-  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
   knetbsd*-gnu* | netbsd*-gnu* | \
   knetbsd*-gnu* | netbsd*-gnu* | \
   kopensolaris*-gnu* | \
   kopensolaris*-gnu* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
   storm-chaos* | os2-emx* | rtmk-nova*)
@@ -225,6 +225,12 @@ case $os in
 	-isc*)
 	-isc*)
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 		;;
 		;;
+	-lynx*178)
+		os=-lynxos178
+		;;
+	-lynx*5)
+		os=-lynxos5
+		;;
 	-lynx*)
 	-lynx*)
 		os=-lynxos
 		os=-lynxos
 		;;
 		;;
@@ -785,6 +791,10 @@ case $basic_machine in
 	microblaze)
 	microblaze)
 		basic_machine=microblaze-xilinx
 		basic_machine=microblaze-xilinx
 		;;
 		;;
+	mingw64)
+		basic_machine=x86_64-pc
+		os=-mingw64
+		;;
 	mingw32)
 	mingw32)
 		basic_machine=i386-pc
 		basic_machine=i386-pc
 		os=-mingw32
 		os=-mingw32
@@ -1346,15 +1356,15 @@ case $os in
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
 	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
 	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
 	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-	      | -openbsd* | -solidbsd* \
+	      | -bitrig* | -openbsd* | -solidbsd* \
 	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
 	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
 	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
 	      | -chorusos* | -chorusrdb* | -cegcc* \
 	      | -chorusos* | -chorusrdb* | -cegcc* \
 	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
 	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -mingw32* | -linux-gnu* | -linux-android* \
-	      | -linux-newlib* | -linux-uclibc* \
+	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
 	      | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@@ -1537,6 +1547,9 @@ case $basic_machine in
 	c4x-* | tic4x-*)
 	c4x-* | tic4x-*)
 		os=-coff
 		os=-coff
 		;;
 		;;
+	hexagon-*)
+		os=-elf
+		;;
 	tic54x-*)
 	tic54x-*)
 		os=-coff
 		os=-coff
 		;;
 		;;

File diff suppressed because it is too large
+ 695 - 397
configure


+ 156 - 85
configure.in

@@ -1,6 +1,6 @@
 #
 #
 # ngIRCd -- The Next Generation IRC Daemon
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
+# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 #
 #
 # This program is free software; you can redistribute it and/or modify
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
@@ -9,46 +9,60 @@
 # Please read the file COPYING, README and AUTHORS for more information.
 # Please read the file COPYING, README and AUTHORS for more information.
 #
 #
 
 
-define(VERSION_ID,esyscmd(git describe|sed -e 's/rel-//g'|sed -e 's/-/~/'|tr -d \\n))
+define(VERSION_ID,esyscmd([
+	V=`git describe 2>/dev/null | sed -e 's/rel-//g' | sed -e 's/-/~/'`;
+	[ -z "$V" -a -r configure ] \
+		&& V=`grep "PACKAGE_STRING=" configure | cut -d"'" -f2 | cut -d' ' -f2`
+	( [ -n "$V" ] && echo "$V" || echo "??" ) | tr -d '\n';
+]))
+
+m4_ifdef([AM_SILENT_RULES],
+	[m4_define([ng_color_tests], [color-tests])],
+	[m4_define([ng_color_tests], [])])
 
 
 # -- Initialisation --
 # -- Initialisation --
 
 
-AC_PREREQ(2.50)
-AC_INIT(ngircd, VERSION_ID)
-AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
-AC_CANONICAL_TARGET
-AM_INIT_AUTOMAKE(1.6)
-AM_CONFIG_HEADER(src/config.h)
+AC_PREREQ([2.61])
+AC_INIT([ngIRCd], VERSION_ID,
+	[ngircd-ml@ngircd.barton.de], [ngircd], [http://ngircd.barton.de/])
+
+AC_CONFIG_SRCDIR([src/ngircd/ngircd.c])
+AC_CONFIG_HEADER([src/config.h])
+AC_CANONICAL_HOST
+
+AM_INIT_AUTOMAKE([-Wall 1.10 ]ng_color_tests)
 
 
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
 
 # -- Templates for config.h --
 # -- Templates for config.h --
 
 
 AH_TEMPLATE([DEBUG], [Define if debug-mode should be enabled])
 AH_TEMPLATE([DEBUG], [Define if debug-mode should be enabled])
+AH_TEMPLATE([HAVE_sockaddr_in_len], [Define if sockaddr_in.sin_len exists])
 AH_TEMPLATE([HAVE_socklen_t], [Define if socklen_t exists])
 AH_TEMPLATE([HAVE_socklen_t], [Define if socklen_t exists])
+AH_TEMPLATE([ICONV], [Define if libiconv can be used, e.g. for CHARCONV])
+AH_TEMPLATE([IDENTAUTH], [Define if the server should do IDENT requests])
+AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used])
+AH_TEMPLATE([PAM], [Define if PAM should be used])
 AH_TEMPLATE([SNIFFER], [Define if IRC sniffer should be enabled])
 AH_TEMPLATE([SNIFFER], [Define if IRC sniffer should be enabled])
 AH_TEMPLATE([STRICT_RFC], [Define if ngIRCd should behave strict RFC compliant])
 AH_TEMPLATE([STRICT_RFC], [Define if ngIRCd should behave strict RFC compliant])
 AH_TEMPLATE([SYSLOG], [Define if syslog should be used for logging])
 AH_TEMPLATE([SYSLOG], [Define if syslog should be used for logging])
-AH_TEMPLATE([ZLIB], [Define if zlib compression should be enabled])
 AH_TEMPLATE([TCPWRAP], [Define if TCP wrappers should be used])
 AH_TEMPLATE([TCPWRAP], [Define if TCP wrappers should be used])
-AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used])
 AH_TEMPLATE([WANT_IPV6], [Define if IPV6 protocol should be enabled])
 AH_TEMPLATE([WANT_IPV6], [Define if IPV6 protocol should be enabled])
-AH_TEMPLATE([IDENTAUTH], [Define if the server should do IDENT requests])
-AH_TEMPLATE([PAM], [Define if PAM should be used])
-AH_TEMPLATE([HAVE_sockaddr_in_len], [Define if sockaddr_in.sin_len exists])
+AH_TEMPLATE([ZLIB], [Define if zlib compression should be enabled])
 
 
-AH_TEMPLATE([TARGET_OS], [Target operating system name])
-AH_TEMPLATE([TARGET_VENDOR], [Target system vendor])
-AH_TEMPLATE([TARGET_CPU], [Target CPU name])
+AH_TEMPLATE([HOST_OS], [Target operating system name])
+AH_TEMPLATE([HOST_VENDOR], [Target system vendor])
+AH_TEMPLATE([HOST_CPU], [Target CPU name])
 
 
 # -- C Compiler --
 # -- C Compiler --
 
 
 AC_PROG_CC
 AC_PROG_CC
 AC_PROG_CC_STDC
 AC_PROG_CC_STDC
-AC_C_PROTOTYPES
 
 
 # -- Helper programs --
 # -- Helper programs --
 
 
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+
 AC_PROG_AWK
 AC_PROG_AWK
 AC_PROG_INSTALL
 AC_PROG_INSTALL
 AC_PROG_LN_S
 AC_PROG_LN_S
@@ -57,9 +71,9 @@ AC_PROG_RANLIB
 
 
 # -- Compiler Features --
 # -- Compiler Features --
 
 
-AM_C_PROTOTYPES
 AC_C_CONST
 AC_C_CONST
 AC_C_INLINE
 AC_C_INLINE
+AM_C_PROTOTYPES
 
 
 # -- Hard coded system and compiler dependencies/features/options ... --
 # -- Hard coded system and compiler dependencies/features/options ... --
 
 
@@ -85,7 +99,7 @@ if test "$GCC" = "yes"; then
 	GCC_STACK_PROTECT_CC
 	GCC_STACK_PROTECT_CC
 fi
 fi
 
 
-case "$target_os" in
+case "$host_os" in
 	hpux*)
 	hpux*)
 		# This is HP/UX, we need to define _XOPEN_SOURCE_EXTENDED
 		# This is HP/UX, we need to define _XOPEN_SOURCE_EXTENDED
 		# (tested with HP/UX 11.11)
 		# (tested with HP/UX 11.11)
@@ -101,28 +115,20 @@ CFLAGS="$CFLAGS -DSYSCONFDIR='\"\$(sysconfdir)\"'"
 # -- Headers --
 # -- Headers --
 
 
 AC_HEADER_STDC
 AC_HEADER_STDC
-AC_HEADER_TIME
 AC_HEADER_SYS_WAIT
 AC_HEADER_SYS_WAIT
+AC_HEADER_TIME
 
 
+# Required header files
 AC_CHECK_HEADERS([ \
 AC_CHECK_HEADERS([ \
-	ctype.h errno.h fcntl.h netdb.h netinet/in.h netinet/in_systm.h \
-	stdlib.h string.h strings.h sys/socket.h sys/time.h unistd.h \
+	fcntl.h netdb.h netinet/in.h netinet/in_systm.h stdlib.h string.h \
+	strings.h sys/socket.h sys/time.h unistd.h \
 	],,AC_MSG_ERROR([required C header missing!]))
 	],,AC_MSG_ERROR([required C header missing!]))
 
 
-AC_CHECK_HEADERS([ \
-	arpa/inet.h ctype.h malloc.h netinet/ip.h stdbool.h stddef.h varargs.h \
-	],[],[],[[
-	#ifdef HAVE_SYS_TYPES_H
-		#include <sys/types.h>
-	#endif
-	#ifdef HAVE_SYS_SOCKET_H
-		#include <sys/socket.h>
-	#endif
-	#ifdef HAVE_NETINET_IN_H
-		#include <netinet/in.h>
-	#endif
-	]]
-)
+# Optional header files
+AC_CHECK_HEADERS_ONCE([ \
+	arpa/inet.h inttypes.h malloc.h netinet/ip.h stdbool.h stddef.h \
+	stdint.h varargs.h \
+	])
 
 
 # -- Datatypes --
 # -- Datatypes --
 
 
@@ -139,33 +145,50 @@ AC_TRY_COMPILE([
 	AC_MSG_RESULT(no)
 	AC_MSG_RESULT(no)
 ])
 ])
 
 
+AC_TYPE_PID_T
 AC_TYPE_SIGNAL
 AC_TYPE_SIGNAL
 AC_TYPE_SIZE_T
 AC_TYPE_SIZE_T
+AC_TYPE_SSIZE_T
+AC_TYPE_UID_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT8_T
 
 
 AC_CHECK_MEMBER([struct sockaddr_in.sin_len], AC_DEFINE(HAVE_sockaddr_in_len),,
 AC_CHECK_MEMBER([struct sockaddr_in.sin_len], AC_DEFINE(HAVE_sockaddr_in_len),,
  [#include <arpa/inet.h>])
  [#include <arpa/inet.h>])
 
 
 # -- Libraries --
 # -- Libraries --
 
 
-# A/UX needs this.
-AC_CHECK_LIB(UTIL,memmove)
-# needed on solaris. GNU libc also has a libnsl, but we do not need it.
-AC_SEARCH_LIBS(gethostbyname,nsl)
-AC_CHECK_LIB(socket,bind)
+# memmove: A/UX libUTIL
+AC_SEARCH_LIBS([memmove], [UTIL], [], [
+	AC_MSG_ERROR([unable to find the memmove() function])
+])
+# gethostbyname: Solaris libnsl
+AC_SEARCH_LIBS([gethostbyname], [bind nsl network], [], [
+	AC_MSG_ERROR([unable to find the gethostbyname() function])
+])
+# bind: SVR4 libsocket
+AC_SEARCH_LIBS([bind], [socket network], [], [
+	AC_MSG_ERROR([unable to find the bind() function])
+])
 
 
 # -- Functions --
 # -- Functions --
 
 
 AC_FUNC_FORK
 AC_FUNC_FORK
 AC_FUNC_STRFTIME
 AC_FUNC_STRFTIME
 
 
+# Required functions
 AC_CHECK_FUNCS([ \
 AC_CHECK_FUNCS([ \
-	bind gethostbyaddr gethostbyname gethostname inet_ntoa \
-	setsid setsockopt socket strcasecmp waitpid],,
+	alarm dup2 endpwent gethostbyaddr gethostbyname gethostname \
+	gettimeofday inet_ntoa memmove memset setsid socket strcasecmp \
+	strchr strcspn strerror strncasecmp strrchr strspn strstr \
+	],,
 	AC_MSG_ERROR([required function missing!]))
 	AC_MSG_ERROR([required function missing!]))
 
 
-AC_CHECK_FUNCS([ \
-	gai_strerror getaddrinfo getnameinfo inet_aton sigaction \
-	sigprocmask snprintf vsnprintf strdup strlcpy strlcat strtok_r])
+# Optional functions
+AC_CHECK_FUNCS_ONCE([ \
+	gai_strerror getaddrinfo getnameinfo inet_aton sigaction sigprocmask \
+	snprintf vsnprintf strdup strlcpy strlcat strtok_r waitpid])
 
 
 # -- Configuration options --
 # -- Configuration options --
 
 
@@ -173,22 +196,20 @@ AC_CHECK_FUNCS([ \
 
 
 x_syslog_on=no
 x_syslog_on=no
 AC_ARG_WITH(syslog,
 AC_ARG_WITH(syslog,
-	[  --without-syslog        disable syslog (autodetected by default)],
+	AS_HELP_STRING([--without-syslog],
+		       [disable syslog (autodetected by default)]),
 	[	if test "$withval" != "no"; then
 	[	if test "$withval" != "no"; then
 			if test "$withval" != "yes"; then
 			if test "$withval" != "yes"; then
 				CFLAGS="-I$withval/include $CFLAGS"
 				CFLAGS="-I$withval/include $CFLAGS"
 				CPPFLAGS="-I$withval/include $CPPFLAGS"
 				CPPFLAGS="-I$withval/include $CPPFLAGS"
 				LDFLAGS="-L$withval/lib $LDFLAGS"
 				LDFLAGS="-L$withval/lib $LDFLAGS"
 			fi
 			fi
-			AC_CHECK_LIB(be, syslog)
-			AC_CHECK_FUNCS(syslog, x_syslog_on=yes,
+			AC_SEARCH_LIBS([syslog], [be], [x_syslog_on=yes], [
 				AC_MSG_ERROR([Can't enable syslog!])
 				AC_MSG_ERROR([Can't enable syslog!])
-			)
+			])
 		fi
 		fi
 	],
 	],
-	[
-		AC_CHECK_LIB(be, syslog)
-		AC_CHECK_FUNCS(syslog, x_syslog_on=yes)
+	[	AC_SEARCH_LIBS([syslog], [be], [x_syslog_on=yes])
 	]
 	]
 )
 )
 if test "$x_syslog_on" = "yes"; then
 if test "$x_syslog_on" = "yes"; then
@@ -200,7 +221,8 @@ fi
 
 
 x_zlib_on=no
 x_zlib_on=no
 AC_ARG_WITH(zlib,
 AC_ARG_WITH(zlib,
-	[  --without-zlib          disable zlib compression (autodetected by default)],
+	AS_HELP_STRING([--without-zlib],
+		       [disable zlib compression (autodetected by default)]),
 	[	if test "$withval" != "no"; then
 	[	if test "$withval" != "no"; then
 			if test "$withval" != "yes"; then
 			if test "$withval" != "yes"; then
 				CFLAGS="-I$withval/include $CFLAGS"
 				CFLAGS="-I$withval/include $CFLAGS"
@@ -227,7 +249,8 @@ fi
 x_io_backend=none
 x_io_backend=none
 
 
 AC_ARG_WITH(select,
 AC_ARG_WITH(select,
-	[  --without-select        disable select IO support (autodetected by default)],
+	AS_HELP_STRING([--without-select],
+		       [disable select IO support (autodetected by default)]),
 	[	if test "$withval" != "no"; then
 	[	if test "$withval" != "no"; then
 			if test "$withval" != "yes"; then
 			if test "$withval" != "yes"; then
 				CFLAGS="-I$withval/include $CFLAGS"
 				CFLAGS="-I$withval/include $CFLAGS"
@@ -245,7 +268,8 @@ AC_ARG_WITH(select,
 )
 )
 
 
 AC_ARG_WITH(poll,
 AC_ARG_WITH(poll,
-	[  --without-poll          disable poll support (autodetected by default)],
+	AS_HELP_STRING([--without-poll],
+		       [disable poll support (autodetected by default)]),
 	[	if test "$withval" != "no"; then
 	[	if test "$withval" != "no"; then
 			if test "$withval" != "yes"; then
 			if test "$withval" != "yes"; then
 				CFLAGS="-I$withval/include $CFLAGS"
 				CFLAGS="-I$withval/include $CFLAGS"
@@ -271,7 +295,8 @@ AC_ARG_WITH(poll,
 )
 )
 
 
 AC_ARG_WITH(devpoll,
 AC_ARG_WITH(devpoll,
-	[  --without-devpoll       disable /dev/poll IO support (autodetected by default)],
+	AS_HELP_STRING([--without-devpoll],
+		       [disable /dev/poll IO support (autodetected by default)]),
 	[	if test "$withval" != "no"; then
 	[	if test "$withval" != "no"; then
 			if test "$withval" != "yes"; then
 			if test "$withval" != "yes"; then
 				CFLAGS="-I$withval/include $CFLAGS"
 				CFLAGS="-I$withval/include $CFLAGS"
@@ -288,7 +313,8 @@ AC_ARG_WITH(devpoll,
 )
 )
 
 
 AC_ARG_WITH(epoll,
 AC_ARG_WITH(epoll,
-	[  --without-epoll         disable epoll IO support (autodetected by default)],
+	AS_HELP_STRING([--without-epoll],
+		       [disable epoll IO support (autodetected by default)]),
 	[	if test "$withval" != "no"; then
 	[	if test "$withval" != "no"; then
 			if test "$withval" != "yes"; then
 			if test "$withval" != "yes"; then
 				CFLAGS="-I$withval/include $CFLAGS"
 				CFLAGS="-I$withval/include $CFLAGS"
@@ -306,7 +332,8 @@ AC_ARG_WITH(epoll,
 )
 )
 
 
 AC_ARG_WITH(kqueue,
 AC_ARG_WITH(kqueue,
-	[  --without-kqueue        disable kqueue IO support (autodetected by default)],
+	AS_HELP_STRING([--without-kqueue],
+		       [disable kqueue IO support (autodetected by default)]),
 	[	if test "$withval" != "no"; then
 	[	if test "$withval" != "no"; then
 			if test "$withval" != "yes"; then
 			if test "$withval" != "yes"; then
 				CFLAGS="-I$withval/include $CFLAGS"
 				CFLAGS="-I$withval/include $CFLAGS"
@@ -346,7 +373,8 @@ fi
 # use SSL?
 # use SSL?
 
 
 AC_ARG_WITH(openssl,
 AC_ARG_WITH(openssl,
-	[  --with-openssl          enable SSL support using OpenSSL],
+	AS_HELP_STRING([--with-openssl],
+		       [enable SSL support using OpenSSL]),
 	[	if test "$withval" != "no"; then
 	[	if test "$withval" != "no"; then
 			if test "$withval" != "yes"; then
 			if test "$withval" != "yes"; then
 				CFLAGS="-I$withval/include $CFLAGS"
 				CFLAGS="-I$withval/include $CFLAGS"
@@ -363,7 +391,8 @@ AC_ARG_WITH(openssl,
 )
 )
 
 
 AC_ARG_WITH(gnutls,
 AC_ARG_WITH(gnutls,
-	[  --with-gnutls           enable SSL support using gnutls],
+	AS_HELP_STRING([--with-gnutls],
+		       [enable SSL support using gnutls]),
 	[	if test "$withval" != "no"; then
 	[	if test "$withval" != "no"; then
 			if test "$withval" != "yes"; then
 			if test "$withval" != "yes"; then
 				CFLAGS="-I$withval/include $CFLAGS"
 				CFLAGS="-I$withval/include $CFLAGS"
@@ -393,7 +422,8 @@ fi
 
 
 x_tcpwrap_on=no
 x_tcpwrap_on=no
 AC_ARG_WITH(tcp-wrappers,
 AC_ARG_WITH(tcp-wrappers,
-	[  --with-tcp-wrappers     enable TCP wrappers support],
+	AS_HELP_STRING([--with-tcp-wrappers],
+		       [enable TCP wrappers support]),
 	[	if test "$withval" != "no"; then
 	[	if test "$withval" != "no"; then
 			if test "$withval" != "yes"; then
 			if test "$withval" != "yes"; then
 				CFLAGS="-I$withval/include $CFLAGS"
 				CFLAGS="-I$withval/include $CFLAGS"
@@ -424,7 +454,8 @@ int deny_severity = 0;
 
 
 x_identauth_on=no
 x_identauth_on=no
 AC_ARG_WITH(ident,
 AC_ARG_WITH(ident,
-	[  --with-ident            enable "IDENT" ("AUTH") protocol support],
+	AS_HELP_STRING([--with-ident],
+		       [enable "IDENT" ("AUTH") protocol support]),
 	[	if test "$withval" != "no"; then
 	[	if test "$withval" != "no"; then
 			if test "$withval" != "yes"; then
 			if test "$withval" != "yes"; then
 				CFLAGS="-I$withval/include $CFLAGS"
 				CFLAGS="-I$withval/include $CFLAGS"
@@ -447,7 +478,8 @@ fi
 
 
 x_pam_on=no
 x_pam_on=no
 AC_ARG_WITH(pam,
 AC_ARG_WITH(pam,
-	[  --with-pam              enable user authentication using PAM],
+	AS_HELP_STRING([--with-pam],
+		       [enable user authentication using PAM]),
 	[	if test "$withval" != "no"; then
 	[	if test "$withval" != "no"; then
 			if test "$withval" != "yes"; then
 			if test "$withval" != "yes"; then
 				CFLAGS="-I$withval/include $CFLAGS"
 				CFLAGS="-I$withval/include $CFLAGS"
@@ -474,17 +506,42 @@ fi
 
 
 x_ircplus_on=yes
 x_ircplus_on=yes
 AC_ARG_ENABLE(ircplus,
 AC_ARG_ENABLE(ircplus,
-	[  --disable-ircplus       disable IRC+ protocol],
+	AS_HELP_STRING([--disable-ircplus],
+		       [disable IRC+ protocol]),
 	if test "$enableval" = "no"; then x_ircplus_on=no; fi
 	if test "$enableval" = "no"; then x_ircplus_on=no; fi
 )
 )
 if test "$x_ircplus_on" = "yes"; then
 if test "$x_ircplus_on" = "yes"; then
 	AC_DEFINE(IRCPLUS, 1)
 	AC_DEFINE(IRCPLUS, 1)
+
+	# Compile in iconv support?
+	# We only check for it when IRC+ is enabled, because the IRC+ command
+	# CHARCONV is the only function depending on it.
+	x_iconv_on=no
+	AC_ARG_WITH(iconv,
+		[  --with-iconv            enable character conversation using libiconv],
+		[ if test "$withval" != "no"; then
+			if test "$withval" != "yes"; then
+				CFLAGS="-I$withval/include $CFLAGS"
+				CPPFLAGS="-I$withval/include $CPPFLAGS"
+				LDFLAGS="-L$withval/lib $LDFLAGS"
+			fi
+			AC_CHECK_LIB(iconv, iconv_open)
+			AC_CHECK_FUNCS(iconv_open, x_iconv_on=yes,
+				AC_MSG_ERROR([Can't enable libiconv support!])
+			)
+		  fi
+		]
+	)
+	if test "$x_iconv_on" = "yes"; then
+		AC_DEFINE(ICONV, 1)
+	fi
 fi
 fi
 
 
 # enable support for IPv6?
 # enable support for IPv6?
 x_ipv6_on=no
 x_ipv6_on=no
 AC_ARG_ENABLE(ipv6,
 AC_ARG_ENABLE(ipv6,
-	[  --enable-ipv6           enable IPv6 protocol support],
+	AS_HELP_STRING([--enable-ipv6],
+		       [enable IPv6 protocol support]),
 	if test "$enableval" = "yes"; then x_ipv6_on=yes; fi
 	if test "$enableval" = "yes"; then x_ipv6_on=yes; fi
 )
 )
 if test "$x_ipv6_on" = "yes"; then
 if test "$x_ipv6_on" = "yes"; then
@@ -500,7 +557,8 @@ fi
 
 
 x_sniffer_on=no; x_debug_on=no
 x_sniffer_on=no; x_debug_on=no
 AC_ARG_ENABLE(sniffer,
 AC_ARG_ENABLE(sniffer,
-	[  --enable-sniffer        enable IRC traffic sniffer (enables debug mode)],
+	AS_HELP_STRING([--enable-sniffer],
+		       [enable IRC traffic sniffer (enables debug mode)]),
 	if test "$enableval" = "yes"; then
 	if test "$enableval" = "yes"; then
 		AC_DEFINE(SNIFFER, 1)
 		AC_DEFINE(SNIFFER, 1)
 		x_sniffer_on=yes; x_debug_on=yes
 		x_sniffer_on=yes; x_debug_on=yes
@@ -510,7 +568,8 @@ AC_ARG_ENABLE(sniffer,
 # enable additional debugging code?
 # enable additional debugging code?
 
 
 AC_ARG_ENABLE(debug,
 AC_ARG_ENABLE(debug,
-	[  --enable-debug          show additional debug output],
+	AS_HELP_STRING([--enable-debug],
+		       [show additional debug output]),
 	if test "$enableval" = "yes"; then x_debug_on=yes; fi
 	if test "$enableval" = "yes"; then x_debug_on=yes; fi
 )
 )
 if test "$x_debug_on" = "yes"; then
 if test "$x_debug_on" = "yes"; then
@@ -523,7 +582,8 @@ fi
 
 
 x_strict_rfc_on=no
 x_strict_rfc_on=no
 AC_ARG_ENABLE(strict-rfc,
 AC_ARG_ENABLE(strict-rfc,
-	[  --enable-strict-rfc     strict RFC conformance -- may break clients!],
+	AS_HELP_STRING([--enable-strict-rfc],
+		       [strict RFC conformance -- may break clients!]),
 	if test "$enableval" = "yes"; then
 	if test "$enableval" = "yes"; then
 		AC_DEFINE(STRICT_RFC, 1)
 		AC_DEFINE(STRICT_RFC, 1)
 		x_strict_rfc_on=yes
 		x_strict_rfc_on=yes
@@ -532,9 +592,9 @@ AC_ARG_ENABLE(strict-rfc,
 
 
 # -- Definitions --
 # -- Definitions --
 
 
-AC_DEFINE_UNQUOTED(TARGET_CPU, "$target_cpu" )
-AC_DEFINE_UNQUOTED(TARGET_VENDOR, "$target_vendor" )
-AC_DEFINE_UNQUOTED(TARGET_OS, "$target_os" )
+AC_DEFINE_UNQUOTED(HOST_CPU, "$host_cpu" )
+AC_DEFINE_UNQUOTED(HOST_VENDOR, "$host_vendor" )
+AC_DEFINE_UNQUOTED(HOST_OS, "$host_os" )
 
 
 # Add additional CFLAGS, eventually specified on the command line, but after
 # Add additional CFLAGS, eventually specified on the command line, but after
 # running this configure script. Useful for "-Werror" for example.
 # running this configure script. Useful for "-Werror" for example.
@@ -542,25 +602,26 @@ test -n "$CFLAGS_END" && CFLAGS="$CFLAGS $CFLAGS_END"
 
 
 # -- Generate files --
 # -- Generate files --
 
 
-AC_OUTPUT([ \
+AC_CONFIG_FILES([ \
 	Makefile \
 	Makefile \
+	contrib/Debian/Makefile \
+	contrib/MacOSX/Makefile \
+	contrib/MacOSX/ngIRCd.pmdoc/Makefile \
+	contrib/MacOSX/ngIRCd.xcodeproj/Makefile \
+	contrib/Makefile \
 	doc/Makefile \
 	doc/Makefile \
 	doc/src/Makefile \
 	doc/src/Makefile \
-	src/Makefile \
-	src/portab/Makefile \
+	man/Makefile \
 	src/ipaddr/Makefile \
 	src/ipaddr/Makefile \
-	src/tool/Makefile \
+	src/Makefile \
 	src/ngircd/Makefile \
 	src/ngircd/Makefile \
+	src/portab/Makefile \
 	src/testsuite/Makefile \
 	src/testsuite/Makefile \
-	man/Makefile \
-	contrib/Makefile \
-	contrib/Anope/Makefile \
-	contrib/Debian/Makefile \
-	contrib/MacOSX/Makefile \
-	contrib/MacOSX/ngIRCd.xcodeproj/Makefile \
-	contrib/MacOSX/ngIRCd.pmdoc/Makefile \
+	src/tool/Makefile \
 ])
 ])
 
 
+AC_OUTPUT
+
 type dpkg >/dev/null 2>&1
 type dpkg >/dev/null 2>&1
 if test $? -eq 0; then
 if test $? -eq 0; then
 	# Generate debian/ link if the dpkg command exists
 	# Generate debian/ link if the dpkg command exists
@@ -582,8 +643,7 @@ C=`eval echo ${sysconfdir}` ; C=`eval echo ${C}`
 M=`eval echo ${mandir}` ; M=`eval echo ${M}`
 M=`eval echo ${mandir}` ; M=`eval echo ${M}`
 D=`eval echo ${docdir}` ; D=`eval echo ${D}`
 D=`eval echo ${docdir}` ; D=`eval echo ${D}`
 
 
-echo "             Target: ${target}"
-test "$target" != "$host" && echo "               Host: ${host}"
+echo "               Host: ${host}"
 echo "           Compiler: ${CC}"
 echo "           Compiler: ${CC}"
 test -n "$CFLAGS"	&& echo "     Compiler flags: ${CFLAGS}"
 test -n "$CFLAGS"	&& echo "     Compiler flags: ${CFLAGS}"
 test -n "$CPPFLAGS"	&& echo " Preprocessor flags: ${CPPFLAGS}"
 test -n "$CPPFLAGS"	&& echo " Preprocessor flags: ${CPPFLAGS}"
@@ -646,6 +706,17 @@ test "$x_pam_on" = "yes" \
 echo $ECHO_N "        SSL support: $ECHO_C"
 echo $ECHO_N "        SSL support: $ECHO_C"
 echo "$x_ssl_lib"
 echo "$x_ssl_lib"
 
 
+echo $ECHO_N "   libiconv support: $ECHO_C"
+	echo "$x_iconv_on"
+
 echo
 echo
 
 
+if ! grep "^AUTOMAKE_OPTIONS = ../portab/ansi2knr" src/ngircd/Makefile.am >/dev/null 2>&1; then
+	echo "WARNING:"
+	echo "This GNU automake generated build system does not support \"de-ANSI-fication\","
+	echo "therefore don't use it to generate \"official\" distribution archives!"
+	echo "(Most probably you want to use GNU automake 1.11.x for this purpose ...)"
+	echo
+fi
+
 # -eof-
 # -eof-

+ 722 - 0
configure.ng

@@ -0,0 +1,722 @@
+#
+# ngIRCd -- The Next Generation IRC Daemon
+# Copyright (c)2001-2012 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# Please read the file COPYING, README and AUTHORS for more information.
+#
+
+define(VERSION_ID,esyscmd([
+	V=`git describe 2>/dev/null | sed -e 's/rel-//g' | sed -e 's/-/~/'`;
+	[ -z "$V" -a -r configure ] \
+		&& V=`grep "PACKAGE_STRING=" configure | cut -d"'" -f2 | cut -d' ' -f2`
+	( [ -n "$V" ] && echo "$V" || echo "??" ) | tr -d '\n';
+]))
+
+m4_ifdef([AM_SILENT_RULES],
+	[m4_define([ng_color_tests], [color-tests])],
+	[m4_define([ng_color_tests], [])])
+
+# -- Initialisation --
+
+AC_PREREQ([2.61])
+AC_INIT([ngIRCd], VERSION_ID,
+	[ngircd-ml@ngircd.barton.de], [ngircd], [http://ngircd.barton.de/])
+
+AC_CONFIG_SRCDIR([src/ngircd/ngircd.c])
+AC_CONFIG_HEADER([src/config.h])
+AC_CANONICAL_HOST
+
+AM_INIT_AUTOMAKE([-Wall 1.10 ]ng_color_tests)
+
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+# -- Templates for config.h --
+
+AH_TEMPLATE([DEBUG], [Define if debug-mode should be enabled])
+AH_TEMPLATE([HAVE_sockaddr_in_len], [Define if sockaddr_in.sin_len exists])
+AH_TEMPLATE([HAVE_socklen_t], [Define if socklen_t exists])
+AH_TEMPLATE([ICONV], [Define if libiconv can be used, e.g. for CHARCONV])
+AH_TEMPLATE([IDENTAUTH], [Define if the server should do IDENT requests])
+AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used])
+AH_TEMPLATE([PAM], [Define if PAM should be used])
+AH_TEMPLATE([SNIFFER], [Define if IRC sniffer should be enabled])
+AH_TEMPLATE([STRICT_RFC], [Define if ngIRCd should behave strict RFC compliant])
+AH_TEMPLATE([SYSLOG], [Define if syslog should be used for logging])
+AH_TEMPLATE([TCPWRAP], [Define if TCP wrappers should be used])
+AH_TEMPLATE([WANT_IPV6], [Define if IPV6 protocol should be enabled])
+AH_TEMPLATE([ZLIB], [Define if zlib compression should be enabled])
+
+AH_TEMPLATE([HOST_OS], [Target operating system name])
+AH_TEMPLATE([HOST_VENDOR], [Target system vendor])
+AH_TEMPLATE([HOST_CPU], [Target CPU name])
+
+# -- C Compiler --
+
+AC_PROG_CC
+AC_PROG_CC_STDC
+
+# -- Helper programs --
+
+m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
+
+AC_PROG_AWK
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+
+# -- Compiler Features --
+
+AC_C_CONST
+AC_C_INLINE
+__ng_PROTOTYPES__
+
+# -- Hard coded system and compiler dependencies/features/options ... --
+
+AC_DEFUN([GCC_STACK_PROTECT_CC],[
+  ssp_cc=yes
+  # we use -fstack-protector-all for the test to enfoce the use of the guard variable 
+  AC_MSG_CHECKING([whether ${CC} accepts -fstack-protector])
+  ssp_old_cflags="$CFLAGS"
+  CFLAGS="$CFLAGS -fstack-protector-all"
+  AC_TRY_LINK(,,, ssp_cc=no)
+  echo $ssp_cc
+  CFLAGS="$ssp_old_cflags"
+  if test "X$ssp_cc" = "Xyes"; then
+      CFLAGS="$CFLAGS -fstack-protector"
+      AC_DEFINE([ENABLE_SSP_CC], 1, [Define if SSP C support is enabled.])
+  fi
+])
+
+if test "$GCC" = "yes"; then
+	# We are using the GNU C compiler. Good!
+	CFLAGS="$CFLAGS -pipe -W -Wall -Wpointer-arith -Wstrict-prototypes"
+
+	GCC_STACK_PROTECT_CC
+fi
+
+case "$host_os" in
+	hpux*)
+		# This is HP/UX, we need to define _XOPEN_SOURCE_EXTENDED
+		# (tested with HP/UX 11.11)
+		CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED"
+		;;
+esac
+
+# Add additional CFLAGS, eventually specified on the command line:
+test -n "$CFLAGS_ADD" && CFLAGS="$CFLAGS $CFLAGS_ADD"
+
+CFLAGS="$CFLAGS -DSYSCONFDIR='\"\$(sysconfdir)\"'"
+
+# -- Headers --
+
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_HEADER_TIME
+
+# Required header files
+AC_CHECK_HEADERS([ \
+	fcntl.h netdb.h netinet/in.h netinet/in_systm.h stdlib.h string.h \
+	strings.h sys/socket.h sys/time.h unistd.h \
+	],,AC_MSG_ERROR([required C header missing!]))
+
+# Optional header files
+AC_CHECK_HEADERS_ONCE([ \
+	arpa/inet.h inttypes.h malloc.h netinet/ip.h stdbool.h stddef.h \
+	stdint.h varargs.h \
+	])
+
+# -- Datatypes --
+
+AC_MSG_CHECKING(whether socklen_t exists)
+AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+	],[
+	socklen_t a, b;
+	a = 2; b = 4; a += b;
+	],[
+	AC_DEFINE(HAVE_socklen_t) AC_MSG_RESULT(yes)
+	],[
+	AC_MSG_RESULT(no)
+])
+
+AC_TYPE_PID_T
+AC_TYPE_SIGNAL
+AC_TYPE_SIZE_T
+AC_TYPE_SSIZE_T
+AC_TYPE_UID_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT8_T
+
+AC_CHECK_MEMBER([struct sockaddr_in.sin_len], AC_DEFINE(HAVE_sockaddr_in_len),,
+ [#include <arpa/inet.h>])
+
+# -- Libraries --
+
+# memmove: A/UX libUTIL
+AC_SEARCH_LIBS([memmove], [UTIL], [], [
+	AC_MSG_ERROR([unable to find the memmove() function])
+])
+# gethostbyname: Solaris libnsl
+AC_SEARCH_LIBS([gethostbyname], [bind nsl network], [], [
+	AC_MSG_ERROR([unable to find the gethostbyname() function])
+])
+# bind: SVR4 libsocket
+AC_SEARCH_LIBS([bind], [socket network], [], [
+	AC_MSG_ERROR([unable to find the bind() function])
+])
+
+# -- Functions --
+
+AC_FUNC_FORK
+AC_FUNC_STRFTIME
+
+# Required functions
+AC_CHECK_FUNCS([ \
+	alarm dup2 endpwent gethostbyaddr gethostbyname gethostname \
+	gettimeofday inet_ntoa memmove memset setsid socket strcasecmp \
+	strchr strcspn strerror strncasecmp strrchr strspn strstr \
+	],,
+	AC_MSG_ERROR([required function missing!]))
+
+# Optional functions
+AC_CHECK_FUNCS_ONCE([ \
+	gai_strerror getaddrinfo getnameinfo inet_aton sigaction sigprocmask \
+	snprintf vsnprintf strdup strlcpy strlcat strtok_r waitpid])
+
+# -- Configuration options --
+
+# use syslog?
+
+x_syslog_on=no
+AC_ARG_WITH(syslog,
+	AS_HELP_STRING([--without-syslog],
+		       [disable syslog (autodetected by default)]),
+	[	if test "$withval" != "no"; then
+			if test "$withval" != "yes"; then
+				CFLAGS="-I$withval/include $CFLAGS"
+				CPPFLAGS="-I$withval/include $CPPFLAGS"
+				LDFLAGS="-L$withval/lib $LDFLAGS"
+			fi
+			AC_SEARCH_LIBS([syslog], [be], [x_syslog_on=yes], [
+				AC_MSG_ERROR([Can't enable syslog!])
+			])
+		fi
+	],
+	[	AC_SEARCH_LIBS([syslog], [be], [x_syslog_on=yes])
+	]
+)
+if test "$x_syslog_on" = "yes"; then
+	AC_DEFINE(SYSLOG, 1)
+	AC_CHECK_HEADERS(syslog.h,,AC_MSG_ERROR([required C header missing!]))
+fi
+
+# use zlib compression?
+
+x_zlib_on=no
+AC_ARG_WITH(zlib,
+	AS_HELP_STRING([--without-zlib],
+		       [disable zlib compression (autodetected by default)]),
+	[	if test "$withval" != "no"; then
+			if test "$withval" != "yes"; then
+				CFLAGS="-I$withval/include $CFLAGS"
+				CPPFLAGS="-I$withval/include $CPPFLAGS"
+				LDFLAGS="-L$withval/lib $LDFLAGS"
+			fi
+			AC_CHECK_LIB(z, deflate)
+			AC_CHECK_FUNCS(deflate, x_zlib_on=yes,
+				AC_MSG_ERROR([Can't enable zlib!])
+			)
+		fi
+	],
+	[	AC_CHECK_LIB(z, deflate)
+		AC_CHECK_FUNCS(deflate, x_zlib_on=yes)
+	]
+)
+if test "$x_zlib_on" = "yes"; then
+	AC_DEFINE(ZLIB, 1)
+	AC_CHECK_HEADERS(zlib.h,,AC_MSG_ERROR([required C header missing!]))
+fi
+
+# detect which IO API to use:
+
+x_io_backend=none
+
+AC_ARG_WITH(select,
+	AS_HELP_STRING([--without-select],
+		       [disable select IO support (autodetected by default)]),
+	[	if test "$withval" != "no"; then
+			if test "$withval" != "yes"; then
+				CFLAGS="-I$withval/include $CFLAGS"
+				CPPFLAGS="-I$withval/include $CPPFLAGS"
+				LDFLAGS="-L$withval/lib $LDFLAGS"
+			fi
+			AC_CHECK_FUNCS(select, x_io_select=yes,
+				AC_MSG_ERROR([Can't enable select IO support!])
+			)
+		fi
+	],
+	[
+		AC_CHECK_FUNCS(select, x_io_select=yes)
+	]
+)
+
+AC_ARG_WITH(poll,
+	AS_HELP_STRING([--without-poll],
+		       [disable poll support (autodetected by default)]),
+	[	if test "$withval" != "no"; then
+			if test "$withval" != "yes"; then
+				CFLAGS="-I$withval/include $CFLAGS"
+				CPPFLAGS="-I$withval/include $CPPFLAGS"
+				LDFLAGS="-L$withval/lib $LDFLAGS"
+			fi
+			AC_CHECK_FUNCS(poll, [
+				AC_CHECK_HEADERS(poll.h,
+					x_io_backend=poll\(\),
+					AC_MSG_ERROR(
+					     [Can't enable poll IO support!])
+				)
+			], [
+				AC_MSG_ERROR([Can't enable poll IO support!])
+			])
+		fi
+	],
+	[
+		AC_CHECK_FUNCS(poll, [
+			AC_CHECK_HEADERS(poll.h, x_io_backend=poll\(\))
+		])
+	]
+)
+
+AC_ARG_WITH(devpoll,
+	AS_HELP_STRING([--without-devpoll],
+		       [disable /dev/poll IO support (autodetected by default)]),
+	[	if test "$withval" != "no"; then
+			if test "$withval" != "yes"; then
+				CFLAGS="-I$withval/include $CFLAGS"
+				CPPFLAGS="-I$withval/include $CPPFLAGS"
+				LDFLAGS="-L$withval/lib $LDFLAGS"
+			fi
+
+				AC_CHECK_HEADERS(sys/devpoll.h,,AC_MSG_ERROR([required C header missing!]))
+		fi
+	],
+	[
+		AC_CHECK_HEADERS(sys/devpoll.h, x_io_backend=/dev/poll)
+	]
+)
+
+AC_ARG_WITH(epoll,
+	AS_HELP_STRING([--without-epoll],
+		       [disable epoll IO support (autodetected by default)]),
+	[	if test "$withval" != "no"; then
+			if test "$withval" != "yes"; then
+				CFLAGS="-I$withval/include $CFLAGS"
+				CPPFLAGS="-I$withval/include $CPPFLAGS"
+				LDFLAGS="-L$withval/lib $LDFLAGS"
+			fi
+			AC_CHECK_FUNCS(epoll_create, x_io_epoll=yes,
+				AC_MSG_ERROR([Can't enable epoll IO support!])
+			)
+		fi
+	],
+	[
+		AC_CHECK_FUNCS(epoll_create, x_io_epoll=yes)
+	]
+)
+
+AC_ARG_WITH(kqueue,
+	AS_HELP_STRING([--without-kqueue],
+		       [disable kqueue IO support (autodetected by default)]),
+	[	if test "$withval" != "no"; then
+			if test "$withval" != "yes"; then
+				CFLAGS="-I$withval/include $CFLAGS"
+				CPPFLAGS="-I$withval/include $CPPFLAGS"
+				LDFLAGS="-L$withval/lib $LDFLAGS"
+			fi
+			AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue\(\),
+				AC_MSG_ERROR([Can't enable kqueue IO support!])
+			)
+		fi
+	],
+	[
+		AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue\(\))
+	]
+)
+
+if test "$x_io_epoll" = "yes" -a "$x_io_select" = "yes"; then
+	# when epoll() and select() are available, we'll use both!
+	x_io_backend="epoll(), select()"
+else
+	if test "$x_io_epoll" = "yes"; then
+		# we prefere epoll() if it is available
+		x_io_backend="epoll()"
+	else
+		if test "$x_io_select" = "yes" -a "$x_io_backend" = "none"; then
+			# we'll use select, when available and no "better"
+			# interface has been detected ...
+			x_io_backend="select()"
+		fi
+	fi
+fi
+
+if test "$x_io_backend" = "none"; then
+	AC_MSG_ERROR([No useable IO API activated/found!?])
+fi
+
+# use SSL?
+
+AC_ARG_WITH(openssl,
+	AS_HELP_STRING([--with-openssl],
+		       [enable SSL support using OpenSSL]),
+	[	if test "$withval" != "no"; then
+			if test "$withval" != "yes"; then
+				CFLAGS="-I$withval/include $CFLAGS"
+				CPPFLAGS="-I$withval/include $CPPFLAGS"
+				LDFLAGS="-L$withval/lib $LDFLAGS"
+			fi
+			AC_CHECK_LIB(crypto, BIO_s_mem)
+			AC_CHECK_LIB(ssl, SSL_library_init)
+			AC_CHECK_FUNCS(SSL_library_init, x_ssl_openssl=yes,
+				AC_MSG_ERROR([Can't enable openssl])
+			)
+		fi
+	]
+)
+
+AC_ARG_WITH(gnutls,
+	AS_HELP_STRING([--with-gnutls],
+		       [enable SSL support using gnutls]),
+	[	if test "$withval" != "no"; then
+			if test "$withval" != "yes"; then
+				CFLAGS="-I$withval/include $CFLAGS"
+				CPPFLAGS="-I$withval/include $CPPFLAGS"
+				LDFLAGS="-L$withval/lib $LDFLAGS"
+			fi
+			AC_CHECK_LIB(gnutls, gnutls_global_init)
+			AC_CHECK_FUNCS(gnutls_global_init, x_ssl_gnutls=yes,
+				AC_MSG_ERROR([Can't enable gnutls])
+			)
+		fi
+	]
+)
+
+x_ssl_lib="no"
+if test "$x_ssl_gnutls" = "yes"; then
+	if test "$x_ssl_openssl" = "yes";then
+		AC_MSG_ERROR([Cannot enable both gnutls and openssl])
+	fi
+	x_ssl_lib=gnutls
+fi
+if test "$x_ssl_openssl" = "yes"; then
+	x_ssl_lib=openssl
+fi
+
+# use TCP wrappers?
+
+x_tcpwrap_on=no
+AC_ARG_WITH(tcp-wrappers,
+	AS_HELP_STRING([--with-tcp-wrappers],
+		       [enable TCP wrappers support]),
+	[	if test "$withval" != "no"; then
+			if test "$withval" != "yes"; then
+				CFLAGS="-I$withval/include $CFLAGS"
+				CPPFLAGS="-I$withval/include $CPPFLAGS"
+				LDFLAGS="-L$withval/lib $LDFLAGS"
+			fi
+			AC_MSG_CHECKING(for hosts_access)
+			LIBS="-lwrap $LIBS"
+			AC_TRY_LINK([
+#include <tcpd.h>
+int allow_severity = 0;
+int deny_severity = 0;
+				],[
+				tcpd_warn("link test");
+				],[
+				AC_MSG_RESULT(yes)
+				AC_DEFINE(TCPWRAP, 1)
+				x_tcpwrap_on=yes
+				],[
+				AC_MSG_RESULT(no)
+				AC_MSG_ERROR([Can't enable TCP wrappers!])
+			])
+		fi
+	]
+)
+
+# do IDENT requests using libident?
+
+x_identauth_on=no
+AC_ARG_WITH(ident,
+	AS_HELP_STRING([--with-ident],
+		       [enable "IDENT" ("AUTH") protocol support]),
+	[	if test "$withval" != "no"; then
+			if test "$withval" != "yes"; then
+				CFLAGS="-I$withval/include $CFLAGS"
+				CPPFLAGS="-I$withval/include $CPPFLAGS"
+				LDFLAGS="-L$withval/lib $LDFLAGS"
+			fi
+			AC_CHECK_LIB(ident, ident_id)
+			AC_CHECK_FUNCS(ident_id, x_identauth_on=yes,
+				AC_MSG_ERROR([Can't enable IDENT support!])
+			)
+		fi
+	]
+)
+if test "$x_identauth_on" = "yes"; then
+	AC_DEFINE(IDENTAUTH, 1)
+	AC_CHECK_HEADERS(ident.h,,AC_MSG_ERROR([required C header missing!]))
+fi
+
+# compile in PAM support?
+
+x_pam_on=no
+AC_ARG_WITH(pam,
+	AS_HELP_STRING([--with-pam],
+		       [enable user authentication using PAM]),
+	[	if test "$withval" != "no"; then
+			if test "$withval" != "yes"; then
+				CFLAGS="-I$withval/include $CFLAGS"
+				CPPFLAGS="-I$withval/include $CPPFLAGS"
+				LDFLAGS="-L$withval/lib $LDFLAGS"
+			fi
+			AC_CHECK_LIB(pam, pam_authenticate)
+			AC_CHECK_FUNCS(pam_authenticate, x_pam_on=yes,
+				AC_MSG_ERROR([Can't enable PAM support!])
+			)
+		fi
+	]
+)
+if test "$x_pam_on" = "yes"; then
+	AC_DEFINE(PAM, 1)
+	AC_CHECK_HEADERS(security/pam_appl.h,pam_ok=yes)
+	if test "$pam_ok" != "yes"; then
+		AC_CHECK_HEADERS(pam/pam_appl.h,pam_ok=yes,
+			AC_MSG_ERROR([required C header missing!]))
+	fi
+fi
+
+# compile in IRC+ protocol support?
+
+x_ircplus_on=yes
+AC_ARG_ENABLE(ircplus,
+	AS_HELP_STRING([--disable-ircplus],
+		       [disable IRC+ protocol]),
+	if test "$enableval" = "no"; then x_ircplus_on=no; fi
+)
+if test "$x_ircplus_on" = "yes"; then
+	AC_DEFINE(IRCPLUS, 1)
+
+	# Compile in iconv support?
+	# We only check for it when IRC+ is enabled, because the IRC+ command
+	# CHARCONV is the only function depending on it.
+	x_iconv_on=no
+	AC_ARG_WITH(iconv,
+		[  --with-iconv            enable character conversation using libiconv],
+		[ if test "$withval" != "no"; then
+			if test "$withval" != "yes"; then
+				CFLAGS="-I$withval/include $CFLAGS"
+				CPPFLAGS="-I$withval/include $CPPFLAGS"
+				LDFLAGS="-L$withval/lib $LDFLAGS"
+			fi
+			AC_CHECK_LIB(iconv, iconv_open)
+			AC_CHECK_FUNCS(iconv_open, x_iconv_on=yes,
+				AC_MSG_ERROR([Can't enable libiconv support!])
+			)
+		  fi
+		]
+	)
+	if test "$x_iconv_on" = "yes"; then
+		AC_DEFINE(ICONV, 1)
+	fi
+fi
+
+# enable support for IPv6?
+x_ipv6_on=no
+AC_ARG_ENABLE(ipv6,
+	AS_HELP_STRING([--enable-ipv6],
+		       [enable IPv6 protocol support]),
+	if test "$enableval" = "yes"; then x_ipv6_on=yes; fi
+)
+if test "$x_ipv6_on" = "yes"; then
+	# getaddrinfo() and getnameinfo() are optional when not compiling
+	# with IPv6 support, but are required for IPv6 to work!
+	AC_CHECK_FUNCS([ \
+		getaddrinfo getnameinfo \
+		],,AC_MSG_ERROR([required function missing for IPv6 support!]))
+	AC_DEFINE(WANT_IPV6, 1)
+fi
+
+# compile in IRC "sniffer"?
+
+x_sniffer_on=no; x_debug_on=no
+AC_ARG_ENABLE(sniffer,
+	AS_HELP_STRING([--enable-sniffer],
+		       [enable IRC traffic sniffer (enables debug mode)]),
+	if test "$enableval" = "yes"; then
+		AC_DEFINE(SNIFFER, 1)
+		x_sniffer_on=yes; x_debug_on=yes
+	fi
+)
+
+# enable additional debugging code?
+
+AC_ARG_ENABLE(debug,
+	AS_HELP_STRING([--enable-debug],
+		       [show additional debug output]),
+	if test "$enableval" = "yes"; then x_debug_on=yes; fi
+)
+if test "$x_debug_on" = "yes"; then
+	AC_DEFINE(DEBUG, 1)
+	test "$GCC" = "yes" && CFLAGS="-pedantic $CFLAGS"
+	AC_CHECK_FUNCS(mtrace)
+fi
+
+# enable "strict RFC rules"?
+
+x_strict_rfc_on=no
+AC_ARG_ENABLE(strict-rfc,
+	AS_HELP_STRING([--enable-strict-rfc],
+		       [strict RFC conformance -- may break clients!]),
+	if test "$enableval" = "yes"; then
+		AC_DEFINE(STRICT_RFC, 1)
+		x_strict_rfc_on=yes
+	fi
+)
+
+# -- Definitions --
+
+AC_DEFINE_UNQUOTED(HOST_CPU, "$host_cpu" )
+AC_DEFINE_UNQUOTED(HOST_VENDOR, "$host_vendor" )
+AC_DEFINE_UNQUOTED(HOST_OS, "$host_os" )
+
+# Add additional CFLAGS, eventually specified on the command line, but after
+# running this configure script. Useful for "-Werror" for example.
+test -n "$CFLAGS_END" && CFLAGS="$CFLAGS $CFLAGS_END"
+
+# -- Generate files --
+
+AC_CONFIG_FILES([ \
+	Makefile \
+	contrib/Debian/Makefile \
+	contrib/MacOSX/Makefile \
+	contrib/MacOSX/ngIRCd.pmdoc/Makefile \
+	contrib/MacOSX/ngIRCd.xcodeproj/Makefile \
+	contrib/Makefile \
+	doc/Makefile \
+	doc/src/Makefile \
+	man/Makefile \
+	src/ipaddr/Makefile \
+	src/Makefile \
+	src/ngircd/Makefile \
+	src/portab/Makefile \
+	src/testsuite/Makefile \
+	src/tool/Makefile \
+])
+
+AC_OUTPUT
+
+type dpkg >/dev/null 2>&1
+if test $? -eq 0; then
+	# Generate debian/ link if the dpkg command exists
+	# (read: if we are running on a debian compatible system)
+	echo "creating Debian-specific links ..."
+	test -f debian/rules || ln -s contrib/Debian debian
+fi
+
+# -- Result --
+
+echo
+echo "ngIRCd $PACKAGE_VERSION has been configured with the following options:"
+echo
+
+# Someone please show me a better way :)  [borrowed by OpenSSH]
+B=`eval echo ${bindir}` ; B=`eval echo ${B}`
+S=`eval echo ${sbindir}` ; S=`eval echo ${S}`
+C=`eval echo ${sysconfdir}` ; C=`eval echo ${C}`
+M=`eval echo ${mandir}` ; M=`eval echo ${M}`
+D=`eval echo ${docdir}` ; D=`eval echo ${D}`
+
+echo "               Host: ${host}"
+echo "           Compiler: ${CC}"
+test -n "$CFLAGS"	&& echo "     Compiler flags: ${CFLAGS}"
+test -n "$CPPFLAGS"	&& echo " Preprocessor flags: ${CPPFLAGS}"
+test -n "$LDFLAGS"	&& echo "       Linker flags: ${LDFLAGS}"
+test -n "$LIBS"		&& echo "          Libraries: ${LIBS}"
+echo
+echo "    'ngircd' binary: $S"
+echo " Configuration file: $C"
+echo "       Manual pages: $M"
+echo "      Documentation: $D"
+echo
+
+echo $ECHO_N "     Syslog support: $ECHO_C"
+test "$x_syslog_on" = "yes" \
+	&& echo $ECHO_N "yes   $ECHO_C" \
+	|| echo $ECHO_N "no    $ECHO_C"
+echo $ECHO_N "  Enable debug code: $ECHO_C"
+test "$x_debug_on" = "yes" \
+	&& echo "yes" \
+	|| echo "no"
+
+echo $ECHO_N "   zlib compression: $ECHO_C"
+test "$x_zlib_on" = "yes" \
+	&& echo $ECHO_N "yes   $ECHO_C" \
+	|| echo $ECHO_N "no    $ECHO_C"
+echo $ECHO_N "        IRC sniffer: $ECHO_C"
+test "$x_sniffer_on" = "yes" \
+	&& echo "yes" \
+	|| echo "no"
+
+echo $ECHO_N "   Use TCP Wrappers: $ECHO_C"
+test "$x_tcpwrap_on" = "yes" \
+	&& echo $ECHO_N "yes   $ECHO_C" \
+	|| echo $ECHO_N "no    $ECHO_C"
+echo $ECHO_N "    Strict RFC mode: $ECHO_C"
+test "$x_strict_rfc_on" = "yes" \
+	&& echo "yes" \
+	|| echo "no"
+
+echo $ECHO_N "      IDENT support: $ECHO_C"
+test "$x_identauth_on" = "yes" \
+	&& echo $ECHO_N "yes   $ECHO_C" \
+	|| echo $ECHO_N "no    $ECHO_C"
+echo $ECHO_N "      IRC+ protocol: $ECHO_C"
+test "$x_ircplus_on" = "yes" \
+	&& echo "yes" \
+	|| echo "no"
+
+echo $ECHO_N "      IPv6 protocol: $ECHO_C"
+test "$x_ipv6_on" = "yes" \
+	&& echo $ECHO_N "yes   $ECHO_C" \
+	|| echo $ECHO_N "no    $ECHO_C"
+echo $ECHO_N "        I/O backend: $ECHO_C"
+	echo "\"$x_io_backend\""
+
+echo $ECHO_N "        PAM support: $ECHO_C"
+test "$x_pam_on" = "yes" \
+	&& echo $ECHO_N "yes   $ECHO_C" \
+	|| echo $ECHO_N "no    $ECHO_C"
+echo $ECHO_N "        SSL support: $ECHO_C"
+echo "$x_ssl_lib"
+
+echo $ECHO_N "   libiconv support: $ECHO_C"
+	echo "$x_iconv_on"
+
+echo
+
+if ! grep "^AUTOMAKE_OPTIONS = ../portab/ansi2knr" src/ngircd/Makefile.am >/dev/null 2>&1; then
+	echo "WARNING:"
+	echo "This GNU automake generated build system does not support \"de-ANSI-fication\","
+	echo "therefore don't use it to generate \"official\" distribution archives!"
+	echo "(Most probably you want to use GNU automake 1.11.x for this purpose ...)"
+	echo
+fi
+
+# -eof-

+ 0 - 495
contrib/Anope/0001-Revert-Removed-ngircd.patch

@@ -1,496 +0,0 @@
-From bc5023fdba8091ab7eee29fe0deeca6843159743 Mon Sep 17 00:00:00 2001
-From: Alexander Barton <alex@barton.de>
-Date: Mon, 16 May 2011 18:23:01 +0200
-Subject: [PATCH 1/2] Revert "Removed ngircd as we've decided not to support it at this time"
-
-This reverts commit 605b5d57171d2f0fac56ee2ee3e1b1bbdadeb24f and re-enables
-the ngIRCd protocol module for Anope.
----
- modules/protocol/ngircd.cpp |  475 +++++++++++++++++++++++++++++++++++++++++++
- 1 files changed, 475 insertions(+), 0 deletions(-)
- create mode 100644 modules/protocol/ngircd.cpp
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-new file mode 100644
-index 0000000..6e1f21f
---- /dev/null
-+++ b/modules/protocol/ngircd.cpp
-@@ -0,0 +1,475 @@
-+/* ngIRCd IRCD functions
-+ *
-+ * (C) 2003-2011 Anope Team
-+ * Contact us at team@anope.org
-+ *
-+ * Please read COPYING and README for further details.
-+ *
-+ * Based on the original code of Epona by Lara.
-+ * Based on the original code of Services by Andy Church.
-+ */
-+
-+#include "services.h"
-+#include "modules.h"
-+
-+IRCDVar myIrcd[] = {
-+	{"ngIRCd",	/* ircd name */
-+	 "+oi",		/* Modes used by pseudoclients */
-+	 0,		/* SVSNICK */
-+	 0,		/* Vhost */
-+	 0,		/* Supports SNlines */
-+	 0,		/* Supports SQlines */
-+	 0,		/* Supports SZlines */
-+	 0,		/* Join 2 Message */
-+	 0,		/* Chan SQlines */
-+	 1,		/* Quit on Kill */
-+	 0,		/* vidents */
-+	 0,		/* svshold */
-+	 0,		/* time stamp on mode */
-+	 0,		/* UMODE */
-+	 0,		/* O:LINE */
-+	 0,		/* No Knock requires +i */
-+	 0,		/* Can remove User Channel Modes with SVSMODE */
-+	 0,		/* Sglines are not enforced until user reconnects */
-+	 0,		/* ts6 */
-+	 "$",		/* TLD Prefix for Global */
-+	 20,		/* Max number of modes we can send per line */
-+	 0,		/* IRCd sends a SSL users certificate fingerprint */
-+	 }
-+	,
-+	{NULL}
-+};
-+
-+/* PASS */
-+class ngIRCdProto : public IRCDProto
-+{
-+	void SendAkill(User *u, const XLine *x)
-+	{
-+		if (SGLine && u == NULL)
-+			for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end();)
-+			{
-+				u = it->second;
-+				++it;
-+				if (SGLine->Check(u) != NULL)
-+					break;
-+			}
-+	}
-+
-+	void SendAkillDel(const XLine*) { }
-+
-+	void SendGlobopsInternal(const BotInfo *source, const Anope::string &buf)
-+	{
-+		send_cmd(source ? source->nick : Config->ServerName, "WALLOPS :%s", buf.c_str());
-+	}
-+
-+	void SendJoin(BotInfo *user, Channel *c, const ChannelStatus *status)
-+	{
-+		send_cmd(user->nick, "JOIN %s", c->name.c_str());
-+		if (status)
-+			for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
-+				if (status->HasFlag(ModeManager::ChannelModes[i]->Name))
-+					c->SetMode(user, ModeManager::ChannelModes[i], user->nick, false);
-+	}
-+
-+	void SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf)
-+	{
-+		send_cmd(source ? source->nick : Config->ServerName, "KILL %s :%s", user->nick.c_str(), buf.c_str());
-+	}
-+
-+	/* SERVER name hop descript */
-+	void SendServer(const Server *server)
-+	{
-+		send_cmd("", "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str());
-+	}
-+
-+	void SendConnect()
-+	{
-+		send_cmd("", "PASS %s 0210-IRC+ Anope|%s:CLHSo P", uplink_server->password.c_str(), Anope::VersionShort().c_str());
-+		/* Make myself known to myself in the serverlist */
-+		SendServer(Me);
-+		/* finish the enhanced server handshake and register the connection */
-+		this->SendNumeric(Config->ServerName, 376, "*", ":End of MOTD command");
-+	}
-+
-+	// Received: :dev.anope.de NICK DukeP 1 ~DukePyro p57ABF9C9.dip.t-dialin.net 1 +i :DukePyrolator
-+	void SendClientIntroduction(const User *u, const Anope::string &modes)
-+	{
-+		EnforceQlinedNick(u->nick, "");
-+		send_cmd(Config->ServerName, "NICK %s 1 %s %s 1 %s :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), modes.c_str(), u->realname.c_str());
-+	}
-+
-+	void SendPartInternal(const BotInfo *bi, const Channel *chan, const Anope::string &buf)
-+	{
-+		if (!buf.empty())
-+			send_cmd(bi->nick, "PART %s :%s", chan->name.c_str(), buf.c_str());
-+		else
-+			send_cmd(bi->nick, "PART %s", chan->name.c_str());
-+	}
-+
-+	void SendModeInternal(const BotInfo *bi, const Channel *dest, const Anope::string &buf)
-+	{
-+		send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", dest->name.c_str(), buf.c_str());
-+	}
-+
-+	void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf)
-+	{
-+		send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", u->nick.c_str(), buf.c_str());
-+	}
-+
-+	void SendKickInternal(const BotInfo *bi, const Channel *chan, const User *user, const Anope::string &buf)
-+	{
-+		if (!buf.empty())
-+			send_cmd(bi->nick, "KICK %s %s :%s", chan->name.c_str(), user->nick.c_str(), buf.c_str());
-+		else
-+			send_cmd(bi->nick, "KICK %s %s", chan->name.c_str(), user->nick.c_str());
-+	}
-+
-+	void SendNoticeChanopsInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf)
-+	{
-+		send_cmd(source ? source->nick : Config->s_ChanServ, "NOTICE @%s :%s", dest->name.c_str(), buf.c_str());
-+	}
-+
-+	/* INVITE */
-+	void SendInvite(BotInfo *source, const Anope::string &chan, const Anope::string &nick)
-+	{
-+		send_cmd(source->nick, "INVITE %s %s", nick.c_str(), chan.c_str());
-+	}
-+
-+	void SendChannel(Channel *c)
-+	{
-+		Anope::string mlock_modes = get_mlock_modes(c->ci, true);
-+		if (mlock_modes.empty())
-+			mlock_modes = "+";
-+		send_cmd(Config->ServerName, "CHANINFO %s %s", c->name.c_str(), mlock_modes.c_str());
-+	}
-+	void SendTopic(BotInfo *bi, Channel *c)
-+	{
-+		send_cmd(bi->nick, "TOPIC %s :%s", c->name.c_str(), c->topic.c_str());
-+	}
-+};
-+
-+class ngIRCdIRCdMessage : public IRCdMessage
-+{
-+ public:
-+	bool OnSJoin(const Anope::string&, const std::vector<Anope::string>&) { return false; }
-+
-+	/*
-+	 * Received: :dev.anope.de MODE #anope +b *!*@*aol*
-+	 */
-+	bool OnMode(const Anope::string &source, const std::vector<Anope::string> &params)
-+	{
-+		if (params.size() < 2)
-+			return true;
-+
-+		Anope::string modes = params[1];
-+		for (unsigned i = 2; i < params.size(); ++i)
-+			modes += " " + params[i];
-+
-+		if (params[0][0] == '#' || params[0][0] == '&')
-+			do_cmode(source, params[0], modes, "");
-+		else
-+			do_umode(params[0], params[1]);
-+
-+		return true;
-+	}
-+
-+	/*
-+	  Received: :DukeP_ NICK :test2
-+	  Received: :dev.anope.de NICK DukeP_ 1 ~DukePyro ip-2-201-236-154.web.vodafone.de 1 + :DukePyrolator
-+	  source = nickname on nickchange, servername on newuser
-+	  params[0] = nick
-+	  params[1] = <unknown>
-+	  params[2] = username
-+	  params[3] = host
-+	  params[4] = <unknown>
-+	  params[5] = modes
-+	  params[6] = info
-+	*/
-+	bool OnNick(const Anope::string &source, const std::vector<Anope::string> &params)
-+	{
-+		if (params.size() == 1)
-+		{
-+			// we have a nickchange
-+			do_nick(source, params[0], "", "", "", "", Anope::CurTime, "", "", "", "");
-+		}
-+		else if (params.size() == 7)
-+		{
-+			// a new user is connecting to the network
-+			User *user = do_nick("", params[0], params[2], params[3], source, params[6], Anope::CurTime, "", "", "", params[5]);
-+			if (user)
-+				validate_user(user);
-+		}
-+		else
-+		{
-+			Log() << "Received NICK with invalid number of parameters. source = " << source << "param[0] = " << params[0] << "params.size() = " << params.size();
-+		}
-+		return true;
-+	}
-+
-+	bool OnServer(const Anope::string &source, const std::vector<Anope::string> &params)
-+	{
-+		if (params.size() == 3)
-+			do_server("", params[0], 0, params[2], params[1]);
-+		else
-+			do_server(source, params[0], params[1].is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0, params[3], params[2]);
-+		return true;
-+	}
-+
-+	bool OnTopic(const Anope::string &source, const std::vector<Anope::string> &params)
-+	{
-+		Channel *c = findchan(params[0]);
-+		if (!c)
-+		{
-+			Log() << "TOPIC for nonexistant channel " << params[0];
-+			return true;
-+		}
-+
-+		c->ChangeTopicInternal(source, params[1]);
-+		return true;
-+	}
-+
-+	/*
-+	 * <@po||ux> DukeP: RFC 2813, 4.2.1: the JOIN command on server-server links
-+	 * separates the modes ("o") with ASCII 7, not space. And you can't see ASCII 7.
-+	 *
-+	 * if a user joins a new channel, the ircd sends <channelname>\7<umode>
-+	 */
-+	bool OnJoin (const Anope::string &source, const std::vector<Anope::string> &params)
-+	{
-+		if (!params.empty())
-+		{
-+			size_t pos = params[0].find('\7');
-+			if (pos != Anope::string::npos)
-+			{
-+				Anope::string channel = params[0].substr(0, pos);
-+				Anope::string mode = '+' + params[0].substr(pos, params[0].length()) + " " + source;
-+				do_join(source, channel, "");
-+				do_cmode(source, channel, mode, "");
-+			}
-+			else
-+				do_join(source, params[0], "");
-+		}
-+		return true;
-+	}
-+};
-+
-+/*
-+ * CHANINFO <chan> +<modes>
-+ * CHANINFO <chan> +<modes> :<topic>
-+ * CHANINFO <chan> +<modes> <key> <limit> :<topic>
-+ */
-+bool event_chaninfo(const Anope::string &source, const std::vector<Anope::string> &params)
-+{
-+
-+	Channel *c = findchan(params[0]);
-+	if (!c)
-+		c = new Channel(params[0]);
-+
-+	Anope::string modes = params[1];
-+	
-+	if (params.size() == 3)
-+	{
-+		c->ChangeTopicInternal(source, params[2], Anope::CurTime);
-+	} 
-+	else if (params.size() == 5)
-+	{
-+		for (size_t i = 0, end = params[1].length(); i < end; ++i)
-+		{
-+			switch(params[1][i])
-+			{
-+				case 'k':
-+					modes += " " + params[2];
-+					continue;
-+				case 'l':
-+					modes += " " + params[3];
-+					continue;
-+			}
-+		}
-+		c->ChangeTopicInternal(source, params[4], Anope::CurTime);
-+	}
-+
-+	c->SetModesInternal(NULL, modes);
-+
-+	return true;
-+}
-+
-+/*
-+ * Received: :dev.anope.de NJOIN #test :DukeP2,@DukeP
-+ */
-+bool event_njoin(const Anope::string &source, const std::vector<Anope::string> &params)
-+{
-+	Channel *c = findchan(params[0]);
-+	commasepstream sep(params[1]);
-+	Anope::string buf;
-+
-+	if (!c)
-+	{
-+		c = new Channel(params[0], Anope::CurTime);
-+		c->SetFlag(CH_SYNCING);
-+	}
-+	
-+	while (sep.GetToken(buf))
-+	{
-+		std::list<ChannelMode *> Status;
-+		char ch;
-+
-+		/* Get prefixes from the nick */
-+		while ((ch = ModeManager::GetStatusChar(buf[0])))
-+		{
-+			buf.erase(buf.begin());
-+			ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
-+			if (!cm)
-+			{
-+				Log() << "Received unknown mode prefix " << ch << " in NJOIN string.";
-+				continue;
-+			}
-+			Status.push_back(cm);
-+		}
-+		User *u = finduser(buf);
-+		if (!u)
-+		{
-+			Log(LOG_DEBUG) << "NJOIN for nonexistant user " << buf << " on " << c->name;
-+			continue;
-+		}
-+
-+		EventReturn MOD_RESULT;
-+		FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c));
-+
-+		/* Add the user to the Channel */
-+		c->JoinUser(u);
-+
-+		/* Update their status internally on the channel
-+		 * This will enforce secureops etc on the user
-+		 */
-+		for (std::list<ChannelMode *>::iterator it = Status.begin(), it_end = Status.end(); it != it_end; ++it)
-+			c->SetModeInternal(*it, buf);
-+		/* Now set whatever modes this user is allowed to have on the channel */
-+		chan_set_correct_modes(u, c, 1);
-+
-+		/* Check to see if modules want the user to join, if they do
-+		 * check to see if they are allowed to join (CheckKick will kick/ban them)
-+		 * Don't trigger OnJoinChannel event then as the user will be destroyed
-+		 */
-+		if (MOD_RESULT != EVENT_STOP && c->ci && c->ci->CheckKick(u))
-+			continue;
-+
-+		FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c));
-+	} /* while */
-+
-+	if (c->HasFlag(CH_SYNCING))
-+	{
-+		c->UnsetFlag(CH_SYNCING);
-+		c->Sync();
-+	}
-+
-+	return true;
-+}
-+
-+bool event_kick(const Anope::string &source, const std::vector<Anope::string> &params)
-+{
-+	if (params.size() > 2)
-+		do_kick(source, params[0], params[1], params[2]);
-+	return true;
-+}
-+
-+bool event_pass(const Anope::string &source, const std::vector<Anope::string> &params)
-+{
-+	return true;
-+}
-+
-+bool event_005(const Anope::string &source, const std::vector<Anope::string> &params)
-+{
-+	size_t pos;
-+	Anope::string name, data;
-+	for (unsigned i = 0, end = params.size(); i < end; ++i)
-+	{
-+		pos = params[i].find('=');
-+		if (pos != Anope::string::npos)
-+		{
-+			name = params[i].substr(0, pos);
-+			data = params[i].substr(pos+1, params[i].length());
-+			if (name == "NICKLEN")
-+			{
-+				unsigned newlen = convertTo<unsigned>(data);
-+				if (Config->NickLen != newlen)
-+				{
-+					Log() << "Config->NickLen changed from " << Config->NickLen << " to " << newlen;
-+					Config->NickLen = newlen;
-+				}
-+			}
-+		}
-+	}
-+	return true;
-+}
-+
-+bool event_442(const Anope::string &source, const std::vector<Anope::string> &params)
-+{
-+	return true;
-+}
-+
-+bool event_376(const Anope::string &source, const std::vector<Anope::string> &params)
-+{
-+	return true;
-+}
-+
-+
-+class ProtongIRCd : public Module
-+{
-+	Message message_kick, message_pass, message_njoin, message_chaninfo, message_005, 
-+		message_442, message_376;
-+	
-+	ngIRCdProto ircd_proto;
-+	ngIRCdIRCdMessage ircd_message;
-+
-+	void AddModes()
-+	{
-+		/* Add user modes */
-+		ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a'));
-+		ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i'));
-+		ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o'));
-+		ModeManager::AddUserMode(new UserMode(UMODE_RESTRICTED, 'r'));
-+		ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's'));
-+		ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
-+		ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
-+
-+		/* b/e/I */
-+		ModeManager::AddChannelMode(new ChannelModeBan(CMODE_BAN, 'b'));
-+		ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
-+
-+		/* v/h/o/a/q */
-+		ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
-+		ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
-+
-+		/* Add channel modes */
-+		// channel modes: biIklmnoPstvz
-+		ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
-+		ModeManager::AddChannelMode(new ChannelModeKey('k'));
-+		ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l'));
-+		ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
-+		ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
-+		ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P'));
-+		ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
-+		ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
-+		ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z'));
-+	}
-+
-+ public:
-+	ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator),
-+		message_kick("KICK", event_kick), message_pass("PASS", event_pass),
-+		message_njoin("NJOIN", event_njoin), message_chaninfo("CHANINFO", event_chaninfo),
-+		message_005("005", event_005), message_442("442", event_442), message_376("376", event_376)
-+	{
-+		this->SetAuthor("Anope");
-+		this->SetType(PROTOCOL);
-+		
-+		Capab.SetFlag(CAPAB_QS);
-+
-+		pmodule_ircd_var(myIrcd);
-+		pmodule_ircd_proto(&this->ircd_proto);
-+		pmodule_ircd_message(&this->ircd_message);
-+
-+		this->AddModes();
-+	}
-+};
-+
-+MODULE_INIT(ProtongIRCd)
-1.7.2.5
-

+ 0 - 59
contrib/Anope/0002-ngircd-whitespace-fixes.patch

@@ -1,60 +0,0 @@
-From 1ea1dd2095e63cef34edbebb729edc687f410a96 Mon Sep 17 00:00:00 2001
-From: Alexander Barton <alex@barton.de>
-Date: Mon, 16 May 2011 18:26:56 +0200
-Subject: [PATCH 2/2] ngircd: whitespace fixes
-
----
- modules/protocol/ngircd.cpp |   12 ++++++------
- 1 files changed, 6 insertions(+), 6 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index 6e1f21f..e546d05 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -266,11 +266,11 @@ bool event_chaninfo(const Anope::string &source, const std::vector<Anope::string
- 		c = new Channel(params[0]);
- 
- 	Anope::string modes = params[1];
--	
-+
- 	if (params.size() == 3)
- 	{
- 		c->ChangeTopicInternal(source, params[2], Anope::CurTime);
--	} 
-+	}
- 	else if (params.size() == 5)
- 	{
- 		for (size_t i = 0, end = params[1].length(); i < end; ++i)
-@@ -307,7 +307,7 @@ bool event_njoin(const Anope::string &source, const std::vector<Anope::string> &
- 		c = new Channel(params[0], Anope::CurTime);
- 		c->SetFlag(CH_SYNCING);
- 	}
--	
-+
- 	while (sep.GetToken(buf))
- 	{
- 		std::list<ChannelMode *> Status;
-@@ -415,9 +415,9 @@ bool event_376(const Anope::string &source, const std::vector<Anope::string> &pa
- 
- class ProtongIRCd : public Module
- {
--	Message message_kick, message_pass, message_njoin, message_chaninfo, message_005, 
-+	Message message_kick, message_pass, message_njoin, message_chaninfo, message_005,
- 		message_442, message_376;
--	
-+
- 	ngIRCdProto ircd_proto;
- 	ngIRCdIRCdMessage ircd_message;
- 
-@@ -461,7 +461,7 @@ class ProtongIRCd : public Module
- 	{
- 		this->SetAuthor("Anope");
- 		this->SetType(PROTOCOL);
--		
-+
- 		Capab.SetFlag(CAPAB_QS);
- 
- 		pmodule_ircd_var(myIrcd);
-1.7.2.5
-

+ 0 - 127
contrib/Anope/0003-Update-ngIRCd-protocol-module-for-current-Anope-1.9.patch

@@ -1,128 +0,0 @@
-From d8eddbeaadc7d161865b5342d59748b80266533c Mon Sep 17 00:00:00 2001
-From: DukePyrolator <DukePyrolator@anope.org>
-Date: Mon, 22 Aug 2011 14:53:37 +0200
-Subject: [PATCH 03/16] Update ngIRCd protocol module for current Anope 1.9
- GIT
-
----
- modules/protocol/ngircd.cpp |   37 ++++++++++++++++++-------------------
- 1 files changed, 18 insertions(+), 19 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index e546d05..790b8f4 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -11,6 +11,8 @@
- 
- #include "services.h"
- #include "modules.h"
-+#include "nickserv.h"
-+#include "oper.h"
- 
- IRCDVar myIrcd[] = {
- 	{"ngIRCd",	/* ircd name */
-@@ -45,14 +47,7 @@ class ngIRCdProto : public IRCDProto
- {
- 	void SendAkill(User *u, const XLine *x)
- 	{
--		if (SGLine && u == NULL)
--			for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end();)
--			{
--				u = it->second;
--				++it;
--				if (SGLine->Check(u) != NULL)
--					break;
--			}
-+		// TODO: ADD SOME CODE
- 	}
- 
- 	void SendAkillDel(const XLine*) { }
-@@ -62,13 +57,16 @@ class ngIRCdProto : public IRCDProto
- 		send_cmd(source ? source->nick : Config->ServerName, "WALLOPS :%s", buf.c_str());
- 	}
- 
--	void SendJoin(BotInfo *user, Channel *c, const ChannelStatus *status)
-+	void SendJoin(User *user, Channel *c, const ChannelStatus *status)
- 	{
- 		send_cmd(user->nick, "JOIN %s", c->name.c_str());
- 		if (status)
-+		{
-+			BotInfo *setter = findbot(user->nick);
- 			for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- 				if (status->HasFlag(ModeManager::ChannelModes[i]->Name))
--					c->SetMode(user, ModeManager::ChannelModes[i], user->nick, false);
-+					c->SetMode(setter, ModeManager::ChannelModes[i], user->nick, false);
-+		}
- 	}
- 
- 	void SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf)
-@@ -84,7 +82,7 @@ class ngIRCdProto : public IRCDProto
- 
- 	void SendConnect()
- 	{
--		send_cmd("", "PASS %s 0210-IRC+ Anope|%s:CLHSo P", uplink_server->password.c_str(), Anope::VersionShort().c_str());
-+		send_cmd("", "PASS %s 0210-IRC+ Anope|%s:CLHSo P", Config->Uplinks[CurrentUplink]->password.c_str(), Anope::VersionShort().c_str());
- 		/* Make myself known to myself in the serverlist */
- 		SendServer(Me);
- 		/* finish the enhanced server handshake and register the connection */
-@@ -92,9 +90,11 @@ class ngIRCdProto : public IRCDProto
- 	}
- 
- 	// Received: :dev.anope.de NICK DukeP 1 ~DukePyro p57ABF9C9.dip.t-dialin.net 1 +i :DukePyrolator
--	void SendClientIntroduction(const User *u, const Anope::string &modes)
-+	void SendClientIntroduction(const User *u)
- 	{
--		EnforceQlinedNick(u->nick, "");
-+		Anope::string modes = "+" + u->GetModes();
-+		XLine x(u->nick, "Reserved for services");
-+		ircdproto->SendSQLine(NULL, &x);
- 		send_cmd(Config->ServerName, "NICK %s 1 %s %s 1 %s :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), modes.c_str(), u->realname.c_str());
- 	}
- 
-@@ -126,7 +126,7 @@ class ngIRCdProto : public IRCDProto
- 
- 	void SendNoticeChanopsInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf)
- 	{
--		send_cmd(source ? source->nick : Config->s_ChanServ, "NOTICE @%s :%s", dest->name.c_str(), buf.c_str());
-+		send_cmd(source->nick, "NOTICE @%s :%s", dest->name.c_str(), buf.c_str());
- 	}
- 
- 	/* INVITE */
-@@ -196,8 +196,8 @@ class ngIRCdIRCdMessage : public IRCdMessage
- 		{
- 			// a new user is connecting to the network
- 			User *user = do_nick("", params[0], params[2], params[3], source, params[6], Anope::CurTime, "", "", "", params[5]);
--			if (user)
--				validate_user(user);
-+			if (user && nickserv)
-+				nickserv->Validate(user);
- 		}
- 		else
- 		{
-@@ -433,7 +433,7 @@ class ProtongIRCd : public Module
- 		ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
- 
- 		/* b/e/I */
--		ModeManager::AddChannelMode(new ChannelModeBan(CMODE_BAN, 'b'));
-+		ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b'));
- 		ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
- 
- 		/* v/h/o/a/q */
-@@ -454,13 +454,12 @@ class ProtongIRCd : public Module
- 	}
- 
-  public:
--	ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator),
-+	ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL),
- 		message_kick("KICK", event_kick), message_pass("PASS", event_pass),
- 		message_njoin("NJOIN", event_njoin), message_chaninfo("CHANINFO", event_chaninfo),
- 		message_005("005", event_005), message_442("442", event_442), message_376("376", event_376)
- 	{
- 		this->SetAuthor("Anope");
--		this->SetType(PROTOCOL);
- 
- 		Capab.SetFlag(CAPAB_QS);
- 
-1.7.8.3
-

+ 0 - 92
contrib/Anope/0004-ngircd-Do-PING-PONG-on-server-burst-to-sync-servers.patch

@@ -1,93 +0,0 @@
-From 88b2b14a76b8ee053b1f6ea64139350260590043 Mon Sep 17 00:00:00 2001
-From: DukePyrolator <DukePyrolator@anope.org>
-Date: Mon, 22 Aug 2011 14:55:07 +0200
-Subject: [PATCH 04/16] ngircd: Do PING-PONG on server burst to "sync servers"
-
-Imagine we had three servers, A, B & C linked like so: A<->B<->C:
-
-If Anope is linked to A and B splits from A and then reconnects B
-introduces itself, introduces C, sends EOS for C, introduces B's clients
-introduces C's clients, sends EOS for B. This causes all of C's clients
-to be introduced with their server "not syncing".
-
-We now send a PING immediately when receiving a new server and then
-finish sync once we get a pong back from that server.
----
- modules/protocol/ngircd.cpp |   28 ++++++++++++++++++++++++++--
- 1 files changed, 26 insertions(+), 2 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index 790b8f4..89aecfd 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -108,11 +108,13 @@ class ngIRCdProto : public IRCDProto
- 
- 	void SendModeInternal(const BotInfo *bi, const Channel *dest, const Anope::string &buf)
- 	{
-+Log(LOG_DEBUG) << "SendModeInternal 1";
- 		send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", dest->name.c_str(), buf.c_str());
- 	}
- 
- 	void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf)
- 	{
-+Log(LOG_DEBUG) << "SendModeInternal 2";
- 		send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", u->nick.c_str(), buf.c_str());
- 	}
- 
-@@ -212,6 +214,8 @@ class ngIRCdIRCdMessage : public IRCdMessage
- 			do_server("", params[0], 0, params[2], params[1]);
- 		else
- 			do_server(source, params[0], params[1].is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0, params[3], params[2]);
-+
-+		ircdproto->SendPing(Config->ServerName, params[0]);
- 		return true;
- 	}
- 
-@@ -253,6 +257,25 @@ class ngIRCdIRCdMessage : public IRCdMessage
- 	}
- };
- 
-+/** This is here because:
-+ *
-+ * If we had three servers, A, B & C linked like so: A<->B<->C
-+ * If Anope is linked to A and B splits from A and then reconnects
-+ * B introduces itself, introduces C, sends EOS for C, introduces Bs clients
-+ * introduces Cs clients, sends EOS for B. This causes all of Cs clients to be introduced
-+ * with their server "not syncing". We now send a PING immediately when receiving a new server
-+ * and then finish sync once we get a pong back from that server.
-+ */
-+bool event_pong(const Anope::string &source, const std::vector<Anope::string> &params)
-+{
-+	Server *s = Server::Find(source);
-+	if (s && !s->IsSynced())
-+		s->Sync(false);
-+	return true;
-+}
-+
-+
-+
- /*
-  * CHANINFO <chan> +<modes>
-  * CHANINFO <chan> +<modes> :<topic>
-@@ -416,7 +439,7 @@ bool event_376(const Anope::string &source, const std::vector<Anope::string> &pa
- class ProtongIRCd : public Module
- {
- 	Message message_kick, message_pass, message_njoin, message_chaninfo, message_005,
--		message_442, message_376;
-+		message_442, message_376, message_pong;
- 
- 	ngIRCdProto ircd_proto;
- 	ngIRCdIRCdMessage ircd_message;
-@@ -457,7 +480,8 @@ class ProtongIRCd : public Module
- 	ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL),
- 		message_kick("KICK", event_kick), message_pass("PASS", event_pass),
- 		message_njoin("NJOIN", event_njoin), message_chaninfo("CHANINFO", event_chaninfo),
--		message_005("005", event_005), message_442("442", event_442), message_376("376", event_376)
-+		message_005("005", event_005), message_442("442", event_442), message_376("376", event_376),
-+		message_pong("PONG", event_pong)
- 	{
- 		this->SetAuthor("Anope");
- 
-1.7.8.3
-

+ 0 - 28
contrib/Anope/0005-ngircd-always-prefix-modes-in-CHANINFO-with.patch

@@ -1,29 +0,0 @@
-From 0d83f8f9ca0de651d664eca6f467f36df0417f7d Mon Sep 17 00:00:00 2001
-From: Alexander Barton <alex@barton.de>
-Date: Mon, 22 Aug 2011 14:59:49 +0200
-Subject: [PATCH 05/16] ngircd: always prefix modes in CHANINFO with "+"
-
----
- modules/protocol/ngircd.cpp |    6 ++----
- 1 files changed, 2 insertions(+), 4 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index 89aecfd..3e5beb3 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -139,10 +139,8 @@ Log(LOG_DEBUG) << "SendModeInternal 2";
- 
- 	void SendChannel(Channel *c)
- 	{
--		Anope::string mlock_modes = get_mlock_modes(c->ci, true);
--		if (mlock_modes.empty())
--			mlock_modes = "+";
--		send_cmd(Config->ServerName, "CHANINFO %s %s", c->name.c_str(), mlock_modes.c_str());
-+		Anope::string modes = c->GetModes(true, true);
-+		send_cmd(Config->ServerName, "CHANINFO %s +%s", c->name.c_str(), modes.c_str());
- 	}
- 	void SendTopic(BotInfo *bi, Channel *c)
- 	{
-1.7.8.3
-

+ 0 - 46
contrib/Anope/0006-ngircd-support-user-mode-R-and-channel-mode-R.patch

@@ -1,47 +0,0 @@
-From 1914a36b83b1fc6b4678ef261a1a06eefab9a0ca Mon Sep 17 00:00:00 2001
-From: Alexander Barton <alex@barton.de>
-Date: Fri, 26 Aug 2011 17:51:37 +0200
-Subject: [PATCH 06/16] ngircd: support user mode "R" and channel mode "R"
-
----
- modules/protocol/ngircd.cpp |    7 ++++---
- 1 files changed, 4 insertions(+), 3 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index 3e5beb3..7f4186e 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -449,26 +449,27 @@ class ProtongIRCd : public Module
- 		ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i'));
- 		ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o'));
- 		ModeManager::AddUserMode(new UserMode(UMODE_RESTRICTED, 'r'));
-+		ModeManager::AddUserMode(new UserMode(UMODE_REGISTERED, 'R'));
- 		ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's'));
- 		ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
- 		ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
- 
--		/* b/e/I */
-+		/* Add modes for ban and invite lists */
- 		ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b'));
- 		ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
- 
--		/* v/h/o/a/q */
-+		/* Add channel user modes */
- 		ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
- 		ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
- 
- 		/* Add channel modes */
--		// channel modes: biIklmnoPstvz
- 		ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
- 		ModeManager::AddChannelMode(new ChannelModeKey('k'));
- 		ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l'));
- 		ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
- 		ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
- 		ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P'));
-+		ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R'));
- 		ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
- 		ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
- 		ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z'));
-1.7.8.3
-

+ 0 - 95
contrib/Anope/0007-ngircd-Fix-handling-of-JOIN-commands.patch

@@ -1,96 +0,0 @@
-From 4c9300ede35310ee5642f34e5ac227bd96fc7384 Mon Sep 17 00:00:00 2001
-From: DukePyrolator <DukePyrolator@anope.org>
-Date: Sun, 4 Sep 2011 15:08:55 +0200
-Subject: [PATCH 07/16] ngircd: Fix handling of JOIN commands
-
----
- modules/protocol/ngircd.cpp |   60 +++++++++++++++++++++++++++++++++++++++---
- 1 files changed, 55 insertions(+), 5 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index 7f4186e..3024fdd 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -240,16 +240,58 @@ class ngIRCdIRCdMessage : public IRCdMessage
- 	{
- 		if (!params.empty())
- 		{
-+			Anope::string channel, mode;
- 			size_t pos = params[0].find('\7');
- 			if (pos != Anope::string::npos)
- 			{
--				Anope::string channel = params[0].substr(0, pos);
--				Anope::string mode = '+' + params[0].substr(pos, params[0].length()) + " " + source;
--				do_join(source, channel, "");
--				do_cmode(source, channel, mode, "");
-+				channel = params[0].substr(0, pos);
-+				mode = '+' + params[0].substr(pos+1, params[0].length()) + " " + source;
- 			}
- 			else
--				do_join(source, params[0], "");
-+				channel = params[0];
-+
-+			Channel *c = findchan(channel);
-+
-+			if (!c)
-+			{
-+				c = new Channel(channel, Anope::CurTime);
-+				c->SetFlag(CH_SYNCING);
-+			}
-+
-+			User *u = finduser(source);
-+
-+			if (!u)
-+			{
-+				Log(LOG_DEBUG) << "JOIN for nonexistant user " << source << " on " << channel;
-+				return false;
-+			}
-+
-+			EventReturn MOD_RESULT;
-+			FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c));
-+
-+			/* Add the user to the channel */
-+			c->JoinUser(u);
-+
-+			/* set the usermodes to the channel */
-+			do_cmode(source, channel, mode, "");
-+
-+			/* Now set whatever modes this user is allowed to have on the channel */
-+			chan_set_correct_modes(u, c, 1);
-+
-+			/* Check to see if modules want the user to join, if they do
-+			 * check to see if they are allowed to join (CheckKick will kick/ban them)
-+			 * Don't trigger OnJoinChannel event then as the user will be destroyed
-+			 */
-+			if (MOD_RESULT != EVENT_STOP && c->ci && c->ci->CheckKick(u))
-+				return false;
-+
-+			FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c));
-+
-+			if (c->HasFlag(CH_SYNCING))
-+			{
-+				c->UnsetFlag(CH_SYNCING);
-+				c->Sync();
-+			}
- 		}
- 		return true;
- 	}
-@@ -491,7 +533,15 @@ class ProtongIRCd : public Module
- 		pmodule_ircd_message(&this->ircd_message);
- 
- 		this->AddModes();
-+
-+		ModuleManager::Attach(I_OnUserNickChange, this);
- 	}
-+
-+	void OnUserNickChange(User *u, const Anope::string &)
-+	{
-+		u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED));
-+	}
-+
- };
- 
- MODULE_INIT(ProtongIRCd)
-1.7.8.3
-

+ 0 - 37
contrib/Anope/0008-ngircd-Allow-setting-modes-by-clients-on-burst.patch

@@ -1,38 +0,0 @@
-From d363ebd841ea7e1db3c62730023759d69520e0d8 Mon Sep 17 00:00:00 2001
-From: Alexander Barton <alex@barton.de>
-Date: Tue, 27 Sep 2011 15:08:09 +0200
-Subject: [PATCH 08/16] ngircd: Allow setting modes by clients on burst
-
-This change is required by commit 43201ead9575a for the ngIRCd protocol
-module as well.
----
- modules/protocol/ngircd.cpp |    7 +++++--
- 1 files changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index 3024fdd..2774168 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -57,14 +57,17 @@ class ngIRCdProto : public IRCDProto
- 		send_cmd(source ? source->nick : Config->ServerName, "WALLOPS :%s", buf.c_str());
- 	}
- 
--	void SendJoin(User *user, Channel *c, const ChannelStatus *status)
-+	void SendJoin(User *user, Channel *c, ChannelStatus *status)
- 	{
- 		send_cmd(user->nick, "JOIN %s", c->name.c_str());
- 		if (status)
- 		{
-+			ChannelStatus cs = *status;
-+			status->ClearFlags();
-+
- 			BotInfo *setter = findbot(user->nick);
- 			for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
--				if (status->HasFlag(ModeManager::ChannelModes[i]->Name))
-+				if (cs.HasFlag(ModeManager::ChannelModes[i]->Name))
- 					c->SetMode(setter, ModeManager::ChannelModes[i], user->nick, false);
- 		}
- 	}
-1.7.8.3
-

+ 0 - 142
contrib/Anope/0009-ngircd-Update-protocol-module-for-current-Anope-1.9.patch

@@ -1,143 +0,0 @@
-From e74a5303f2357f4a9915bb91038a2e326323db3c Mon Sep 17 00:00:00 2001
-From: Alexander Barton <alex@barton.de>
-Date: Fri, 25 Nov 2011 19:16:37 +0100
-Subject: [PATCH 09/16] ngircd: Update protocol module for current Anope 1.9
- GIT
-
-This changes are rquired by:
-
- - b14f5ea88: Fixed accidentally clearing botmodes when joins are sent
- - cef3eb78d: Remove send_cmd and replace it with a stringstream
- - ddc3c2f38: Added options:nonicknameownership config option
----
- modules/protocol/ngircd.cpp |   54 ++++++++++++++++++++++--------------------
- 1 files changed, 28 insertions(+), 26 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index 2774168..55cb8d7 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -54,16 +54,22 @@ class ngIRCdProto : public IRCDProto
- 
- 	void SendGlobopsInternal(const BotInfo *source, const Anope::string &buf)
- 	{
--		send_cmd(source ? source->nick : Config->ServerName, "WALLOPS :%s", buf.c_str());
-+		UplinkSocket::Message(source ? source->nick : Config->ServerName) << "WALLOPS :" << buf;
- 	}
- 
--	void SendJoin(User *user, Channel *c, ChannelStatus *status)
-+	void SendJoin(User *user, Channel *c, const ChannelStatus *status)
- 	{
--		send_cmd(user->nick, "JOIN %s", c->name.c_str());
-+		UplinkSocket::Message(user->nick) << "JOIN " << c->name;
- 		if (status)
- 		{
-+			/* First save the channel status incase uc->Status == status */
- 			ChannelStatus cs = *status;
--			status->ClearFlags();
-+			/* If the user is internally on the channel with flags, kill them so that
-+			 * the stacker will allow this.
-+			 */
-+			UserContainer *uc = c->FindUser(user);
-+			if (uc != NULL)
-+				uc->Status->ClearFlags();
- 
- 			BotInfo *setter = findbot(user->nick);
- 			for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
-@@ -74,18 +80,18 @@ class ngIRCdProto : public IRCDProto
- 
- 	void SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf)
- 	{
--		send_cmd(source ? source->nick : Config->ServerName, "KILL %s :%s", user->nick.c_str(), buf.c_str());
-+		UplinkSocket::Message(source ? source->nick : Config->ServerName) << "KILL " << user->nick << " :" << buf;
- 	}
- 
- 	/* SERVER name hop descript */
- 	void SendServer(const Server *server)
- 	{
--		send_cmd("", "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str());
-+		UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :" << server->GetDescription();
- 	}
- 
- 	void SendConnect()
- 	{
--		send_cmd("", "PASS %s 0210-IRC+ Anope|%s:CLHSo P", Config->Uplinks[CurrentUplink]->password.c_str(), Anope::VersionShort().c_str());
-+		UplinkSocket::Message() << "PASS " << Config->Uplinks[CurrentUplink]->password << " 0210-IRC+ Anope|" << Anope::VersionShort() << ":CLHSo P";
- 		/* Make myself known to myself in the serverlist */
- 		SendServer(Me);
- 		/* finish the enhanced server handshake and register the connection */
-@@ -98,56 +104,52 @@ class ngIRCdProto : public IRCDProto
- 		Anope::string modes = "+" + u->GetModes();
- 		XLine x(u->nick, "Reserved for services");
- 		ircdproto->SendSQLine(NULL, &x);
--		send_cmd(Config->ServerName, "NICK %s 1 %s %s 1 %s :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), modes.c_str(), u->realname.c_str());
-+		UplinkSocket::Message(Config->ServerName) << "NICK " << u->nick << " 1 " << u->GetIdent() << " " << u->host << " 1 " << modes << " :" << u->realname;
- 	}
- 
- 	void SendPartInternal(const BotInfo *bi, const Channel *chan, const Anope::string &buf)
- 	{
- 		if (!buf.empty())
--			send_cmd(bi->nick, "PART %s :%s", chan->name.c_str(), buf.c_str());
-+			UplinkSocket::Message(bi->nick) << "PART " << chan->name << " :" << buf;
- 		else
--			send_cmd(bi->nick, "PART %s", chan->name.c_str());
-+			UplinkSocket::Message(bi->nick) << "PART " << chan->name;
- 	}
- 
- 	void SendModeInternal(const BotInfo *bi, const Channel *dest, const Anope::string &buf)
- 	{
--Log(LOG_DEBUG) << "SendModeInternal 1";
--		send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", dest->name.c_str(), buf.c_str());
-+		UplinkSocket::Message(bi ? bi->nick : Config->ServerName) << "MODE " << dest->name << " " << buf;
- 	}
- 
- 	void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf)
- 	{
--Log(LOG_DEBUG) << "SendModeInternal 2";
--		send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", u->nick.c_str(), buf.c_str());
-+		UplinkSocket::Message(bi ? bi->nick : Config->ServerName) << "MODE " << u->nick << " " << buf;
- 	}
- 
- 	void SendKickInternal(const BotInfo *bi, const Channel *chan, const User *user, const Anope::string &buf)
- 	{
- 		if (!buf.empty())
--			send_cmd(bi->nick, "KICK %s %s :%s", chan->name.c_str(), user->nick.c_str(), buf.c_str());
-+			UplinkSocket::Message(bi->nick) << "KICK " << chan->name << " " << user->nick << " :" << buf;
- 		else
--			send_cmd(bi->nick, "KICK %s %s", chan->name.c_str(), user->nick.c_str());
-+			UplinkSocket::Message(bi->nick) << "KICK " << chan->name << " " << user->nick;
- 	}
- 
--	void SendNoticeChanopsInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf)
-+	void SendChannel(Channel *c)
- 	{
--		send_cmd(source->nick, "NOTICE @%s :%s", dest->name.c_str(), buf.c_str());
-+		Anope::string modes = c->GetModes(true, true);
-+		UplinkSocket::Message(Config->ServerName) << "CHANINFO " << c->name << " +" << modes;
- 	}
- 
--	/* INVITE */
--	void SendInvite(BotInfo *source, const Anope::string &chan, const Anope::string &nick)
-+	void SendTopic(BotInfo *bi, Channel *c)
- 	{
--		send_cmd(source->nick, "INVITE %s %s", nick.c_str(), chan.c_str());
-+		UplinkSocket::Message(bi->nick) << "TOPIC " << c->name << " :" << c->topic;
- 	}
- 
--	void SendChannel(Channel *c)
-+	void SendLogin(User *u)
- 	{
--		Anope::string modes = c->GetModes(true, true);
--		send_cmd(Config->ServerName, "CHANINFO %s +%s", c->name.c_str(), modes.c_str());
- 	}
--	void SendTopic(BotInfo *bi, Channel *c)
-+
-+	void SendLogout(User *u)
- 	{
--		send_cmd(bi->nick, "TOPIC %s :%s", c->name.c_str(), c->topic.c_str());
- 	}
- };
- 
-1.7.8.3
-

+ 0 - 56
contrib/Anope/0010-ngircd-Add-ProtongIRCd.patch

@@ -1,57 +0,0 @@
-From d2c45d7c578ec684d3b471020f631847316de196 Mon Sep 17 00:00:00 2001
-From: Alexander Barton <alex@barton.de>
-Date: Fri, 25 Nov 2011 19:17:19 +0100
-Subject: [PATCH 10/16] ngircd: Add ~ProtongIRCd()
-
----
- modules/protocol/ngircd.cpp |   13 ++++++++-----
- 1 files changed, 8 insertions(+), 5 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index 55cb8d7..5fd62db 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -302,8 +302,7 @@ class ngIRCdIRCdMessage : public IRCdMessage
- 	}
- };
- 
--/** This is here because:
-- *
-+/*
-  * If we had three servers, A, B & C linked like so: A<->B<->C
-  * If Anope is linked to A and B splits from A and then reconnects
-  * B introduces itself, introduces C, sends EOS for C, introduces Bs clients
-@@ -319,8 +318,6 @@ bool event_pong(const Anope::string &source, const std::vector<Anope::string> &p
- 	return true;
- }
- 
--
--
- /*
-  * CHANINFO <chan> +<modes>
-  * CHANINFO <chan> +<modes> :<topic>
-@@ -480,7 +477,6 @@ bool event_376(const Anope::string &source, const std::vector<Anope::string> &pa
- 	return true;
- }
- 
--
- class ProtongIRCd : public Module
- {
- 	Message message_kick, message_pass, message_njoin, message_chaninfo, message_005,
-@@ -542,6 +538,13 @@ class ProtongIRCd : public Module
- 		ModuleManager::Attach(I_OnUserNickChange, this);
- 	}
- 
-+        ~ProtongIRCd()
-+        {
-+                pmodule_ircd_var(NULL);
-+                pmodule_ircd_proto(NULL);
-+                pmodule_ircd_message(NULL);
-+        }
-+
- 	void OnUserNickChange(User *u, const Anope::string &)
- 	{
- 		u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED));
-1.7.8.3
-

+ 0 - 28
contrib/Anope/0011-ngircd-Update-protocol-module-for-current-Anope-1.9.patch

@@ -1,29 +0,0 @@
-From 4dc5a3d3e2fbb218461d9459bff1c0a392a75881 Mon Sep 17 00:00:00 2001
-From: Alexander Barton <alex@barton.de>
-Date: Sat, 31 Dec 2011 16:12:52 +0100
-Subject: [PATCH 11/16] ngircd: Update protocol module for current Anope 1.9
- GIT
-
-This changes are rquired by:
-
- - 150831c1a: Made capab management a bit simplier
----
- modules/protocol/ngircd.cpp |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index 5fd62db..9c26ec8 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -527,7 +527,7 @@ class ProtongIRCd : public Module
- 	{
- 		this->SetAuthor("Anope");
- 
--		Capab.SetFlag(CAPAB_QS);
-+		Capab.insert("QS");
- 
- 		pmodule_ircd_var(myIrcd);
- 		pmodule_ircd_proto(&this->ircd_proto);
-1.7.8.3
-

+ 0 - 24
contrib/Anope/0012-ngircd-Channel-mode-r-is-supported-now.patch

@@ -1,25 +0,0 @@
-From 99c18cafdee28bfb17fad5f0526b3ed5d1f5f312 Mon Sep 17 00:00:00 2001
-From: Alexander Barton <alex@barton.de>
-Date: Sat, 31 Dec 2011 16:17:50 +0100
-Subject: [PATCH 12/16] ngircd: let Anope know that channel mode "r" is
- supported
-
----
- modules/protocol/ngircd.cpp |    1 +
- 1 files changed, 1 insertions(+), 0 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index 9c26ec8..6155667 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -512,6 +512,7 @@ class ProtongIRCd : public Module
- 		ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
- 		ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
- 		ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P'));
-+		ModeManager::AddChannelMode(new ChannelModeRegistered('r'));
- 		ModeManager::AddChannelMode(new ChannelMode(CMODE_REGISTEREDONLY, 'R'));
- 		ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
- 		ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
-1.7.8.3
-

+ 0 - 27
contrib/Anope/0013-ngircd-Update-copyright-notice.patch

@@ -1,28 +0,0 @@
-From 5a19b69f0daceb5b12ec751bc919519a7f712f2d Mon Sep 17 00:00:00 2001
-From: Alexander Barton <alex@barton.de>
-Date: Sun, 15 Jan 2012 13:36:14 +0100
-Subject: [PATCH 13/16] ngircd: Update copyright notice
-
----
- modules/protocol/ngircd.cpp |    7 ++++---
- 1 files changed, 4 insertions(+), 3 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index 6155667..024c61d 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -1,7 +1,8 @@
--/* ngIRCd IRCD functions
-+/*
-+ * ngIRCd Protocol module for Anope IRC Services
-  *
-- * (C) 2003-2011 Anope Team
-- * Contact us at team@anope.org
-+ * (C) 2011-2012 Alexander Barton <alex@barton.de>
-+ * (C) 2011 Anope Team <team@anope.org>
-  *
-  * Please read COPYING and README for further details.
-  *
-1.7.8.3
-

+ 0 - 34
contrib/Anope/0014-ngircd-set-unset-GLINE-s-on-AKILL-commands.patch

@@ -1,35 +0,0 @@
-From acc24a7f4488f6ef0fb240a76766db4220b62d53 Mon Sep 17 00:00:00 2001
-From: Alexander Barton <alex@barton.de>
-Date: Sun, 22 Jan 2012 19:05:28 +0100
-Subject: [PATCH 14/16] ngircd: set/unset GLINE's on AKILL commands
-
----
- modules/protocol/ngircd.cpp |   10 ++++++++--
- 1 files changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index 024c61d..3bc3812 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -48,10 +48,16 @@ class ngIRCdProto : public IRCDProto
- {
- 	void SendAkill(User *u, const XLine *x)
- 	{
--		// TODO: ADD SOME CODE
-+		// Calculate the time left before this would expire, capping it at 2 days
-+		time_t timeleft = x->Expires - Anope::CurTime;
-+		if (timeleft > 172800 || !x->Expires)
-+			timeleft = 172800;
-+		UplinkSocket::Message(Config->ServerName) << "GLINE " << x->Mask << " " << timeleft << " :" << x->Reason << " (" << x->By << ")";
- 	}
- 
--	void SendAkillDel(const XLine*) { }
-+	void SendAkillDel(const XLine *x) {
-+		UplinkSocket::Message(Config->ServerName) << "GLINE " << x->Mask;
-+	}
- 
- 	void SendGlobopsInternal(const BotInfo *source, const Anope::string &buf)
- 	{
-1.7.8.3
-

+ 0 - 26
contrib/Anope/0015-ngircd-ngIRCd-supports-channel-mode-e-now.patch

@@ -1,27 +0,0 @@
-From 3a61b190db79848d4519296432ebb2ab714c42b7 Mon Sep 17 00:00:00 2001
-From: Alexander Barton <alex@barton.de>
-Date: Sun, 22 Jan 2012 19:06:34 +0100
-Subject: [PATCH 15/16] ngircd: ngIRCd supports channel mode 'e' now
-
----
- modules/protocol/ngircd.cpp |    3 ++-
- 1 files changed, 2 insertions(+), 1 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index 3bc3812..0f87cbd 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -504,8 +504,9 @@ class ProtongIRCd : public Module
- 		ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
- 		ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
- 
--		/* Add modes for ban and invite lists */
-+		/* Add modes for ban, exception, and invite lists */
- 		ModeManager::AddChannelMode(new ChannelModeList(CMODE_BAN, 'b'));
-+		ModeManager::AddChannelMode(new ChannelModeList(CMODE_EXCEPT, 'e'));
- 		ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
- 
- 		/* Add channel user modes */
-1.7.8.3
-

+ 0 - 34
contrib/Anope/0016-ngircd-support-SQUERY-command.patch

@@ -1,35 +0,0 @@
-From a7c48fcf47af757cf1b4eeaa6bcc96f4ae1f7410 Mon Sep 17 00:00:00 2001
-From: Alexander Barton <alex@barton.de>
-Date: Sat, 4 Feb 2012 11:13:36 +0100
-Subject: [PATCH 16/16] ngircd: support SQUERY command
-
-Thanks to DukePyrolator for explaining these changes to me.
----
- modules/protocol/ngircd.cpp |    4 ++--
- 1 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
-index 0f87cbd..530686e 100644
---- a/modules/protocol/ngircd.cpp
-+++ b/modules/protocol/ngircd.cpp
-@@ -487,7 +487,7 @@ bool event_376(const Anope::string &source, const std::vector<Anope::string> &pa
- class ProtongIRCd : public Module
- {
- 	Message message_kick, message_pass, message_njoin, message_chaninfo, message_005,
--		message_442, message_376, message_pong;
-+		message_442, message_376, message_pong, message_squery;
- 
- 	ngIRCdProto ircd_proto;
- 	ngIRCdIRCdMessage ircd_message;
-@@ -532,7 +532,7 @@ class ProtongIRCd : public Module
- 		message_kick("KICK", event_kick), message_pass("PASS", event_pass),
- 		message_njoin("NJOIN", event_njoin), message_chaninfo("CHANINFO", event_chaninfo),
- 		message_005("005", event_005), message_442("442", event_442), message_376("376", event_376),
--		message_pong("PONG", event_pong)
-+		message_pong("PONG", event_pong), message_squery("SQUERY", ::OnPrivmsg)
- 	{
- 		this->SetAuthor("Anope");
- 
-1.7.8.3
-

+ 0 - 34
contrib/Anope/Makefile.am

@@ -1,34 +0,0 @@
-#
-# ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2011 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-# Please read the file COPYING, README and AUTHORS for more information.
-#
-
-EXTRA_DIST = \
-	README \
-	0001-Revert-Removed-ngircd.patch \
-	0002-ngircd-whitespace-fixes.patch \
-	0003-Update-ngIRCd-protocol-module-for-current-Anope-1.9.patch \
-	0004-ngircd-Do-PING-PONG-on-server-burst-to-sync-servers.patch \
-	0005-ngircd-always-prefix-modes-in-CHANINFO-with.patch \
-	0006-ngircd-support-user-mode-R-and-channel-mode-R.patch \
-	0007-ngircd-Fix-handling-of-JOIN-commands.patch \
-	0008-ngircd-Allow-setting-modes-by-clients-on-burst.patch \
-	0009-ngircd-Update-protocol-module-for-current-Anope-1.9.patch \
-	0010-ngircd-Add-ProtongIRCd.patch \
-	0011-ngircd-Update-protocol-module-for-current-Anope-1.9.patch \
-	0012-ngircd-Channel-mode-r-is-supported-now.patch \
-	0013-ngircd-Update-copyright-notice.patch \
-	0014-ngircd-set-unset-GLINE-s-on-AKILL-commands.patch \
-	0015-ngircd-ngIRCd-supports-channel-mode-e-now.patch \
-	0016-ngircd-support-SQUERY-command.patch
-
-maintainer-clean-local:
-	rm -f Makefile Makefile.in
-
-# -eof-

+ 0 - 375
contrib/Anope/Makefile.in

@@ -1,375 +0,0 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-#
-# ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2011 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-# Please read the file COPYING, README and AUTHORS for more information.
-#
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-target_triplet = @target@
-subdir = contrib/Anope
-DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-	$(ACLOCAL_M4)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/src/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-AM_V_GEN = $(am__v_GEN_$(V))
-am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
-am__v_GEN_0 = @echo "  GEN   " $@;
-AM_V_at = $(am__v_at_$(V))
-am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
-am__v_at_0 = @
-SOURCES =
-DIST_SOURCES =
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-GREP = @GREP@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-OBJEXT = @OBJEXT@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-RANLIB = @RANLIB@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-U = @U@
-VERSION = @VERSION@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target = @target@
-target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-EXTRA_DIST = \
-	README \
-	0001-Revert-Removed-ngircd.patch \
-	0002-ngircd-whitespace-fixes.patch \
-	0003-Update-ngIRCd-protocol-module-for-current-Anope-1.9.patch \
-	0004-ngircd-Do-PING-PONG-on-server-burst-to-sync-servers.patch \
-	0005-ngircd-always-prefix-modes-in-CHANINFO-with.patch \
-	0006-ngircd-support-user-mode-R-and-channel-mode-R.patch \
-	0007-ngircd-Fix-handling-of-JOIN-commands.patch \
-	0008-ngircd-Allow-setting-modes-by-clients-on-burst.patch \
-	0009-ngircd-Update-protocol-module-for-current-Anope-1.9.patch \
-	0010-ngircd-Add-ProtongIRCd.patch \
-	0011-ngircd-Update-protocol-module-for-current-Anope-1.9.patch \
-	0012-ngircd-Channel-mode-r-is-supported-now.patch \
-	0013-ngircd-Update-copyright-notice.patch \
-	0014-ngircd-set-unset-GLINE-s-on-AKILL-commands.patch \
-	0015-ngircd-ngIRCd-supports-channel-mode-e-now.patch \
-	0016-ngircd-support-SQUERY-command.patch
-
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
-	@for dep in $?; do \
-	  case '$(am__configure_deps)' in \
-	    *$$dep*) \
-	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-	        && { if test -f $@; then exit 0; else break; fi; }; \
-	      exit 1;; \
-	  esac; \
-	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu contrib/Anope/Makefile'; \
-	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --gnu contrib/Anope/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-	@case '$?' in \
-	  *config.status*) \
-	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-	  *) \
-	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-	esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure:  $(am__configure_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
-	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-tags: TAGS
-TAGS:
-
-ctags: CTAGS
-CTAGS:
-
-
-distdir: $(DISTFILES)
-	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-	list='$(DISTFILES)'; \
-	  dist_files=`for file in $$list; do echo $$file; done | \
-	  sed -e "s|^$$srcdirstrip/||;t" \
-	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-	case $$dist_files in \
-	  */*) $(MKDIR_P) `echo "$$dist_files" | \
-			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-			   sort -u` ;; \
-	esac; \
-	for file in $$dist_files; do \
-	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-	  if test -d $$d/$$file; then \
-	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-	    if test -d "$(distdir)/$$file"; then \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-	    fi; \
-	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-	  else \
-	    test -f "$(distdir)/$$file" \
-	    || cp -p $$d/$$file "$(distdir)/$$file" \
-	    || exit 1; \
-	  fi; \
-	done
-check-am: all-am
-check: check-am
-all-am: Makefile
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
-	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
-	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
-	@echo "This command is intended for maintainers to use"
-	@echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic mostlyclean-am
-
-distclean: distclean-am
-	-rm -f Makefile
-distclean-am: clean-am distclean-generic
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
-	-rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic \
-	maintainer-clean-local
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-generic
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am:
-
-.MAKE: install-am install-strip
-
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-data install-data-am install-dvi \
-	install-dvi-am install-exec install-exec-am install-html \
-	install-html-am install-info install-info-am install-man \
-	install-pdf install-pdf-am install-ps install-ps-am \
-	install-strip installcheck installcheck-am installdirs \
-	maintainer-clean maintainer-clean-generic \
-	maintainer-clean-local mostlyclean mostlyclean-generic pdf \
-	pdf-am ps ps-am uninstall uninstall-am
-
-
-maintainer-clean-local:
-	rm -f Makefile Makefile.in
-
-# -eof-
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:

+ 0 - 35
contrib/Anope/README

@@ -1,35 +0,0 @@
-
-                     ngIRCd - Next Generation IRC Server
-                           http://ngircd.barton.de/
-
-               (c)2001-2012 Alexander Barton and Contributors.
-               ngIRCd is free software and published under the
-                   terms of the GNU General Public License.
-
-                          -- contrib/Anope/README --
-
-
-This directory contains two preliminary patches that (re-) add a ngIRCd
-protocol module to the Anope 1.9 development branch. It has been tested
-with Anope 1.9.6, there is no guarantee that it will work with other
-versions as Anope 1.9.x is under heavy development ...
-
-To build this Anope protocol module, you have to
-
- - Download the Anope 1.9.x sources (only tested with 1.9.6!),
- - Patch in the ngIRCd protocol module,
- - Build and install Anope as usual,
- - Configure Anope as usual, use "ngircd" as protocol module.
-
-So the command sequence can be something like this:
-
- $ tar xzf anope-1.9.6-source.tar.gz
- $ cd anope-1.9.6-source
- $ for p in .../ngircd/contrib/Anope/*.patch ; do patch -p1 < $p ; done
- $ ./Config
- $ cd build
- $ make
- $ make install
-
-Please have a look at the file doc/Services.txt for more information about
-how to set up ngIRCd and Anope.

+ 1 - 6
contrib/Debian/Makefile.in

@@ -44,11 +44,10 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 build_triplet = @build@
 host_triplet = @host@
 host_triplet = @host@
-target_triplet = @target@
 subdir = contrib/Debian
 subdir = contrib/Debian
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 mkinstalldirs = $(install_sh) -d
@@ -158,11 +157,7 @@ sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 sysconfdir = @sysconfdir@
-target = @target@
 target_alias = @target_alias@
 target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 top_srcdir = @top_srcdir@

+ 18 - 0
contrib/Debian/changelog

@@ -1,3 +1,21 @@
+ngircd (20-0ab1) unstable; urgency=low
+
+  * New "upstream" release: ngIRCd 20.
+
+ -- Alexander Barton <alex@barton.de>  Mon, 17 Dec 2012 13:04:15 +0100
+
+ngircd (20~rc2-0ab1) unstable; urgency=low
+
+  * New "upstream" release candidate 2 for ngIRCd Release 20.
+
+ -- Alexander Barton <alex@barton.de>  Sun, 02 Dec 2012 18:51:06 +0100
+
+ngircd (20~rc1-0ab1) unstable; urgency=low
+
+  * New "upstream" release candidate 1 for ngIRCd Release 20.
+
+ -- Alexander Barton <alex@barton.de>  Sun, 11 Nov 2012 16:03:32 +0100
+
 ngircd (19.2-0ab1) unstable; urgency=low
 ngircd (19.2-0ab1) unstable; urgency=low
 
 
   * New "upstream" release: ngIRCd 19.2.
   * New "upstream" release: ngIRCd 19.2.

+ 16 - 16
contrib/Debian/control

@@ -10,7 +10,7 @@ Build-Depends: debhelper (>> 4.0.0),
     libident-dev,
     libident-dev,
     libgnutls-dev,
     libgnutls-dev,
     libpam0g-dev,
     libpam0g-dev,
-    telnet,
+    telnet | telnet-ssl,
 Standards-Version: 3.9.1
 Standards-Version: 3.9.1
 
 
 Package: ngircd
 Package: ngircd
@@ -18,11 +18,11 @@ Architecture: any
 Depends: ${shlibs:Depends}, ${misc:Depends}
 Depends: ${shlibs:Depends}, ${misc:Depends}
 Provides: ircd
 Provides: ircd
 Description: lightweight Internet Relay Chat server
 Description: lightweight Internet Relay Chat server
- This package provides ngIRCd, a lightweight Internet Relay Chat
- server for small or private networks. It is simple to configure, can
- cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
- is written from scratch, not based on the original IRCd and quite
- portable.
+ This package provides ngIRCd, a portable and lightweight Internet Relay
+ Chat server for small or private networks, developed under the GNU
+ General Public License (GPL). It is simple to configure, can cope with
+ dynamic IP addresses, and supports IPv6 as well as SSL. It is written
+ from scratch and not based on the original IRCd.
  .
  .
  This package contains the "standard distribution", including support for
  This package contains the "standard distribution", including support for
  syslog logging and compressed server-links using zlib. Please have a look
  syslog logging and compressed server-links using zlib. Please have a look
@@ -35,11 +35,11 @@ Depends: ${shlibs:Depends}, ${misc:Depends}
 Provides: ircd
 Provides: ircd
 Conflicts: ngircd, ngircd-dbg
 Conflicts: ngircd, ngircd-dbg
 Description: lightweight Internet Relay Chat server
 Description: lightweight Internet Relay Chat server
- This package provides ngIRCd, a lightweight Internet Relay Chat
- server for small or private networks. It is simple to configure, can
- cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
- is written from scratch, not based on the original IRCd and quite
- portable.
+ This package provides ngIRCd, a portable and lightweight Internet Relay
+ Chat server for small or private networks, developed under the GNU
+ General Public License (GPL). It is simple to configure, can cope with
+ dynamic IP addresses, and supports IPv6 as well as SSL. It is written
+ from scratch and not based on the original IRCd.
  .
  .
  In addition to the features of the "standard package", this package
  In addition to the features of the "standard package", this package
  includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
  includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
@@ -51,11 +51,11 @@ Depends: ${shlibs:Depends}, ${misc:Depends}
 Provides: ircd
 Provides: ircd
 Conflicts: ngircd, ngircd-full
 Conflicts: ngircd, ngircd-full
 Description: lightweight Internet Relay Chat server
 Description: lightweight Internet Relay Chat server
- This package provides ngIRCd, a lightweight Internet Relay Chat
- server for small or private networks. It is simple to configure, can
- cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
- is written from scratch, not based on the original IRCd and quite
- portable.
+ This package provides ngIRCd, a portable and lightweight Internet Relay
+ Chat server for small or private networks, developed under the GNU
+ General Public License (GPL). It is simple to configure, can cope with
+ dynamic IP addresses, and supports IPv6 as well as SSL. It is written
+ from scratch and not based on the original IRCd.
  .
  .
  In addition to the features of the "standard package", this package
  In addition to the features of the "standard package", this package
  includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
  includes support for TCP wrappers, IDENT requests, the IPv6 protocol and

+ 5 - 3
contrib/Debian/rules

@@ -1,7 +1,7 @@
 #!/usr/bin/make -f
 #!/usr/bin/make -f
 #
 #
 # ngIRCd -- The Next Generation IRC Daemon
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2009 Alexander Barton <alex@barton.de>
+# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 #
 #
 # This program is free software; you can redistribute it and/or modify
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
@@ -53,7 +53,8 @@ configure-ngircd-full: configure
 	  --sysconfdir=/etc/ngircd \
 	  --sysconfdir=/etc/ngircd \
 	  --mandir=\$${prefix}/share/man \
 	  --mandir=\$${prefix}/share/man \
 	  --with-syslog --with-zlib \
 	  --with-syslog --with-zlib \
-	  --with-gnutls --with-ident --with-tcp-wrappers --with-pam \
+	  --with-gnutls --with-iconv --with-ident --with-tcp-wrappers \
+	  --with-pam \
 	  --enable-ipv6
 	  --enable-ipv6
 
 
 configure-ngircd-full-dbg: configure
 configure-ngircd-full-dbg: configure
@@ -66,7 +67,8 @@ configure-ngircd-full-dbg: configure
 	  --mandir=\$${prefix}/share/man \
 	  --mandir=\$${prefix}/share/man \
 	  --enable-debug --enable-sniffer \
 	  --enable-debug --enable-sniffer \
 	  --with-syslog --with-zlib \
 	  --with-syslog --with-zlib \
-	  --with-gnutls --with-ident --with-tcp-wrappers --with-pam \
+	  --with-gnutls --with-iconv --with-ident --with-tcp-wrappers \
+	  --with-pam \
 	  --enable-ipv6
 	  --enable-ipv6
 
 
 build:
 build:

+ 1 - 6
contrib/MacOSX/Makefile.in

@@ -44,11 +44,10 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 build_triplet = @build@
 host_triplet = @host@
 host_triplet = @host@
-target_triplet = @target@
 subdir = contrib/MacOSX
 subdir = contrib/MacOSX
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 mkinstalldirs = $(install_sh) -d
@@ -198,11 +197,7 @@ sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 sysconfdir = @sysconfdir@
-target = @target@
 target_alias = @target_alias@
 target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 top_srcdir = @top_srcdir@

+ 10 - 2
contrib/MacOSX/config.h

@@ -1,6 +1,6 @@
 /*
 /*
  * ngIRCd -- The Next Generation IRC Daemon
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * it under the terms of the GNU General Public License as published by
@@ -11,7 +11,8 @@
  * Static configuration file for Mac OS X Xcode project
  * Static configuration file for Mac OS X Xcode project
  */
  */
 
 
-#define PACKAGE_NAME "ngircd"
+#define PACKAGE_NAME "ngIRCd"
+#define PACKAGE "ngircd"
 #ifndef VERSION
 #ifndef VERSION
 #define VERSION "??("__DATE__")"
 #define VERSION "??("__DATE__")"
 #endif
 #endif
@@ -51,6 +52,9 @@
 /* Define if PAM should be used */
 /* Define if PAM should be used */
 #define PAM 1
 #define PAM 1
 
 
+/* Define if libiconv can be used, e.g. for CHARCONV */
+#define ICONV 1
+
 /* -- Supported features -- */
 /* -- Supported features -- */
 
 
 /* Define if SSP C support is enabled. */
 /* Define if SSP C support is enabled. */
@@ -76,6 +80,8 @@
 
 
 /* Define to 1 if you have the `gai_strerror' function. */
 /* Define to 1 if you have the `gai_strerror' function. */
 #define HAVE_GAI_STRERROR 1
 #define HAVE_GAI_STRERROR 1
+/* Define to 1 if you have the `iconv_open' function. */
+#define HAVE_ICONV_OPEN 1
 /* Define to 1 if you have the `kqueue' function. */
 /* Define to 1 if you have the `kqueue' function. */
 #define HAVE_KQUEUE 1
 #define HAVE_KQUEUE 1
 /* Define to 1 if you have the `inet_ntoa' function. */
 /* Define to 1 if you have the `inet_ntoa' function. */
@@ -98,6 +104,8 @@
 #define HAVE_GETNAMEINFO 1
 #define HAVE_GETNAMEINFO 1
 /* Define to 1 if you have the `sigaction' function. */
 /* Define to 1 if you have the `sigaction' function. */
 #define HAVE_SIGACTION 1
 #define HAVE_SIGACTION 1
+/* Define to 1 if you have the `setsid' function. */
+#define HAVE_SETSID 1
 
 
 /* Define if socklen_t exists */
 /* Define if socklen_t exists */
 #define HAVE_socklen_t 1
 #define HAVE_socklen_t 1

+ 1 - 6
contrib/MacOSX/ngIRCd.pmdoc/Makefile.in

@@ -44,11 +44,10 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 build_triplet = @build@
 host_triplet = @host@
 host_triplet = @host@
-target_triplet = @target@
 subdir = contrib/MacOSX/ngIRCd.pmdoc
 subdir = contrib/MacOSX/ngIRCd.pmdoc
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 mkinstalldirs = $(install_sh) -d
@@ -158,11 +157,7 @@ sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 sysconfdir = @sysconfdir@
-target = @target@
 target_alias = @target_alias@
 target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 top_srcdir = @top_srcdir@

+ 1 - 6
contrib/MacOSX/ngIRCd.xcodeproj/Makefile.in

@@ -44,11 +44,10 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 build_triplet = @build@
 host_triplet = @host@
 host_triplet = @host@
-target_triplet = @target@
 subdir = contrib/MacOSX/ngIRCd.xcodeproj
 subdir = contrib/MacOSX/ngIRCd.xcodeproj
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 mkinstalldirs = $(install_sh) -d
@@ -158,11 +157,7 @@ sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 sysconfdir = @sysconfdir@
-target = @target@
 target_alias = @target_alias@
 target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 top_srcdir = @top_srcdir@

+ 36 - 11
contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj

@@ -36,6 +36,10 @@
 		FA322DBE0CEF7766001761B3 /* tool.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D330CEF74B1001761B3 /* tool.c */; };
 		FA322DBE0CEF7766001761B3 /* tool.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D330CEF74B1001761B3 /* tool.c */; };
 		FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA322DC00CEF77CB001761B3 /* libz.dylib */; };
 		FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA322DC00CEF77CB001761B3 /* libz.dylib */; };
 		FA407F2E0DB159F400271AF1 /* ng_ipaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */; };
 		FA407F2E0DB159F400271AF1 /* ng_ipaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */; };
+		FA4F165A164836B100DBD011 /* irc-metadata.c in Sources */ = {isa = PBXBuildFile; fileRef = FA4F1659164836B100DBD011 /* irc-metadata.c */; };
+		FA6BBC631605F0AC0004247A /* conn-encoding.c in Sources */ = {isa = PBXBuildFile; fileRef = FA6BBC5F1605F0AB0004247A /* conn-encoding.c */; };
+		FA6BBC641605F0AC0004247A /* irc-encoding.c in Sources */ = {isa = PBXBuildFile; fileRef = FA6BBC611605F0AC0004247A /* irc-encoding.c */; };
+		FA6BBC661605F6D60004247A /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA6BBC651605F6D60004247A /* libiconv.dylib */; };
 		FA85178C0FA061EC006A1F5A /* op.c in Sources */ = {isa = PBXBuildFile; fileRef = FA85178B0FA061EC006A1F5A /* op.c */; };
 		FA85178C0FA061EC006A1F5A /* op.c in Sources */ = {isa = PBXBuildFile; fileRef = FA85178B0FA061EC006A1F5A /* op.c */; };
 		FA99428C10E82A27007F27ED /* proc.c in Sources */ = {isa = PBXBuildFile; fileRef = FA99428B10E82A27007F27ED /* proc.c */; };
 		FA99428C10E82A27007F27ED /* proc.c in Sources */ = {isa = PBXBuildFile; fileRef = FA99428B10E82A27007F27ED /* proc.c */; };
 		FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA3D2790F139CDC00B2447E /* conn-ssl.c */; };
 		FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA3D2790F139CDC00B2447E /* conn-ssl.c */; };
@@ -203,6 +207,13 @@
 		FA4B08E613E7F91700765BA3 /* ngIRCd-Logo.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "ngIRCd-Logo.gif"; sourceTree = "<group>"; };
 		FA4B08E613E7F91700765BA3 /* ngIRCd-Logo.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "ngIRCd-Logo.gif"; sourceTree = "<group>"; };
 		FA4B08E713E7F91700765BA3 /* ngircd-redhat.init */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "ngircd-redhat.init"; sourceTree = "<group>"; };
 		FA4B08E713E7F91700765BA3 /* ngircd-redhat.init */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "ngircd-redhat.init"; sourceTree = "<group>"; };
 		FA4B08E813E7F91C00765BA3 /* platformtest.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = platformtest.sh; sourceTree = "<group>"; };
 		FA4B08E813E7F91C00765BA3 /* platformtest.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = platformtest.sh; sourceTree = "<group>"; };
+		FA4F1659164836B100DBD011 /* irc-metadata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "irc-metadata.c"; sourceTree = "<group>"; };
+		FA4F165C164836BF00DBD011 /* irc-metadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "irc-metadata.h"; sourceTree = "<group>"; };
+		FA6BBC5F1605F0AB0004247A /* conn-encoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "conn-encoding.c"; sourceTree = "<group>"; };
+		FA6BBC601605F0AC0004247A /* conn-encoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "conn-encoding.h"; sourceTree = "<group>"; };
+		FA6BBC611605F0AC0004247A /* irc-encoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "irc-encoding.c"; sourceTree = "<group>"; };
+		FA6BBC621605F0AC0004247A /* irc-encoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "irc-encoding.h"; sourceTree = "<group>"; };
+		FA6BBC651605F6D60004247A /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = ../../../../../../../usr/lib/libiconv.dylib; sourceTree = "<group>"; };
 		FA77849A133FB9FF00740057 /* sample-ngircd.conf.tmpl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "sample-ngircd.conf.tmpl"; sourceTree = "<group>"; };
 		FA77849A133FB9FF00740057 /* sample-ngircd.conf.tmpl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "sample-ngircd.conf.tmpl"; sourceTree = "<group>"; };
 		FA85178A0FA061EC006A1F5A /* op.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = op.h; sourceTree = "<group>"; };
 		FA85178A0FA061EC006A1F5A /* op.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = op.h; sourceTree = "<group>"; };
 		FA85178B0FA061EC006A1F5A /* op.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = op.c; sourceTree = "<group>"; };
 		FA85178B0FA061EC006A1F5A /* op.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = op.c; sourceTree = "<group>"; };
@@ -258,6 +269,7 @@
 			files = (
 			files = (
 				FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */,
 				FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */,
 				FA2D567B11EA1AB300D37A35 /* libpam.dylib in Frameworks */,
 				FA2D567B11EA1AB300D37A35 /* libpam.dylib in Frameworks */,
+				FA6BBC661605F6D60004247A /* libiconv.dylib in Frameworks */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
@@ -283,8 +295,9 @@
 				FA322D600CEF750F001761B3 /* configure.in */,
 				FA322D600CEF750F001761B3 /* configure.in */,
 				FA322D630CEF750F001761B3 /* Makefile.am */,
 				FA322D630CEF750F001761B3 /* Makefile.am */,
 				1AB674ADFE9D54B511CA2CBB /* Products */,
 				1AB674ADFE9D54B511CA2CBB /* Products */,
-				FA322DC00CEF77CB001761B3 /* libz.dylib */,
+				FA6BBC651605F6D60004247A /* libiconv.dylib */,
 				FA2D567A11EA1AB300D37A35 /* libpam.dylib */,
 				FA2D567A11EA1AB300D37A35 /* libpam.dylib */,
+				FA322DC00CEF77CB001761B3 /* libz.dylib */,
 			);
 			);
 			name = ngIRCd;
 			name = ngIRCd;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -328,12 +341,14 @@
 				FA322CDF0CEF74B1001761B3 /* conf.c */,
 				FA322CDF0CEF74B1001761B3 /* conf.c */,
 				FA322CE00CEF74B1001761B3 /* conf.h */,
 				FA322CE00CEF74B1001761B3 /* conf.h */,
 				FAA3D2780F139CDC00B2447E /* conf-ssl.h */,
 				FAA3D2780F139CDC00B2447E /* conf-ssl.h */,
+				FA322CE50CEF74B1001761B3 /* conn.c */,
+				FA322CE60CEF74B1001761B3 /* conn.h */,
+				FA6BBC5F1605F0AB0004247A /* conn-encoding.c */,
+				FA6BBC601605F0AC0004247A /* conn-encoding.h */,
 				FA322CE10CEF74B1001761B3 /* conn-func.c */,
 				FA322CE10CEF74B1001761B3 /* conn-func.c */,
 				FA322CE20CEF74B1001761B3 /* conn-func.h */,
 				FA322CE20CEF74B1001761B3 /* conn-func.h */,
 				FA322CE30CEF74B1001761B3 /* conn-zip.c */,
 				FA322CE30CEF74B1001761B3 /* conn-zip.c */,
 				FA322CE40CEF74B1001761B3 /* conn-zip.h */,
 				FA322CE40CEF74B1001761B3 /* conn-zip.h */,
-				FA322CE50CEF74B1001761B3 /* conn.c */,
-				FA322CE60CEF74B1001761B3 /* conn.h */,
 				FAA3D2790F139CDC00B2447E /* conn-ssl.c */,
 				FAA3D2790F139CDC00B2447E /* conn-ssl.c */,
 				FAA3D27A0F139CDC00B2447E /* conn-ssl.h */,
 				FAA3D27A0F139CDC00B2447E /* conn-ssl.h */,
 				FA322CE70CEF74B1001761B3 /* defines.h */,
 				FA322CE70CEF74B1001761B3 /* defines.h */,
@@ -341,14 +356,20 @@
 				FA322CE90CEF74B1001761B3 /* hash.h */,
 				FA322CE90CEF74B1001761B3 /* hash.h */,
 				FA322CEA0CEF74B1001761B3 /* io.c */,
 				FA322CEA0CEF74B1001761B3 /* io.c */,
 				FA322CEB0CEF74B1001761B3 /* io.h */,
 				FA322CEB0CEF74B1001761B3 /* io.h */,
+				FA322CFC0CEF74B1001761B3 /* irc.c */,
+				FA322CFD0CEF74B1001761B3 /* irc.h */,
 				FAD5853315271AB800328741 /* irc-cap.c */,
 				FAD5853315271AB800328741 /* irc-cap.c */,
 				FAD5853415271AB800328741 /* irc-cap.h */,
 				FAD5853415271AB800328741 /* irc-cap.h */,
 				FA322CEC0CEF74B1001761B3 /* irc-channel.c */,
 				FA322CEC0CEF74B1001761B3 /* irc-channel.c */,
 				FA322CED0CEF74B1001761B3 /* irc-channel.h */,
 				FA322CED0CEF74B1001761B3 /* irc-channel.h */,
+				FA6BBC611605F0AC0004247A /* irc-encoding.c */,
+				FA6BBC621605F0AC0004247A /* irc-encoding.h */,
 				FA322CEE0CEF74B1001761B3 /* irc-info.c */,
 				FA322CEE0CEF74B1001761B3 /* irc-info.c */,
 				FA322CEF0CEF74B1001761B3 /* irc-info.h */,
 				FA322CEF0CEF74B1001761B3 /* irc-info.h */,
 				FA322CF00CEF74B1001761B3 /* irc-login.c */,
 				FA322CF00CEF74B1001761B3 /* irc-login.c */,
 				FA322CF10CEF74B1001761B3 /* irc-login.h */,
 				FA322CF10CEF74B1001761B3 /* irc-login.h */,
+				FA4F1659164836B100DBD011 /* irc-metadata.c */,
+				FA4F165C164836BF00DBD011 /* irc-metadata.h */,
 				FA322CF20CEF74B1001761B3 /* irc-mode.c */,
 				FA322CF20CEF74B1001761B3 /* irc-mode.c */,
 				FA322CF30CEF74B1001761B3 /* irc-mode.h */,
 				FA322CF30CEF74B1001761B3 /* irc-mode.h */,
 				FA322CF40CEF74B1001761B3 /* irc-op.c */,
 				FA322CF40CEF74B1001761B3 /* irc-op.c */,
@@ -359,8 +380,6 @@
 				FA322CF90CEF74B1001761B3 /* irc-server.h */,
 				FA322CF90CEF74B1001761B3 /* irc-server.h */,
 				FA322CFA0CEF74B1001761B3 /* irc-write.c */,
 				FA322CFA0CEF74B1001761B3 /* irc-write.c */,
 				FA322CFB0CEF74B1001761B3 /* irc-write.h */,
 				FA322CFB0CEF74B1001761B3 /* irc-write.h */,
-				FA322CFC0CEF74B1001761B3 /* irc.c */,
-				FA322CFD0CEF74B1001761B3 /* irc.h */,
 				FA322CFE0CEF74B1001761B3 /* lists.c */,
 				FA322CFE0CEF74B1001761B3 /* lists.c */,
 				FA322CFF0CEF74B1001761B3 /* lists.h */,
 				FA322CFF0CEF74B1001761B3 /* lists.h */,
 				FA322D000CEF74B1001761B3 /* log.c */,
 				FA322D000CEF74B1001761B3 /* log.c */,
@@ -750,6 +769,9 @@
 				FAD5853215271AAB00328741 /* client-cap.c in Sources */,
 				FAD5853215271AAB00328741 /* client-cap.c in Sources */,
 				FAD5853515271AB800328741 /* irc-cap.c in Sources */,
 				FAD5853515271AB800328741 /* irc-cap.c in Sources */,
 				FAD5853815272C2600328741 /* login.c in Sources */,
 				FAD5853815272C2600328741 /* login.c in Sources */,
+				FA6BBC631605F0AC0004247A /* conn-encoding.c in Sources */,
+				FA6BBC641605F0AC0004247A /* irc-encoding.c in Sources */,
+				FA4F165A164836B100DBD011 /* irc-metadata.c in Sources */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};
@@ -779,7 +801,7 @@
 				GCC_WARN_UNUSED_PARAMETER = YES;
 				GCC_WARN_UNUSED_PARAMETER = YES;
 				GCC_WARN_UNUSED_VALUE = YES;
 				GCC_WARN_UNUSED_VALUE = YES;
 				INSTALL_PATH = /usr/local/bin;
 				INSTALL_PATH = /usr/local/bin;
-				PRODUCT_NAME = ngIRCd;
+				PRODUCT_NAME = ngircd;
 			};
 			};
 			name = Default;
 			name = Default;
 		};
 		};
@@ -787,10 +809,12 @@
 			isa = XCBuildConfiguration;
 			isa = XCBuildConfiguration;
 			buildSettings = {
 			buildSettings = {
 				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
 				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
-				GCC_VERSION = 4.2;
+				CODE_SIGN_IDENTITY = "";
+				GCC_VERSION = "";
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				SDKROOT = macosx10.6;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				SDKROOT = "";
 			};
 			};
 			name = Default;
 			name = Default;
 		};
 		};
@@ -800,11 +824,12 @@
 				ARCHS = "$(NATIVE_ARCH_ACTUAL)";
 				ARCHS = "$(NATIVE_ARCH_ACTUAL)";
 				GCC_DEBUGGING_SYMBOLS = full;
 				GCC_DEBUGGING_SYMBOLS = full;
 				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_OPTIMIZATION_LEVEL = 0;
-				GCC_VERSION = 4.2;
+				GCC_VERSION = "";
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
 				ONLY_ACTIVE_ARCH = YES;
 				ONLY_ACTIVE_ARCH = YES;
-				SDKROOT = macosx;
+				SDKROOT = "";
 			};
 			};
 			name = Debug;
 			name = Debug;
 		};
 		};
@@ -831,7 +856,7 @@
 				GCC_WARN_UNUSED_PARAMETER = YES;
 				GCC_WARN_UNUSED_PARAMETER = YES;
 				GCC_WARN_UNUSED_VALUE = YES;
 				GCC_WARN_UNUSED_VALUE = YES;
 				INSTALL_PATH = /usr/local/bin;
 				INSTALL_PATH = /usr/local/bin;
-				PRODUCT_NAME = ngIRCd;
+				PRODUCT_NAME = ngircd;
 			};
 			};
 			name = Debug;
 			name = Debug;
 		};
 		};

+ 11 - 4
contrib/Makefile.am

@@ -1,6 +1,6 @@
 #
 #
 # ngIRCd -- The Next Generation IRC Daemon
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
+# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 #
 #
 # This program is free software; you can redistribute it and/or modify
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
@@ -9,10 +9,17 @@
 # Please read the file COPYING, README and AUTHORS for more information.
 # Please read the file COPYING, README and AUTHORS for more information.
 #
 #
 
 
-SUBDIRS = Anope Debian MacOSX
+SUBDIRS = Debian MacOSX
 
 
-EXTRA_DIST = README ngircd.spec systrace.policy ngindent ngircd-bsd.sh \
-	ngIRCd-Logo.gif ngircd-redhat.init platformtest.sh
+EXTRA_DIST = README \
+	ngindent \
+	ngircd-bsd.sh \
+	ngIRCd-Logo.gif \
+	ngircd-redhat.init \
+	ngircd.service \
+	ngircd.spec \
+	platformtest.sh \
+	systrace.policy
 
 
 maintainer-clean-local:
 maintainer-clean-local:
 	rm -f Makefile Makefile.in
 	rm -f Makefile Makefile.in

+ 12 - 10
contrib/Makefile.in

@@ -17,7 +17,7 @@
 
 
 #
 #
 # ngIRCd -- The Next Generation IRC Daemon
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
+# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 #
 #
 # This program is free software; you can redistribute it and/or modify
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
@@ -44,11 +44,10 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 build_triplet = @build@
 host_triplet = @host@
 host_triplet = @host@
-target_triplet = @target@
 subdir = contrib
 subdir = contrib
 DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 mkinstalldirs = $(install_sh) -d
@@ -198,17 +197,20 @@ sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 sysconfdir = @sysconfdir@
-target = @target@
 target_alias = @target_alias@
 target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 top_srcdir = @top_srcdir@
-SUBDIRS = Anope Debian MacOSX
-EXTRA_DIST = README ngircd.spec systrace.policy ngindent ngircd-bsd.sh \
-	ngIRCd-Logo.gif ngircd-redhat.init platformtest.sh
+SUBDIRS = Debian MacOSX
+EXTRA_DIST = README \
+	ngindent \
+	ngircd-bsd.sh \
+	ngIRCd-Logo.gif \
+	ngircd-redhat.init \
+	ngircd.service \
+	ngircd.spec \
+	platformtest.sh \
+	systrace.policy
 
 
 all: all-recursive
 all: all-recursive
 
 

+ 0 - 3
contrib/README

@@ -9,9 +9,6 @@
                             -- Contributions --
                             -- Contributions --
 
 
 
 
-Anope/
- - A preliminary patch that adds a ngIRCd protocol module to Anope 1.9.
-
 Debian/
 Debian/
  - Various files for building Debian GNU/Linux packages (".deb's").
  - Various files for building Debian GNU/Linux packages (".deb's").
 
 

+ 11 - 0
contrib/ngircd.service

@@ -0,0 +1,11 @@
+[Unit]
+Description=Next Generation IRC Daemon
+After=network.target
+
+[Service]
+# don't daemonize to simplify stuff
+ExecStart=/usr/sbin/ngircd -n
+ExecReload=/bin/kill -HUP $MAINPID
+
+[Install]
+WantedBy=multi-user.target

+ 6 - 6
contrib/ngircd.spec

@@ -1,5 +1,5 @@
 %define name    ngircd
 %define name    ngircd
-%define version 19.2
+%define version 20
 %define release 1
 %define release 1
 %define prefix  %{_prefix}
 %define prefix  %{_prefix}
 
 
@@ -15,11 +15,11 @@ BuildRoot:    %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires:  zlib-devel, openssl-devel
 BuildRequires:  zlib-devel, openssl-devel
 
 
 %description
 %description
-This package provides ngIRCd, a lightweight Internet Relay Chat
-server for small or private networks. It is simple to configure, can
-cope with dynamic IP addresses, and supports IPv6 as well as SSL. It
-is written from scratch, not based on the original IRCd and quite
-portable.
+This package provides ngIRCd, a portable and lightweight Internet Relay
+Chat server for small or private networks, developed under the GNU
+General Public License (GPL). It is simple to configure, can cope with
+dynamic IP addresses, and supports IPv6 as well as SSL. It is written
+from scratch and not based on the original IRCd.
 
 
 Advantages:
 Advantages:
  - well arranged (lean) configuration file
  - well arranged (lean) configuration file

+ 6 - 6
contrib/platformtest.sh

@@ -54,8 +54,8 @@ if [ $? -ne 0 ]; then
 	cd ..
 	cd ..
 fi
 fi
 
 
-echo "$NAME: Checking for \"./autogen.sh\" script ..."
-if [ -r ./autogen.sh ]; then
+echo "$NAME: Checking for \"./configure\" script ..."
+if [ ! -e ./configure ]; then
 	echo "$NAME: Running \"./autogen.sh\" ..."
 	echo "$NAME: Running \"./autogen.sh\" ..."
 	[ -n "$VERBOSE" ] && ./autogen.sh || ./autogen.sh >/dev/null
 	[ -n "$VERBOSE" ] && ./autogen.sh || ./autogen.sh >/dev/null
 fi
 fi
@@ -76,7 +76,7 @@ if [ -r ./configure ]; then
 				R_RUN=$R_CHECK
 				R_RUN=$R_CHECK
 			else
 			else
 				./src/ngircd/ngircd --help 2>/dev/null \
 				./src/ngircd/ngircd --help 2>/dev/null \
-				 | grep "^ngircd" >/dev/null
+				 | grep "^ngIRCd" >/dev/null
 				[ $? -eq 0 ] && R_RUN=1
 				[ $? -eq 0 ] && R_RUN=1
 			fi
 			fi
 		fi
 		fi
@@ -85,9 +85,9 @@ fi
 
 
 # Get target platform information
 # Get target platform information
 if [ -r "src/config.h" ]; then
 if [ -r "src/config.h" ]; then
-	CPU=`grep "TARGET_CPU" "src/config.h" | cut -d'"' -f2`
-	OS=`grep "TARGET_OS" "src/config.h" | cut -d'"' -f2`
-	VENDOR=`grep "TARGET_VENDOR" "src/config.h" | cut -d'"' -f2`
+	CPU=`grep "HOST_CPU" "src/config.h" | cut -d'"' -f2`
+	OS=`grep "HOST_OS" "src/config.h" | cut -d'"' -f2`
+	VENDOR=`grep "HOST_VENDOR" "src/config.h" | cut -d'"' -f2`
 	PLATFORM="$CPU/$VENDOR/$OS"
 	PLATFORM="$CPU/$VENDOR/$OS"
 fi
 fi
 if [ -z "$PLATFORM" ]; then
 if [ -z "$PLATFORM" ]; then

+ 54 - 0
doc/Contributing.txt

@@ -0,0 +1,54 @@
+
+                     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.
+
+                            -- Contributing.txt --
+
+
+If you want to contribute to ngIRCd, please read the following paragraphs to
+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
+   much easier ;-)
+
+ - Don't forget to include documentation
+
+   When adding features and new configuration options, don't forget to not
+   only code the features but to describe them in doc/sample-ngircd.conf,
+   man/ngircd.8.tmp and/or man/ngircd.conf.5.tmpl as well!
+
+ - Be present on IRC
+
+   If you intend to code some new features or do some code cleanups or better
+   documentation, please be present on <irc://irc.barton.de/#ngircd> and
+   discuss your plans early! So other developers have an idea on what others
+   are working on, can offer help, and can synchronize their own work.
+
+ - Check and validate your work!
+
+   Use "make check" to validate your work, and use "make distcheck" to
+   validate the resulting archives, especially when adding/removing files!
+
+ - Send patches in "unified diff" format
+
+   Please send patches in "unified" format, that is, use "diff -u".
+   Or even better: use GIT ("git diff"), see above.
+
+ - Send patches to the mailing list
+
+   If you have some code to present, send the patch(es) and/or pointers to
+   your GIT repository to the official ngIRCd mailing list for review, not
+   only to #ngircd: so it becomes archived and more people have a chance to
+   review your patch.
+
+   Sure it is a good idea to post some notes to #ngircd, too! :-)
+
+   And this is open source, your work must not be 100% finished and perfect,
+   work in progress is interesting, too: "release early, release often"!

+ 1 - 1
doc/HowToRelease.txt

@@ -40,7 +40,7 @@ a) Make sure the source tree is in a releasable state ;-)
 
 
 b) Make sure you have working versions of GNU autoconf and GNU automake
 b) Make sure you have working versions of GNU autoconf and GNU automake
    installed on the system you use for generating the release:
    installed on the system you use for generating the release:
-   as of October 2010 we are using GNU autoconf 2.61 and GNU automake 1.10.1
+   as of October 2010 we are using GNU autoconf 2.67 and GNU automake 1.11.1
    which seem to work just fine.
    which seem to work just fine.
 
 
 c) Update the files describing the new release:
 c) Update the files describing the new release:

+ 24 - 3
doc/Makefile.am

@@ -10,7 +10,7 @@
 #
 #
 
 
 .tmpl:
 .tmpl:
-	sed \
+	$(AM_V_GEN)sed \
 	    -e s@:ETCDIR:@${sysconfdir}@ \
 	    -e s@:ETCDIR:@${sysconfdir}@ \
 	    <$< >$@
 	    <$< >$@
 
 
@@ -19,6 +19,7 @@ SUFFIXES = .tmpl
 static_docs = \
 static_docs = \
 	Bopm.txt \
 	Bopm.txt \
 	Capabilities.txt \
 	Capabilities.txt \
+	Contributing.txt \
 	FAQ.txt \
 	FAQ.txt \
 	GIT.txt \
 	GIT.txt \
 	HowToRelease.txt \
 	HowToRelease.txt \
@@ -52,8 +53,8 @@ all: $(generated_docs)
 
 
 install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
 install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
 	$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
 	$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
-	if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
-	  $(INSTALL) -m 600 -c sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; \
+	@if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
+	  make install-config; \
 	 fi
 	 fi
 	$(mkinstalldirs) $(DESTDIR)$(docdir)
 	$(mkinstalldirs) $(DESTDIR)$(docdir)
 	for f in $(static_docs) $(toplevel_docs); do \
 	for f in $(static_docs) $(toplevel_docs); do \
@@ -63,10 +64,30 @@ install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
 	  $(INSTALL) -m 644 -c $$f $(DESTDIR)$(docdir)/; \
 	  $(INSTALL) -m 644 -c $$f $(DESTDIR)$(docdir)/; \
 	 done
 	 done
 
 
+install-config:
+	$(INSTALL) -m 600 -c sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf
+	@echo; \
+	 echo " ** NOTE: Installed sample configuration file:"; \
+	 echo " ** \"$(DESTDIR)$(sysconfdir)/ngircd.conf\""; \
+	 echo
+
 uninstall-hook:
 uninstall-hook:
 	rm -rf $(DESTDIR)$(docdir)
 	rm -rf $(DESTDIR)$(docdir)
+	@if cmp --silent sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; then \
+	  make uninstall-config; \
+	 else \
+	  echo; \
+	  echo " ** NOTE: Not uninstalling changed configuration file:"; \
+	  echo " ** \"$(DESTDIR)$(sysconfdir)/ngircd.conf\""; \
+	  echo; \
+	 fi
+
+uninstall-config:
+	rm -f $(DESTDIR)$(sysconfdir)/ngircd.conf
 
 
 srcdoc:
 srcdoc:
 	make -C src srcdoc
 	make -C src srcdoc
 
 
+.PHONY: install-config uninstall-config srcdoc
+
 # -eof-
 # -eof-

+ 25 - 9
doc/Makefile.in

@@ -44,11 +44,10 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 build_triplet = @build@
 host_triplet = @host@
 host_triplet = @host@
-target_triplet = @target@
 subdir = doc
 subdir = doc
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 mkinstalldirs = $(install_sh) -d
@@ -198,11 +197,7 @@ sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 sysconfdir = @sysconfdir@
-target = @target@
 target_alias = @target_alias@
 target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 top_srcdir = @top_srcdir@
@@ -210,6 +205,7 @@ SUFFIXES = .tmpl
 static_docs = \
 static_docs = \
 	Bopm.txt \
 	Bopm.txt \
 	Capabilities.txt \
 	Capabilities.txt \
+	Contributing.txt \
 	FAQ.txt \
 	FAQ.txt \
 	GIT.txt \
 	GIT.txt \
 	HowToRelease.txt \
 	HowToRelease.txt \
@@ -578,7 +574,7 @@ uninstall-am:
 
 
 
 
 .tmpl:
 .tmpl:
-	sed \
+	$(AM_V_GEN)sed \
 	    -e s@:ETCDIR:@${sysconfdir}@ \
 	    -e s@:ETCDIR:@${sysconfdir}@ \
 	    <$< >$@
 	    <$< >$@
 
 
@@ -589,8 +585,8 @@ all: $(generated_docs)
 
 
 install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
 install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
 	$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
 	$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
-	if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
-	  $(INSTALL) -m 600 -c sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; \
+	@if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
+	  make install-config; \
 	 fi
 	 fi
 	$(mkinstalldirs) $(DESTDIR)$(docdir)
 	$(mkinstalldirs) $(DESTDIR)$(docdir)
 	for f in $(static_docs) $(toplevel_docs); do \
 	for f in $(static_docs) $(toplevel_docs); do \
@@ -600,12 +596,32 @@ install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
 	  $(INSTALL) -m 644 -c $$f $(DESTDIR)$(docdir)/; \
 	  $(INSTALL) -m 644 -c $$f $(DESTDIR)$(docdir)/; \
 	 done
 	 done
 
 
+install-config:
+	$(INSTALL) -m 600 -c sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf
+	@echo; \
+	 echo " ** NOTE: Installed sample configuration file:"; \
+	 echo " ** \"$(DESTDIR)$(sysconfdir)/ngircd.conf\""; \
+	 echo
+
 uninstall-hook:
 uninstall-hook:
 	rm -rf $(DESTDIR)$(docdir)
 	rm -rf $(DESTDIR)$(docdir)
+	@if cmp --silent sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; then \
+	  make uninstall-config; \
+	 else \
+	  echo; \
+	  echo " ** NOTE: Not uninstalling changed configuration file:"; \
+	  echo " ** \"$(DESTDIR)$(sysconfdir)/ngircd.conf\""; \
+	  echo; \
+	 fi
+
+uninstall-config:
+	rm -f $(DESTDIR)$(sysconfdir)/ngircd.conf
 
 
 srcdoc:
 srcdoc:
 	make -C src srcdoc
 	make -C src srcdoc
 
 
+.PHONY: install-config uninstall-config srcdoc
+
 # -eof-
 # -eof-
 
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Tell versions [3.59,3.63) of GNU make to not export all variables.

+ 12 - 1
doc/Modes.txt

@@ -2,7 +2,7 @@
                      ngIRCd - Next Generation IRC Server
                      ngIRCd - Next Generation IRC Server
                            http://ngircd.barton.de/
                            http://ngircd.barton.de/
 
 
-               (c)2001-2011 Alexander Barton and Contributors.
+               (c)2001-2012 Alexander Barton and Contributors.
                ngIRCd is free software and published under the
                ngIRCd is free software and published under the
                    terms of the GNU General Public License.
                    terms of the GNU General Public License.
 
 
@@ -22,10 +22,13 @@ channels he is using at the moment.
   mode	since	description
   mode	since	description
 
 
   a	0.3.0	User is away.
   a	0.3.0	User is away.
+  b	20	User blocks private messages and notices.
+  B	20	User is flagged as a "bot".
   c	17	IRC operator wants to receive connect/disconnect NOTICEs.
   c	17	IRC operator wants to receive connect/disconnect NOTICEs.
   C	19	Only users that share a channel are allowed to send messages.
   C	19	Only users that share a channel are allowed to send messages.
   i	0.0.1	User is "invisible".
   i	0.0.1	User is "invisible".
   o	0.0.1	User is IRC operator.
   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.
   r	0.0.1	User is restricted.
   R (1)	19	User is registered (e.g. by NickServ).
   R (1)	19	User is registered (e.g. by NickServ).
   s	0.4.0	User wants to receive server notices.
   s	0.4.0	User wants to receive server notices.
@@ -49,13 +52,16 @@ users to lists (e.g. "invite list", "ban list"), others have parameters
   k	0.6.0	Channel has a "key" (a password).
   k	0.6.0	Channel has a "key" (a password).
   l	0.6.0	Channel has a user limit.
   l	0.6.0	Channel has a user limit.
   m	0.3.0	Channel is moderated, only "voiced" users can send messages.
   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	0.3.0	Channel doesn't allow messages of users not being members.
   O	18	Only IRC operators are allowed to join this channel.
   O	18	Only IRC operators are allowed to join this channel.
   P	0.5.0	Channel is "persistent".
   P	0.5.0	Channel is "persistent".
+  Q	20	Nobody can be kicked from the channel.
   r (1)	19	Channel is "registered" (e.g. by ChanServ).
   r (1)	19	Channel is "registered" (e.g. by ChanServ).
   R	19	Only registered users are allowed to join this channel.
   R	19	Only registered users are allowed to join this channel.
   s	0.9.0	Channel is "secret".
   s	0.9.0	Channel is "secret".
   t	0.3.0	Only ChanOps are allowed to modify the channel topic.
   t	0.3.0	Only ChanOps are allowed to modify the channel topic.
+  V	20	Channel doesn't allow invites.
   z	16	Only users connected via SSL are allowed to join the channel.
   z	16	Only users connected via SSL are allowed to join the channel.
 
 
 III. Channel User Modes
 III. Channel User Modes
@@ -66,7 +72,12 @@ channel of which he is a member.
 
 
   mode	since	description
   mode	since	description
 
 
+  q	20	User is channel owner can only be set by a service, other
+		owner and irc op. Can promote other users to q, a, o, h, v.
+  a	20	User is channel admin and can promote other users to v, h, o
   o	0.2.0	User is channel operator and can op/kick/... other members.
   o	0.2.0	User is channel operator and can op/kick/... other members.
+  h	20	User is half op and can set channel modes imntvIbek and kick
+		voiced and normal users.
   v	0.2.0	User is "voiced" and can speak even if channel is moderated.
   v	0.2.0	User is "voiced" and can speak even if channel is moderated.
 
 
 
 

+ 8 - 5
doc/Platforms.txt

@@ -39,8 +39,8 @@ i386/pc/solaris2.9          gcc 3.2.2    CVSHEAD    04-02-24 alex   Y Y Y Y
 i386/pc/solaris2.11         gcc 3.4.3    19         12-02-26 alex   Y Y N Y (4)
 i386/pc/solaris2.11         gcc 3.4.3    19         12-02-26 alex   Y Y N Y (4)
 i386/pc/solaris2.11         gcc 4.2.3    19.1       12-05-29 goetz  Y Y Y Y (4)
 i386/pc/solaris2.11         gcc 4.2.3    19.1       12-05-29 goetz  Y Y Y Y (4)
 i386/unknown/freebsd5.2.1   gcc 3.3.3    0.8.0      04-05-30 alex   Y Y Y Y
 i386/unknown/freebsd5.2.1   gcc 3.3.3    0.8.0      04-05-30 alex   Y Y Y Y
-i386/unknown/freebsd6.2     gcc 3.4.6    19         12-02-26 alex   Y Y Y Y (3)
-i386/unknown/freebsd7.3     gcc 4.2.1    19         12-02-26 alex   Y Y Y Y (3)
+i386/unknown/freebsd6.2     gcc 3.4.6    20~rc1     12-11-13 alex   Y Y Y Y (3)
+i386/unknown/freebsd7.3     gcc 4.2.1    20~rc1     12-11-13 alex   Y Y Y Y (3)
 i686/unknown/gnu0.3         gcc 4.4.5    19         12-02-29 alex   Y Y Y Y
 i686/unknown/gnu0.3         gcc 4.4.5    19         12-02-29 alex   Y Y Y Y
 i686/unkn./kfreebsd7.2-gnu  gcc 4.3.4    15         09-12-02 alex   Y Y Y Y (3)
 i686/unkn./kfreebsd7.2-gnu  gcc 4.3.4    15         09-12-02 alex   Y Y Y Y (3)
 i386/unknown/netbsdelf1.6.2 gcc 2.95.3   18         11-07-10 goetz  Y Y Y Y
 i386/unknown/netbsdelf1.6.2 gcc 2.95.3   18         11-07-10 goetz  Y Y Y Y
@@ -49,6 +49,7 @@ i386/unknown/netbsdelf4.0   gcc 4.1.2    19         12-02-29 alex   Y Y Y Y (3)
 i386/unknown/netbsdelf5.0.2 gcc 4.1.3    19         12-02-26 alex   Y Y Y Y (3)
 i386/unknown/netbsdelf5.0.2 gcc 4.1.3    19         12-02-26 alex   Y Y Y Y (3)
 i386/unknown/openbsd3.9     gcc 3.3.5    0.10.0-p1  06-08-30 alex   Y Y Y Y (3)
 i386/unknown/openbsd3.9     gcc 3.3.5    0.10.0-p1  06-08-30 alex   Y Y Y Y (3)
 i386/unknown/openbsd4.1     gcc 3.3.5    16         10-04-11 alex   Y Y Y Y (3)
 i386/unknown/openbsd4.1     gcc 3.3.5    16         10-04-11 alex   Y Y Y Y (3)
+i586/pc/haiku               gcc 2.95.3   19.2~138   12-10-11 user   Y Y N N
 i586/pc/interix3.5          gcc 3.3      19         12-02-29 alex   Y Y N Y
 i586/pc/interix3.5          gcc 3.3      19         12-02-29 alex   Y Y N Y
 i686/pc/cygwin              gcc 3.3.1    0.8.0      04-05-30 alex   Y Y N Y
 i686/pc/cygwin              gcc 3.3.1    0.8.0      04-05-30 alex   Y Y N Y
 i686/pc/linux-gnu           gcc 2.7.2    19.1       12-05-30 goetz  Y Y Y Y (1)
 i686/pc/linux-gnu           gcc 2.7.2    19.1       12-05-30 goetz  Y Y Y Y (1)
@@ -72,10 +73,12 @@ powerpc/unknown/openbsd3.6  gcc 2.95.3   0.10.0     06-10-08 alex   Y Y N Y
 sparc/sun/solaris2.6        gcc 2.95.3   0.7.x-CVS  03-04-22 alex   Y Y Y Y
 sparc/sun/solaris2.6        gcc 2.95.3   0.7.x-CVS  03-04-22 alex   Y Y Y Y
 sparc/sun/solaris2.7        gcc 3.3      0.8.0      04-05-30 alex   Y Y Y Y
 sparc/sun/solaris2.7        gcc 3.3      0.8.0      04-05-30 alex   Y Y Y Y
 sparc/unkn./netbsdelf1.6.1  gcc 2.95.3   0.8.0      04-05-30 alex   Y Y Y Y
 sparc/unkn./netbsdelf1.6.1  gcc 2.95.3   0.8.0      04-05-30 alex   Y Y Y Y
-x86_64/unknown/freebsd8.1   gcc 4.2.1    19         12-02-26 alex   Y Y Y Y (3)
+x86_64/apple/darwin12.2.0   gcc 4.2.1    20~rc1     12-11-13 alex   Y Y Y Y (3)
+x86_64/unknown/freebsd8.1   gcc 4.2.1    20~rc1     12-11-13 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/unkn./freebsd8.1-gnu gcc 4.4.5    19         12-02-26 alex   Y Y Y Y (3)
-x86_64/unknown/linux-gnu    gcc 4.4.5    19         12-02-26 alex   Y Y Y Y (1)
-x86_64/unknown/openbsd4.7   gcc 3.3.5    19         12-02-26 alex   Y Y Y Y (3)
+x86_64/unknown/linux-gnu    gcc 4.4.5    20~rc1     12-02-26 alex   Y Y Y Y (1)
+x86_64/unknown/openbsd4.7   gcc 3.3.5    20~rc1     12-02-26 alex   Y Y Y Y (3)
+x86_64/unknown/openbsd4.8   gcc 4.2.1    20~rc1     12-11-13 alex   Y Y Y Y (3)
 
 
 
 
 Notes
 Notes

+ 75 - 4
doc/Protocol.txt

@@ -1,9 +1,8 @@
 
 
                      ngIRCd - Next Generation IRC Server
                      ngIRCd - Next Generation IRC Server
+                           http://ngircd.barton.de/
 
 
-                        (c)2001-2008 Alexander Barton,
-                    alex@barton.de, http://www.barton.de/
-
+               (c)2001-2012 Alexander Barton and Contributors.
                ngIRCd is free software and published under the
                ngIRCd is free software and published under the
                    terms of the GNU General Public License.
                    terms of the GNU General Public License.
 
 
@@ -82,11 +81,17 @@ The following <serverflags> are defined at the moment:
 - H: The server supports the "enhanced server handshake", see section II.2
 - H: The server supports the "enhanced server handshake", see section II.2
      for a detailed description.
      for a detailed description.
 
 
+- M: Changing client "metadata" (hostname, real name, ...) using the
+     METADATA command is supported.
+
 - o: IRC operators are allowed to change channel- and channel-user-modes
 - o: IRC operators are allowed to change channel- and channel-user-modes
      even if they aren't channel-operator of the affected channel.
      even if they aren't channel-operator of the affected channel.
 
 
 - S: The server supports the SERVICE command (on this link).
 - S: The server supports the SERVICE command (on this link).
 
 
+- X: Server supports XOP channel modes (owner, admin, halfop) and supports
+     these user prefixes in CHANINFO commands, for example.
+
 - Z: Compressed server links are supported by the server.
 - Z: Compressed server links are supported by the server.
 
 
 Example for a complete <flags> string: "ngircd|0.7.5:CZ".
 Example for a complete <flags> string: "ngircd|0.7.5:CZ".
@@ -134,7 +139,7 @@ protocol which allows at max 15 arguments per command).
 Please see <http://www.irc.org/tech_docs/005.html> for details.
 Please see <http://www.irc.org/tech_docs/005.html> for details.
 
 
 The information exchanged using ISUPPORT can be used to detect configuration
 The information exchanged using ISUPPORT can be used to detect configuration
-incompatibilities (different maximum nick name length, for example) and
+incompatibilities (different maximum nickname length, for example) and
 therefore to disconnect the peer prior to registering it in the network.
 therefore to disconnect the peer prior to registering it in the network.
 
 
 
 
@@ -181,3 +186,69 @@ first command sent to the server, even before USER and NICK commands!
 The <password> must be set in the server configuration file to prevent
 The <password> must be set in the server configuration file to prevent
 unauthorized clients to fake their identity; it is an arbitrary string.
 unauthorized clients to fake their identity; it is an arbitrary string.
 
 
+
+II.5 Client character encoding conversion
+
+     Command: CHARCONV
+  Parameters: <client-charset>
+     Used by: registered clients
+     Replies: RPL_IP_CHARCONV, ERR_IP_CHARCONV
+
+A client can set its character set encoding using the CHARCONV command:
+after receiving such a command, the server translates all message data
+received from the client using the set <client-charset> to the server
+encoding (UTF-8), and all message data which is to be sent to the client
+from the server encoding (UTF-8) to <client-charset>.
+
+The list of supported client character sets is implementation dependent.
+
+If a client sets its <client-charset> to the server encoding (UTF-8),
+it disables all conversions; the connection behaves as if no CHARCONV
+command has been sent at all in this session.
+
+
+II.6 Update client "metadata"
+
+     Command: METADATA
+  Parameters: <target> <key> <value>
+     Used by: servers only
+
+The METADATA command is used on server-links to update "metadata" information
+of clients, like the hostname, the info text ("real name"), or the user name.
+
+The server updates its client database according to the received <key> and
+<value> parameters, and passes the METADATA command on to all the other
+servers in the network that support this command (see section II.1 "Register
+new server link", <serverflag> "M"), even if it doesn't support the given
+<key> itself: unknown <key> names are ignored silently!
+
+The following <key> names are defined:
+
+ - "host": the hostname of a client (can't be empty)
+ - "cloakhost": the cloaked hostname of a client
+ - "info": info text ("real name") of a client
+ - "user": the user name of a client (can't be empty)
+
+
+III. Numerics used by IRC+ Protocol
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The IRC+ protocol uses numerics in the range 800-899 which aren't used by
+RFC 2812 and hopefully don't clash with other implementations ...
+
+Numerics 800-849 are used for status and success messages, and numerics
+850-899 are failure and error messages.
+
+
+III.1 IRC+ status and success numerics
+
+801 - RPL_IP_CHARCONV
+	%1 :Client encoding set"
+
+		%1	client character set
+
+
+III.2 IRC+ failure and error numerics
+
+851 - ERR_IP_CHARCONV
+	:Can't initialize client encoding

+ 60 - 39
doc/Services.txt

@@ -9,17 +9,20 @@
                               -- Services.txt --
                               -- Services.txt --
 
 
 
 
-At the moment, ngIRCd doesn't implement a "special IRC services interface".
-But services acting as a "regular server" are supported, either using the IRC
-protocol defined in RFC 1459 or RFC 2812.
+ngIRCd doesn't implement a "special IRC services interface", but services
+acting as a "regular servers" ("pseudo servers") are supported, either
+using the IRC protocol as defined in RFC 1459 or RFC 2812.
 
 
-Support for Services has been tested using "IRC Services" version 5.x by
-Andrew Church (<http://achurch.org/services/>), Anope 1.9 using a
-preliminary protocol module for ngIRCd (<http://www.anope.org/>), and
-Atheme 7.0.2 or later.
+Support for Services has been tested using
+ - Anope 1.9.8 or later (<http://www.anope.org/>; unreleased!)
+ - Atheme 7.0.2 or later (<http://www.atheme.net>)
+ - "IRC Services" 5.1.x by Andrew Church (<http://achurch.org/services/>)
 
 
 This document describes setting up ngIRCd and these services.
 This document describes setting up ngIRCd and these services.
 
 
+Please let us know if you are successfully using other IRC service packages or
+which problems you encounter -- thanks!
+
 
 
 Setting up ngIRCd
 Setting up ngIRCd
 ~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~
@@ -41,13 +44,21 @@ Example:
 Setting up Anope 1.9.x
 Setting up Anope 1.9.x
 ~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~
 
 
-Anope 1.9.4 (and above) can be used with ngIRCd using a preliminary "ngircd"
-protocol module contained in our contrib/Anope/ directory. Please see the
-file contrib/Anope/README for installation instructions!
+Anope 1.9.8 or later (<http://www.anope.org/>; unreleased as of 2012-11-10)
+may be used with ngIRCd using the "ngircd" protocol module.
+Until Anope 1.9.8 is released, you have to use the sources from the Anope
+development GIT tree, see <http://sourceforge.net/projects/anope/develop/>!
+
+At least the following settings have to be tweaked, in addition to all the
+settings marked as required by Anope:
 
 
-After patching and installing Anope, at least the following configuration
-variables have to be adjusted in data/services.conf, in addition to all the
-settings marked as required:
+In conf/services.conf:
+
+  define
+  {
+	name = "services.host"
+	value = "services.irc.net"
+  }
 
 
   uplink
   uplink
   {
   {
@@ -56,13 +67,46 @@ settings marked as required:
 	password = "123abc"
 	password = "123abc"
   }
   }
 
 
-  serverinfo
+  # Load ngIRCd protocol module
+  module { name = "ngircd" }
+
+  networkinfo
+  {
+	# Must be set to the "MaxNickLength" setting of ngIRCd!
+	nicklen = 9
+
+	chanlen = 50
+  }
+
+In conf/nickserv.conf:
+
+  nickserv
   {
   {
-	name = "services.irc.net"
-	type = "ngircd"
+	# not required if you are running ngIRCd with a higher nickname limit
+	# ("MaxNickLength") than 11 characters, but REQUIRED by default!
+	guestnickprefix = "G-"
   }
   }
 
 
 
 
+Setting up Atheme 7.0.2 or later
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Atheme 7.0.2 or later (<http://www.atheme.net>) may be used with ngIRCd using
+the "ngircd" protocol module.
+
+The following settings need to be in atheme.conf:
+
+  loadmodule "modules/protocol/ngircd";
+
+  uplink "server.irc.net" {
+	password = "123abc";
+	port = 6667;
+  };
+
+The documentation of Atheme can be found in the doc/ directory of the
+Atheme source distribution.
+
+
 Setting up IRC Services 5.1.x
 Setting up IRC Services 5.1.x
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
@@ -92,26 +136,3 @@ In modules.conf:
 
 
 The documentation of IRC Services can be found here:
 The documentation of IRC Services can be found here:
 <http://www.ircservices.za.net/docs/>
 <http://www.ircservices.za.net/docs/>
-
-
-Setting up Atheme 7.0.2 or later
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Atheme 7.0.2 or later may be used with ngIRCd using the "ngircd" protocol
-module.
-
-The following settings need to be in atheme.conf:
-
-loadmodule "modules/protocol/ngircd";
-
-uplink "server.irc.net" {
-	password = "123abc";
-	port = 6667;
-};
-
-The documentation of Atheme can be found in the doc/ directory of the
-Atheme source distribution.
-
-
-Please let us know if you are successfully using other IRC service packages or
-which problems you encounter, thanks!

+ 22 - 12
doc/sample-ngircd.conf.tmpl

@@ -95,11 +95,15 @@
 	# Maximum number of channels a user can be member of (0: no limit):
 	# Maximum number of channels a user can be member of (0: no limit):
 	;MaxJoins = 10
 	;MaxJoins = 10
 
 
-	# Maximum length of an user nick name (Default: 9, as in RFC 2812).
+	# Maximum length of an user nickname (Default: 9, as in RFC 2812).
 	# Please note that all servers in an IRC network MUST use the same
 	# Please note that all servers in an IRC network MUST use the same
-	# maximum nick name length!
+	# maximum nickname length!
 	;MaxNickLength = 9
 	;MaxNickLength = 9
 
 
+	# Maximum number of channels returned in response to a /list
+	# command (0: unlimited):
+	;MaxListSize = 100
+
 	# After <PingTimeout> seconds of inactivity the server will send a
 	# After <PingTimeout> seconds of inactivity the server will send a
 	# PING to the peer to test whether it is alive or not.
 	# PING to the peer to test whether it is alive or not.
 	;PingTimeout = 120
 	;PingTimeout = 120
@@ -125,17 +129,19 @@
 	;ChrootDir = /var/empty
 	;ChrootDir = /var/empty
 
 
 	# Set this hostname for every client instead of the real one.
 	# Set this hostname for every client instead of the real one.
-	# Please note: don't use the percentage sign ("%"), it is reserved for
-	# future extensions!
+	# Use %x to add the hashed value of the original hostname.
 	;CloakHost = cloaked.host
 	;CloakHost = cloaked.host
 
 
 	# Use this hostname for hostname cloaking on clients that have the
 	# Use this hostname for hostname cloaking on clients that have the
 	# user mode "+x" set, instead of the name of the server.
 	# user mode "+x" set, instead of the name of the server.
-	# Please note: don't use the percentage sign ("%"), it is reserved for
-	# future extensions!
+	# Use %x to add the hashed value of the original hostname.
 	;CloakHostModeX = cloaked.user
 	;CloakHostModeX = cloaked.user
 
 
-	# Set every clients' user name to their nick name
+	# The Salt for cloaked hostname hashing. When undefined a random
+	# hash is generated after each server start.
+	;CloakHostSalt = abcdefghijklmnopqrstuvwxyz
+
+	# Set every clients' user name to their nickname
 	;CloakUserToNick = yes
 	;CloakUserToNick = yes
 
 
 	# Try to connect to other IRC servers using IPv4 and IPv6, if possible.
 	# Try to connect to other IRC servers using IPv4 and IPv6, if possible.
@@ -163,6 +169,9 @@
 	# they are not(!) channel-operators?
 	# they are not(!) channel-operators?
 	;OperCanUseMode = no
 	;OperCanUseMode = no
 
 
+	# Should IRC Operators get AutoOp (+o) in persistent (+P) channels?
+	;OperChanPAutoOp = yes
+
 	# Mask IRC Operator mode requests as if they were coming from the
 	# Mask IRC Operator mode requests as if they were coming from the
 	# server? (This is a compatibility hack for ircd-irc2 servers)
 	# server? (This is a compatibility hack for ircd-irc2 servers)
 	;OperServerMode = no
 	;OperServerMode = no
@@ -232,7 +241,7 @@
 	# [Operator] sections are used to define IRC Operators. There may be
 	# [Operator] sections are used to define IRC Operators. There may be
 	# more than one [Operator] block, one for each local operator.
 	# more than one [Operator] block, one for each local operator.
 
 
-	# ID of the operator (may be different of the nick name)
+	# ID of the operator (may be different of the nickname)
 	;Name = TheOper
 	;Name = TheOper
 
 
 	# Password of the IRC operator
 	# Password of the IRC operator
@@ -295,15 +304,16 @@
 	# Connect to the remote server using TLS/SSL (Default: false)
 	# Connect to the remote server using TLS/SSL (Default: false)
 	;SSLConnect = yes
 	;SSLConnect = yes
 
 
-	# Define a (case insensitive) mask matching nick names that should be
-	# treated as IRC services when introduced via this remote server.
+	# Define a (case insensitive) list of masks matching nicknames that
+	# should be treated as IRC services when introduced via this remote
+	# server, separated by commas (",").
 	# REGULAR SERVERS DON'T NEED this parameter, so leave it empty
 	# REGULAR SERVERS DON'T NEED this parameter, so leave it empty
 	# (which is the default).
 	# (which is the default).
 	# When you are connecting IRC services which mask as a IRC server
 	# When you are connecting IRC services which mask as a IRC server
 	# and which use "virtual users" to communicate with, for example
 	# and which use "virtual users" to communicate with, for example
 	# "NickServ" and "ChanServ", you should set this parameter to
 	# "NickServ" and "ChanServ", you should set this parameter to
-	# something like "*Serv".
-	;ServiceMask = *Serv
+	# something like "*Serv" or "NickServ,ChanServ,XyzServ".
+	;ServiceMask = *Serv,Global
 
 
 [Server]
 [Server]
 	# More [Server] sections, if you like ...
 	# More [Server] sections, if you like ...

+ 1 - 6
doc/src/Makefile.in

@@ -44,11 +44,10 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 build_triplet = @build@
 host_triplet = @host@
 host_triplet = @host@
-target_triplet = @target@
 subdir = doc/src
 subdir = doc/src
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 mkinstalldirs = $(install_sh) -d
@@ -158,11 +157,7 @@ sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 sysconfdir = @sysconfdir@
-target = @target@
 target_alias = @target_alias@
 target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 top_srcdir = @top_srcdir@

+ 1 - 1
man/Makefile.am

@@ -17,7 +17,7 @@ TEMPLATE_MANS = ngircd.conf.5.tmpl ngircd.8.tmpl
 SUFFIXES = .tmpl .
 SUFFIXES = .tmpl .
 
 
 .tmpl:
 .tmpl:
-	sed \
+	$(AM_V_GEN)sed \
 	    -e s@:SBINDIR:@${sbindir}@ \
 	    -e s@:SBINDIR:@${sbindir}@ \
 	    -e s@:BINDIR:@${bindir}@ \
 	    -e s@:BINDIR:@${bindir}@ \
 	    -e s@:ETCDIR:@${sysconfdir}@ \
 	    -e s@:ETCDIR:@${sysconfdir}@ \

+ 2 - 7
man/Makefile.in

@@ -47,11 +47,10 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 build_triplet = @build@
 host_triplet = @host@
 host_triplet = @host@
-target_triplet = @target@
 subdir = man
 subdir = man
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 mkinstalldirs = $(install_sh) -d
@@ -187,11 +186,7 @@ sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 sysconfdir = @sysconfdir@
-target = @target@
 target_alias = @target_alias@
 target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 top_srcdir = @top_srcdir@
@@ -478,7 +473,7 @@ uninstall-man: uninstall-man5 uninstall-man8
 
 
 
 
 .tmpl:
 .tmpl:
-	sed \
+	$(AM_V_GEN)sed \
 	    -e s@:SBINDIR:@${sbindir}@ \
 	    -e s@:SBINDIR:@${sbindir}@ \
 	    -e s@:BINDIR:@${bindir}@ \
 	    -e s@:BINDIR:@${bindir}@ \
 	    -e s@:ETCDIR:@${sysconfdir}@ \
 	    -e s@:ETCDIR:@${sysconfdir}@ \

+ 17 - 12
man/ngircd.8.tmpl

@@ -1,30 +1,35 @@
 .\"
 .\"
 .\" ngircd(8) manual page template
 .\" ngircd(8) manual page template
 .\"
 .\"
-.TH ngircd 8 "Mar 2012" ngircd "ngIRCd Manual"
+.TH ngircd 8 "Oct 2012" ngIRCd "ngIRCd Manual"
 .SH NAME
 .SH NAME
-ngIRCd \- the next generation IRC daemon
+ngIRCd \- the "next generation" IRC daemon
 .SH SYNOPSIS
 .SH SYNOPSIS
-.B ngircd [
+.B ngircd
+[
 .I Options
 .I Options
-.B ]
+]
 .SH DESCRIPTION
 .SH DESCRIPTION
 .BR ngIRCd
 .BR ngIRCd
-is a free open source daemon for the Internet Relay Chat (IRC),
-developed under the GNU General Public License (GPL).
+is a free, portable and lightweight Internet Relay Chat server for small
+or private networks, developed under the GNU General Public License (GPL).
+It is easy to configure, can cope with dynamic IP addresses, and supports
+IPv6, SSL-protected connections as well as PAM for authentication.
+It is written from scratch and not based on the original IRCd.
 .PP
 .PP
-It's written from scratch and is not based upon the original IRCd like
-many others. It is easy to configure, supports server links (even with
-original ircd's) and runs on hosts with changing IP addresses (such as
-dial-in networks).
+The name ngIRCd means
+.IR "next generation IRC daemon",
+which is a little bit exaggerated:
+.IR "lightweight Internet Relay Chat server"
+most probably would have been a better name :-)
 .PP
 .PP
 Currently supported platforms include AIX, A/UX, FreeBSD, HP-UX, IRIX,
 Currently supported platforms include AIX, A/UX, FreeBSD, HP-UX, IRIX,
 Linux, Mac OS X, NetBSD, OpenBSD, Solaris, and Windows with Cygwin.
 Linux, Mac OS X, NetBSD, OpenBSD, Solaris, and Windows with Cygwin.
 .PP
 .PP
 As ngIRCd relies on UNIX standards and uses GNU automake and GNU autoconf
 As ngIRCd relies on UNIX standards and uses GNU automake and GNU autoconf
 there are good chances that it also supports other UNIX-based operating
 there are good chances that it also supports other UNIX-based operating
-systems as well. By default, ngIRCd writes diagnostic and informational messages using
-the syslog mechanism.
+systems as well. By default, ngIRCd writes diagnostic and informational
+messages using the syslog mechanism.
 .SH OPTIONS
 .SH OPTIONS
 The default behavior of
 The default behavior of
 .BR ngircd
 .BR ngircd

+ 24 - 23
man/ngircd.conf.5.tmpl

@@ -1,7 +1,7 @@
 .\"
 .\"
 .\" ngircd.conf(5) manual page template
 .\" ngircd.conf(5) manual page template
 .\"
 .\"
-.TH ngircd.conf 5 "Mar 2012" ngircd "ngIRCd Manual"
+.TH ngircd.conf 5 "Nov 2012" ngIRCd "ngIRCd Manual"
 .SH NAME
 .SH NAME
 ngircd.conf \- configuration file of ngIRCd
 ngircd.conf \- configuration file of ngIRCd
 .SH SYNOPSIS
 .SH SYNOPSIS
@@ -178,10 +178,13 @@ Maximum number of channels a user can be member of (0: no limit).
 Default: 10.
 Default: 10.
 .TP
 .TP
 \fBMaxNickLength\fR (number)
 \fBMaxNickLength\fR (number)
-Maximum length of an user nick name (Default: 9, as in RFC 2812). Please
-note that all servers in an IRC network MUST use the same maximum nick name
+Maximum length of an user nickname (Default: 9, as in RFC 2812). Please
+note that all servers in an IRC network MUST use the same maximum nickname
 length!
 length!
 .TP
 .TP
+\fBMaxListSize\fR (number)
+Maximum number of channels returned in response to a LIST command. Default: 100.
+.TP
 \fBPingTimeout\fR (number)
 \fBPingTimeout\fR (number)
 After <PingTimeout> seconds of inactivity the server will send a PING to
 After <PingTimeout> seconds of inactivity the server will send a PING to
 the peer to test whether it is alive or not. Default: 120.
 the peer to test whether it is alive or not. Default: 120.
@@ -212,27 +215,19 @@ For this to work the server must have been started with root privileges!
 .TP
 .TP
 \fBCloakHost\fR (string)
 \fBCloakHost\fR (string)
 Set this hostname for every client instead of the real one. Default: empty,
 Set this hostname for every client instead of the real one. Default: empty,
-don't change.
-.PP
-.RS
-.B Please note:
-.br
-Don't use the percentage sign ("%"), it is reserved for future extensions!
-.RE
+don't change. Use %x to add the hashed value of the original hostname.
 .TP
 .TP
 \fBCloakHostModeX\fR (string)
 \fBCloakHostModeX\fR (string)
 Use this hostname for hostname cloaking on clients that have the user mode
 Use this hostname for hostname cloaking on clients that have the user mode
 "+x" set, instead of the name of the server. Default: empty, use the name
 "+x" set, instead of the name of the server. Default: empty, use the name
-of the server.
-.PP
-.RS
-.B Please note:
-.br
-Don't use the percentage sign ("%"), it is reserved for future extensions!
-.RE
+of the server. Use %x to add the hashed value of the original hostname
+.TP
+\fBCloakHostSalt\fR (string)
+The Salt for cloaked hostname hashing. When undefined a random hash is
+generated after each server start.
 .TP
 .TP
 \fBCloakUserToNick\fR (boolean)
 \fBCloakUserToNick\fR (boolean)
-Set every clients' user name to their nick name and hide the one supplied
+Set every clients' user name to their nickname and hide the one supplied
 by the IRC client. Default: no.
 by the IRC client. Default: no.
 .TP
 .TP
 \fBConnectIPv4\fR (boolean)
 \fBConnectIPv4\fR (boolean)
@@ -276,6 +271,10 @@ while connecting. Default: no.
 Should IRC Operators be allowed to use the MODE command even if they are
 Should IRC Operators be allowed to use the MODE command even if they are
 not(!) channel-operators? Default: no.
 not(!) channel-operators? Default: no.
 .TP
 .TP
+\fBOperChanPAutoOp\fR (boolean)
+Should IRC Operators get AutoOp (+o) in persistent (+P) channels?
+Default: yes.
+.TP
 \fBOperServerMode\fR (boolean)
 \fBOperServerMode\fR (boolean)
 If \fBOperCanUseMode\fR is enabled, this may lead the compatibility problems
 If \fBOperCanUseMode\fR is enabled, this may lead the compatibility problems
 with Servers that run the ircd-irc2 Software. This Option "masks" mode
 with Servers that run the ircd-irc2 Software. This Option "masks" mode
@@ -370,7 +369,7 @@ sections are used to define IRC Operators. There may be more than one
 block, one for each local operator.
 block, one for each local operator.
 .TP
 .TP
 \fBName\fR (string)
 \fBName\fR (string)
-ID of the operator (may be different of the nick name).
+ID of the operator (may be different of the nickname).
 .TP
 .TP
 \fBPassword\fR (string)
 \fBPassword\fR (string)
 Password of the IRC operator.
 Password of the IRC operator.
@@ -430,14 +429,16 @@ You can use the IRC Operator command CONNECT later on to create the link.
 Connect to the remote server using TLS/SSL. Default: false.
 Connect to the remote server using TLS/SSL. Default: false.
 .TP
 .TP
 \fBServiceMask\fR (string)
 \fBServiceMask\fR (string)
-Define a (case insensitive) mask matching nick names that should be treated as
-IRC services when introduced via this remote server. REGULAR SERVERS DON'T NEED
-this parameter, so leave it empty (which is the default).
+Define a (case insensitive) list of masks matching nicknames that should be
+treated as IRC services when introduced via this remote server, separated
+by commas (","). REGULAR SERVERS DON'T NEED this parameter, so leave it empty
+(which is the default).
 .PP
 .PP
 .RS
 .RS
 When you are connecting IRC services which mask as a IRC server and which use
 When you are connecting IRC services which mask as a IRC server and which use
 "virtual users" to communicate with, for example "NickServ" and "ChanServ",
 "virtual users" to communicate with, for example "NickServ" and "ChanServ",
-you should set this parameter to something like "*Serv".
+you should set this parameter to something like "*Serv", "*Serv,OtherNick",
+or "NickServ,ChanServ,XyzServ".
 .SH [CHANNEL]
 .SH [CHANNEL]
 Pre-defined channels can be configured in
 Pre-defined channels can be configured in
 .I [Channel]
 .I [Channel]

+ 1 - 6
src/Makefile.in

@@ -46,12 +46,11 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 build_triplet = @build@
 host_triplet = @host@
 host_triplet = @host@
-target_triplet = @target@
 subdir = src
 subdir = src
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 	$(srcdir)/config.h.in
 	$(srcdir)/config.h.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 mkinstalldirs = $(install_sh) -d
@@ -201,11 +200,7 @@ sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 sysconfdir = @sysconfdir@
-target = @target@
 target_alias = @target_alias@
 target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 top_srcdir = @top_srcdir@

+ 89 - 34
src/config.h.in

@@ -1,4 +1,4 @@
-/* src/config.h.in.  Generated from configure.in by autoheader.  */
+/* src/config.h.in.  Generated from configure.ac by autoheader.  */
 
 
 /* Define if debug-mode should be enabled */
 /* Define if debug-mode should be enabled */
 #undef DEBUG
 #undef DEBUG
@@ -6,24 +6,24 @@
 /* Define if SSP C support is enabled. */
 /* Define if SSP C support is enabled. */
 #undef ENABLE_SSP_CC
 #undef ENABLE_SSP_CC
 
 
+/* Define to 1 if you have the `alarm' function. */
+#undef HAVE_ALARM
+
 /* Define to 1 if you have the <arpa/inet.h> header file. */
 /* Define to 1 if you have the <arpa/inet.h> header file. */
 #undef HAVE_ARPA_INET_H
 #undef HAVE_ARPA_INET_H
 
 
-/* Define to 1 if you have the `bind' function. */
-#undef HAVE_BIND
-
-/* Define to 1 if you have the <ctype.h> header file. */
-#undef HAVE_CTYPE_H
-
 /* Define to 1 if you have the `deflate' function. */
 /* Define to 1 if you have the `deflate' function. */
 #undef HAVE_DEFLATE
 #undef HAVE_DEFLATE
 
 
+/* Define to 1 if you have the `dup2' function. */
+#undef HAVE_DUP2
+
+/* Define to 1 if you have the `endpwent' function. */
+#undef HAVE_ENDPWENT
+
 /* Define to 1 if you have the `epoll_create' function. */
 /* Define to 1 if you have the `epoll_create' function. */
 #undef HAVE_EPOLL_CREATE
 #undef HAVE_EPOLL_CREATE
 
 
-/* Define to 1 if you have the <errno.h> header file. */
-#undef HAVE_ERRNO_H
-
 /* Define to 1 if you have the <fcntl.h> header file. */
 /* Define to 1 if you have the <fcntl.h> header file. */
 #undef HAVE_FCNTL_H
 #undef HAVE_FCNTL_H
 
 
@@ -48,9 +48,15 @@
 /* Define to 1 if you have the `getnameinfo' function. */
 /* Define to 1 if you have the `getnameinfo' function. */
 #undef HAVE_GETNAMEINFO
 #undef HAVE_GETNAMEINFO
 
 
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
 /* Define to 1 if you have the `gnutls_global_init' function. */
 /* Define to 1 if you have the `gnutls_global_init' function. */
 #undef HAVE_GNUTLS_GLOBAL_INIT
 #undef HAVE_GNUTLS_GLOBAL_INIT
 
 
+/* Define to 1 if you have the `iconv_open' function. */
+#undef HAVE_ICONV_OPEN
+
 /* Define to 1 if you have the <ident.h> header file. */
 /* Define to 1 if you have the <ident.h> header file. */
 #undef HAVE_IDENT_H
 #undef HAVE_IDENT_H
 
 
@@ -69,39 +75,39 @@
 /* Define to 1 if you have the `kqueue' function. */
 /* Define to 1 if you have the `kqueue' function. */
 #undef HAVE_KQUEUE
 #undef HAVE_KQUEUE
 
 
-/* Define to 1 if you have the `be' library (-lbe). */
-#undef HAVE_LIBBE
-
 /* Define to 1 if you have the `crypto' library (-lcrypto). */
 /* Define to 1 if you have the `crypto' library (-lcrypto). */
 #undef HAVE_LIBCRYPTO
 #undef HAVE_LIBCRYPTO
 
 
 /* Define to 1 if you have the `gnutls' library (-lgnutls). */
 /* Define to 1 if you have the `gnutls' library (-lgnutls). */
 #undef HAVE_LIBGNUTLS
 #undef HAVE_LIBGNUTLS
 
 
+/* Define to 1 if you have the `iconv' library (-liconv). */
+#undef HAVE_LIBICONV
+
 /* Define to 1 if you have the `ident' library (-lident). */
 /* Define to 1 if you have the `ident' library (-lident). */
 #undef HAVE_LIBIDENT
 #undef HAVE_LIBIDENT
 
 
 /* Define to 1 if you have the `pam' library (-lpam). */
 /* Define to 1 if you have the `pam' library (-lpam). */
 #undef HAVE_LIBPAM
 #undef HAVE_LIBPAM
 
 
-/* Define to 1 if you have the `socket' library (-lsocket). */
-#undef HAVE_LIBSOCKET
-
 /* Define to 1 if you have the `ssl' library (-lssl). */
 /* Define to 1 if you have the `ssl' library (-lssl). */
 #undef HAVE_LIBSSL
 #undef HAVE_LIBSSL
 
 
-/* Define to 1 if you have the `UTIL' library (-lUTIL). */
-#undef HAVE_LIBUTIL
-
 /* Define to 1 if you have the `z' library (-lz). */
 /* Define to 1 if you have the `z' library (-lz). */
 #undef HAVE_LIBZ
 #undef HAVE_LIBZ
 
 
 /* Define to 1 if you have the <malloc.h> header file. */
 /* Define to 1 if you have the <malloc.h> header file. */
 #undef HAVE_MALLOC_H
 #undef HAVE_MALLOC_H
 
 
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
 /* Define to 1 if you have the <memory.h> header file. */
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 #undef HAVE_MEMORY_H
 
 
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
 /* Define to 1 if you have the `mtrace' function. */
 /* Define to 1 if you have the `mtrace' function. */
 #undef HAVE_MTRACE
 #undef HAVE_MTRACE
 
 
@@ -138,9 +144,6 @@
 /* Define to 1 if you have the `setsid' function. */
 /* Define to 1 if you have the `setsid' function. */
 #undef HAVE_SETSID
 #undef HAVE_SETSID
 
 
-/* Define to 1 if you have the `setsockopt' function. */
-#undef HAVE_SETSOCKOPT
-
 /* Define to 1 if you have the `sigaction' function. */
 /* Define to 1 if you have the `sigaction' function. */
 #undef HAVE_SIGACTION
 #undef HAVE_SIGACTION
 
 
@@ -171,9 +174,18 @@
 /* Define to 1 if you have the `strcasecmp' function. */
 /* Define to 1 if you have the `strcasecmp' function. */
 #undef HAVE_STRCASECMP
 #undef HAVE_STRCASECMP
 
 
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strcspn' function. */
+#undef HAVE_STRCSPN
+
 /* Define to 1 if you have the `strdup' function. */
 /* Define to 1 if you have the `strdup' function. */
 #undef HAVE_STRDUP
 #undef HAVE_STRDUP
 
 
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
 /* Define to 1 if you have the `strftime' function. */
 /* Define to 1 if you have the `strftime' function. */
 #undef HAVE_STRFTIME
 #undef HAVE_STRFTIME
 
 
@@ -189,12 +201,21 @@
 /* Define to 1 if you have the `strlcpy' function. */
 /* Define to 1 if you have the `strlcpy' function. */
 #undef HAVE_STRLCPY
 #undef HAVE_STRLCPY
 
 
+/* Define to 1 if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
+
+/* Define to 1 if you have the `strrchr' function. */
+#undef HAVE_STRRCHR
+
+/* Define to 1 if you have the `strspn' function. */
+#undef HAVE_STRSPN
+
+/* Define to 1 if you have the `strstr' function. */
+#undef HAVE_STRSTR
+
 /* Define to 1 if you have the `strtok_r' function. */
 /* Define to 1 if you have the `strtok_r' function. */
 #undef HAVE_STRTOK_R
 #undef HAVE_STRTOK_R
 
 
-/* Define to 1 if you have the `syslog' function. */
-#undef HAVE_SYSLOG
-
 /* Define to 1 if you have the <syslog.h> header file. */
 /* Define to 1 if you have the <syslog.h> header file. */
 #undef HAVE_SYSLOG_H
 #undef HAVE_SYSLOG_H
 
 
@@ -249,6 +270,18 @@
 /* Define if socklen_t exists */
 /* Define if socklen_t exists */
 #undef HAVE_socklen_t
 #undef HAVE_socklen_t
 
 
+/* Target CPU name */
+#undef HOST_CPU
+
+/* Target operating system name */
+#undef HOST_OS
+
+/* Target system vendor */
+#undef HOST_VENDOR
+
+/* Define if libiconv can be used, e.g. for CHARCONV */
+#undef ICONV
+
 /* Define if the server should do IDENT requests */
 /* Define if the server should do IDENT requests */
 #undef IDENTAUTH
 #undef IDENTAUTH
 
 
@@ -297,15 +330,6 @@
 /* Define if syslog should be used for logging */
 /* Define if syslog should be used for logging */
 #undef SYSLOG
 #undef SYSLOG
 
 
-/* Target CPU name */
-#undef TARGET_CPU
-
-/* Target operating system name */
-#undef TARGET_OS
-
-/* Target system vendor */
-#undef TARGET_VENDOR
-
 /* Define if TCP wrappers should be used */
 /* Define if TCP wrappers should be used */
 #undef TCPWRAP
 #undef TCPWRAP
 
 
@@ -321,12 +345,25 @@
 /* Define if zlib compression should be enabled */
 /* Define if zlib compression should be enabled */
 #undef ZLIB
 #undef ZLIB
 
 
+/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
+   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+   #define below would cause a syntax error. */
+#undef _UINT32_T
+
+/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
+   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+   #define below would cause a syntax error. */
+#undef _UINT8_T
+
 /* Define like PROTOTYPES; this can be used by system headers. */
 /* Define like PROTOTYPES; this can be used by system headers. */
 #undef __PROTOTYPES
 #undef __PROTOTYPES
 
 
 /* Define to empty if `const' does not conform to ANSI C. */
 /* Define to empty if `const' does not conform to ANSI C. */
 #undef const
 #undef const
 
 
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
 /* Define to `__inline__' or `__inline' if that's what the C compiler
 /* Define to `__inline__' or `__inline' if that's what the C compiler
    calls it, or to nothing if 'inline' is not supported under any name.  */
    calls it, or to nothing if 'inline' is not supported under any name.  */
 #ifndef __cplusplus
 #ifndef __cplusplus
@@ -339,5 +376,23 @@
 /* Define to `unsigned int' if <sys/types.h> does not define. */
 /* Define to `unsigned int' if <sys/types.h> does not define. */
 #undef size_t
 #undef size_t
 
 
+/* Define to `int' if <sys/types.h> does not define. */
+#undef ssize_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
+
+/* Define to the type of an unsigned integer type of width exactly 16 bits if
+   such a type exists and the standard includes do not define it. */
+#undef uint16_t
+
+/* Define to the type of an unsigned integer type of width exactly 32 bits if
+   such a type exists and the standard includes do not define it. */
+#undef uint32_t
+
+/* Define to the type of an unsigned integer type of width exactly 8 bits if
+   such a type exists and the standard includes do not define it. */
+#undef uint8_t
+
 /* Define as `fork' if `vfork' does not work. */
 /* Define as `fork' if `vfork' does not work. */
 #undef vfork
 #undef vfork

+ 10 - 3
src/ipaddr/Makefile.am

@@ -1,6 +1,13 @@
-AUTOMAKE_OPTIONS = ansi2knr
+#
+# ipaddr/Makefile.am
+# (c) 2008 Florian Westphal <fw@strlen.de>, public domain.
+#
 
 
-INCLUDES = -I$(srcdir)/../portab
+AUTOMAKE_OPTIONS = ../portab/ansi2knr
+
+EXTRA_DIST = Makefile.ng
+
+AM_CPPFLAGS = -I$(srcdir)/../portab
 
 
 noinst_LIBRARIES = libngipaddr.a
 noinst_LIBRARIES = libngipaddr.a
 
 
@@ -9,6 +16,6 @@ libngipaddr_a_SOURCES = ng_ipaddr.c
 noinst_HEADERS = ng_ipaddr.h
 noinst_HEADERS = ng_ipaddr.h
 
 
 maintainer-clean-local:
 maintainer-clean-local:
-	rm -f Makefile Makefile.in
+	rm -f Makefile Makefile.in Makefile.am
 
 
 # -eof-
 # -eof-

+ 25 - 29
src/ipaddr/Makefile.in

@@ -15,6 +15,11 @@
 
 
 @SET_MAKE@
 @SET_MAKE@
 
 
+#
+# ipaddr/Makefile.am
+# (c) 2008 Florian Westphal <fw@strlen.de>, public domain.
+#
+
 
 
 VPATH = @srcdir@
 VPATH = @srcdir@
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgdatadir = $(datadir)/@PACKAGE@
@@ -35,13 +40,12 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 build_triplet = @build@
 host_triplet = @host@
 host_triplet = @host@
-target_triplet = @target@
-ANSI2KNR = @ANSI2KNR@
+ANSI2KNR = ../portab/ansi2knr
 subdir = src/ipaddr
 subdir = src/ipaddr
 DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
 DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
-	$(srcdir)/Makefile.in ansi2knr.1 ansi2knr.c
+	$(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 mkinstalldirs = $(install_sh) -d
@@ -178,16 +182,13 @@ sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 sysconfdir = @sysconfdir@
-target = @target@
 target_alias = @target_alias@
 target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 top_srcdir = @top_srcdir@
-AUTOMAKE_OPTIONS = ansi2knr
-INCLUDES = -I$(srcdir)/../portab
+AUTOMAKE_OPTIONS = ../portab/ansi2knr
+EXTRA_DIST = Makefile.ng
+AM_CPPFLAGS = -I$(srcdir)/../portab
 noinst_LIBRARIES = libngipaddr.a
 noinst_LIBRARIES = libngipaddr.a
 libngipaddr_a_SOURCES = ng_ipaddr.c
 libngipaddr_a_SOURCES = ng_ipaddr.c
 noinst_HEADERS = ng_ipaddr.h
 noinst_HEADERS = ng_ipaddr.h
@@ -238,12 +239,8 @@ mostlyclean-compile:
 
 
 distclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 	-rm -f *.tab.c
-./ansi2knr: ansi2knr.$(OBJEXT)
-	$(LINK) ansi2knr.$(OBJEXT) $(LIBS)
-ansi2knr.$(OBJEXT): $(CONFIG_HEADER)
-
-clean-krextra:
-	-rm -f ansi2knr
+../portab/ansi2knr:
+	$(am__cd) ../portab && $(MAKE) $(AM_MAKEFLAGS) ./ansi2knr
 
 
 mostlyclean-kr:
 mostlyclean-kr:
 	-test "$U" = "" || rm -f *_.c
 	-test "$U" = "" || rm -f *_.c
@@ -353,7 +350,7 @@ distdir: $(DISTFILES)
 	done
 	done
 check-am: all-am
 check-am: all-am
 check: check-am
 check: check-am
-all-am: Makefile $(ANSI2KNR) $(LIBRARIES) $(HEADERS)
+all-am: Makefile $(LIBRARIES) $(HEADERS)
 installdirs:
 installdirs:
 install: install-am
 install: install-am
 install-exec: install-exec-am
 install-exec: install-exec-am
@@ -382,8 +379,7 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 clean: clean-am
 
 
-clean-am: clean-generic clean-krextra clean-noinstLIBRARIES \
-	mostlyclean-am
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
 
 
 distclean: distclean-am
 distclean: distclean-am
 	-rm -rf ./$(DEPDIR)
 	-rm -rf ./$(DEPDIR)
@@ -451,24 +447,24 @@ ps-am:
 
 
 uninstall-am:
 uninstall-am:
 
 
-.MAKE: install-am install-strip
+.MAKE: ../portab/ansi2knr install-am install-strip
 
 
 .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
 .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-	clean-krextra clean-noinstLIBRARIES ctags distclean \
-	distclean-compile distclean-generic distclean-tags distdir dvi \
-	dvi-am html html-am info info-am install install-am \
-	install-data install-data-am install-dvi install-dvi-am \
-	install-exec install-exec-am install-html install-html-am \
-	install-info install-info-am install-man install-pdf \
-	install-pdf-am install-ps install-ps-am install-strip \
-	installcheck installcheck-am installdirs maintainer-clean \
+	clean-noinstLIBRARIES ctags distclean distclean-compile \
+	distclean-generic distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
 	maintainer-clean-generic maintainer-clean-local mostlyclean \
 	maintainer-clean-generic maintainer-clean-local mostlyclean \
 	mostlyclean-compile mostlyclean-generic mostlyclean-kr pdf \
 	mostlyclean-compile mostlyclean-generic mostlyclean-kr pdf \
 	pdf-am ps ps-am tags uninstall uninstall-am
 	pdf-am ps ps-am tags uninstall uninstall-am
 
 
 
 
 maintainer-clean-local:
 maintainer-clean-local:
-	rm -f Makefile Makefile.in
+	rm -f Makefile Makefile.in Makefile.am
 
 
 # -eof-
 # -eof-
 
 

+ 21 - 0
src/ipaddr/Makefile.ng

@@ -0,0 +1,21 @@
+#
+# ipaddr/Makefile.am
+# (c) 2008 Florian Westphal <fw@strlen.de>, public domain.
+#
+
+__ng_Makefile_am_template__
+
+EXTRA_DIST = Makefile.ng
+
+AM_CPPFLAGS = -I$(srcdir)/../portab
+
+noinst_LIBRARIES = libngipaddr.a
+
+libngipaddr_a_SOURCES = ng_ipaddr.c
+
+noinst_HEADERS = ng_ipaddr.h
+
+maintainer-clean-local:
+	rm -f Makefile Makefile.in Makefile.am
+
+# -eof-

+ 0 - 36
src/ipaddr/ansi2knr.1

@@ -1,36 +0,0 @@
-.TH ANSI2KNR 1 "19 Jan 1996"
-.SH NAME
-ansi2knr \- convert ANSI C to Kernighan & Ritchie C
-.SH SYNOPSIS
-.I ansi2knr
-[--varargs] input_file [output_file]
-.SH DESCRIPTION
-If no output_file is supplied, output goes to stdout.
-.br
-There are no error messages.
-.sp
-.I ansi2knr
-recognizes function definitions by seeing a non-keyword identifier at the left
-margin, followed by a left parenthesis, with a right parenthesis as the last
-character on the line, and with a left brace as the first token on the
-following line (ignoring possible intervening comments).  It will recognize a
-multi-line header provided that no intervening line ends with a left or right
-brace or a semicolon.  These algorithms ignore whitespace and comments, except
-that the function name must be the first thing on the line.
-.sp
-The following constructs will confuse it:
-.br
-     - Any other construct that starts at the left margin and follows the
-above syntax (such as a macro or function call).
-.br
-     - Some macros that tinker with the syntax of the function header.
-.sp
-The --varargs switch is obsolete, and is recognized only for
-backwards compatibility.  The present version of
-.I ansi2knr
-will always attempt to convert a ... argument to va_alist and va_dcl.
-.SH AUTHOR
-L. Peter Deutsch <ghost@aladdin.com> wrote the original ansi2knr and
-continues to maintain the current version; most of the code in the current
-version is his work.  ansi2knr also includes contributions by Francois
-Pinard <pinard@iro.umontreal.ca> and Jim Avera <jima@netcom.com>.

+ 0 - 739
src/ipaddr/ansi2knr.c

@@ -1,739 +0,0 @@
-/* Copyright (C) 1989, 2000 Aladdin Enterprises.  All rights reserved. */
-
-/*$Id: ansi2knr.c,v 1.14 2003/09/06 05:36:56 eggert Exp $*/
-/* Convert ANSI C function definitions to K&R ("traditional C") syntax */
-
-/*
-ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY.  No author or distributor accepts responsibility to anyone for the
-consequences of using it or for whether it serves any particular purpose or
-works at all, unless he says so in writing.  Refer to the GNU General Public
-License (the "GPL") for full details.
-
-Everyone is granted permission to copy, modify and redistribute ansi2knr,
-but only under the conditions described in the GPL.  A copy of this license
-is supposed to have been given to you along with ansi2knr so you can know
-your rights and responsibilities.  It should be in a file named COPYLEFT,
-or, if there is no file named COPYLEFT, a file named COPYING.  Among other
-things, the copyright notice and this notice must be preserved on all
-copies.
-
-We explicitly state here what we believe is already implied by the GPL: if
-the ansi2knr program is distributed as a separate set of sources and a
-separate executable file which are aggregated on a storage medium together
-with another program, this in itself does not bring the other program under
-the GPL, nor does the mere fact that such a program or the procedures for
-constructing it invoke the ansi2knr executable bring any other part of the
-program under the GPL.
-*/
-
-/*
- * Usage:
-	ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]
- * --filename provides the file name for the #line directive in the output,
- * overriding input_file (if present).
- * If no input_file is supplied, input is read from stdin.
- * If no output_file is supplied, output goes to stdout.
- * There are no error messages.
- *
- * ansi2knr recognizes function definitions by seeing a non-keyword
- * identifier at the left margin, followed by a left parenthesis, with a
- * right parenthesis as the last character on the line, and with a left
- * brace as the first token on the following line (ignoring possible
- * intervening comments and/or preprocessor directives), except that a line
- * consisting of only
- *	identifier1(identifier2)
- * will not be considered a function definition unless identifier2 is
- * the word "void", and a line consisting of
- *	identifier1(identifier2, <<arbitrary>>)
- * will not be considered a function definition.
- * ansi2knr will recognize a multi-line header provided that no intervening
- * line ends with a left or right brace or a semicolon.  These algorithms
- * ignore whitespace, comments, and preprocessor directives, except that
- * the function name must be the first thing on the line.  The following
- * constructs will confuse it:
- *	- Any other construct that starts at the left margin and
- *	    follows the above syntax (such as a macro or function call).
- *	- Some macros that tinker with the syntax of function headers.
- */
-
-/*
- * The original and principal author of ansi2knr is L. Peter Deutsch
- * <ghost@aladdin.com>.  Other authors are noted in the change history
- * that follows (in reverse chronological order):
-
-	lpd 2000-04-12 backs out Eggert's changes because of bugs:
-	- concatlits didn't declare the type of its bufend argument;
-	- concatlits didn't recognize when it was inside a comment;
-	- scanstring could scan backward past the beginning of the string; when
-	- the check for \ + newline in scanstring was unnecessary.
-
-	2000-03-05  Paul Eggert  <eggert@twinsun.com>
-
-	Add support for concatenated string literals.
-	* ansi2knr.c (concatlits): New decl.
-	(main): Invoke concatlits to concatenate string literals.
-	(scanstring): Handle backslash-newline correctly.  Work with
-	character constants.  Fix bug when scanning backwards through
-	backslash-quote.  Check for unterminated strings.
-	(convert1): Parse character constants, too.
-	(appendline, concatlits): New functions.
-	* ansi2knr.1: Document this.
-
-	lpd 1999-08-17 added code to allow preprocessor directives
-		wherever comments are allowed
-	lpd 1999-04-12 added minor fixes from Pavel Roskin
-		<pavel_roskin@geocities.com> for clean compilation with
-		gcc -W -Wall
-	lpd 1999-03-22 added hack to recognize lines consisting of
-		identifier1(identifier2, xxx) as *not* being procedures
-	lpd 1999-02-03 made indentation of preprocessor commands consistent
-	lpd 1999-01-28 fixed two bugs: a '/' in an argument list caused an
-		endless loop; quoted strings within an argument list
-		confused the parser
-	lpd 1999-01-24 added a check for write errors on the output,
-		suggested by Jim Meyering <meyering@ascend.com>
-	lpd 1998-11-09 added further hack to recognize identifier(void)
-		as being a procedure
-	lpd 1998-10-23 added hack to recognize lines consisting of
-		identifier1(identifier2) as *not* being procedures
-	lpd 1997-12-08 made input_file optional; only closes input and/or
-		output file if not stdin or stdout respectively; prints
-		usage message on stderr rather than stdout; adds
-		--filename switch (changes suggested by
-		<ceder@lysator.liu.se>)
-	lpd 1996-01-21 added code to cope with not HAVE_CONFIG_H and with
-		compilers that don't understand void, as suggested by
-		Tom Lane
-	lpd 1996-01-15 changed to require that the first non-comment token
-		on the line following a function header be a left brace,
-		to reduce sensitivity to macros, as suggested by Tom Lane
-		<tgl@sss.pgh.pa.us>
-	lpd 1995-06-22 removed #ifndefs whose sole purpose was to define
-		undefined preprocessor symbols as 0; changed all #ifdefs
-		for configuration symbols to #ifs
-	lpd 1995-04-05 changed copyright notice to make it clear that
-		including ansi2knr in a program does not bring the entire
-		program under the GPL
-	lpd 1994-12-18 added conditionals for systems where ctype macros
-		don't handle 8-bit characters properly, suggested by
-		Francois Pinard <pinard@iro.umontreal.ca>;
-		removed --varargs switch (this is now the default)
-	lpd 1994-10-10 removed CONFIG_BROKETS conditional
-	lpd 1994-07-16 added some conditionals to help GNU `configure',
-		suggested by Francois Pinard <pinard@iro.umontreal.ca>;
-		properly erase prototype args in function parameters,
-		contributed by Jim Avera <jima@netcom.com>;
-		correct error in writeblanks (it shouldn't erase EOLs)
-	lpd 1989-xx-xx original version
- */
-
-/* Most of the conditionals here are to make ansi2knr work with */
-/* or without the GNU configure machinery. */
-
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <ctype.h>
-
-#if HAVE_CONFIG_H
-
-/*
-   For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
-   This will define HAVE_CONFIG_H and so, activate the following lines.
- */
-
-# if STDC_HEADERS || HAVE_STRING_H
-#  include <string.h>
-# else
-#  include <strings.h>
-# endif
-
-#else /* not HAVE_CONFIG_H */
-
-/* Otherwise do it the hard way */
-
-# ifdef BSD
-#  include <strings.h>
-# else
-#  ifdef VMS
-    extern int strlen(), strncmp();
-#  else
-#   include <string.h>
-#  endif
-# endif
-
-#endif /* not HAVE_CONFIG_H */
-
-#if STDC_HEADERS
-# include <stdlib.h>
-#else
-/*
-   malloc and free should be declared in stdlib.h,
-   but if you've got a K&R compiler, they probably aren't.
- */
-# ifdef MSDOS
-#  include <malloc.h>
-# else
-#  ifdef VMS
-     extern char *malloc();
-     extern void free();
-#  else
-     extern char *malloc();
-     extern int free();
-#  endif
-# endif
-
-#endif
-
-/* Define NULL (for *very* old compilers). */
-#ifndef NULL
-# define NULL (0)
-#endif
-
-/*
- * The ctype macros don't always handle 8-bit characters correctly.
- * Compensate for this here.
- */
-#ifdef isascii
-# undef HAVE_ISASCII		/* just in case */
-# define HAVE_ISASCII 1
-#else
-#endif
-#if STDC_HEADERS || !HAVE_ISASCII
-# define is_ascii(c) 1
-#else
-# define is_ascii(c) isascii(c)
-#endif
-
-#define is_space(c) (is_ascii(c) && isspace(c))
-#define is_alpha(c) (is_ascii(c) && isalpha(c))
-#define is_alnum(c) (is_ascii(c) && isalnum(c))
-
-/* Scanning macros */
-#define isidchar(ch) (is_alnum(ch) || (ch) == '_')
-#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
-
-/* Forward references */
-char *ppdirforward();
-char *ppdirbackward();
-char *skipspace();
-char *scanstring();
-int writeblanks();
-int test1();
-int convert1();
-
-/* The main program */
-int
-main(argc, argv)
-    int argc;
-    char *argv[];
-{	FILE *in = stdin;
-	FILE *out = stdout;
-	char *filename = 0;
-	char *program_name = argv[0];
-	char *output_name = 0;
-#define bufsize 5000			/* arbitrary size */
-	char *buf;
-	char *line;
-	char *more;
-	char *usage =
-	  "Usage: ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]\n";
-	/*
-	 * In previous versions, ansi2knr recognized a --varargs switch.
-	 * If this switch was supplied, ansi2knr would attempt to convert
-	 * a ... argument to va_alist and va_dcl; if this switch was not
-	 * supplied, ansi2knr would simply drop any such arguments.
-	 * Now, ansi2knr always does this conversion, and we only
-	 * check for this switch for backward compatibility.
-	 */
-	int convert_varargs = 1;
-	int output_error;
-
-	while ( argc > 1 && argv[1][0] == '-' ) {
-	  if ( !strcmp(argv[1], "--varargs") ) {
-	    convert_varargs = 1;
-	    argc--;
-	    argv++;
-	    continue;
-	  }
-	  if ( !strcmp(argv[1], "--filename") && argc > 2 ) {
-	    filename = argv[2];
-	    argc -= 2;
-	    argv += 2;
-	    continue;
-	  }
-	  fprintf(stderr, "%s: Unrecognized switch: %s\n", program_name,
-		  argv[1]);
-	  fprintf(stderr, usage);
-	  exit(1);
-	}
-	switch ( argc )
-	   {
-	default:
-		fprintf(stderr, usage);
-		exit(0);
-	case 3:
-		output_name = argv[2];
-		out = fopen(output_name, "w");
-		if ( out == NULL ) {
-		  fprintf(stderr, "%s: Cannot open output file %s\n",
-			  program_name, output_name);
-		  exit(1);
-		}
-		/* falls through */
-	case 2:
-		in = fopen(argv[1], "r");
-		if ( in == NULL ) {
-		  fprintf(stderr, "%s: Cannot open input file %s\n",
-			  program_name, argv[1]);
-		  exit(1);
-		}
-		if ( filename == 0 )
-		  filename = argv[1];
-		/* falls through */
-	case 1:
-		break;
-	   }
-	if ( filename )
-	  fprintf(out, "#line 1 \"%s\"\n", filename);
-	buf = malloc(bufsize);
-	if ( buf == NULL )
-	   {
-		fprintf(stderr, "Unable to allocate read buffer!\n");
-		exit(1);
-	   }
-	line = buf;
-	while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
-	   {
-test:		line += strlen(line);
-		switch ( test1(buf) )
-		   {
-		case 2:			/* a function header */
-			convert1(buf, out, 1, convert_varargs);
-			break;
-		case 1:			/* a function */
-			/* Check for a { at the start of the next line. */
-			more = ++line;
-f:			if ( line >= buf + (bufsize - 1) ) /* overflow check */
-			  goto wl;
-			if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL )
-			  goto wl;
-			switch ( *skipspace(ppdirforward(more), 1) )
-			  {
-			  case '{':
-			    /* Definitely a function header. */
-			    convert1(buf, out, 0, convert_varargs);
-			    fputs(more, out);
-			    break;
-			  case 0:
-			    /* The next line was blank or a comment: */
-			    /* keep scanning for a non-comment. */
-			    line += strlen(line);
-			    goto f;
-			  default:
-			    /* buf isn't a function header, but */
-			    /* more might be. */
-			    fputs(buf, out);
-			    strcpy(buf, more);
-			    line = buf;
-			    goto test;
-			  }
-			break;
-		case -1:		/* maybe the start of a function */
-			if ( line != buf + (bufsize - 1) ) /* overflow check */
-			  continue;
-			/* falls through */
-		default:		/* not a function */
-wl:			fputs(buf, out);
-			break;
-		   }
-		line = buf;
-	   }
-	if ( line != buf )
-	  fputs(buf, out);
-	free(buf);
-	if ( output_name ) {
-	  output_error = ferror(out);
-	  output_error |= fclose(out);
-	} else {		/* out == stdout */
-	  fflush(out);
-	  output_error = ferror(out);
-	}
-	if ( output_error ) {
-	  fprintf(stderr, "%s: error writing to %s\n", program_name,
-		  (output_name ? output_name : "stdout"));
-	  exit(1);
-	}
-	if ( in != stdin )
-	  fclose(in);
-	return 0;
-}
-
-/*
- * Skip forward or backward over one or more preprocessor directives.
- */
-char *
-ppdirforward(p)
-    char *p;
-{
-    for (; *p == '#'; ++p) {
-	for (; *p != '\r' && *p != '\n'; ++p)
-	    if (*p == 0)
-		return p;
-	if (*p == '\r' && p[1] == '\n')
-	    ++p;
-    }
-    return p;
-}
-char *
-ppdirbackward(p, limit)
-    char *p;
-    char *limit;
-{
-    char *np = p;
-
-    for (;; p = --np) {
-	if (*np == '\n' && np[-1] == '\r')
-	    --np;
-	for (; np > limit && np[-1] != '\r' && np[-1] != '\n'; --np)
-	    if (np[-1] == 0)
-		return np;
-	if (*np != '#')
-	    return p;
-    }
-}
-
-/*
- * Skip over whitespace, comments, and preprocessor directives,
- * in either direction.
- */
-char *
-skipspace(p, dir)
-    char *p;
-    int dir;			/* 1 for forward, -1 for backward */
-{
-    for ( ; ; ) {
-	while ( is_space(*p) )
-	    p += dir;
-	if ( !(*p == '/' && p[dir] == '*') )
-	    break;
-	p += dir;  p += dir;
-	while ( !(*p == '*' && p[dir] == '/') ) {
-	    if ( *p == 0 )
-		return p;	/* multi-line comment?? */
-	    p += dir;
-	}
-	p += dir;  p += dir;
-    }
-    return p;
-}
-
-/* Scan over a quoted string, in either direction. */
-char *
-scanstring(p, dir)
-    char *p;
-    int dir;
-{
-    for (p += dir; ; p += dir)
-	if (*p == '"' && p[-dir] != '\\')
-	    return p + dir;
-}
-
-/*
- * Write blanks over part of a string.
- * Don't overwrite end-of-line characters.
- */
-int
-writeblanks(start, end)
-    char *start;
-    char *end;
-{	char *p;
-	for ( p = start; p < end; p++ )
-	  if ( *p != '\r' && *p != '\n' )
-	    *p = ' ';
-	return 0;
-}
-
-/*
- * Test whether the string in buf is a function definition.
- * The string may contain and/or end with a newline.
- * Return as follows:
- *	0 - definitely not a function definition;
- *	1 - definitely a function definition;
- *	2 - definitely a function prototype (NOT USED);
- *	-1 - may be the beginning of a function definition,
- *		append another line and look again.
- * The reason we don't attempt to convert function prototypes is that
- * Ghostscript's declaration-generating macros look too much like
- * prototypes, and confuse the algorithms.
- */
-int
-test1(buf)
-    char *buf;
-{	char *p = buf;
-	char *bend;
-	char *endfn;
-	int contin;
-
-	if ( !isidfirstchar(*p) )
-	  return 0;		/* no name at left margin */
-	bend = skipspace(ppdirbackward(buf + strlen(buf) - 1, buf), -1);
-	switch ( *bend )
-	   {
-	   case ';': contin = 0 /*2*/; break;
-	   case ')': contin = 1; break;
-	   case '{': return 0;		/* not a function */
-	   case '}': return 0;		/* not a function */
-	   default: contin = -1;
-	   }
-	while ( isidchar(*p) )
-	  p++;
-	endfn = p;
-	p = skipspace(p, 1);
-	if ( *p++ != '(' )
-	  return 0;		/* not a function */
-	p = skipspace(p, 1);
-	if ( *p == ')' )
-	  return 0;		/* no parameters */
-	/* Check that the apparent function name isn't a keyword. */
-	/* We only need to check for keywords that could be followed */
-	/* by a left parenthesis (which, unfortunately, is most of them). */
-	   {	static char *words[] =
-		   {	"asm", "auto", "case", "char", "const", "double",
-			"extern", "float", "for", "if", "int", "long",
-			"register", "return", "short", "signed", "sizeof",
-			"static", "switch", "typedef", "unsigned",
-			"void", "volatile", "while", 0
-		   };
-		char **key = words;
-		char *kp;
-		unsigned len = endfn - buf;
-
-		while ( (kp = *key) != 0 )
-		   {	if ( strlen(kp) == len && !strncmp(kp, buf, len) )
-			  return 0;	/* name is a keyword */
-			key++;
-		   }
-	   }
-	   {
-	       char *id = p;
-	       int len;
-	       /*
-		* Check for identifier1(identifier2) and not
-		* identifier1(void), or identifier1(identifier2, xxxx).
-		*/
-
-	       while ( isidchar(*p) )
-		   p++;
-	       len = p - id;
-	       p = skipspace(p, 1);
-	       if (*p == ',' ||
-		   (*p == ')' && (len != 4 || strncmp(id, "void", 4)))
-		   )
-		   return 0;	/* not a function */
-	   }
-	/*
-	 * If the last significant character was a ), we need to count
-	 * parentheses, because it might be part of a formal parameter
-	 * that is a procedure.
-	 */
-	if (contin > 0) {
-	    int level = 0;
-
-	    for (p = skipspace(buf, 1); *p; p = skipspace(p + 1, 1))
-		level += (*p == '(' ? 1 : *p == ')' ? -1 : 0);
-	    if (level > 0)
-		contin = -1;
-	}
-	return contin;
-}
-
-/* Convert a recognized function definition or header to K&R syntax. */
-int
-convert1(buf, out, header, convert_varargs)
-    char *buf;
-    FILE *out;
-    int header;			/* Boolean */
-    int convert_varargs;	/* Boolean */
-{	char *endfn;
-	char *p;
-	/*
-	 * The breaks table contains pointers to the beginning and end
-	 * of each argument.
-	 */
-	char **breaks;
-	unsigned num_breaks = 2;	/* for testing */
-	char **btop;
-	char **bp;
-	char **ap;
-	char *vararg = 0;
-
-	/* Pre-ANSI implementations don't agree on whether strchr */
-	/* is called strchr or index, so we open-code it here. */
-	for ( endfn = buf; *(endfn++) != '('; )
-	  ;
-top:	p = endfn;
-	breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
-	if ( breaks == NULL )
-	   {	/* Couldn't allocate break table, give up */
-		fprintf(stderr, "Unable to allocate break table!\n");
-		fputs(buf, out);
-		return -1;
-	   }
-	btop = breaks + num_breaks * 2 - 2;
-	bp = breaks;
-	/* Parse the argument list */
-	do
-	   {	int level = 0;
-		char *lp = NULL;
-		char *rp = NULL;
-		char *end = NULL;
-
-		if ( bp >= btop )
-		   {	/* Filled up break table. */
-			/* Allocate a bigger one and start over. */
-			free((char *)breaks);
-			num_breaks <<= 1;
-			goto top;
-		   }
-		*bp++ = p;
-		/* Find the end of the argument */
-		for ( ; end == NULL; p++ )
-		   {	switch(*p)
-			   {
-			   case ',':
-				if ( !level ) end = p;
-				break;
-			   case '(':
-				if ( !level ) lp = p;
-				level++;
-				break;
-			   case ')':
-				if ( --level < 0 ) end = p;
-				else rp = p;
-				break;
-			   case '/':
-				if (p[1] == '*')
-				    p = skipspace(p, 1) - 1;
-				break;
-			   case '"':
-			       p = scanstring(p, 1) - 1;
-			       break;
-			   default:
-				;
-			   }
-		   }
-		/* Erase any embedded prototype parameters. */
-		if ( lp && rp )
-		  writeblanks(lp + 1, rp);
-		p--;			/* back up over terminator */
-		/* Find the name being declared. */
-		/* This is complicated because of procedure and */
-		/* array modifiers. */
-		for ( ; ; )
-		   {	p = skipspace(p - 1, -1);
-			switch ( *p )
-			   {
-			   case ']':	/* skip array dimension(s) */
-			   case ')':	/* skip procedure args OR name */
-			   {	int level = 1;
-				while ( level )
-				 switch ( *--p )
-				   {
-				   case ']': case ')':
-				       level++;
-				       break;
-				   case '[': case '(':
-				       level--;
-				       break;
-				   case '/':
-				       if (p > buf && p[-1] == '*')
-					   p = skipspace(p, -1) + 1;
-				       break;
-				   case '"':
-				       p = scanstring(p, -1) + 1;
-				       break;
-				   default: ;
-				   }
-			   }
-				if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
-				   {	/* We found the name being declared */
-					while ( !isidfirstchar(*p) )
-					  p = skipspace(p, 1) + 1;
-					goto found;
-				   }
-				break;
-			   default:
-				goto found;
-			   }
-		   }
-found:		if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
-		  {	if ( convert_varargs )
-			  {	*bp++ = "va_alist";
-				vararg = p-2;
-			  }
-			else
-			  {	p++;
-				if ( bp == breaks + 1 )	/* sole argument */
-				  writeblanks(breaks[0], p);
-				else
-				  writeblanks(bp[-1] - 1, p);
-				bp--;
-			  }
-		   }
-		else
-		   {	while ( isidchar(*p) ) p--;
-			*bp++ = p+1;
-		   }
-		p = end;
-	   }
-	while ( *p++ == ',' );
-	*bp = p;
-	/* Make a special check for 'void' arglist */
-	if ( bp == breaks+2 )
-	   {	p = skipspace(breaks[0], 1);
-		if ( !strncmp(p, "void", 4) )
-		   {	p = skipspace(p+4, 1);
-			if ( p == breaks[2] - 1 )
-			   {	bp = breaks;	/* yup, pretend arglist is empty */
-				writeblanks(breaks[0], p + 1);
-			   }
-		   }
-	   }
-	/* Put out the function name and left parenthesis. */
-	p = buf;
-	while ( p != endfn ) putc(*p, out), p++;
-	/* Put out the declaration. */
-	if ( header )
-	  {	fputs(");", out);
-		for ( p = breaks[0]; *p; p++ )
-		  if ( *p == '\r' || *p == '\n' )
-		    putc(*p, out);
-	  }
-	else
-	  {	for ( ap = breaks+1; ap < bp; ap += 2 )
-		  {	p = *ap;
-			while ( isidchar(*p) )
-			  putc(*p, out), p++;
-			if ( ap < bp - 1 )
-			  fputs(", ", out);
-		  }
-		fputs(")  ", out);
-		/* Put out the argument declarations */
-		for ( ap = breaks+2; ap <= bp; ap += 2 )
-		  (*ap)[-1] = ';';
-		if ( vararg != 0 )
-		  {	*vararg = 0;
-			fputs(breaks[0], out);		/* any prior args */
-			fputs("va_dcl", out);		/* the final arg */
-			fputs(bp[0], out);
-		  }
-		else
-		  fputs(breaks[0], out);
-	  }
-	free((char *)breaks);
-	return 0;
-}

+ 12 - 4
src/ngircd/Makefile.am

@@ -1,6 +1,6 @@
 #
 #
 # ngIRCd -- The Next Generation IRC Daemon
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2012 Alexander Barton (alex@barton.de)
+# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 #
 #
 # This program is free software; you can redistribute it and/or modify
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
@@ -11,7 +11,9 @@
 
 
 AUTOMAKE_OPTIONS = ../portab/ansi2knr
 AUTOMAKE_OPTIONS = ../portab/ansi2knr
 
 
-INCLUDES = -I$(srcdir)/../portab -I$(srcdir)/../tool -I$(srcdir)/../ipaddr
+EXTRA_DIST = Makefile.ng
+
+AM_CPPFLAGS = -I$(srcdir)/../portab -I$(srcdir)/../tool -I$(srcdir)/../ipaddr
 
 
 LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN \
 LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN \
  -varuse -retvalother -emptyret -unrecog
  -varuse -retvalother -emptyret -unrecog
@@ -27,6 +29,7 @@ ngircd_SOURCES = \
 	client-cap.c \
 	client-cap.c \
 	conf.c \
 	conf.c \
 	conn.c \
 	conn.c \
+	conn-encoding.c \
 	conn-func.c \
 	conn-func.c \
 	conn-ssl.c \
 	conn-ssl.c \
 	conn-zip.c \
 	conn-zip.c \
@@ -35,8 +38,10 @@ ngircd_SOURCES = \
 	irc.c \
 	irc.c \
 	irc-cap.c \
 	irc-cap.c \
 	irc-channel.c \
 	irc-channel.c \
+	irc-encoding.c \
 	irc-info.c \
 	irc-info.c \
 	irc-login.c \
 	irc-login.c \
+	irc-metadata.c \
 	irc-mode.c \
 	irc-mode.c \
 	irc-op.c \
 	irc-op.c \
 	irc-oper.c \
 	irc-oper.c \
@@ -68,6 +73,7 @@ noinst_HEADERS = \
 	conf.h \
 	conf.h \
 	conf-ssl.h \
 	conf-ssl.h \
 	conn.h \
 	conn.h \
+	conn-encoding.h \
 	conn-func.h \
 	conn-func.h \
 	conn-ssl.h \
 	conn-ssl.h \
 	conn-zip.h \
 	conn-zip.h \
@@ -77,8 +83,10 @@ noinst_HEADERS = \
 	irc.h \
 	irc.h \
 	irc-cap.h \
 	irc-cap.h \
 	irc-channel.h \
 	irc-channel.h \
+	irc-encoding.h \
 	irc-info.h \
 	irc-info.h \
 	irc-login.h \
 	irc-login.h \
+	irc-metadata.h \
 	irc-mode.h \
 	irc-mode.h \
 	irc-op.h \
 	irc-op.h \
 	irc-oper.h \
 	irc-oper.h \
@@ -101,7 +109,7 @@ clean-local:
 	rm -f check-version check-help lint.out
 	rm -f check-version check-help lint.out
 
 
 maintainer-clean-local:
 maintainer-clean-local:
-	rm -f Makefile Makefile.in
+	rm -f Makefile Makefile.in Makefile.am
 
 
 check-version: Makefile
 check-version: Makefile
 	echo "#!/bin/sh" > check-version
 	echo "#!/bin/sh" > check-version
@@ -120,7 +128,7 @@ lint:
 	for f in *.c; do \
 	for f in *.c; do \
 	 echo "checking $$f ..."; \
 	 echo "checking $$f ..."; \
 	 splint $$f $(LINTARGS) -I$(srcdir) -I$(srcdir)/.. \
 	 splint $$f $(LINTARGS) -I$(srcdir) -I$(srcdir)/.. \
-	  $(INCLUDES) $(AM_CFLAGS) >lint.out 2>&1; \
+	  $(AM_CPPFLAGS) $(AM_CFLAGS) >lint.out 2>&1; \
 	 grep "no warnings" lint.out > /dev/null 2>&1; \
 	 grep "no warnings" lint.out > /dev/null 2>&1; \
 	 if [ $$? -ne 0 ]; then \
 	 if [ $$? -ne 0 ]; then \
 	  waswarning=1; \
 	  waswarning=1; \

+ 49 - 23
src/ngircd/Makefile.in

@@ -17,7 +17,7 @@
 
 
 #
 #
 # ngIRCd -- The Next Generation IRC Daemon
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2012 Alexander Barton (alex@barton.de)
+# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 #
 #
 # This program is free software; you can redistribute it and/or modify
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
@@ -46,14 +46,13 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 build_triplet = @build@
 host_triplet = @host@
 host_triplet = @host@
-target_triplet = @target@
 ANSI2KNR = ../portab/ansi2knr
 ANSI2KNR = ../portab/ansi2knr
 sbin_PROGRAMS = ngircd$(EXEEXT)
 sbin_PROGRAMS = ngircd$(EXEEXT)
 subdir = src/ngircd
 subdir = src/ngircd
 DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
 DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in
 	$(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
 	$(ACLOCAL_M4)
 mkinstalldirs = $(install_sh) -d
 mkinstalldirs = $(install_sh) -d
@@ -65,16 +64,17 @@ PROGRAMS = $(sbin_PROGRAMS)
 am_ngircd_OBJECTS = ngircd$U.$(OBJEXT) array$U.$(OBJEXT) \
 am_ngircd_OBJECTS = ngircd$U.$(OBJEXT) array$U.$(OBJEXT) \
 	channel$U.$(OBJEXT) class$U.$(OBJEXT) client$U.$(OBJEXT) \
 	channel$U.$(OBJEXT) class$U.$(OBJEXT) client$U.$(OBJEXT) \
 	client-cap$U.$(OBJEXT) conf$U.$(OBJEXT) conn$U.$(OBJEXT) \
 	client-cap$U.$(OBJEXT) conf$U.$(OBJEXT) conn$U.$(OBJEXT) \
-	conn-func$U.$(OBJEXT) conn-ssl$U.$(OBJEXT) \
-	conn-zip$U.$(OBJEXT) hash$U.$(OBJEXT) io$U.$(OBJEXT) \
-	irc$U.$(OBJEXT) irc-cap$U.$(OBJEXT) irc-channel$U.$(OBJEXT) \
+	conn-encoding$U.$(OBJEXT) conn-func$U.$(OBJEXT) \
+	conn-ssl$U.$(OBJEXT) conn-zip$U.$(OBJEXT) hash$U.$(OBJEXT) \
+	io$U.$(OBJEXT) irc$U.$(OBJEXT) irc-cap$U.$(OBJEXT) \
+	irc-channel$U.$(OBJEXT) irc-encoding$U.$(OBJEXT) \
 	irc-info$U.$(OBJEXT) irc-login$U.$(OBJEXT) \
 	irc-info$U.$(OBJEXT) irc-login$U.$(OBJEXT) \
-	irc-mode$U.$(OBJEXT) irc-op$U.$(OBJEXT) irc-oper$U.$(OBJEXT) \
-	irc-server$U.$(OBJEXT) irc-write$U.$(OBJEXT) lists$U.$(OBJEXT) \
-	log$U.$(OBJEXT) login$U.$(OBJEXT) match$U.$(OBJEXT) \
-	numeric$U.$(OBJEXT) op$U.$(OBJEXT) pam$U.$(OBJEXT) \
-	parse$U.$(OBJEXT) proc$U.$(OBJEXT) resolve$U.$(OBJEXT) \
-	sighandlers$U.$(OBJEXT)
+	irc-metadata$U.$(OBJEXT) irc-mode$U.$(OBJEXT) \
+	irc-op$U.$(OBJEXT) irc-oper$U.$(OBJEXT) irc-server$U.$(OBJEXT) \
+	irc-write$U.$(OBJEXT) lists$U.$(OBJEXT) log$U.$(OBJEXT) \
+	login$U.$(OBJEXT) match$U.$(OBJEXT) numeric$U.$(OBJEXT) \
+	op$U.$(OBJEXT) pam$U.$(OBJEXT) parse$U.$(OBJEXT) \
+	proc$U.$(OBJEXT) resolve$U.$(OBJEXT) sighandlers$U.$(OBJEXT)
 ngircd_OBJECTS = $(am_ngircd_OBJECTS)
 ngircd_OBJECTS = $(am_ngircd_OBJECTS)
 ngircd_DEPENDENCIES =
 ngircd_DEPENDENCIES =
 ngircd_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(ngircd_LDFLAGS) \
 ngircd_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(ngircd_LDFLAGS) \
@@ -104,8 +104,21 @@ DIST_SOURCES = $(ngircd_SOURCES)
 HEADERS = $(noinst_HEADERS)
 HEADERS = $(noinst_HEADERS)
 ETAGS = etags
 ETAGS = etags
 CTAGS = ctags
 CTAGS = ctags
+# If stdout is a non-dumb tty, use colors.  If test -t is not supported,
+# then this fails; a conservative approach.  Of course do not redirect
+# stdout here, just stderr.
 am__tty_colors = \
 am__tty_colors = \
-red=; grn=; lgn=; blu=; std=
+red=; grn=; lgn=; blu=; std=; \
+test "X$(AM_COLOR_TESTS)" != Xno \
+&& test "X$$TERM" != Xdumb \
+&& { test "X$(AM_COLOR_TESTS)" = Xalways || test -t 1 2>/dev/null; } \
+&& { \
+  red=''; \
+  grn=''; \
+  lgn=''; \
+  blu=''; \
+  std=''; \
+}
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
 AMTAR = @AMTAR@
@@ -201,16 +214,13 @@ sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sharedstatedir = @sharedstatedir@
 srcdir = @srcdir@
 srcdir = @srcdir@
 sysconfdir = @sysconfdir@
 sysconfdir = @sysconfdir@
-target = @target@
 target_alias = @target_alias@
 target_alias = @target_alias@
-target_cpu = @target_cpu@
-target_os = @target_os@
-target_vendor = @target_vendor@
 top_build_prefix = @top_build_prefix@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 top_srcdir = @top_srcdir@
 AUTOMAKE_OPTIONS = ../portab/ansi2knr
 AUTOMAKE_OPTIONS = ../portab/ansi2knr
-INCLUDES = -I$(srcdir)/../portab -I$(srcdir)/../tool -I$(srcdir)/../ipaddr
+EXTRA_DIST = Makefile.ng
+AM_CPPFLAGS = -I$(srcdir)/../portab -I$(srcdir)/../tool -I$(srcdir)/../ipaddr
 LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN \
 LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN \
  -varuse -retvalother -emptyret -unrecog
  -varuse -retvalother -emptyret -unrecog
 
 
@@ -223,6 +233,7 @@ ngircd_SOURCES = \
 	client-cap.c \
 	client-cap.c \
 	conf.c \
 	conf.c \
 	conn.c \
 	conn.c \
+	conn-encoding.c \
 	conn-func.c \
 	conn-func.c \
 	conn-ssl.c \
 	conn-ssl.c \
 	conn-zip.c \
 	conn-zip.c \
@@ -231,8 +242,10 @@ ngircd_SOURCES = \
 	irc.c \
 	irc.c \
 	irc-cap.c \
 	irc-cap.c \
 	irc-channel.c \
 	irc-channel.c \
+	irc-encoding.c \
 	irc-info.c \
 	irc-info.c \
 	irc-login.c \
 	irc-login.c \
+	irc-metadata.c \
 	irc-mode.c \
 	irc-mode.c \
 	irc-op.c \
 	irc-op.c \
 	irc-oper.c \
 	irc-oper.c \
@@ -262,6 +275,7 @@ noinst_HEADERS = \
 	conf.h \
 	conf.h \
 	conf-ssl.h \
 	conf-ssl.h \
 	conn.h \
 	conn.h \
+	conn-encoding.h \
 	conn-func.h \
 	conn-func.h \
 	conn-ssl.h \
 	conn-ssl.h \
 	conn-zip.h \
 	conn-zip.h \
@@ -271,8 +285,10 @@ noinst_HEADERS = \
 	irc.h \
 	irc.h \
 	irc-cap.h \
 	irc-cap.h \
 	irc-channel.h \
 	irc-channel.h \
+	irc-encoding.h \
 	irc-info.h \
 	irc-info.h \
 	irc-login.h \
 	irc-login.h \
+	irc-metadata.h \
 	irc-mode.h \
 	irc-mode.h \
 	irc-op.h \
 	irc-op.h \
 	irc-oper.h \
 	irc-oper.h \
@@ -385,6 +401,7 @@ mostlyclean-kr:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client-cap$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client-cap$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conn$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conn$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conn-encoding$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conn-func$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conn-func$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conn-ssl$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conn-ssl$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conn-zip$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conn-zip$U.Po@am__quote@
@@ -393,8 +410,10 @@ mostlyclean-kr:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-cap$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-cap$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-channel$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-channel$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-encoding$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-info$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-info$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-login$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-login$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-metadata$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-mode$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-mode$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-op$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-op$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-oper$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/irc-oper$U.Po@am__quote@
@@ -442,6 +461,8 @@ conf_.c: conf.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/conf.c; then echo $(srcdir)/conf.c; else echo conf.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/conf.c; then echo $(srcdir)/conf.c; else echo conf.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 conn_.c: conn.c $(ANSI2KNR)
 conn_.c: conn.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/conn.c; then echo $(srcdir)/conn.c; else echo conn.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/conn.c; then echo $(srcdir)/conn.c; else echo conn.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+conn-encoding_.c: conn-encoding.c $(ANSI2KNR)
+	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/conn-encoding.c; then echo $(srcdir)/conn-encoding.c; else echo conn-encoding.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 conn-func_.c: conn-func.c $(ANSI2KNR)
 conn-func_.c: conn-func.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/conn-func.c; then echo $(srcdir)/conn-func.c; else echo conn-func.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/conn-func.c; then echo $(srcdir)/conn-func.c; else echo conn-func.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 conn-ssl_.c: conn-ssl.c $(ANSI2KNR)
 conn-ssl_.c: conn-ssl.c $(ANSI2KNR)
@@ -458,10 +479,14 @@ irc-cap_.c: irc-cap.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/irc-cap.c; then echo $(srcdir)/irc-cap.c; else echo irc-cap.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/irc-cap.c; then echo $(srcdir)/irc-cap.c; else echo irc-cap.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 irc-channel_.c: irc-channel.c $(ANSI2KNR)
 irc-channel_.c: irc-channel.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/irc-channel.c; then echo $(srcdir)/irc-channel.c; else echo irc-channel.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/irc-channel.c; then echo $(srcdir)/irc-channel.c; else echo irc-channel.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+irc-encoding_.c: irc-encoding.c $(ANSI2KNR)
+	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/irc-encoding.c; then echo $(srcdir)/irc-encoding.c; else echo irc-encoding.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 irc-info_.c: irc-info.c $(ANSI2KNR)
 irc-info_.c: irc-info.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/irc-info.c; then echo $(srcdir)/irc-info.c; else echo irc-info.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/irc-info.c; then echo $(srcdir)/irc-info.c; else echo irc-info.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 irc-login_.c: irc-login.c $(ANSI2KNR)
 irc-login_.c: irc-login.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/irc-login.c; then echo $(srcdir)/irc-login.c; else echo irc-login.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/irc-login.c; then echo $(srcdir)/irc-login.c; else echo irc-login.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+irc-metadata_.c: irc-metadata.c $(ANSI2KNR)
+	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/irc-metadata.c; then echo $(srcdir)/irc-metadata.c; else echo irc-metadata.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 irc-mode_.c: irc-mode.c $(ANSI2KNR)
 irc-mode_.c: irc-mode.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/irc-mode.c; then echo $(srcdir)/irc-mode.c; else echo irc-mode.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/irc-mode.c; then echo $(srcdir)/irc-mode.c; else echo irc-mode.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 irc-op_.c: irc-op.c $(ANSI2KNR)
 irc-op_.c: irc-op.c $(ANSI2KNR)
@@ -498,9 +523,10 @@ sighandlers_.c: sighandlers.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/sighandlers.c; then echo $(srcdir)/sighandlers.c; else echo sighandlers.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/sighandlers.c; then echo $(srcdir)/sighandlers.c; else echo sighandlers.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 array_.$(OBJEXT) channel_.$(OBJEXT) class_.$(OBJEXT) client_.$(OBJEXT) \
 array_.$(OBJEXT) channel_.$(OBJEXT) class_.$(OBJEXT) client_.$(OBJEXT) \
 client-cap_.$(OBJEXT) conf_.$(OBJEXT) conn_.$(OBJEXT) \
 client-cap_.$(OBJEXT) conf_.$(OBJEXT) conn_.$(OBJEXT) \
-conn-func_.$(OBJEXT) conn-ssl_.$(OBJEXT) conn-zip_.$(OBJEXT) \
-hash_.$(OBJEXT) io_.$(OBJEXT) irc_.$(OBJEXT) irc-cap_.$(OBJEXT) \
-irc-channel_.$(OBJEXT) irc-info_.$(OBJEXT) irc-login_.$(OBJEXT) \
+conn-encoding_.$(OBJEXT) conn-func_.$(OBJEXT) conn-ssl_.$(OBJEXT) \
+conn-zip_.$(OBJEXT) hash_.$(OBJEXT) io_.$(OBJEXT) irc_.$(OBJEXT) \
+irc-cap_.$(OBJEXT) irc-channel_.$(OBJEXT) irc-encoding_.$(OBJEXT) \
+irc-info_.$(OBJEXT) irc-login_.$(OBJEXT) irc-metadata_.$(OBJEXT) \
 irc-mode_.$(OBJEXT) irc-op_.$(OBJEXT) irc-oper_.$(OBJEXT) \
 irc-mode_.$(OBJEXT) irc-op_.$(OBJEXT) irc-oper_.$(OBJEXT) \
 irc-server_.$(OBJEXT) irc-write_.$(OBJEXT) lists_.$(OBJEXT) \
 irc-server_.$(OBJEXT) irc-write_.$(OBJEXT) lists_.$(OBJEXT) \
 log_.$(OBJEXT) login_.$(OBJEXT) match_.$(OBJEXT) ngircd_.$(OBJEXT) \
 log_.$(OBJEXT) login_.$(OBJEXT) match_.$(OBJEXT) ngircd_.$(OBJEXT) \
@@ -806,7 +832,7 @@ clean-local:
 	rm -f check-version check-help lint.out
 	rm -f check-version check-help lint.out
 
 
 maintainer-clean-local:
 maintainer-clean-local:
-	rm -f Makefile Makefile.in
+	rm -f Makefile Makefile.in Makefile.am
 
 
 check-version: Makefile
 check-version: Makefile
 	echo "#!/bin/sh" > check-version
 	echo "#!/bin/sh" > check-version
@@ -825,7 +851,7 @@ lint:
 	for f in *.c; do \
 	for f in *.c; do \
 	 echo "checking $$f ..."; \
 	 echo "checking $$f ..."; \
 	 splint $$f $(LINTARGS) -I$(srcdir) -I$(srcdir)/.. \
 	 splint $$f $(LINTARGS) -I$(srcdir) -I$(srcdir)/.. \
-	  $(INCLUDES) $(AM_CFLAGS) >lint.out 2>&1; \
+	  $(AM_CPPFLAGS) $(AM_CFLAGS) >lint.out 2>&1; \
 	 grep "no warnings" lint.out > /dev/null 2>&1; \
 	 grep "no warnings" lint.out > /dev/null 2>&1; \
 	 if [ $$? -ne 0 ]; then \
 	 if [ $$? -ne 0 ]; then \
 	  waswarning=1; \
 	  waswarning=1; \

+ 152 - 0
src/ngircd/Makefile.ng

@@ -0,0 +1,152 @@
+#
+# ngIRCd -- The Next Generation IRC Daemon
+# Copyright (c)2001-2012 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
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# Please read the file COPYING, README and AUTHORS for more information.
+#
+
+__ng_Makefile_am_template__
+
+EXTRA_DIST = Makefile.ng
+
+AM_CPPFLAGS = -I$(srcdir)/../portab -I$(srcdir)/../tool -I$(srcdir)/../ipaddr
+
+LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN \
+ -varuse -retvalother -emptyret -unrecog
+
+sbin_PROGRAMS = ngircd
+
+ngircd_SOURCES = \
+	ngircd.c \
+	array.c \
+	channel.c \
+	class.c \
+	client.c \
+	client-cap.c \
+	conf.c \
+	conn.c \
+	conn-encoding.c \
+	conn-func.c \
+	conn-ssl.c \
+	conn-zip.c \
+	hash.c \
+	io.c \
+	irc.c \
+	irc-cap.c \
+	irc-channel.c \
+	irc-encoding.c \
+	irc-info.c \
+	irc-login.c \
+	irc-metadata.c \
+	irc-mode.c \
+	irc-op.c \
+	irc-oper.c \
+	irc-server.c \
+	irc-write.c \
+	lists.c \
+	log.c \
+	login.c \
+	match.c \
+	numeric.c \
+	op.c \
+	pam.c \
+	parse.c \
+	proc.c \
+	resolve.c \
+	sighandlers.c
+
+ngircd_LDFLAGS = -L../portab -L../tool -L../ipaddr
+
+ngircd_LDADD = -lngportab -lngtool -lngipaddr
+
+noinst_HEADERS = \
+	ngircd.h \
+	array.h \
+	channel.h \
+	class.h \
+	client.h \
+	client-cap.h \
+	conf.h \
+	conf-ssl.h \
+	conn.h \
+	conn-encoding.h \
+	conn-func.h \
+	conn-ssl.h \
+	conn-zip.h \
+	defines.h \
+	hash.h \
+	io.h \
+	irc.h \
+	irc-cap.h \
+	irc-channel.h \
+	irc-encoding.h \
+	irc-info.h \
+	irc-login.h \
+	irc-metadata.h \
+	irc-mode.h \
+	irc-op.h \
+	irc-oper.h \
+	irc-server.h \
+	irc-write.h \
+	lists.h \
+	log.h \
+	login.h \
+	match.h \
+	messages.h \
+	numeric.h \
+	op.h \
+	pam.h \
+	parse.h \
+	proc.h \
+	resolve.h \
+	sighandlers.h
+
+clean-local:
+	rm -f check-version check-help lint.out
+
+maintainer-clean-local:
+	rm -f Makefile Makefile.in Makefile.am
+
+check-version: Makefile
+	echo "#!/bin/sh" > check-version
+	echo "./ngircd --version | grep ngircd >/dev/null 2>&1" >>check-version
+	chmod 755 check-version
+
+check-help: Makefile
+	echo "#!/bin/sh" > check-help
+	echo "./ngircd --help | grep help >/dev/null 2>&1" >>check-help
+	chmod 755 check-help
+
+lint:
+	@splint --version >/dev/null 2>&1 \
+	 || ( echo; echo "Error: \"splint\" not found!"; echo; exit 1 )
+	@echo; warnings=0; files=0; \
+	for f in *.c; do \
+	 echo "checking $$f ..."; \
+	 splint $$f $(LINTARGS) -I$(srcdir) -I$(srcdir)/.. \
+	  $(AM_CPPFLAGS) $(AM_CFLAGS) >lint.out 2>&1; \
+	 grep "no warnings" lint.out > /dev/null 2>&1; \
+	 if [ $$? -ne 0 ]; then \
+	  waswarning=1; \
+	  echo; grep -v "^Command Line: " lint.out; echo; \
+	  w=$$( grep "code warning" lint.out | $(AWK) "{ print \$$4 }" ); \
+	  [ "$$w" -gt 0 ] && warnings=`expr $$warnings + $$w`; \
+	  files=`expr $$files + 1`; \
+	 else \
+	  waswarning=0; \
+	 fi; \
+	 rm -f lint.out; \
+	done; \
+	[ $$waswarning -eq 0 ] && echo; \
+	[ $$warnings -gt 0 ] \
+	 && echo "Result: $$warnings warning(s) in $$files file(s)!" \
+	 || echo "Result: no warnings found."; \
+	echo; [ $$warnings -gt 0 ] && exit 1
+
+TESTS = check-version check-help
+
+# -eof-

+ 89 - 77
src/ngircd/channel.c

@@ -66,16 +66,8 @@ static void Set_KeyFile PARAMS((CHANNEL *Chan, const char *KeyFile));
 GLOBAL void
 GLOBAL void
 Channel_Init( void )
 Channel_Init( void )
 {
 {
-	CHANNEL *sc;
-
 	My_Channels = NULL;
 	My_Channels = NULL;
 	My_Cl2Chan = NULL;
 	My_Cl2Chan = NULL;
-
-	sc = Channel_Create("&SERVER");
-	if (sc) {
-		Channel_SetModes(sc, "mnPt");
-		Channel_SetTopic(sc, Client_ThisServer(), "Server Messages");
-	}
 } /* Channel_Init */
 } /* Channel_Init */
 
 
 
 
@@ -103,11 +95,12 @@ Channel_GetListInvites(CHANNEL *c)
 }
 }
 
 
 
 
+/**
+ * Generate predefined persistent channels and &SERVER
+ */
 GLOBAL void
 GLOBAL void
 Channel_InitPredefined( void )
 Channel_InitPredefined( void )
 {
 {
-	/* Generate predefined persistent channels */
-
 	CHANNEL *new_chan;
 	CHANNEL *new_chan;
 	const struct Conf_Channel *conf_chan;
 	const struct Conf_Channel *conf_chan;
 	const char *c;
 	const char *c;
@@ -160,6 +153,18 @@ Channel_InitPredefined( void )
 	}
 	}
 	if (channel_count)
 	if (channel_count)
 		array_free(&Conf_Channels);
 		array_free(&Conf_Channels);
+
+	/* Make sure the local &SERVER channel exists */
+	if (!Channel_Search("&SERVER")) {
+		new_chan = Channel_Create("&SERVER");
+		if (new_chan) {
+			Channel_SetModes(new_chan, "mnPt");
+			Channel_SetTopic(new_chan, Client_ThisServer(),
+					 "Server Messages");
+		} else
+			Log(LOG_ERR, "Failed to create \"&SERVER\" channel!");
+	} else
+		LogDebug("Required channel \"&SERVER\" already exists, ok.");
 } /* Channel_InitPredefined */
 } /* Channel_InitPredefined */
 
 
 
 
@@ -294,6 +299,8 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
 	     const char *Reason )
 	     const char *Reason )
 {
 {
 	CHANNEL *chan;
 	CHANNEL *chan;
+	char *ptr, *target_modes;
+	bool can_kick = false;
 
 
 	assert(Peer != NULL);
 	assert(Peer != NULL);
 	assert(Target != NULL);
 	assert(Target != NULL);
@@ -314,14 +321,63 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
 		/* Check that user is on the specified channel */
 		/* Check that user is on the specified channel */
 		if (!Channel_IsMemberOf(chan, Origin)) {
 		if (!Channel_IsMemberOf(chan, Origin)) {
 			IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG,
 			IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG,
-					   Client_ID(Origin), Name);
+					    Client_ID(Origin), Name);
 			return;
 			return;
 		}
 		}
+	}
+
+	if(Client_Type(Peer) == CLIENT_USER) {
+		/* Channel mode 'Q' and user mode 'q' on target: nobody but
+		 * IRC Operators and servers can kick the target user */
+		if ((strchr(Channel_Modes(chan), 'Q')
+		     || Client_HasMode(Target, 'q')
+		     || Client_Type(Target) == CLIENT_SERVICE)
+		    && !Client_HasMode(Origin, 'o')) {
+			IRC_WriteStrClient(Origin, ERR_KICKDENY_MSG,
+					   Client_ID(Origin), Name,
+					   Client_ID(Target));
+			return;
+		}
+
+		/* Check if client has the rights to kick target */
+		ptr = Channel_UserModes(chan, Peer);
+		target_modes = Channel_UserModes(chan, Target);
+		while(*ptr) {
+			/* Owner can kick everyone */
+			if ( *ptr == 'q') {
+				can_kick = true;
+				break;
+			}
+			/* Admin can't kick owner */
+			if ( *ptr == 'a' ) {
+				if (!strchr(target_modes, 'q')) {
+					can_kick = true;
+					break;
+				}
+			}
+			/* Op can't kick owner | admin */
+			if ( *ptr == 'o' ) {
+				if (!strchr(target_modes, 'q') &&
+				    !strchr(target_modes, 'a')) {
+					can_kick = true;
+					break;
+				}
+			}
+			/* Half Op can't kick owner | admin | op */ 
+			if ( *ptr == 'h' ) {
+				if (!strchr(target_modes, 'q') &&
+				    !strchr(target_modes, 'a') &&
+				    !strchr(target_modes, 'o')) {
+					can_kick = true;
+					break;
+				}
+			}
+			ptr++;
+		}
 
 
-		/* Check if user has operator status */
-		if (!strchr(Channel_UserModes(chan, Origin), 'o')) {
-			IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG,
-					   Client_ID(Origin), Name);
+		if(!can_kick) {
+			IRC_WriteStrClient(Origin, ERR_CHANOPPRIVTOOLOW_MSG,
+				Client_ID(Origin), Name);
 			return;
 			return;
 		}
 		}
 	}
 	}
@@ -807,9 +863,9 @@ Channel_SetMaxUsers(CHANNEL *Chan, unsigned long Count)
 static bool
 static bool
 Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
 Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
 {
 {
-	bool is_member, has_voice, is_op;
+	bool is_member, has_voice, is_halfop, is_op, is_chanadmin, is_owner;
 
 
-	is_member = has_voice = is_op = false;
+	is_member = has_voice = is_halfop = is_op = is_chanadmin = is_owner = false;
 
 
 	/* The server itself always can send messages :-) */
 	/* The server itself always can send messages :-) */
 	if (Client_ThisServer() == From)
 	if (Client_ThisServer() == From)
@@ -819,8 +875,14 @@ Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
 		is_member = true;
 		is_member = true;
 		if (strchr(Channel_UserModes(Chan, From), 'v'))
 		if (strchr(Channel_UserModes(Chan, From), 'v'))
 			has_voice = true;
 			has_voice = true;
+		if (strchr(Channel_UserModes(Chan, From), 'h'))
+			is_halfop = true;
 		if (strchr(Channel_UserModes(Chan, From), 'o'))
 		if (strchr(Channel_UserModes(Chan, From), 'o'))
 			is_op = true;
 			is_op = true;
+		if (strchr(Channel_UserModes(Chan, From), 'a'))
+			is_chanadmin = true;
+		if (strchr(Channel_UserModes(Chan, From), 'q'))
+			is_owner = true;
 	}
 	}
 
 
 	/*
 	/*
@@ -832,7 +894,11 @@ Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
 	if (strchr(Channel_Modes(Chan), 'n') && !is_member)
 	if (strchr(Channel_Modes(Chan), 'n') && !is_member)
 		return false;
 		return false;
 
 
-	if (is_op || has_voice)
+	if (strchr(Channel_Modes(Chan), 'M') && !Client_HasMode(From, 'R')
+	    && !Client_HasMode(From, 'o'))
+		return false;
+
+	if (has_voice || is_halfop || is_op || is_chanadmin || is_owner)
 		return true;
 		return true;
 
 
 	if (strchr(Channel_Modes(Chan), 'm'))
 	if (strchr(Channel_Modes(Chan), 'm'))
@@ -852,7 +918,11 @@ Channel_Write(CHANNEL *Chan, CLIENT *From, CLIENT *Client, const char *Command,
 	if (!Can_Send_To_Channel(Chan, From)) {
 	if (!Can_Send_To_Channel(Chan, From)) {
 		if (! SendErrors)
 		if (! SendErrors)
 			return CONNECTED;	/* no error, see RFC 2812 */
 			return CONNECTED;	/* no error, see RFC 2812 */
-		return IRC_WriteStrClient(From, ERR_CANNOTSENDTOCHAN_MSG,
+		if (strchr(Channel_Modes(Chan), 'M'))
+			return IRC_WriteStrClient(From, ERR_NEEDREGGEDNICK_MSG,
+						  Client_ID(From), Channel_Name(Chan));
+		else
+			return IRC_WriteStrClient(From, ERR_CANNOTSENDTOCHAN_MSG,
 					  Client_ID(From), Channel_Name(Chan));
 					  Client_ID(From), Channel_Name(Chan));
 	}
 	}
 
 
@@ -1187,64 +1257,6 @@ Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const char *Key)
 } /* Channel_CheckKey */
 } /* Channel_CheckKey */
 
 
 
 
-/**
- * Check wether a client is allowed to administer a channel or not.
- *
- * @param Chan		The channel to test.
- * @param Client	The client from which the command has been received.
- * @param Origin	The originator of the command (or NULL).
- * @param OnChannel	Set to true if the originator is member of the channel.
- * @param AdminOk	Set to true if the client is allowed to do
- *			administrative tasks on this channel.
- * @param UseServerMode	Set to true if ngIRCd should emulate "server mode",
- *			that is send commands as if originating from a server
- *			and not the originator of the command.
- */
-GLOBAL void
-Channel_CheckAdminRights(CHANNEL *Chan, CLIENT *Client, CLIENT *Origin,
-			 bool *OnChannel, bool *AdminOk, bool *UseServerMode)
-{
-	assert (Chan != NULL);
-	assert (Client != NULL);
-	assert (OnChannel != NULL);
-	assert (AdminOk != NULL);
-	assert (UseServerMode != NULL);
-
-	/* Use the client as origin, if no origin has been given (no prefix?) */
-	if (!Origin)
-		Origin = Client;
-
-	*OnChannel = false;
-	*AdminOk = false;
-	*UseServerMode = false;
-
-	if (Client_Type(Client) != CLIENT_USER
-	    && Client_Type(Client) != CLIENT_SERVER
-	    && Client_Type(Client) != CLIENT_SERVICE)
-		return;
-
-	/* Allow channel administration if the client is a server or service */
-	if (Client_Type(Client) != CLIENT_USER) {
-		*AdminOk = true;
-		return;
-	}
-
-	*OnChannel = Channel_IsMemberOf(Chan, Origin);
-
-	if (*OnChannel && strchr(Channel_UserModes(Chan, Origin), 'o')) {
-		/* User is a channel operator */
-		*AdminOk = true;
-	} else if (Conf_OperCanMode) {
-		/* IRC operators are allowed to administer channels as well */
-		if (Client_OperByMe(Origin)) {
-			*AdminOk = true;
-			if (Conf_OperServerMode)
-				*UseServerMode = true;
-		}
-	}
-} /* Channel_CheckAdminRights */
-
-
 static CL2CHAN *
 static CL2CHAN *
 Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan )
 Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan )
 {
 {

+ 95 - 36
src/ngircd/client.c

@@ -1,6 +1,6 @@
 /*
 /*
  * ngIRCd -- The Next Generation IRC Daemon
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2012 Alexander Barton (alex@barton.de)
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * it under the terms of the GNU General Public License as published by
@@ -331,9 +331,15 @@ Client_SetHostname( CLIENT *Client, const char *Hostname )
 	assert(Hostname != NULL);
 	assert(Hostname != NULL);
 
 
 	if (strlen(Conf_CloakHost)) {
 	if (strlen(Conf_CloakHost)) {
+		char cloak[GETID_LEN];
+
+		strlcpy(cloak, Hostname, GETID_LEN);
+		strlcat(cloak, Conf_CloakHostSalt, GETID_LEN);
+		snprintf(cloak, GETID_LEN, Conf_CloakHost, Hash(cloak));
+
 		LogDebug("Updating hostname of \"%s\": \"%s\" -> \"%s\"",
 		LogDebug("Updating hostname of \"%s\": \"%s\" -> \"%s\"",
-			 Client_ID(Client), Client->host, Conf_CloakHost);
-		strlcpy(Client->host, Conf_CloakHost, sizeof(Client->host));
+			Client_ID(Client), Client->host, cloak);
+		strlcpy(Client->host, cloak, sizeof(Client->host));
 	} else {
 	} else {
 		LogDebug("Updating hostname of \"%s\": \"%s\" -> \"%s\"",
 		LogDebug("Updating hostname of \"%s\": \"%s\" -> \"%s\"",
 			 Client_ID(Client), Client->host, Hostname);
 			 Client_ID(Client), Client->host, Hostname);
@@ -435,18 +441,6 @@ Client_SetFlags( CLIENT *Client, const char *Flags )
 
 
 
 
 GLOBAL void
 GLOBAL void
-Client_SetPassword( CLIENT *Client, const char *Pwd )
-{
-	/* set password sent by client */
-
-	assert( Client != NULL );
-	assert( Pwd != NULL );
-
-	strlcpy(Client->pwd, Pwd, sizeof(Client->pwd));
-} /* Client_SetPassword */
-
-
-GLOBAL void
 Client_SetAway( CLIENT *Client, const char *Txt )
 Client_SetAway( CLIENT *Client, const char *Txt )
 {
 {
 	/* Set AWAY reason of client */
 	/* Set AWAY reason of client */
@@ -677,7 +671,6 @@ Client_OrigUser(CLIENT *Client) {
 
 
 #endif
 #endif
 
 
-
 /**
 /**
  * Return the hostname of a client.
  * Return the hostname of a client.
  * @param Client Pointer to client structure
  * @param Client Pointer to client structure
@@ -688,33 +681,88 @@ Client_Hostname(CLIENT *Client)
 {
 {
 	assert (Client != NULL);
 	assert (Client != NULL);
 	return Client->host;
 	return Client->host;
-} /* Client_Hostname */
+}
 
 
+/**
+ * Return the cloaked hostname of a client, if set.
+ * @param Client Pointer to the client structure.
+ * @return Pointer to the cloaked hostname or NULL if not set.
+ */
+GLOBAL char *
+Client_HostnameCloaked(CLIENT *Client)
+{
+	assert(Client != NULL);
+	return Client->cloaked;
+}
 
 
 /**
 /**
- * Get potentially cloaked hostname of a client.
+ * Get (potentially cloaked) hostname of a client to display it to other users.
+ *
  * If the client has not enabled cloaking, the real hostname is used.
  * If the client has not enabled cloaking, the real hostname is used.
+ * Please note that this function uses a global static buffer, so you can't
+ * nest invocations without overwriting earlier results!
+ *
  * @param Client Pointer to client structure
  * @param Client Pointer to client structure
  * @return Pointer to client hostname
  * @return Pointer to client hostname
  */
  */
 GLOBAL char *
 GLOBAL char *
-Client_HostnameCloaked(CLIENT *Client)
+Client_HostnameDisplayed(CLIENT *Client)
 {
 {
 	assert(Client != NULL);
 	assert(Client != NULL);
-	if (Client_HasMode(Client, 'x'))
-		return Client_ID(Client->introducer);
-	else
+
+	/* Client isn't cloaked at all, return real hostname: */
+	if (!Client_HasMode(Client, 'x'))
 		return Client_Hostname(Client);
 		return Client_Hostname(Client);
-} /* Client_HostnameCloaked */
 
 
+	/* Use an already saved cloaked hostname, if there is one */
+	if (Client->cloaked[0])
+		return Client->cloaked;
 
 
-GLOBAL char *
-Client_Password( CLIENT *Client )
+	Client_UpdateCloakedHostname(Client, NULL, NULL);
+	return Client->cloaked;
+}
+
+/**
+ * Update (and generate, if necessary) the cloaked hostname of a client.
+ *
+ * The newly set cloaked hostname is announced in the network using METADATA
+ * commands to peers that support this feature.
+ *
+ * @param Client The client of which the cloaked hostname should be updated.
+ * @param Origin The originator of the hostname change, or NULL if this server.
+ * @param Hostname The new cloaked hostname, or NULL if it should be generated.
+ */
+GLOBAL void
+Client_UpdateCloakedHostname(CLIENT *Client, CLIENT *Origin,
+			     const char *Hostname)
 {
 {
-	assert( Client != NULL );
-	return Client->pwd;
-} /* Client_Password */
+	static char Cloak_Buffer[CLIENT_HOST_LEN];
 
 
+	assert(Client != NULL);
+	if (!Origin)
+		Origin = Client_ThisServer();
+
+	if (!Hostname) {
+		/* Generate new cloaked hostname */
+		if (*Conf_CloakHostModeX) {
+			strlcpy(Cloak_Buffer, Client->host, CLIENT_HOST_LEN);
+			strlcat(Cloak_Buffer, Conf_CloakHostSalt,
+				CLIENT_HOST_LEN);
+			snprintf(Client->cloaked, sizeof(Client->cloaked),
+				 Conf_CloakHostModeX, Hash(Cloak_Buffer));
+		} else
+			strlcpy(Client->cloaked, Client_ID(Client->introducer),
+				sizeof(Client->cloaked));
+	} else
+		strlcpy(Client->cloaked, Hostname, sizeof(Client->cloaked));
+	LogDebug("Cloaked hostname of \"%s\" updated to \"%s\"",
+		 Client_ID(Client), Client->cloaked);
+
+	/* Inform other servers in the network */
+	IRC_WriteStrServersPrefixFlag(Client_NextHop(Origin), Origin, 'M',
+				      "METADATA %s cloakhost :%s",
+				      Client_ID(Client), Client->cloaked);
+}
 
 
 GLOBAL char *
 GLOBAL char *
 Client_Modes( CLIENT *Client )
 Client_Modes( CLIENT *Client )
@@ -806,10 +854,12 @@ Client_Mask( CLIENT *Client )
 
 
 /**
 /**
  * Return ID of a client with cloaked hostname: "client!user@server-name"
  * Return ID of a client with cloaked hostname: "client!user@server-name"
+ *
  * This client ID is used for IRC prefixes, for example.
  * This client ID is used for IRC prefixes, for example.
  * Please note that this function uses a global static buffer, so you can't
  * Please note that this function uses a global static buffer, so you can't
  * nest invocations without overwriting earlier results!
  * nest invocations without overwriting earlier results!
  * If the client has not enabled cloaking, the real hostname is used.
  * If the client has not enabled cloaking, the real hostname is used.
+ *
  * @param Client Pointer to client structure
  * @param Client Pointer to client structure
  * @return Pointer to global buffer containing the client ID
  * @return Pointer to global buffer containing the client ID
  */
  */
@@ -822,12 +872,11 @@ Client_MaskCloaked(CLIENT *Client)
 
 
 	/* Is the client using cloaking at all? */
 	/* Is the client using cloaking at all? */
 	if (!Client_HasMode(Client, 'x'))
 	if (!Client_HasMode(Client, 'x'))
-	    return Client_Mask(Client);
+		return Client_Mask(Client);
+
+	snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user,
+		 Client_HostnameDisplayed(Client));
 
 
-	snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s",
-		 Client->id, Client->user,
-		 *Conf_CloakHostModeX ? Conf_CloakHostModeX
-				      : Client_ID(Client->introducer));
 	return Mask_Buffer;
 	return Mask_Buffer;
 } /* Client_MaskCloaked */
 } /* Client_MaskCloaked */
 
 
@@ -871,7 +920,7 @@ Client_Away( CLIENT *Client )
  * the appropriate error messages.
  * the appropriate error messages.
  *
  *
  * @param	Client Client that wants to change the nickname.
  * @param	Client Client that wants to change the nickname.
- * @param	Nick New nick name.
+ * @param	Nick New nickname.
  * @returns	true if nickname is valid, false otherwise.
  * @returns	true if nickname is valid, false otherwise.
  */
  */
 GLOBAL bool
 GLOBAL bool
@@ -891,6 +940,16 @@ Client_CheckNick(CLIENT *Client, char *Nick)
 		return false;
 		return false;
 	}
 	}
 
 
+	if (Client_Type(Client) != CLIENT_SERVER
+	    && Client_Type(Client) != CLIENT_SERVICE) {
+		/* Make sure that this isn't a restricted/forbidden nickname */
+		if (Conf_NickIsBlocked(Nick)) {
+			IRC_WriteStrClient(Client, ERR_FORBIDDENNICKNAME_MSG,
+					   Client_ID(Client), Nick);
+			return false;
+		}
+	}
+
 	/* Nickname already registered? */
 	/* Nickname already registered? */
 	if (Client_Search(Nick)) {
 	if (Client_Search(Nick)) {
 		IRC_WriteStrClient(Client, ERR_NICKNAMEINUSE_MSG,
 		IRC_WriteStrClient(Client, ERR_NICKNAMEINUSE_MSG,
@@ -1161,7 +1220,7 @@ Client_Introduce(CLIENT *From, CLIENT *Client, int Type)
 	Client_SetType(Client, Type);
 	Client_SetType(Client, Type);
 
 
 	if (From) {
 	if (From) {
-		if (Conf_IsService(Conf_GetServer(Client_Conn(From)),
+		if (Conf_NickIsService(Conf_GetServer(Client_Conn(From)),
 				   Client_ID(Client)))
 				   Client_ID(Client)))
 			Client_SetType(Client, CLIENT_SERVICE);
 			Client_SetType(Client, CLIENT_SERVICE);
 		LogDebug("%s \"%s\" (+%s) registered (via %s, on %s, %d hop%s).",
 		LogDebug("%s \"%s\" (+%s) registered (via %s, on %s, %d hop%s).",
@@ -1325,7 +1384,7 @@ Client_RegisterWhowas( CLIENT *Client )
 		 sizeof( My_Whowas[slot].id ));
 		 sizeof( My_Whowas[slot].id ));
 	strlcpy( My_Whowas[slot].user, Client_User( Client ),
 	strlcpy( My_Whowas[slot].user, Client_User( Client ),
 		 sizeof( My_Whowas[slot].user ));
 		 sizeof( My_Whowas[slot].user ));
-	strlcpy( My_Whowas[slot].host, Client_HostnameCloaked( Client ),
+	strlcpy( My_Whowas[slot].host, Client_HostnameDisplayed( Client ),
 		 sizeof( My_Whowas[slot].host ));
 		 sizeof( My_Whowas[slot].host ));
 	strlcpy( My_Whowas[slot].info, Client_Info( Client ),
 	strlcpy( My_Whowas[slot].info, Client_Info( Client ),
 		 sizeof( My_Whowas[slot].info ));
 		 sizeof( My_Whowas[slot].info ));

+ 8 - 5
src/ngircd/client.h

@@ -47,8 +47,8 @@ typedef struct _CLIENT
 	CONN_ID conn_id;		/* ID of the connection (if local) or NONE (remote) */
 	CONN_ID conn_id;		/* ID of the connection (if local) or NONE (remote) */
 	struct _CLIENT *introducer;	/* ID of the servers which the client is connected to */
 	struct _CLIENT *introducer;	/* ID of the servers which the client is connected to */
 	struct _CLIENT *topserver;	/* toplevel servers (only valid if client is a server) */
 	struct _CLIENT *topserver;	/* toplevel servers (only valid if client is a server) */
-	char pwd[CLIENT_PASS_LEN];	/* password received of the client */
 	char host[CLIENT_HOST_LEN];	/* hostname of the client */
 	char host[CLIENT_HOST_LEN];	/* hostname of the client */
+	char cloaked[CLIENT_HOST_LEN];	/* cloaked hostname of the client */
 	char user[CLIENT_USER_LEN];	/* user name ("login") */
 	char user[CLIENT_USER_LEN];	/* user name ("login") */
 #if defined(PAM) && defined(IDENTAUTH)
 #if defined(PAM) && defined(IDENTAUTH)
 	char orig_user[CLIENT_USER_LEN];/* user name supplied by USER command */
 	char orig_user[CLIENT_USER_LEN];/* user name supplied by USER command */
@@ -72,7 +72,7 @@ typedef POINTER CLIENT;
 typedef struct _WHOWAS
 typedef struct _WHOWAS
 {
 {
 	time_t time;			/* time stamp of entry or 0 if unused */
 	time_t time;			/* time stamp of entry or 0 if unused */
-	char id[CLIENT_NICK_LEN];	/* client nick name */
+	char id[CLIENT_NICK_LEN];	/* client nickname */
 	char host[CLIENT_HOST_LEN];	/* hostname of the client */
 	char host[CLIENT_HOST_LEN];	/* hostname of the client */
 	char user[CLIENT_USER_LEN];	/* user name ("login") */
 	char user[CLIENT_USER_LEN];	/* user name ("login") */
 	char info[CLIENT_INFO_LEN];	/* long user name */
 	char info[CLIENT_INFO_LEN];	/* long user name */
@@ -108,8 +108,8 @@ GLOBAL char *Client_User PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_OrigUser PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_OrigUser PARAMS(( CLIENT *Client ));
 #endif
 #endif
 GLOBAL char *Client_Hostname PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_Hostname PARAMS(( CLIENT *Client ));
-GLOBAL char *Client_HostnameCloaked PARAMS(( CLIENT *Client ));
-GLOBAL char *Client_Password PARAMS(( CLIENT *Client ));
+GLOBAL char *Client_HostnameCloaked PARAMS((CLIENT *Client));
+GLOBAL char *Client_HostnameDisplayed PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_Modes PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_Modes PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_Flags PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_Flags PARAMS(( CLIENT *Client ));
 GLOBAL CLIENT *Client_Introducer PARAMS(( CLIENT *Client ));
 GLOBAL CLIENT *Client_Introducer PARAMS(( CLIENT *Client ));
@@ -129,7 +129,6 @@ GLOBAL void Client_SetID PARAMS(( CLIENT *Client, const char *Nick ));
 GLOBAL void Client_SetUser PARAMS(( CLIENT *Client, const char *User, bool Idented ));
 GLOBAL void Client_SetUser PARAMS(( CLIENT *Client, const char *User, bool Idented ));
 GLOBAL void Client_SetOrigUser PARAMS(( CLIENT *Client, const char *User ));
 GLOBAL void Client_SetOrigUser PARAMS(( CLIENT *Client, const char *User ));
 GLOBAL void Client_SetInfo PARAMS(( CLIENT *Client, const char *Info ));
 GLOBAL void Client_SetInfo PARAMS(( CLIENT *Client, const char *Info ));
-GLOBAL void Client_SetPassword PARAMS(( CLIENT *Client, const char *Pwd ));
 GLOBAL void Client_SetType PARAMS(( CLIENT *Client, int Type ));
 GLOBAL void Client_SetType PARAMS(( CLIENT *Client, int Type ));
 GLOBAL void Client_SetHops PARAMS(( CLIENT *Client, int Hops ));
 GLOBAL void Client_SetHops PARAMS(( CLIENT *Client, int Hops ));
 GLOBAL void Client_SetToken PARAMS(( CLIENT *Client, int Token ));
 GLOBAL void Client_SetToken PARAMS(( CLIENT *Client, int Token ));
@@ -169,6 +168,10 @@ GLOBAL void Client_Reject PARAMS((CLIENT *Client, const char *Reason,
 				  bool InformClient));
 				  bool InformClient));
 GLOBAL void Client_Introduce PARAMS((CLIENT *From, CLIENT *Client, int Type));
 GLOBAL void Client_Introduce PARAMS((CLIENT *From, CLIENT *Client, int Type));
 
 
+GLOBAL void Client_UpdateCloakedHostname PARAMS((CLIENT *Client,
+						 CLIENT *Originator,
+						 const char *hostname));
+
 
 
 #ifdef DEBUG
 #ifdef DEBUG
 GLOBAL void Client_DebugDump PARAMS((void));
 GLOBAL void Client_DebugDump PARAMS((void));

+ 4 - 8
src/ngircd/conf-ssl.h

@@ -33,19 +33,15 @@ struct ConnSSL_State {
 	SSL *ssl;
 	SSL *ssl;
 #endif
 #endif
 #ifdef HAVE_LIBGNUTLS
 #ifdef HAVE_LIBGNUTLS
-	gnutls_session gnutls_session;
+	gnutls_session_t gnutls_session;
 	void *cookie;		/* pointer to server configuration structure
 	void *cookie;		/* pointer to server configuration structure
 				   (for outgoing connections), or NULL. */
 				   (for outgoing connections), or NULL. */
 #endif
 #endif
 };
 };
 
 
-bool
-ConnSSL_InitLibrary(void);
-#else
-static inline bool
-ConnSSL_InitLibrary(void)
-{ return true; }
-#endif /* SSL_SUPPORT */
+#endif
+
+bool	ConnSSL_InitLibrary(void);
 
 
 #endif /* conf_ssl_h */
 #endif /* conf_ssl_h */
 
 

+ 84 - 18
src/ngircd/conf.c

@@ -18,6 +18,7 @@
 
 
 #include "imp.h"
 #include "imp.h"
 #include <assert.h>
 #include <assert.h>
+#include <ctype.h>
 #include <errno.h>
 #include <errno.h>
 #ifdef PROTOTYPES
 #ifdef PROTOTYPES
 #	include <stdarg.h>
 #	include <stdarg.h>
@@ -34,9 +35,6 @@
 #include <sys/types.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <unistd.h>
 
 
-#ifdef HAVE_CTYPE_H
-# include <ctype.h>
-#endif
 
 
 #include "array.h"
 #include "array.h"
 #include "ngircd.h"
 #include "ngircd.h"
@@ -106,6 +104,8 @@ ConfSSL_Init(void)
 	free(Conf_SSLOptions.DHFile);
 	free(Conf_SSLOptions.DHFile);
 	Conf_SSLOptions.DHFile = NULL;
 	Conf_SSLOptions.DHFile = NULL;
 	array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
 	array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
+
+	array_free(&Conf_SSLOptions.ListenPorts);
 }
 }
 
 
 /**
 /**
@@ -346,10 +346,11 @@ Conf_Test( void )
 
 
 	puts("[LIMITS]");
 	puts("[LIMITS]");
 	printf("  ConnectRetry = %d\n", Conf_ConnectRetry);
 	printf("  ConnectRetry = %d\n", Conf_ConnectRetry);
-	printf("  MaxConnections = %ld\n", Conf_MaxConnections);
+	printf("  MaxConnections = %d\n", Conf_MaxConnections);
 	printf("  MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP);
 	printf("  MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP);
 	printf("  MaxJoins = %d\n", Conf_MaxJoins > 0 ? Conf_MaxJoins : -1);
 	printf("  MaxJoins = %d\n", Conf_MaxJoins > 0 ? Conf_MaxJoins : -1);
 	printf("  MaxNickLength = %u\n", Conf_MaxNickLength - 1);
 	printf("  MaxNickLength = %u\n", Conf_MaxNickLength - 1);
+	printf("  MaxListSize = %d\n", Conf_MaxListSize);
 	printf("  PingTimeout = %d\n", Conf_PingTimeout);
 	printf("  PingTimeout = %d\n", Conf_PingTimeout);
 	printf("  PongTimeout = %d\n", Conf_PongTimeout);
 	printf("  PongTimeout = %d\n", Conf_PongTimeout);
 	puts("");
 	puts("");
@@ -359,6 +360,7 @@ Conf_Test( void )
 	printf("  ChrootDir = %s\n", Conf_Chroot);
 	printf("  ChrootDir = %s\n", Conf_Chroot);
 	printf("  CloakHost = %s\n", Conf_CloakHost);
 	printf("  CloakHost = %s\n", Conf_CloakHost);
 	printf("  CloakHostModeX = %s\n", Conf_CloakHostModeX);
 	printf("  CloakHostModeX = %s\n", Conf_CloakHostModeX);
+	printf("  CloakHostSalt = %s\n", Conf_CloakHostSalt);
 	printf("  CloakUserToNick = %s\n", yesno_to_str(Conf_CloakUserToNick));
 	printf("  CloakUserToNick = %s\n", yesno_to_str(Conf_CloakUserToNick));
 #ifdef WANT_IPV6
 #ifdef WANT_IPV6
 	printf("  ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
 	printf("  ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
@@ -371,6 +373,7 @@ Conf_Test( void )
 	printf("  MorePrivacy = %s\n", yesno_to_str(Conf_MorePrivacy));
 	printf("  MorePrivacy = %s\n", yesno_to_str(Conf_MorePrivacy));
 	printf("  NoticeAuth = %s\n", yesno_to_str(Conf_NoticeAuth));
 	printf("  NoticeAuth = %s\n", yesno_to_str(Conf_NoticeAuth));
 	printf("  OperCanUseMode = %s\n", yesno_to_str(Conf_OperCanMode));
 	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));
 	printf("  OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode));
 #ifdef PAM
 #ifdef PAM
 	printf("  PAM = %s\n", yesno_to_str(Conf_PAM));
 	printf("  PAM = %s\n", yesno_to_str(Conf_PAM));
@@ -478,8 +481,12 @@ Conf_UnsetServer( CONN_ID Idx )
 				 * require the next attempt to be delayed. */
 				 * require the next attempt to be delayed. */
 				Conf_Server[i].lasttry =
 				Conf_Server[i].lasttry =
 					t - Conf_ConnectRetry + RECONNECT_DELAY;
 					t - Conf_ConnectRetry + RECONNECT_DELAY;
-			} else
-				Conf_Server[i].lasttry = t;
+			} else {
+				/* "Short" connection, enforce "ConnectRetry"
+				 * but randomize it a little bit: 15 seconds. */
+				Conf_Server[i].lasttry =
+					t + rand() / (RAND_MAX / 15);
+			}
 		}
 		}
 	}
 	}
 }
 }
@@ -487,7 +494,7 @@ Conf_UnsetServer( CONN_ID Idx )
 /**
 /**
  * Set connection information for specified configured server.
  * Set connection information for specified configured server.
  */
  */
-GLOBAL void
+GLOBAL bool
 Conf_SetServer( int ConfServer, CONN_ID Idx )
 Conf_SetServer( int ConfServer, CONN_ID Idx )
 {
 {
 	assert( ConfServer > NONE );
 	assert( ConfServer > NONE );
@@ -495,13 +502,15 @@ Conf_SetServer( int ConfServer, CONN_ID Idx )
 
 
 	if (Conf_Server[ConfServer].conn_id > NONE &&
 	if (Conf_Server[ConfServer].conn_id > NONE &&
 	    Conf_Server[ConfServer].conn_id != Idx) {
 	    Conf_Server[ConfServer].conn_id != Idx) {
-		Log(LOG_ALERT,
-			"Trying to update connection index for already registered server \"%s\": %d/%d - ignored.",
-			Conf_Server[ConfServer].name,
-			Conf_Server[ConfServer].conn_id, Idx);
-		return;
+		Log(LOG_ERR,
+		    "Connection %d: Server configuration of \"%s\" already in use by connection %d!",
+		    Idx, Conf_Server[ConfServer].name,
+		    Conf_Server[ConfServer].conn_id);
+		Conn_Close(Idx, NULL, "Server configuration already in use", true);
+		return false;
 	}
 	}
 	Conf_Server[ConfServer].conn_id = Idx;
 	Conf_Server[ConfServer].conn_id = Idx;
+	return true;
 }
 }
 
 
 /**
 /**
@@ -635,14 +644,41 @@ Conf_AddServer(const char *Name, UINT16 Port, const char *Host,
 }
 }
 
 
 /**
 /**
- * Check if the given nick name is an service.
+ * Check if the given nickname is reserved for services on a particular server.
  *
  *
- * @returns true if the given nick name belongs to an "IRC service".
+ * @param ConfServer The server index to check.
+ * @param Nick The nickname to check.
+ * @returns true if the given nickname belongs to an "IRC service".
  */
  */
 GLOBAL bool
 GLOBAL bool
-Conf_IsService(int ConfServer, const char *Nick)
+Conf_NickIsService(int ConfServer, const char *Nick)
 {
 {
-	return MatchCaseInsensitive(Conf_Server[ConfServer].svs_mask, Nick);
+	assert (ConfServer >= 0);
+	assert (ConfServer < MAX_SERVERS);
+
+	return MatchCaseInsensitiveList(Conf_Server[ConfServer].svs_mask,
+					Nick, ",");
+}
+
+/**
+ * Check if the given nickname is blocked for "normal client" use.
+ *
+ * @param ConfServer The server index or NONE to check all configured servers.
+ * @param Nick The nickname to check.
+ * @returns true if the given nickname belongs to an "IRC service".
+ */
+GLOBAL bool
+Conf_NickIsBlocked(const char *Nick)
+{
+	int i;
+
+	for(i = 0; i < MAX_SERVERS; i++) {
+		if (!Conf_Server[i].name[0])
+			continue;
+		if (Conf_NickIsService(i, Nick))
+			return true;
+	}
+	return false;
 }
 }
 
 
 /**
 /**
@@ -652,6 +688,7 @@ static void
 Set_Defaults(bool InitServers)
 Set_Defaults(bool InitServers)
 {
 {
 	int i;
 	int i;
+	char random[RANDOM_SALT_LEN + 1];
 
 
 	/* Global */
 	/* Global */
 	strcpy(Conf_ServerName, "");
 	strcpy(Conf_ServerName, "");
@@ -662,6 +699,7 @@ Set_Defaults(bool InitServers)
 		 PACKAGE_NAME, PACKAGE_VERSION);
 		 PACKAGE_NAME, PACKAGE_VERSION);
 	free(Conf_ListenAddress);
 	free(Conf_ListenAddress);
 	Conf_ListenAddress = NULL;
 	Conf_ListenAddress = NULL;
+	array_free(&Conf_ListenPorts);
 	array_free(&Conf_Motd);
 	array_free(&Conf_Motd);
 	strlcpy(Conf_MotdFile, SYSCONFDIR, sizeof(Conf_MotdFile));
 	strlcpy(Conf_MotdFile, SYSCONFDIR, sizeof(Conf_MotdFile));
 	strlcat(Conf_MotdFile, MOTD_FILE, sizeof(Conf_MotdFile));
 	strlcat(Conf_MotdFile, MOTD_FILE, sizeof(Conf_MotdFile));
@@ -675,6 +713,7 @@ Set_Defaults(bool InitServers)
 	Conf_MaxConnectionsIP = 5;
 	Conf_MaxConnectionsIP = 5;
 	Conf_MaxJoins = 10;
 	Conf_MaxJoins = 10;
 	Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
 	Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
+	Conf_MaxListSize = 100;
 	Conf_PingTimeout = 120;
 	Conf_PingTimeout = 120;
 	Conf_PongTimeout = 20;
 	Conf_PongTimeout = 20;
 
 
@@ -686,6 +725,8 @@ Set_Defaults(bool InitServers)
 	strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot));
 	strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot));
 	strcpy(Conf_CloakHost, "");
 	strcpy(Conf_CloakHost, "");
 	strcpy(Conf_CloakHostModeX, "");
 	strcpy(Conf_CloakHostModeX, "");
+	strlcpy(Conf_CloakHostSalt, ngt_RandomStr(random, RANDOM_SALT_LEN),
+		sizeof(Conf_CloakHostSalt));
 	Conf_CloakUserToNick = false;
 	Conf_CloakUserToNick = false;
 	Conf_ConnectIPv4 = true;
 	Conf_ConnectIPv4 = true;
 #ifdef WANT_IPV6
 #ifdef WANT_IPV6
@@ -702,6 +743,7 @@ Set_Defaults(bool InitServers)
 	Conf_MorePrivacy = false;
 	Conf_MorePrivacy = false;
 	Conf_NoticeAuth = false;
 	Conf_NoticeAuth = false;
 	Conf_OperCanMode = false;
 	Conf_OperCanMode = false;
+	Conf_OperChanPAutoOp = true;
 	Conf_OperServerMode = false;
 	Conf_OperServerMode = false;
 #ifdef PAM
 #ifdef PAM
 	Conf_PAM = true;
 	Conf_PAM = true;
@@ -1033,7 +1075,7 @@ Check_ArgIsTrue(const char *Arg)
  *
  *
  * @param Line	Line number in configuration file.
  * @param Line	Line number in configuration file.
  * @raram Arg	Input string.
  * @raram Arg	Input string.
- * @returns	New configured maximum nick name length.
+ * @returns	New configured maximum nickname length.
  */
  */
 static unsigned int
 static unsigned int
 Handle_MaxNickLength(int Line, const char *Arg)
 Handle_MaxNickLength(int Line, const char *Arg)
@@ -1150,6 +1192,7 @@ CheckLegacyGlobalOption(int Line, char *Var, char *Arg)
 	    || strcasecmp(Var, "ConnectIPv4") == 0
 	    || strcasecmp(Var, "ConnectIPv4") == 0
 	    || strcasecmp(Var, "ConnectIPv6") == 0
 	    || strcasecmp(Var, "ConnectIPv6") == 0
 	    || strcasecmp(Var, "OperCanUseMode") == 0
 	    || strcasecmp(Var, "OperCanUseMode") == 0
+	    || strcasecmp(Var, "OperChanPAutoOp") == 0
 	    || strcasecmp(Var, "OperServerMode") == 0
 	    || strcasecmp(Var, "OperServerMode") == 0
 	    || strcasecmp(Var, "PredefChannelsOnly") == 0
 	    || strcasecmp(Var, "PredefChannelsOnly") == 0
 	    || strcasecmp(Var, "SyslogFacility") == 0
 	    || strcasecmp(Var, "SyslogFacility") == 0
@@ -1402,7 +1445,7 @@ Handle_LIMITS(int Line, char *Var, char *Arg)
 		return;
 		return;
 	}
 	}
 	if (strcasecmp(Var, "MaxConnections") == 0) {
 	if (strcasecmp(Var, "MaxConnections") == 0) {
-		Conf_MaxConnections = atol(Arg);
+		Conf_MaxConnections = atoi(Arg);
 		if (!Conf_MaxConnections && strcmp(Arg, "0"))
 		if (!Conf_MaxConnections && strcmp(Arg, "0"))
 			Config_Error_NaN(Line, Var);
 			Config_Error_NaN(Line, Var);
 		return;
 		return;
@@ -1423,6 +1466,12 @@ Handle_LIMITS(int Line, char *Var, char *Arg)
 		Conf_MaxNickLength = Handle_MaxNickLength(Line, Arg);
 		Conf_MaxNickLength = Handle_MaxNickLength(Line, Arg);
 		return;
 		return;
 	}
 	}
+	if (strcasecmp(Var, "MaxListSize") == 0) {
+		Conf_MaxListSize = atoi(Arg);
+		if (!Conf_MaxListSize && strcmp(Arg, "0"))
+			Config_Error_NaN(Line, Var);
+		return;
+	}
 	if (strcasecmp(Var, "PingTimeout") == 0) {
 	if (strcasecmp(Var, "PingTimeout") == 0) {
 		Conf_PingTimeout = atoi(Arg);
 		Conf_PingTimeout = atoi(Arg);
 		if (Conf_PingTimeout < 5) {
 		if (Conf_PingTimeout < 5) {
@@ -1485,6 +1534,12 @@ Handle_OPTIONS(int Line, char *Var, char *Arg)
 			Config_Error_TooLong(Line, Var);
 			Config_Error_TooLong(Line, Var);
 		return;
 		return;
 	}
 	}
+	if (strcasecmp(Var, "CloakHostSalt") == 0) {
+		len = strlcpy(Conf_CloakHostSalt, Arg, sizeof(Conf_CloakHostSalt));
+		if (len >= sizeof(Conf_CloakHostSalt))
+			Config_Error_TooLong(Line, Var);
+		return;
+	}
 	if (strcasecmp(Var, "CloakUserToNick") == 0) {
 	if (strcasecmp(Var, "CloakUserToNick") == 0) {
 		Conf_CloakUserToNick = Check_ArgIsTrue(Arg);
 		Conf_CloakUserToNick = Check_ArgIsTrue(Arg);
 		return;
 		return;
@@ -1519,6 +1574,10 @@ Handle_OPTIONS(int Line, char *Var, char *Arg)
 		Conf_OperCanMode = Check_ArgIsTrue(Arg);
 		Conf_OperCanMode = Check_ArgIsTrue(Arg);
 		return;
 		return;
 	}
 	}
+	if (strcasecmp(Var, "OperChanPAutoOp") == 0) {
+		Conf_OperChanPAutoOp = Check_ArgIsTrue(Arg);
+		return;
+	}
 	if (strcasecmp(Var, "OperServerMode") == 0) {
 	if (strcasecmp(Var, "OperServerMode") == 0) {
 		Conf_OperServerMode = Check_ArgIsTrue(Arg);
 		Conf_OperServerMode = Check_ArgIsTrue(Arg);
 		return;
 		return;
@@ -1875,6 +1934,13 @@ Validate_Config(bool Configtest, bool Rehash)
 	bool config_valid = true;
 	bool config_valid = true;
 	char *ptr;
 	char *ptr;
 
 
+	/* Emit a warning when the config file is not a full path name */
+	if (NGIRCd_ConfFile[0] && NGIRCd_ConfFile[0] != '/') {
+		Config_Error(LOG_WARNING,
+			"Not specifying a full path name to \"%s\" can cause problems when rehashing the server!",
+			NGIRCd_ConfFile);
+	}
+
 	/* Validate configured server name, see RFC 2812 section 2.3.1 */
 	/* Validate configured server name, see RFC 2812 section 2.3.1 */
 	ptr = Conf_ServerName;
 	ptr = Conf_ServerName;
 	do {
 	do {

+ 17 - 7
src/ngircd/conf.h

@@ -1,6 +1,6 @@
 /*
 /*
  * ngIRCd -- The Next Generation IRC Daemon
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * it under the terms of the GNU General Public License as published by
@@ -62,7 +62,7 @@ typedef struct _Conf_Server
 #ifdef SSL_SUPPORT
 #ifdef SSL_SUPPORT
 	bool SSLConnect;		/**< Establish connection using SSL? */
 	bool SSLConnect;		/**< Establish connection using SSL? */
 #endif
 #endif
-	char svs_mask[CLIENT_ID_LEN];	/**< Mask of nick names that should be
+	char svs_mask[CLIENT_ID_LEN];	/**< Mask of nicknames that should be
 					     treated and counted as services */
 					     treated and counted as services */
 } CONF_SERVER;
 } CONF_SERVER;
 
 
@@ -151,6 +151,9 @@ GLOBAL bool Conf_PredefChannelsOnly;
 /** Flag indicating if IRC operators are allowed to always use MODE (true) */
 /** Flag indicating if IRC operators are allowed to always use MODE (true) */
 GLOBAL bool Conf_OperCanMode;
 GLOBAL bool Conf_OperCanMode;
 
 
+/** Flag indicating if IRC operators get AutoOp in persistent (+P) channels */
+GLOBAL bool Conf_OperChanPAutoOp;
+
 /**
 /**
  * If true, mask channel MODE commands of IRC operators to the server.
  * If true, mask channel MODE commands of IRC operators to the server.
  * Background: ircd2 will ignore channel MODE commands if an IRC operator
  * Background: ircd2 will ignore channel MODE commands if an IRC operator
@@ -169,7 +172,10 @@ GLOBAL char Conf_CloakHost[CLIENT_ID_LEN];
 /** Cloaked hostname for clients that did +x */
 /** Cloaked hostname for clients that did +x */
 GLOBAL char Conf_CloakHostModeX[CLIENT_ID_LEN];
 GLOBAL char Conf_CloakHostModeX[CLIENT_ID_LEN];
 
 
-/** Use nick name as user name? */
+/** Salt for hostname hash for cloaked hostnames */
+GLOBAL char Conf_CloakHostSalt[CLIENT_ID_LEN];
+
+/** Use nickname as user name? */
 GLOBAL bool Conf_CloakUserToNick;
 GLOBAL bool Conf_CloakUserToNick;
 
 
 /** Enable all DNS functions? */
 /** Enable all DNS functions? */
@@ -203,7 +209,7 @@ GLOBAL bool Conf_ConnectIPv6;
 GLOBAL bool Conf_ConnectIPv4;
 GLOBAL bool Conf_ConnectIPv4;
 
 
 /** Maximum number of simultaneous connections to this server */
 /** Maximum number of simultaneous connections to this server */
-GLOBAL long Conf_MaxConnections;
+GLOBAL int Conf_MaxConnections;
 
 
 /** Maximum number of channels a user can join */
 /** Maximum number of channels a user can join */
 GLOBAL int Conf_MaxJoins;
 GLOBAL int Conf_MaxJoins;
@@ -211,9 +217,12 @@ GLOBAL int Conf_MaxJoins;
 /** Maximum number of connections per IP address */
 /** Maximum number of connections per IP address */
 GLOBAL int Conf_MaxConnectionsIP;
 GLOBAL int Conf_MaxConnectionsIP;
 
 
-/** Maximum length of a nick name */
+/** Maximum length of a nickname */
 GLOBAL unsigned int Conf_MaxNickLength;
 GLOBAL unsigned int Conf_MaxNickLength;
 
 
+/** Maximum number of channels returned to /list */
+GLOBAL int Conf_MaxListSize;
+
 #ifndef STRICT_RFC
 #ifndef STRICT_RFC
 
 
 /** Require "AUTH PING-PONG" on login */
 /** Require "AUTH PING-PONG" on login */
@@ -233,7 +242,7 @@ GLOBAL bool Conf_Rehash PARAMS((void));
 GLOBAL int Conf_Test PARAMS((void));
 GLOBAL int Conf_Test PARAMS((void));
 
 
 GLOBAL void Conf_UnsetServer PARAMS(( CONN_ID Idx ));
 GLOBAL void Conf_UnsetServer PARAMS(( CONN_ID Idx ));
-GLOBAL void Conf_SetServer PARAMS(( int ConfServer, CONN_ID Idx ));
+GLOBAL bool Conf_SetServer PARAMS(( int ConfServer, CONN_ID Idx ));
 GLOBAL int Conf_GetServer PARAMS(( CONN_ID Idx ));
 GLOBAL int Conf_GetServer PARAMS(( CONN_ID Idx ));
 
 
 GLOBAL bool Conf_EnableServer PARAMS(( const char *Name, UINT16 Port ));
 GLOBAL bool Conf_EnableServer PARAMS(( const char *Name, UINT16 Port ));
@@ -241,7 +250,8 @@ GLOBAL bool Conf_EnablePassiveServer PARAMS((const char *Name));
 GLOBAL bool Conf_DisableServer PARAMS(( const char *Name ));
 GLOBAL bool Conf_DisableServer PARAMS(( const char *Name ));
 GLOBAL bool Conf_AddServer PARAMS(( const char *Name, UINT16 Port, const char *Host, const char *MyPwd, const char *PeerPwd ));
 GLOBAL bool Conf_AddServer PARAMS(( const char *Name, UINT16 Port, const char *Host, const char *MyPwd, const char *PeerPwd ));
 
 
-GLOBAL bool Conf_IsService PARAMS((int ConfServer, const char *Nick));
+GLOBAL bool Conf_NickIsService PARAMS((int ConfServer, const char *Nick));
+GLOBAL bool Conf_NickIsBlocked PARAMS((const char *Nick));
 
 
 /* Password required by WEBIRC command */
 /* Password required by WEBIRC command */
 GLOBAL char Conf_WebircPwd[CLIENT_PASS_LEN];
 GLOBAL char Conf_WebircPwd[CLIENT_PASS_LEN];

+ 192 - 0
src/ngircd/conn-encoding.c

@@ -0,0 +1,192 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ * Copyright (c)2001-2012 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * Please read the file COPYING, README and AUTHORS for more information.
+ */
+
+#define __conn_encoding_c__
+
+#define CONN_MODULE
+
+#include "portab.h"
+
+/**
+ * @file
+ * Functions to deal with character encodings and conversions
+ */
+
+#include "imp.h"
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "defines.h"
+#include "conn.h"
+#include "log.h"
+
+#include "exp.h"
+#include "conn-encoding.h"
+
+#ifdef ICONV
+
+char Encoding_Buffer[COMMAND_LEN];
+
+char *Convert_Message PARAMS((iconv_t Handle, char *Message));
+
+
+/**
+ * Set client character encoding on a connection.
+ *
+ * @param Conn Connection identifier.
+ * @param ClientEnc Client encoding (for example "ASCII", "MacRoman", ...).
+ * @return true on success, false otherwise.
+ */
+GLOBAL bool
+Conn_SetEncoding(CONN_ID Conn, const char *ClientEnc)
+{
+	char client_enc[25], server_enc[25];
+
+	assert(Conn > NONE);
+	assert(ClientEnc != NULL);
+
+	Conn_UnsetEncoding(Conn);
+
+	/* Is the client character set identical to server character set? */
+	if (strcasecmp(ClientEnc, "UTF-8") == 0)
+		return true;
+
+	snprintf(client_enc, sizeof(client_enc), "%s//TRANSLIT", ClientEnc);
+	snprintf(server_enc, sizeof(server_enc), "%s//TRANSLIT", "UTF-8");
+
+	My_Connections[Conn].iconv_from = iconv_open(server_enc, client_enc);
+	if (My_Connections[Conn].iconv_from == (iconv_t)(-1)) {
+		Conn_UnsetEncoding(Conn);
+		return false;
+	}
+	My_Connections[Conn].iconv_to = iconv_open(client_enc, server_enc);
+	if (My_Connections[Conn].iconv_to == (iconv_t)(-1)) {
+		Conn_UnsetEncoding(Conn);
+		return false;
+	}
+
+	LogDebug("Set client character set of connection \"%d\" to \"%s\".",
+		 Conn, client_enc);
+	return true;
+}
+
+/**
+ * Remove client character encoding conversion on a connection.
+ *
+ * @param Conn Connection identifier.
+ */
+GLOBAL void
+Conn_UnsetEncoding(CONN_ID Conn)
+{
+	assert(Conn > NONE);
+
+	if (My_Connections[Conn].iconv_from != (iconv_t)(-1))
+		iconv_close(My_Connections[Conn].iconv_from);
+	if (My_Connections[Conn].iconv_to != (iconv_t)(-1))
+		iconv_close(My_Connections[Conn].iconv_to);
+
+	My_Connections[Conn].iconv_from = (iconv_t)(-1);
+	My_Connections[Conn].iconv_to = (iconv_t)(-1);
+
+	LogDebug("Unset character conversion of connection %d.", Conn);
+}
+
+/**
+ * Convert the encoding of a given message.
+ *
+ * This function uses a static buffer for the result of the encoding
+ * conversion which is overwritten by subsequent calls to this function!
+ *
+ * @param Handle libiconv handle.
+ * @param Message The message to convert.
+ * @return Pointer to the result.
+ */
+char *
+Convert_Message(iconv_t Handle, char *Message)
+{
+	size_t in_left, out_left;
+	char *out = Encoding_Buffer;
+
+	assert (Handle != (iconv_t)(-1));
+	assert (Message != NULL);
+
+	in_left = strlen(Message);
+	out_left = sizeof(Encoding_Buffer) - 1;
+
+	if (iconv(Handle, &Message, &in_left, &out, &out_left) == (size_t)(-1)) {
+		/* An error occured! */
+		LogDebug("Error converting message encoding!");
+		strlcpy(Encoding_Buffer, Message, sizeof(Encoding_Buffer));
+		iconv(Handle, NULL, NULL, NULL, NULL);
+	} else
+		*out = '\0';
+
+	return Encoding_Buffer;
+}
+
+#endif
+
+/**
+ * Convert encoding of a message received from a connection.
+ *
+ * Note 1: If no conversion is required, this function returns the original
+ * pointer to the message.
+ *
+ * Note 2: This function uses Convert_Message(), so subsequent calls to this
+ * function will overwrite the earlier results.
+ *
+ * @param Conn Connection identifier.
+ * @param Message The message to convert.
+ * @return Pointer to the result.
+ * @see Convert_Message
+ */
+GLOBAL char *
+Conn_EncodingFrom(UNUSED CONN_ID Conn, char *Message)
+{
+	assert(Conn > NONE);
+	assert (Message != NULL);
+
+#ifdef ICONV
+	if (My_Connections[Conn].iconv_from != (iconv_t)(-1))
+		return Convert_Message(My_Connections[Conn].iconv_from, Message);
+#endif
+	return Message;
+}
+
+/**
+ * Convert encoding of a message for sending on a connection.
+ *
+ * Note 1: If no conversion is required, this function returns the original
+ * pointer to the message.
+ *
+ * Note 2: This function uses Convert_Message(), so subsequent calls to this
+ * function will overwrite the earlier results.
+ *
+ * @param Conn Connection identifier.
+ * @param Message The message to convert.
+ * @return Pointer to the result.
+ * @see Convert_Message
+ */
+GLOBAL char *
+Conn_EncodingTo(UNUSED CONN_ID Conn, char *Message)
+{
+	assert(Conn > NONE);
+	assert (Message != NULL);
+
+#ifdef ICONV
+	if (My_Connections[Conn].iconv_to != (iconv_t)(-1))
+		return Convert_Message(My_Connections[Conn].iconv_to, Message);
+#endif
+	return Message;
+}
+
+/* -eof- */

+ 30 - 0
src/ngircd/conn-encoding.h

@@ -0,0 +1,30 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ * Copyright (c)2001-2012 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * Please read the file COPYING, README and AUTHORS for more information.
+ */
+
+#ifndef __conn_encoding_h__
+#define __conn_encoding_h__
+
+/**
+ * @file
+ * Functions to deal with character encodings and conversions (header)
+ */
+
+#ifdef ICONV
+
+GLOBAL bool Conn_SetEncoding PARAMS((CONN_ID Idx, const char *ClientEnc));
+GLOBAL void Conn_UnsetEncoding PARAMS((CONN_ID Idx));
+
+#endif /* ICONV */
+
+GLOBAL char* Conn_EncodingFrom PARAMS((CONN_ID Idx, char *Message));
+GLOBAL char* Conn_EncodingTo PARAMS((CONN_ID Idx, char *Message));
+
+#endif

+ 23 - 5
src/ngircd/conn-ssl.c

@@ -156,7 +156,7 @@ Load_DH_params(void)
 	bool ret = true;
 	bool ret = true;
 
 
 	if (!Conf_SSLOptions.DHFile) {
 	if (!Conf_SSLOptions.DHFile) {
-		Log(LOG_NOTICE, "Configuration option \"SSLDHFile\" not set!");
+		Log(LOG_NOTICE, "Configuration option \"DHFile\" not set!");
 		return false;
 		return false;
 	}
 	}
 	fp = fopen(Conf_SSLOptions.DHFile, "r");
 	fp = fopen(Conf_SSLOptions.DHFile, "r");
@@ -201,7 +201,7 @@ Load_DH_params(void)
 	}
 	}
 	if (need_dhgenerate) {
 	if (need_dhgenerate) {
 		Log(LOG_WARNING,
 		Log(LOG_WARNING,
-		    "SSLDHFile not set, generating %u bit DH parameters. This may take a while ...",
+		    "DHFile not set, generating %u bit DH parameters. This may take a while ...",
 		    DH_BITS);
 		    DH_BITS);
 		err = gnutls_dh_params_generate2(tmp_dh_params, DH_BITS);
 		err = gnutls_dh_params_generate2(tmp_dh_params, DH_BITS);
 		if (err < 0) {
 		if (err < 0) {
@@ -241,6 +241,9 @@ void ConnSSL_Free(CONNECTION *c)
 bool
 bool
 ConnSSL_InitLibrary( void )
 ConnSSL_InitLibrary( void )
 {
 {
+	if (!array_bytes(&Conf_SSLOptions.ListenPorts))
+		return true;
+
 #ifdef HAVE_LIBSSL
 #ifdef HAVE_LIBSSL
 	SSL_CTX *newctx;
 	SSL_CTX *newctx;
 
 
@@ -256,12 +259,14 @@ ConnSSL_InitLibrary( void )
 		 * According to OpenSSL RAND_egd(3): "The automatic query of /var/run/egd-pool et al was added in OpenSSL 0.9.7";
 		 * According to OpenSSL RAND_egd(3): "The automatic query of /var/run/egd-pool et al was added in OpenSSL 0.9.7";
 		 * so it makes little sense to deal with PRNGD seeding ourselves.
 		 * so it makes little sense to deal with PRNGD seeding ourselves.
 		 */
 		 */
+		array_free(&Conf_SSLOptions.ListenPorts);
 		return false;
 		return false;
 	}
 	}
 
 
 	newctx = SSL_CTX_new(SSLv23_method());
 	newctx = SSL_CTX_new(SSLv23_method());
 	if (!newctx) {
 	if (!newctx) {
 		LogOpenSSLError("SSL_CTX_new()", NULL);
 		LogOpenSSLError("SSL_CTX_new()", NULL);
+		array_free(&Conf_SSLOptions.ListenPorts);
 		return false;
 		return false;
 	}
 	}
 
 
@@ -276,6 +281,7 @@ ConnSSL_InitLibrary( void )
 	return true;
 	return true;
 out:
 out:
 	SSL_CTX_free(newctx);
 	SSL_CTX_free(newctx);
+	array_free(&Conf_SSLOptions.ListenPorts);
 	return false;
 	return false;
 #endif
 #endif
 #ifdef HAVE_LIBGNUTLS
 #ifdef HAVE_LIBGNUTLS
@@ -287,10 +293,13 @@ out:
 	err = gnutls_global_init();
 	err = gnutls_global_init();
 	if (err) {
 	if (err) {
 		Log(LOG_ERR, "gnutls_global_init(): %s", gnutls_strerror(err));
 		Log(LOG_ERR, "gnutls_global_init(): %s", gnutls_strerror(err));
+		array_free(&Conf_SSLOptions.ListenPorts);
 		return false;
 		return false;
 	}
 	}
-	if (!ConnSSL_LoadServerKey_gnutls())
+	if (!ConnSSL_LoadServerKey_gnutls()) {
+		array_free(&Conf_SSLOptions.ListenPorts);
 		return false;
 		return false;
+	}
 	Log(LOG_INFO, "gnutls %s initialized.", gnutls_check_version(NULL));
 	Log(LOG_INFO, "gnutls %s initialized.", gnutls_check_version(NULL));
 	initialized = true;
 	initialized = true;
 	return true;
 	return true;
@@ -313,7 +322,7 @@ ConnSSL_LoadServerKey_gnutls(void)
 
 
 	cert_file = Conf_SSLOptions.CertFile ? Conf_SSLOptions.CertFile:Conf_SSLOptions.KeyFile;
 	cert_file = Conf_SSLOptions.CertFile ? Conf_SSLOptions.CertFile:Conf_SSLOptions.KeyFile;
 	if (!cert_file) {
 	if (!cert_file) {
-		Log(LOG_NOTICE, "No SSL server key configured, SSL disabled.");
+		Log(LOG_ERR, "No SSL server key configured!");
 		return false;
 		return false;
 	}
 	}
 
 
@@ -344,7 +353,7 @@ ConnSSL_LoadServerKey_openssl(SSL_CTX *ctx)
 
 
 	assert(ctx);
 	assert(ctx);
 	if (!Conf_SSLOptions.KeyFile) {
 	if (!Conf_SSLOptions.KeyFile) {
-		Log(LOG_NOTICE, "No SSL server key configured, SSL disabled.");
+		Log(LOG_ERR, "No SSL server key configured!");
 		return false;
 		return false;
 	}
 	}
 
 
@@ -625,6 +634,8 @@ ConnectAccept( CONNECTION *c, bool connect)
 #endif /* _GNUTLS */
 #endif /* _GNUTLS */
 	Conn_OPTION_DEL(c, (CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ|CONN_SSL_CONNECT));
 	Conn_OPTION_DEL(c, (CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ|CONN_SSL_CONNECT));
 	ConnSSL_LogCertInfo(c);
 	ConnSSL_LogCertInfo(c);
+
+	Conn_StartLogin(CONNECTION2ID(c));
 	return 1;
 	return 1;
 }
 }
 
 
@@ -712,6 +723,13 @@ ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len)
 #endif
 #endif
 }
 }
 
 
+#else
+
+bool
+ConnSSL_InitLibrary(void)
+{
+	return true;
+}
 
 
 #endif /* SSL_SUPPORT */
 #endif /* SSL_SUPPORT */
 /* -eof- */
 /* -eof- */

+ 110 - 34
src/ngircd/conn.c

@@ -47,10 +47,6 @@
 # include <netinet/ip.h>
 # include <netinet/ip.h>
 #endif
 #endif
 
 
-#ifdef HAVE_STDINT_H
-# include <stdint.h>			/* e.g. for Mac OS X */
-#endif
-
 #ifdef TCPWRAP
 #ifdef TCPWRAP
 # include <tcpd.h>			/* for TCP Wrappers */
 # include <tcpd.h>			/* for TCP Wrappers */
 #endif
 #endif
@@ -67,6 +63,7 @@
 #include "client.h"
 #include "client.h"
 #include "class.h"
 #include "class.h"
 #include "conf.h"
 #include "conf.h"
+#include "conn-encoding.h"
 #include "conn-ssl.h"
 #include "conn-ssl.h"
 #include "conn-zip.h"
 #include "conn-zip.h"
 #include "conn-func.h"
 #include "conn-func.h"
@@ -88,7 +85,7 @@
 
 
 static bool Handle_Write PARAMS(( CONN_ID Idx ));
 static bool Handle_Write PARAMS(( CONN_ID Idx ));
 static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
 static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
-static int New_Connection PARAMS(( int Sock ));
+static int New_Connection PARAMS(( int Sock, bool IsSSL ));
 static CONN_ID Socket2Index PARAMS(( int Sock ));
 static CONN_ID Socket2Index PARAMS(( int Sock ));
 static void Read_Request PARAMS(( CONN_ID Idx ));
 static void Read_Request PARAMS(( CONN_ID Idx ));
 static unsigned int Handle_Buffer PARAMS(( CONN_ID Idx ));
 static unsigned int Handle_Buffer PARAMS(( CONN_ID Idx ));
@@ -134,7 +131,7 @@ static void
 cb_listen(int sock, short irrelevant)
 cb_listen(int sock, short irrelevant)
 {
 {
 	(void) irrelevant;
 	(void) irrelevant;
-	(void) New_Connection(sock);
+	(void) New_Connection(sock, false);
 }
 }
 
 
 
 
@@ -152,7 +149,7 @@ cb_listen_ssl(int sock, short irrelevant)
 	int fd;
 	int fd;
 
 
 	(void) irrelevant;
 	(void) irrelevant;
-	fd = New_Connection(sock);
+	fd = New_Connection(sock, true);
 	if (fd < 0)
 	if (fd < 0)
 		return;
 		return;
 	io_event_setcb(My_Connections[fd].sock, cb_clientserver_ssl);
 	io_event_setcb(My_Connections[fd].sock, cb_clientserver_ssl);
@@ -865,6 +862,9 @@ va_dcl
 #endif
 #endif
 {
 {
 	char buffer[COMMAND_LEN];
 	char buffer[COMMAND_LEN];
+#ifdef ICONV
+	char *ptr, *message;
+#endif
 	size_t len;
 	size_t len;
 	bool ok;
 	bool ok;
 	va_list ap;
 	va_list ap;
@@ -905,6 +905,16 @@ va_dcl
 			CUT_TXTSUFFIX);
 			CUT_TXTSUFFIX);
 	}
 	}
 
 
+#ifdef ICONV
+	ptr = strchr(buffer + 1, ':');
+	if (ptr) {
+		ptr++;
+		message = Conn_EncodingTo(Idx, ptr);
+		if (message != ptr)
+			strlcpy(ptr, message, sizeof(buffer) - (ptr - buffer));
+	}
+#endif
+
 #ifdef SNIFFER
 #ifdef SNIFFER
 	if (NGIRCd_Sniffer)
 	if (NGIRCd_Sniffer)
 		Log(LOG_DEBUG, " -> connection %d: '%s'.", Idx, buffer);
 		Log(LOG_DEBUG, " -> connection %d: '%s'.", Idx, buffer);
@@ -918,6 +928,30 @@ va_dcl
 	return ok;
 	return ok;
 } /* Conn_WriteStr */
 } /* Conn_WriteStr */
 
 
+GLOBAL char*
+Conn_Password( CONN_ID Idx )
+{
+	assert( Idx > NONE );
+	if (My_Connections[Idx].pwd == NULL)
+		return (char*)"\0";
+	else
+		return My_Connections[Idx].pwd;
+} /* Conn_Password */
+
+GLOBAL void
+Conn_SetPassword( CONN_ID Idx, const char *Pwd )
+{
+	assert( Idx > NONE );
+
+	if (My_Connections[Idx].pwd)
+		free(My_Connections[Idx].pwd);
+
+	My_Connections[Idx].pwd = strdup(Pwd);
+	if (My_Connections[Idx].pwd == NULL) {
+		Log(LOG_EMERG, "Can't allocate memory! [Conn_SetPassword]");
+		exit(1);
+	}
+} /* Conn_SetPassword */
 
 
 /**
 /**
  * Append Data to the outbound write buffer of a connection.
  * Append Data to the outbound write buffer of a connection.
@@ -1146,6 +1180,8 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
 
 
 	array_free(&My_Connections[Idx].rbuf);
 	array_free(&My_Connections[Idx].rbuf);
 	array_free(&My_Connections[Idx].wbuf);
 	array_free(&My_Connections[Idx].wbuf);
+	if (My_Connections[Idx].pwd != NULL)
+		free(My_Connections[Idx].pwd);
 
 
 	/* Clean up connection structure (=free it) */
 	/* Clean up connection structure (=free it) */
 	Init_Conn_Struct( Idx );
 	Init_Conn_Struct( Idx );
@@ -1336,17 +1372,18 @@ Count_Connections(ng_ipaddr_t *a)
  * Initialize new client connection on a listening socket.
  * Initialize new client connection on a listening socket.
  *
  *
  * @param Sock	Listening socket descriptor.
  * @param Sock	Listening socket descriptor.
+ * @param IsSSL	true if this socket expects SSL-encrypted data.
  * @returns	Accepted socket descriptor or -1 on error.
  * @returns	Accepted socket descriptor or -1 on error.
  */
  */
 static int
 static int
-New_Connection(int Sock)
+New_Connection(int Sock, UNUSED bool IsSSL)
 {
 {
 #ifdef TCPWRAP
 #ifdef TCPWRAP
 	struct request_info req;
 	struct request_info req;
 #endif
 #endif
 	ng_ipaddr_t new_addr;
 	ng_ipaddr_t new_addr;
 	char ip_str[NG_INET_ADDRSTRLEN];
 	char ip_str[NG_INET_ADDRSTRLEN];
-	int new_sock, new_sock_len, identsock;
+	int new_sock, new_sock_len;
 	CLIENT *c;
 	CLIENT *c;
 	long cnt;
 	long cnt;
 
 
@@ -1466,30 +1503,56 @@ New_Connection(int Sock)
 	Log(LOG_INFO, "Accepted connection %d from %s:%d on socket %d.",
 	Log(LOG_INFO, "Accepted connection %d from %s:%d on socket %d.",
 	    new_sock, My_Connections[new_sock].host,
 	    new_sock, My_Connections[new_sock].host,
 	    ng_ipaddr_getport(&new_addr), Sock);
 	    ng_ipaddr_getport(&new_addr), Sock);
+	Account_Connection();
+
+#ifdef SSL_SUPPORT
+	/* Delay connection initalization until SSL handshake is finished */
+	if (!IsSSL)
+#endif
+		Conn_StartLogin(new_sock);
+
+	return new_sock;
+} /* New_Connection */
+
+
+/**
+ * Finish connection initialization, start resolver subprocess.
+ *
+ * @param Idx Connection index.
+ */
+GLOBAL void
+Conn_StartLogin(CONN_ID Idx)
+{
+	int ident_sock = -1;
+
+	assert(Idx >= 0);
+
+	/* Nothing to do if DNS (and resolver subprocess) is disabled */
+	if (!Conf_DNS)
+		return;
 
 
-	identsock = new_sock;
 #ifdef IDENTAUTH
 #ifdef IDENTAUTH
-	if (!Conf_Ident)
-		identsock = -1;
+	/* Should we make an IDENT request? */
+	if (Conf_Ident)
+		ident_sock = My_Connections[Idx].sock;
 #endif
 #endif
-	if (Conf_DNS) {
-		if (Conf_NoticeAuth) {
+
+	if (Conf_NoticeAuth) {
+		/* Send "NOTICE AUTH" messages to the client */
 #ifdef IDENTAUTH
 #ifdef IDENTAUTH
-			if (Conf_Ident)
-				(void)Conn_WriteStr(new_sock,
-					"NOTICE AUTH :*** Looking up your hostname and checking ident");
-			else
+		if (Conf_Ident)
+			(void)Conn_WriteStr(Idx,
+				"NOTICE AUTH :*** Looking up your hostname and checking ident");
+		else
 #endif
 #endif
-				(void)Conn_WriteStr(new_sock,
-					"NOTICE AUTH :*** Looking up your hostname");
-		}
-		Resolve_Addr(&My_Connections[new_sock].proc_stat, &new_addr,
-			     identsock, cb_Read_Resolver_Result);
+			(void)Conn_WriteStr(Idx,
+				"NOTICE AUTH :*** Looking up your hostname");
+		(void)Handle_Write(Idx);
 	}
 	}
 
 
-	Account_Connection();
-	return new_sock;
-} /* New_Connection */
+	Resolve_Addr(&My_Connections[Idx].proc_stat, &My_Connections[Idx].addr,
+		     ident_sock, cb_Read_Resolver_Result);
+}
 
 
 
 
 /**
 /**
@@ -1839,10 +1902,10 @@ Check_Connections(void)
 				if (My_Connections[i].lastping <
 				if (My_Connections[i].lastping <
 				    time(NULL) - Conf_PongTimeout) {
 				    time(NULL) - Conf_PongTimeout) {
 					/* Timeout */
 					/* Timeout */
-					LogDebug
-					    ("Connection %d: Ping timeout: %d seconds.",
-					     i, Conf_PongTimeout);
-					snprintf(msg, sizeof(msg), "Ping timeout: %d seconds", Conf_PongTimeout);
+					snprintf(msg, sizeof(msg),
+						 "Ping timeout: %d seconds",
+						 Conf_PongTimeout);
+					LogDebug("Connection %d: %s.", i, msg);
 					Conn_Close(i, NULL, msg, true);
 					Conn_Close(i, NULL, msg, true);
 				}
 				}
 			} else if (My_Connections[i].lastdata <
 			} else if (My_Connections[i].lastdata <
@@ -2016,7 +2079,8 @@ New_Server( int Server , ng_ipaddr_t *dest)
 	Client_SetToken( c, TOKEN_OUTBOUND );
 	Client_SetToken( c, TOKEN_OUTBOUND );
 
 
 	/* Register connection */
 	/* Register connection */
-	Conf_SetServer(Server, new_sock);
+	if (!Conf_SetServer(Server, new_sock))
+		return;
 	My_Connections[new_sock].sock = new_sock;
 	My_Connections[new_sock].sock = new_sock;
 	My_Connections[new_sock].addr = *dest;
 	My_Connections[new_sock].addr = *dest;
 	My_Connections[new_sock].client = c;
 	My_Connections[new_sock].client = c;
@@ -2056,6 +2120,11 @@ Init_Conn_Struct(CONN_ID Idx)
 	My_Connections[Idx].lastdata = now;
 	My_Connections[Idx].lastdata = now;
 	My_Connections[Idx].lastprivmsg = now;
 	My_Connections[Idx].lastprivmsg = now;
 	Proc_InitStruct(&My_Connections[Idx].proc_stat);
 	Proc_InitStruct(&My_Connections[Idx].proc_stat);
+
+#ifdef ICONV
+	My_Connections[Idx].iconv_from = (iconv_t)(-1);
+	My_Connections[Idx].iconv_to = (iconv_t)(-1);
+#endif
 } /* Init_Conn_Struct */
 } /* Init_Conn_Struct */
 
 
 
 
@@ -2231,7 +2300,8 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 		Client_SetHostname(c, readbuf);
 		Client_SetHostname(c, readbuf);
 		if (Conf_NoticeAuth)
 		if (Conf_NoticeAuth)
 			(void)Conn_WriteStr(i,
 			(void)Conn_WriteStr(i,
-					"NOTICE AUTH :*** Found your hostname");
+					"NOTICE AUTH :*** Found your hostname: %s",
+					My_Connections[i].host);
 #ifdef IDENTAUTH
 #ifdef IDENTAUTH
 		++identptr;
 		++identptr;
 		if (*identptr) {
 		if (*identptr) {
@@ -2256,8 +2326,10 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 			}
 			}
 			if (Conf_NoticeAuth) {
 			if (Conf_NoticeAuth) {
 				(void)Conn_WriteStr(i,
 				(void)Conn_WriteStr(i,
-					"NOTICE AUTH :*** Got %sident response",
-					*ptr ? "invalid " : "");
+					"NOTICE AUTH :*** Got %sident response%s%s",
+					*ptr ? "invalid " : "",
+					*ptr ? "" : ": ",
+					*ptr ? "" : identptr);
 			}
 			}
 		} else {
 		} else {
 			Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
 			Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
@@ -2266,6 +2338,10 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 					"NOTICE AUTH :*** No ident response");
 					"NOTICE AUTH :*** No ident response");
 		}
 		}
 #endif
 #endif
+
+		if (Conf_NoticeAuth)
+			(void)Handle_Write(i);
+
 		Class_HandleServerBans(c);
 		Class_HandleServerBans(c);
 	}
 	}
 #ifdef DEBUG
 #ifdef DEBUG

+ 18 - 1
src/ngircd/conn.h

@@ -42,7 +42,7 @@
 #define CONN_SSL_WANT_READ	128	/* SSL/TLS library needs to read protocol data */
 #define CONN_SSL_WANT_READ	128	/* SSL/TLS library needs to read protocol data */
 #define CONN_SSL_FLAGS_ALL	(CONN_SSL_CONNECT|CONN_SSL|CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ)
 #define CONN_SSL_FLAGS_ALL	(CONN_SSL_CONNECT|CONN_SSL|CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ)
 #endif
 #endif
-typedef long CONN_ID;
+typedef int CONN_ID;
 
 
 #include "client.h"
 #include "client.h"
 #include "proc.h"
 #include "proc.h"
@@ -54,6 +54,10 @@ typedef long CONN_ID;
 #include "tool.h"
 #include "tool.h"
 #include "ng_ipaddr.h"
 #include "ng_ipaddr.h"
 
 
+#ifdef ICONV
+# include <iconv.h>
+#endif
+
 #ifdef ZLIB
 #ifdef ZLIB
 #include <zlib.h>
 #include <zlib.h>
 typedef struct _ZipData
 typedef struct _ZipData
@@ -72,6 +76,7 @@ typedef struct _Connection
 	ng_ipaddr_t addr;		/* Client address */
 	ng_ipaddr_t addr;		/* Client address */
 	PROC_STAT proc_stat;		/* Status of resolver process */
 	PROC_STAT proc_stat;		/* Status of resolver process */
 	char host[HOST_LEN];		/* Hostname */
 	char host[HOST_LEN];		/* Hostname */
+	char *pwd;			/* password received of the client */
 	array rbuf;			/* Read buffer */
 	array rbuf;			/* Read buffer */
 	array wbuf;			/* Write buffer */
 	array wbuf;			/* Write buffer */
 	time_t signon;			/* Signon ("connect") time */
 	time_t signon;			/* Signon ("connect") time */
@@ -94,12 +99,18 @@ typedef struct _Connection
 #ifndef STRICT_RFC
 #ifndef STRICT_RFC
 	long auth_ping;			/** PING response expected on login */
 	long auth_ping;			/** PING response expected on login */
 #endif
 #endif
+#ifdef ICONV
+	iconv_t iconv_from;		/** iconv: convert from client to server */
+	iconv_t iconv_to;		/** iconv: convert from server to client */
+#endif
 } CONNECTION;
 } CONNECTION;
 
 
 GLOBAL CONNECTION *My_Connections;
 GLOBAL CONNECTION *My_Connections;
 GLOBAL CONN_ID Pool_Size;
 GLOBAL CONN_ID Pool_Size;
 GLOBAL long WCounter;
 GLOBAL long WCounter;
 
 
+#define CONNECTION2ID(x) (long)(x - My_Connections)
+
 #endif /* CONN_MODULE */
 #endif /* CONN_MODULE */
 
 
 
 
@@ -111,10 +122,15 @@ GLOBAL void Conn_CloseAllSockets PARAMS((int ExceptOf));
 GLOBAL unsigned int Conn_InitListeners PARAMS(( void ));
 GLOBAL unsigned int Conn_InitListeners PARAMS(( void ));
 GLOBAL void Conn_ExitListeners PARAMS(( void ));
 GLOBAL void Conn_ExitListeners PARAMS(( void ));
 
 
+GLOBAL void Conn_StartLogin PARAMS((CONN_ID Idx));
+
 GLOBAL void Conn_Handler PARAMS(( void ));
 GLOBAL void Conn_Handler PARAMS(( void ));
 
 
 GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, const char *Format, ... ));
 GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, const char *Format, ... ));
 
 
+GLOBAL char* Conn_Password PARAMS(( CONN_ID Idx ));
+GLOBAL void Conn_SetPassword PARAMS(( CONN_ID Idx, const char *Pwd ));
+
 GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient ));
 GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient ));
 
 
 GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
 GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
@@ -122,6 +138,7 @@ GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
 GLOBAL CONN_ID Conn_GetFromProc PARAMS((int fd));
 GLOBAL CONN_ID Conn_GetFromProc PARAMS((int fd));
 GLOBAL CLIENT* Conn_GetClient PARAMS((CONN_ID i));
 GLOBAL CLIENT* Conn_GetClient PARAMS((CONN_ID i));
 GLOBAL PROC_STAT* Conn_GetProcStat PARAMS((CONN_ID i));
 GLOBAL PROC_STAT* Conn_GetProcStat PARAMS((CONN_ID i));
+
 #ifdef SSL_SUPPORT
 #ifdef SSL_SUPPORT
 GLOBAL bool Conn_GetCipherInfo PARAMS((CONN_ID Idx, char *buf, size_t len));
 GLOBAL bool Conn_GetCipherInfo PARAMS((CONN_ID Idx, char *buf, size_t len));
 GLOBAL bool Conn_UsesSSL PARAMS((CONN_ID Idx));
 GLOBAL bool Conn_UsesSSL PARAMS((CONN_ID Idx));

+ 15 - 11
src/ngircd/defines.h

@@ -44,9 +44,12 @@
 /** Max. length of file name. */
 /** Max. length of file name. */
 #define FNAME_LEN 256
 #define FNAME_LEN 256
 
 
-/** Max. lenght of fully qualified host names (e. g. "abc.domain.tld"). */
+/** Max. length of fully qualified host names (e. g. "abc.domain.tld"). */
 #define HOST_LEN 256
 #define HOST_LEN 256
 
 
+/** Max. length of random salt */
+#define RANDOM_SALT_LEN 32
+
 
 
 /* Size of structures */
 /* Size of structures */
 
 
@@ -89,14 +92,18 @@
 /** Default nick length (including NULL), see. RFC 2812 section 1.2.1. */
 /** Default nick length (including NULL), see. RFC 2812 section 1.2.1. */
 #define CLIENT_NICK_LEN_DEFAULT 10
 #define CLIENT_NICK_LEN_DEFAULT 10
 
 
-/** Maximum nick name length (including NULL). */
+/** Maximum nickname length (including NULL). */
 #define CLIENT_NICK_LEN 32
 #define CLIENT_NICK_LEN 32
 
 
 /** Max. password length (including NULL). */
 /** Max. password length (including NULL). */
 #define CLIENT_PASS_LEN 21
 #define CLIENT_PASS_LEN 21
 
 
 /** Max. length of user name ("login"; incl. NULL), RFC 2812, section 1.2.1. */
 /** Max. length of user name ("login"; incl. NULL), RFC 2812, section 1.2.1. */
-#define CLIENT_USER_LEN 10
+#ifndef STRICT_RFC
+# define CLIENT_USER_LEN 20
+#else
+# define CLIENT_USER_LEN 10
+#endif
 
 
 /** Max. length of "real names" (including NULL). */
 /** Max. length of "real names" (including NULL). */
 #define CLIENT_NAME_LEN 32
 #define CLIENT_NAME_LEN 32
@@ -105,7 +112,7 @@
 #define CLIENT_HOST_LEN 64
 #define CLIENT_HOST_LEN 64
 
 
 /** Max. length of all client modes (including NULL). */
 /** Max. length of all client modes (including NULL). */
-#define CLIENT_MODE_LEN 16
+#define CLIENT_MODE_LEN 21
 
 
 /** Max. length of server info texts (including NULL). */
 /** Max. length of server info texts (including NULL). */
 #define CLIENT_INFO_LEN 64
 #define CLIENT_INFO_LEN 64
@@ -120,7 +127,7 @@
 #define CHANNEL_NAME_LEN 51
 #define CHANNEL_NAME_LEN 51
 
 
 /** Max. length of channel modes (including NULL). */
 /** Max. length of channel modes (including NULL). */
-#define CHANNEL_MODE_LEN 9
+#define CHANNEL_MODE_LEN 21
 
 
 /** Max. IRC command length (including NULL), see. RFC 2812 section 3.2. */
 /** Max. IRC command length (including NULL), see. RFC 2812 section 3.2. */
 #define COMMAND_LEN 513
 #define COMMAND_LEN 513
@@ -154,14 +161,14 @@
 
 
 #ifdef IRCPLUS
 #ifdef IRCPLUS
 /** Standard IRC+ flags. */
 /** Standard IRC+ flags. */
-# define IRCPLUSFLAGS "CHLS"
+# define IRCPLUSFLAGS "CHLMSX"
 #endif
 #endif
 
 
 /** Supported user modes. */
 /** Supported user modes. */
-#define USERMODES "acCiorRswx"
+#define USERMODES "abBcCioqrRswx"
 
 
 /** Supported channel modes. */
 /** Supported channel modes. */
-#define CHANMODES "beiIklmnoOPrRstvz"
+#define CHANMODES "abehiIklmMnoOPqQrRstvVz"
 
 
 /** Away message for users connected to linked servers. */
 /** Away message for users connected to linked servers. */
 #define DEFAULT_AWAY_MSG "Away"
 #define DEFAULT_AWAY_MSG "Away"
@@ -178,9 +185,6 @@
 
 
 /* Defaults and limits for IRC commands */
 /* Defaults and limits for IRC commands */
 
 
-/** Max. number of LIST replies. */
-#define MAX_RPL_LIST 100
-
 /** Max. number of elemets allowed in channel invite and ban lists. */
 /** Max. number of elemets allowed in channel invite and ban lists. */
 #define MAX_HNDL_CHANNEL_LISTS 50
 #define MAX_HNDL_CHANNEL_LISTS 50
 
 

+ 14 - 0
src/ngircd/io.c

@@ -86,6 +86,20 @@ static int io_masterfd;
 
 
 static int io_dispatch_kqueue(struct timeval *tv);
 static int io_dispatch_kqueue(struct timeval *tv);
 static bool io_event_change_kqueue(int, short, const int action);
 static bool io_event_change_kqueue(int, short, const int action);
+
+#ifndef EV_SET
+/* Taken from /usr/include/sys/event.h of FreeBSD 8.1 and required by all
+ * platforms that have kqueue but lack EV_SET() -- for example FreeBSD 4. */
+#define EV_SET(kevp, a, b, c, d, e, f) do {	\
+	struct kevent *__kevp__ = (kevp);	\
+	__kevp__->ident = (a);			\
+	__kevp__->filter = (b);			\
+	__kevp__->flags = (c);			\
+	__kevp__->fflags = (d);			\
+	__kevp__->data = (e);			\
+	__kevp__->udata = (f);			\
+} while(0)
+#endif
 #endif
 #endif
 
 
 #ifdef IO_USE_POLL
 #ifdef IO_USE_POLL

+ 2 - 2
src/ngircd/irc-cap.c

@@ -275,8 +275,8 @@ Parse_CAP(int Capabilities, char *Args)
  * @param Capabilities Capability flags (bitmask).
  * @param Capabilities Capability flags (bitmask).
  * @return Pointer to textual representation.
  * @return Pointer to textual representation.
  */
  */
-char
-*Get_CAP_String(int Capabilities)
+char *
+Get_CAP_String(int Capabilities)
 {
 {
 	static char txt[COMMAND_LEN];
 	static char txt[COMMAND_LEN];
 
 

+ 30 - 17
src/ngircd/irc-channel.c

@@ -167,8 +167,10 @@ join_set_channelmodes(CHANNEL *chan, CLIENT *target, const char *flags)
 		}
 		}
 	}
 	}
 
 
-	/* If channel persistent and client is ircop: make client chanop */
-	if (strchr(Channel_Modes(chan), 'P') && strchr(Client_Modes(target), 'o'))
+	/* If the channel is persistent (+P) and client is an IRC op:
+	 * make client chanop, if not disabled in configuration. */
+	if (strchr(Channel_Modes(chan), 'P') && Conf_OperChanPAutoOp
+	    && strchr(Client_Modes(target), 'o'))
 		Channel_UserModeAdd(chan, target, 'o');
 		Channel_UserModeAdd(chan, target, 'o');
 } /* join_set_channelmodes */
 } /* join_set_channelmodes */
 
 
@@ -363,7 +365,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 		chan = Channel_Search(channame);
 		chan = Channel_Search(channame);
 		if (!chan && Conf_PredefChannelsOnly) {
 		if (!chan && Conf_PredefChannelsOnly) {
 			 /* channel must be created, but forbidden by config */
 			 /* channel must be created, but forbidden by config */
-			IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG,
+			IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG,
 					   Client_ID(Client), channame);
 					   Client_ID(Client), channame);
 			goto join_next;
 			goto join_next;
 		}
 		}
@@ -510,7 +512,7 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 	CHANNEL *chan;
 	CHANNEL *chan;
 	CLIENT *from;
 	CLIENT *from;
 	char *topic;
 	char *topic;
-	bool onchannel, topicok, use_servermode, r;
+	bool r, topic_power;
 
 
 	assert( Client != NULL );
 	assert( Client != NULL );
 	assert( Req != NULL );
 	assert( Req != NULL );
@@ -533,12 +535,17 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 		return IRC_WriteStrClient(from, ERR_NOSUCHCHANNEL_MSG,
 		return IRC_WriteStrClient(from, ERR_NOSUCHCHANNEL_MSG,
 					  Client_ID(from), Req->argv[0]);
 					  Client_ID(from), Req->argv[0]);
 
 
-	Channel_CheckAdminRights(chan, Client, from,
-				 &onchannel, &topicok, &use_servermode);
-
-	if (!onchannel && !topicok)
-		return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG,
-					  Client_ID(from), Req->argv[0]);
+	/* Only remote servers and channel members are allowed to change the
+	 * channel topic, and IRC opreators when the Conf_OperCanMode option
+	 * is set in the server configuration. */
+	if (Client_Type(Client) != CLIENT_SERVER) {
+		topic_power = Client_HasMode(from, 'o');
+		if (!Channel_IsMemberOf(chan, from)
+		    && !(Conf_OperCanMode && topic_power))
+			return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG,
+						  Client_ID(from), Req->argv[0]);
+	} else
+		topic_power = true;
 
 
 	if (Req->argc == 1) {
 	if (Req->argc == 1) {
 		/* Request actual topic */
 		/* Request actual topic */
@@ -565,8 +572,12 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 	}
 	}
 
 
 	if (strchr(Channel_Modes(chan), 't')) {
 	if (strchr(Channel_Modes(chan), 't')) {
-		/* Topic Lock. Is the user a channel or IRC operator? */
-		if (!topicok)
+		/* Topic Lock. Is the user a channel op or IRC operator? */
+		if(!topic_power &&
+		   !strchr(Channel_UserModes(chan, from), 'h') &&
+		   !strchr(Channel_UserModes(chan, from), 'o') &&
+		   !strchr(Channel_UserModes(chan, from), 'a') &&
+		   !strchr(Channel_UserModes(chan, from), 'q'))
 			return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
 			return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
 						  Client_ID(from),
 						  Client_ID(from),
 						  Channel_Name(chan));
 						  Channel_Name(chan));
@@ -578,7 +589,7 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 		 Client_TypeText(from), Client_Mask(from), Channel_Name(chan),
 		 Client_TypeText(from), Client_Mask(from), Channel_Name(chan),
 		 Req->argv[1][0] ? Req->argv[1] : "<none>");
 		 Req->argv[1][0] ? Req->argv[1] : "<none>");
 
 
-	if (use_servermode)
+	if (Conf_OperServerMode)
 		from = Client_ThisServer();
 		from = Client_ThisServer();
 
 
 	/* Update channel and forward new topic to other servers */
 	/* Update channel and forward new topic to other servers */
@@ -666,10 +677,12 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
 			if (MatchCaseInsensitive(pattern, Channel_Name(chan))) {
 			if (MatchCaseInsensitive(pattern, Channel_Name(chan))) {
 				/* Gotcha! */
 				/* Gotcha! */
 				if (!strchr(Channel_Modes(chan), 's')
 				if (!strchr(Channel_Modes(chan), 's')
-				    || Channel_IsMemberOf(chan, from)) {
-					if (IRC_CheckListTooBig(from, count,
-								 MAX_RPL_LIST,
-								 "LIST"))
+				    || Channel_IsMemberOf(chan, from)
+				    || (!Conf_MorePrivacy && Client_OperByMe(Client))) {
+					if ((Conf_MaxListSize > 0)
+					    && IRC_CheckListTooBig(from, count,
+								   Conf_MaxListSize,
+								   "LIST"))
 						break;
 						break;
 					if (!IRC_WriteStrClient(from,
 					if (!IRC_WriteStrClient(from,
 					     RPL_LIST_MSG, Client_ID(from),
 					     RPL_LIST_MSG, Client_ID(from),

+ 68 - 0
src/ngircd/irc-encoding.c

@@ -0,0 +1,68 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ * Copyright (c)2001-2012 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * Please read the file COPYING, README and AUTHORS for more information.
+ */
+
+#include "portab.h"
+
+/**
+ * @file
+ * IRC encoding commands
+ */
+
+#include "imp.h"
+#include <assert.h>
+#include <string.h>
+
+#include "conn-func.h"
+#include "channel.h"
+#include "conn-encoding.h"
+#include "irc-write.h"
+#include "messages.h"
+#include "parse.h"
+#include "tool.h"
+
+#include "exp.h"
+#include "irc-encoding.h"
+
+#ifdef ICONV
+
+/**
+ * Handler for the IRC+ "CHARCONV" command.
+ *
+ * @param Client The client from which this command has been received.
+ * @param Req Request structure with prefix and all parameters.
+ * @returns CONNECTED or DISCONNECTED.
+ */
+GLOBAL bool
+IRC_CHARCONV(CLIENT *Client, REQUEST *Req)
+{
+	char encoding[20];
+
+	assert (Client != NULL);
+	assert (Req != NULL);
+
+	if (Req->argc != 1)
+		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+					  Client_ID(Client), Req->command);
+
+	strlcpy(encoding, Req->argv[0], sizeof(encoding));
+	ngt_UpperStr(encoding);
+
+	if (!Conn_SetEncoding(Client_Conn(Client), encoding))
+		return IRC_WriteStrClient(Client, ERR_IP_CHARCONV_MSG,
+					  Client_ID(Client), encoding);
+
+	return IRC_WriteStrClient(Client, RPL_IP_CHARCONV_MSG,
+				  Client_ID(Client), encoding);
+} /* IRC_CHARCONV */
+
+#endif
+
+/* -eof- */

+ 24 - 0
src/ngircd/irc-encoding.h

@@ -0,0 +1,24 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ * Copyright (c)2001-2012 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * Please read the file COPYING, README and AUTHORS for more information.
+ */
+
+#ifndef __irc_encoding_h__
+#define __irc_encoding_h__
+
+/**
+ * @file
+ * IRC encoding commands (header)
+ */
+
+GLOBAL bool IRC_CHARCONV PARAMS((CLIENT *Client, REQUEST *Req));
+
+#endif
+
+/* -eof- */

+ 87 - 45
src/ngircd/irc-info.c

@@ -117,7 +117,7 @@ IRC_INFO(CLIENT * Client, REQUEST * Req)
 		target = Client_Search(Req->argv[0]);
 		target = Client_Search(Req->argv[0]);
 	else
 	else
 		target = Client_ThisServer();
 		target = Client_ThisServer();
-	
+
 	/* Make sure that the target is a server */
 	/* Make sure that the target is a server */
 	if (target && Client_Type(target) != CLIENT_SERVER)
 	if (target && Client_Type(target) != CLIENT_SERVER)
 		target = Client_Introducer(target);
 		target = Client_Introducer(target);
@@ -727,7 +727,7 @@ IRC_USERHOST(CLIENT *Client, REQUEST *Req)
 				strlcat(rpl, "+", sizeof(rpl));
 				strlcat(rpl, "+", sizeof(rpl));
 			strlcat(rpl, Client_User(c), sizeof(rpl));
 			strlcat(rpl, Client_User(c), sizeof(rpl));
 			strlcat(rpl, "@", sizeof(rpl));
 			strlcat(rpl, "@", sizeof(rpl));
-			strlcat(rpl, Client_HostnameCloaked(c), sizeof(rpl));
+			strlcat(rpl, Client_HostnameDisplayed(c), sizeof(rpl));
 			strlcat(rpl, " ", sizeof(rpl));
 			strlcat(rpl, " ", sizeof(rpl));
 		}
 		}
 	}
 	}
@@ -792,7 +792,7 @@ write_whoreply(CLIENT *Client, CLIENT *c, const char *channelname, const char *f
 {
 {
 	return IRC_WriteStrClient(Client, RPL_WHOREPLY_MSG, Client_ID(Client),
 	return IRC_WriteStrClient(Client, RPL_WHOREPLY_MSG, Client_ID(Client),
 				  channelname, Client_User(c),
 				  channelname, Client_User(c),
-				  Client_HostnameCloaked(c),
+				  Client_HostnameDisplayed(c),
 				  Client_ID(Client_Introducer(c)), Client_ID(c),
 				  Client_ID(Client_Introducer(c)), Client_ID(c),
 				  flags, Client_Hops(c), Client_Info(c));
 				  flags, Client_Hops(c), Client_Info(c));
 }
 }
@@ -807,22 +807,48 @@ who_flags_status(const char *client_modes)
 }
 }
 
 
 
 
-static const char *
-who_flags_qualifier(CLIENT *Client, const char *chan_user_modes)
+/**
+ * Return channel user mode prefix(es).
+ *
+ * @param Client The client requesting the mode prefixes.
+ * @param chan_user_modes String with channel user modes.
+ * @param str String buffer to which the prefix(es) will be appended.
+ * @param len Size of "str" buffer.
+ * @return Pointer to "str".
+ */
+static char *
+who_flags_qualifier(CLIENT *Client, const char *chan_user_modes,
+		    char *str, size_t len)
 {
 {
 	assert(Client != NULL);
 	assert(Client != NULL);
 
 
 	if (Client_Cap(Client) & CLIENT_CAP_MULTI_PREFIX) {
 	if (Client_Cap(Client) & CLIENT_CAP_MULTI_PREFIX) {
-		if (strchr(chan_user_modes, 'o') &&
-		    strchr(chan_user_modes, 'v'))
-			return "@+";
+		if (strchr(chan_user_modes, 'q'))
+			strlcat(str, "~", len);
+		if (strchr(chan_user_modes, 'a'))
+			strlcat(str, "&", len);
+		if (strchr(chan_user_modes, 'o'))
+			strlcat(str, "@", len);
+		if (strchr(chan_user_modes, 'h'))
+			strlcat(str, "%", len);
+		if (strchr(chan_user_modes, 'v'))
+			strlcat(str, "+", len);
+
+		return str;
 	}
 	}
 
 
-	if (strchr(chan_user_modes, 'o'))
-		return "@";
+	if (strchr(chan_user_modes, 'q'))
+		strlcat(str, "~", len);
+	else if (strchr(chan_user_modes, 'a'))
+		strlcat(str, "&", len);
+	else if (strchr(chan_user_modes, 'o'))
+		strlcat(str, "@", len);
+	else if (strchr(chan_user_modes, 'h'))
+		strlcat(str, "%", len);
 	else if (strchr(chan_user_modes, 'v'))
 	else if (strchr(chan_user_modes, 'v'))
-		return "+";
-	return "";
+		strlcat(str, "+", len);
+
+	return str;
 }
 }
 
 
 
 
@@ -840,14 +866,15 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
 	bool is_visible, is_member, is_ircop;
 	bool is_visible, is_member, is_ircop;
 	CL2CHAN *cl2chan;
 	CL2CHAN *cl2chan;
 	const char *client_modes;
 	const char *client_modes;
-	const char *chan_user_modes;
-	char flags[8];
+	char flags[10];
 	CLIENT *c;
 	CLIENT *c;
 	int count = 0;
 	int count = 0;
 
 
 	assert( Client != NULL );
 	assert( Client != NULL );
 	assert( Chan != NULL );
 	assert( Chan != NULL );
 
 
+	IRC_SetPenalty(Client, 1);
+
 	is_member = Channel_IsMemberOf(Chan, Client);
 	is_member = Channel_IsMemberOf(Chan, Client);
 
 
 	/* Secret channel? */
 	/* Secret channel? */
@@ -866,16 +893,12 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
 
 
 		is_visible = strchr(client_modes, 'i') == NULL;
 		is_visible = strchr(client_modes, 'i') == NULL;
 		if (is_member || is_visible) {
 		if (is_member || is_visible) {
-			if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO"))
-				break;
-
 			strcpy(flags, who_flags_status(client_modes));
 			strcpy(flags, who_flags_status(client_modes));
 			if (is_ircop)
 			if (is_ircop)
 				strlcat(flags, "*", sizeof(flags));
 				strlcat(flags, "*", sizeof(flags));
 
 
-			chan_user_modes = Channel_UserModes(Chan, c);
-			strlcat(flags, who_flags_qualifier(c, chan_user_modes),
-				sizeof(flags));
+			who_flags_qualifier(Client, Channel_UserModes(Chan, c),
+					    flags, sizeof(flags));
 
 
 			if (!write_whoreply(Client, c, Channel_Name(Chan),
 			if (!write_whoreply(Client, c, Channel_Name(Chan),
 					    flags))
 					    flags))
@@ -883,6 +906,11 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
 			count++;
 			count++;
 		}
 		}
 	}
 	}
+
+	/* If there are a lot of clients, augment penalty a bit */
+	if (count > MAX_RPL_WHO)
+		IRC_SetPenalty(Client, 1);
+
 	return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client),
 	return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client),
 				  Channel_Name(Chan));
 				  Channel_Name(Chan));
 }
 }
@@ -911,6 +939,7 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps)
 	if (Mask)
 	if (Mask)
 		ngt_LowerStr(Mask);
 		ngt_LowerStr(Mask);
 
 
+	IRC_SetPenalty(Client, 3);
 	for (c = Client_First(); c != NULL; c = Client_Next(c)) {
 	for (c = Client_First(); c != NULL; c = Client_Next(c)) {
 		if (Client_Type(c) != CLIENT_USER)
 		if (Client_Type(c) != CLIENT_USER)
 			continue;
 			continue;
@@ -958,7 +987,7 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps)
 		if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO"))
 		if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO"))
 			break;
 			break;
 
 
-		strcpy(flags, who_flags_status(Client_Modes(c)));
+		strlcpy(flags, who_flags_status(Client_Modes(c)), sizeof(flags));
 		if (strchr(Client_Modes(c), 'o'))
 		if (strchr(Client_Modes(c), 'o'))
 			strlcat(flags, "*", sizeof(flags));
 			strlcat(flags, "*", sizeof(flags));
 
 
@@ -1014,13 +1043,11 @@ IRC_WHO(CLIENT *Client, REQUEST *Req)
 		chan = Channel_Search(Req->argv[0]);
 		chan = Channel_Search(Req->argv[0]);
 		if (chan) {
 		if (chan) {
 			/* Members of a channel have been requested */
 			/* Members of a channel have been requested */
-			IRC_SetPenalty(Client, 1);
 			return IRC_WHO_Channel(Client, chan, only_ops);
 			return IRC_WHO_Channel(Client, chan, only_ops);
 		}
 		}
 		if (strcmp(Req->argv[0], "0") != 0) {
 		if (strcmp(Req->argv[0], "0") != 0) {
 			/* A mask has been given. But please note this RFC
 			/* A mask has been given. But please note this RFC
 			 * stupidity: "0" is same as no arguments ... */
 			 * stupidity: "0" is same as no arguments ... */
-			IRC_SetPenalty(Client, 3);
 			return IRC_WHO_Mask(Client, Req->argv[0], only_ops);
 			return IRC_WHO_Mask(Client, Req->argv[0], only_ops);
 		}
 		}
 	}
 	}
@@ -1053,7 +1080,7 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
 	/* Nick, user, hostname and client info */
 	/* Nick, user, hostname and client info */
 	if (!IRC_WriteStrClient(from, RPL_WHOISUSER_MSG, Client_ID(from),
 	if (!IRC_WriteStrClient(from, RPL_WHOISUSER_MSG, Client_ID(from),
 				Client_ID(c), Client_User(c),
 				Client_ID(c), Client_User(c),
-				Client_HostnameCloaked(c), Client_Info(c)))
+				Client_HostnameDisplayed(c), Client_Info(c)))
 		return DISCONNECTED;
 		return DISCONNECTED;
 
 
 	/* Server */
 	/* Server */
@@ -1087,8 +1114,8 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
 		if (str[strlen(str) - 1] != ':')
 		if (str[strlen(str) - 1] != ':')
 			strlcat(str, " ", sizeof(str));
 			strlcat(str, " ", sizeof(str));
 
 
-		strlcat(str, who_flags_qualifier(c, Channel_UserModes(chan, c)),
-						 sizeof(str));
+		who_flags_qualifier(Client, Channel_UserModes(chan, c),
+				    str, sizeof(str));
 		strlcat(str, Channel_Name(chan), sizeof(str));
 		strlcat(str, Channel_Name(chan), sizeof(str));
 
 
 		if (strlen(str) > (LINE_LEN - CHANNEL_NAME_LEN - 4)) {
 		if (strlen(str) > (LINE_LEN - CHANNEL_NAME_LEN - 4)) {
@@ -1111,23 +1138,37 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
 				Client_ID(from), Client_ID(c)))
 				Client_ID(from), Client_ID(c)))
 		return DISCONNECTED;
 		return DISCONNECTED;
 
 
+	/* IRC-Bot? */
+	if (Client_HasMode(c, 'B') &&
+	    !IRC_WriteStrClient(from, RPL_WHOISBOT_MSG,
+				Client_ID(from), Client_ID(c)))
+		return DISCONNECTED;
+
 	/* Connected using SSL? */
 	/* Connected using SSL? */
 	if (Conn_UsesSSL(Client_Conn(c)) &&
 	if (Conn_UsesSSL(Client_Conn(c)) &&
 	    !IRC_WriteStrClient(from, RPL_WHOISSSL_MSG, Client_ID(from),
 	    !IRC_WriteStrClient(from, RPL_WHOISSSL_MSG, Client_ID(from),
 				Client_ID(c)))
 				Client_ID(c)))
 		return DISCONNECTED;
 		return DISCONNECTED;
 
 
-	/* Registered nick name? */
+	/* Registered nickname? */
 	if (Client_HasMode(c, 'R') &&
 	if (Client_HasMode(c, 'R') &&
 	    !IRC_WriteStrClient(from, RPL_WHOISREGNICK_MSG,
 	    !IRC_WriteStrClient(from, RPL_WHOISREGNICK_MSG,
 				Client_ID(from), Client_ID(c)))
 				Client_ID(from), Client_ID(c)))
 		return DISCONNECTED;
 		return DISCONNECTED;
 
 
-	if (Client_Conn(c) > NONE && (Client_OperByMe(from) || from == c) &&
-	    !IRC_WriteStrClient(from, RPL_WHOISHOST_MSG, Client_ID(from),
-				Client_ID(c), Client_Hostname(c),
-				Conn_GetIPAInfo(Client_Conn(c))))
-		return DISCONNECTED;
+	/* 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')))) {
+		/* Client hostname */
+		if (!IRC_WriteStrClient(from, RPL_WHOISHOST_MSG,
+		    Client_ID(from), Client_ID(c), Client_Hostname(c),
+		    Conn_GetIPAInfo(Client_Conn(c))))
+			return DISCONNECTED;
+		/* Client modes */
+		if (!IRC_WriteStrClient(from, RPL_WHOISMODES_MSG,
+		    Client_ID(from), Client_ID(c), Client_Modes(c)))
+			return DISCONNECTED;
+	}
 
 
 	/* Idle and signon time (local clients only!) */
 	/* Idle and signon time (local clients only!) */
 	if (!Conf_MorePrivacy && Client_Conn(c) > NONE &&
 	if (!Conf_MorePrivacy && Client_Conn(c) > NONE &&
@@ -1187,7 +1228,7 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
 	/* Get target server for this command */
 	/* Get target server for this command */
 	if (Req->argc > 1) {
 	if (Req->argc > 1) {
 		/* Search the target server, which can be specified as a
 		/* Search the target server, which can be specified as a
-		 * nick name on that server as well: */
+		 * nickname on that server as well: */
 		target = Client_Search(Req->argv[0]);
 		target = Client_Search(Req->argv[0]);
 		if (!target)
 		if (!target)
 			return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
 			return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
@@ -1456,7 +1497,7 @@ IRC_Send_LUSERS(CLIENT *Client)
 			Conn_CountMax(), Conn_CountAccepted()))
 			Conn_CountMax(), Conn_CountAccepted()))
 		return DISCONNECTED;
 		return DISCONNECTED;
 #endif
 #endif
-	
+
 	return CONNECTED;
 	return CONNECTED;
 } /* IRC_Send_LUSERS */
 } /* IRC_Send_LUSERS */
 
 
@@ -1477,7 +1518,15 @@ Show_MOTD_Sendline(CLIENT *Client, const char *msg)
 static bool
 static bool
 Show_MOTD_End(CLIENT *Client)
 Show_MOTD_End(CLIENT *Client)
 {
 {
-	return IRC_WriteStrClient( Client, RPL_ENDOFMOTD_MSG, Client_ID( Client ));
+	if (!IRC_WriteStrClient(Client, RPL_ENDOFMOTD_MSG, Client_ID(Client)))
+		return DISCONNECTED;
+
+	if (*Conf_CloakHost)
+		return IRC_WriteStrClient(Client, RPL_HOSTHIDDEN_MSG,
+					  Client_ID(Client),
+					  Client_Hostname(Client));
+
+	return CONNECTED;
 }
 }
 
 
 #ifdef SSL_SUPPORT
 #ifdef SSL_SUPPORT
@@ -1578,16 +1627,9 @@ IRC_Send_NAMES(CLIENT * Client, CHANNEL * Chan)
 		if (is_member || is_visible) {
 		if (is_member || is_visible) {
 			if (str[strlen(str) - 1] != ':')
 			if (str[strlen(str) - 1] != ':')
 				strlcat(str, " ", sizeof(str));
 				strlcat(str, " ", sizeof(str));
-			if (Client_Cap(cl) & CLIENT_CAP_MULTI_PREFIX) {
-				if (strchr(Channel_UserModes(Chan, cl), 'o') &&
-				    strchr(Channel_UserModes(Chan, cl), 'v'))
-					strlcat(str, "@+", sizeof(str));
-			} else {
-				if (strchr(Channel_UserModes(Chan, cl), 'o'))
-					strlcat(str, "@", sizeof(str));
-				else if (strchr(Channel_UserModes(Chan, cl), 'v'))
-					strlcat(str, "+", sizeof(str));
-			}
+
+			who_flags_qualifier(Client, Channel_UserModes(Chan, cl),
+					    str, sizeof(str));
 			strlcat(str, Client_ID(cl), sizeof(str));
 			strlcat(str, Client_ID(cl), sizeof(str));
 
 
 			if (strlen(str) > (LINE_LEN - CLIENT_NICK_LEN - 4)) {
 			if (strlen(str) > (LINE_LEN - CLIENT_NICK_LEN - 4)) {

+ 107 - 45
src/ngircd/irc-login.c

@@ -1,6 +1,6 @@
 /*
 /*
  * ngIRCd -- The Next Generation IRC Daemon
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
 
 
 #include "imp.h"
 #include "imp.h"
 #include <assert.h>
 #include <assert.h>
+#include <ctype.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
 #include <strings.h>
 #include <strings.h>
@@ -37,7 +38,10 @@
 #include "exp.h"
 #include "exp.h"
 #include "irc-login.h"
 #include "irc-login.h"
 
 
-static void Kill_Nick PARAMS(( char *Nick, char *Reason ));
+static void Kill_Nick PARAMS((char *Nick, char *Reason));
+static void Change_Nick PARAMS((CLIENT * Origin, CLIENT * Target, char *NewNick,
+				bool InformClient));
+
 
 
 /**
 /**
  * Handler for the IRC "PASS" command.
  * Handler for the IRC "PASS" command.
@@ -87,7 +91,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
 					  Client_ID(Client));
 					  Client_ID(Client));
 	}
 	}
 
 
-	Client_SetPassword(Client, Req->argv[0]);
+	Conn_SetPassword(Client_Conn(Client), Req->argv[0]);
 
 
 	/* Protocol version */
 	/* Protocol version */
 	if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) {
 	if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) {
@@ -274,40 +278,9 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
 				Client_SetType( Client, CLIENT_GOTNICK );
 				Client_SetType( Client, CLIENT_GOTNICK );
 		} else {
 		} else {
 			/* Nickname change */
 			/* Nickname change */
-			if (Client_Conn(target) > NONE) {
-				/* Local client */
-				Log(LOG_INFO,
-				    "%s \"%s\" changed nick (connection %d): \"%s\" -> \"%s\".",
-				    Client_TypeText(target), Client_Mask(target),
-				    Client_Conn(target), Client_ID(target),
-				    Req->argv[0]);
-				Conn_UpdateIdle(Client_Conn(target));
-			} else {
-				/* Remote client */
-				LogDebug("%s \"%s\" changed nick: \"%s\" -> \"%s\".",
-					 Client_TypeText(target),
-					 Client_Mask(target), Client_ID(target),
-					 Req->argv[0]);
-			}
-
-			/* Inform all users and servers (which have to know)
-			 * of this nickname change */
-			if( Client_Type( Client ) == CLIENT_USER )
-				IRC_WriteStrClientPrefix( Client, Client,
-							  "NICK :%s",
-							  Req->argv[0] );
-			IRC_WriteStrServersPrefix( Client, target,
-						   "NICK :%s", Req->argv[0] );
-			IRC_WriteStrRelatedPrefix( target, target, false,
-						   "NICK :%s", Req->argv[0] );
-
-			/* Register old nickname for WHOWAS queries */
-			Client_RegisterWhowas( target );
-
-			/* Save new nickname */
-			Client_SetID( target, Req->argv[0] );
-
-			IRC_SetPenalty( target, 2 );
+			Change_Nick(Client, target, Req->argv[0],
+				    Client_Type(Client) == CLIENT_USER ? true : false);
+			IRC_SetPenalty(target, 2);
 		}
 		}
 
 
 		return CONNECTED;
 		return CONNECTED;
@@ -388,6 +361,54 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
 
 
 
 
 /**
 /**
+ * Handler for the IRC "SVSNICK" command.
+ *
+ * @param Client The client from which this command has been received.
+ * @param Req Request structure with prefix and all parameters.
+ * @return CONNECTED or DISCONNECTED.
+ */
+GLOBAL bool
+IRC_SVSNICK(CLIENT *Client, REQUEST *Req)
+{
+	CLIENT *from, *target;
+
+	assert(Client != NULL);
+	assert(Req != NULL);
+
+	if (Req->argc != 2)
+		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+					  Client_ID(Client), Req->command);
+
+	/* Search the originator */
+	from = Client_Search(Req->prefix);
+	if (!from)
+		from = Client;
+
+	/* Search the target */
+	target = Client_Search(Req->argv[0]);
+	if (!target || Client_Type(target) != CLIENT_USER) {
+		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
+					  Client_ID(Client), Req->argv[0]);
+	}
+
+	if (Client_Conn(target) <= NONE) {
+		/* We have to forward the message to the server handling
+		 * this user; this is required to make sure all servers
+		 * in the network do follow the nick name change! */
+		return IRC_WriteStrClientPrefix(Client_NextHop(target), from,
+						"SVSNICK %s %s",
+						Req->argv[0], Req->argv[1]);
+	}
+
+	/* Make sure that the new nickname is valid */
+	if (!Client_CheckNick(from, Req->argv[1]))
+		return CONNECTED;
+
+	Change_Nick(from, target, Req->argv[1], true);
+	return CONNECTED;
+}
+
+/**
  * Handler for the IRC "USER" command.
  * Handler for the IRC "USER" command.
  *
  *
  * See RFC 2812, 3.1.3 "User message".
  * See RFC 2812, 3.1.3 "User message".
@@ -418,12 +439,13 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
 						  Client_ID(Client),
 						  Client_ID(Client),
 						  Req->command);
 						  Req->command);
 
 
-		/* User name: only alphanumeric characters are allowed! */
+		/* User name: only alphanumeric characters and limited
+		   punctuation is allowed.*/
 		ptr = Req->argv[0];
 		ptr = Req->argv[0];
 		while (*ptr) {
 		while (*ptr) {
-			if ((*ptr < '0' || *ptr > '9') &&
-			    (*ptr < 'A' || *ptr > 'Z') &&
-			    (*ptr < 'a' || *ptr > 'z')) {
+			if (!isalnum((int)*ptr) &&
+			    *ptr != '+' && *ptr != '-' &&
+			    *ptr != '.' && *ptr != '_') {
 				Conn_Close(Client_Conn(Client), NULL,
 				Conn_Close(Client_Conn(Client), NULL,
 					   "Invalid user name", true);
 					   "Invalid user name", true);
 				return DISCONNECTED;
 				return DISCONNECTED;
@@ -544,10 +566,10 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req)
 	hops = atoi(Req->argv[4]);
 	hops = atoi(Req->argv[4]);
 	info = Req->argv[5];
 	info = Req->argv[5];
 
 
-	/* Validate service name ("nick name") */
+	/* Validate service name ("nickname") */
 	c = Client_Search(nick);
 	c = Client_Search(nick);
 	if(c) {
 	if(c) {
-		/* Nick name collission: disconnect (KILL) both clients! */
+		/* Nickname collission: disconnect (KILL) both clients! */
 		Log(LOG_ERR, "Server %s introduces already registered service \"%s\"!",
 		Log(LOG_ERR, "Server %s introduces already registered service \"%s\"!",
 		    Client_ID(Client), nick);
 		    Client_ID(Client), nick);
 		Kill_Nick(nick, "Nick collision");
 		Kill_Nick(nick, "Nick collision");
@@ -898,9 +920,9 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
 
 
 
 
 /**
 /**
- * Kill all users with a specific nick name in the network.
+ * Kill all users with a specific nickname in the network.
  *
  *
- * @param Nick		Nick name.
+ * @param Nick		Nickname.
  * @param Reason	Reason for the KILL.
  * @param Reason	Reason for the KILL.
  */
  */
 static void
 static void
@@ -923,4 +945,44 @@ Kill_Nick(char *Nick, char *Reason)
 } /* Kill_Nick */
 } /* Kill_Nick */
 
 
 
 
+/**
+ * Change the nickname of a client.
+ *
+ * @param Origin The client which caused the nickname change.
+ * @param Target The client of which the nickname should be changed.
+ * @param NewNick The new nickname.
+ */
+static void
+Change_Nick(CLIENT *Origin, CLIENT *Target, char *NewNick, bool InformClient)
+{
+	if (Client_Conn(Target) > NONE) {
+		/* Local client */
+		Log(LOG_INFO,
+		    "%s \"%s\" changed nick (connection %d): \"%s\" -> \"%s\".",
+		    Client_TypeText(Target), Client_Mask(Target),
+		    Client_Conn(Target), Client_ID(Target), NewNick);
+		Conn_UpdateIdle(Client_Conn(Target));
+	} else {
+		/* Remote client */
+		LogDebug("%s \"%s\" changed nick: \"%s\" -> \"%s\".",
+			 Client_TypeText(Target),
+			 Client_Mask(Target), Client_ID(Target), NewNick);
+	}
+
+	/* Inform all servers and users (which have to know) of the new name */
+	if (InformClient) {
+		IRC_WriteStrClientPrefix(Target, Target, "NICK :%s", NewNick);
+		IRC_WriteStrServersPrefix(NULL, Target, "NICK :%s", NewNick);
+	} else
+		IRC_WriteStrServersPrefix(Origin, Target, "NICK :%s", NewNick);
+	IRC_WriteStrRelatedPrefix(Target, Target, false, "NICK :%s", NewNick);
+
+	/* Register old nickname for WHOWAS queries */
+	Client_RegisterWhowas(Target);
+
+	/* Save new nickname */
+	Client_SetID(Target, NewNick);
+}
+
+
 /* -eof- */
 /* -eof- */

+ 2 - 1
src/ngircd/irc-login.h

@@ -1,6 +1,6 @@
 /*
 /*
  * ngIRCd -- The Next Generation IRC Daemon
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
  *
  *
  * This program is free software; you can redistribute it and/or modify
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@ GLOBAL bool IRC_PING PARAMS((CLIENT *Client, REQUEST *Req));
 GLOBAL bool IRC_PONG PARAMS((CLIENT *Client, REQUEST *Req));
 GLOBAL bool IRC_PONG PARAMS((CLIENT *Client, REQUEST *Req));
 GLOBAL bool IRC_QUIT PARAMS((CLIENT *Client, REQUEST *Req));
 GLOBAL bool IRC_QUIT PARAMS((CLIENT *Client, REQUEST *Req));
 GLOBAL bool IRC_QUIT_HTTP PARAMS((CLIENT *Client, REQUEST *Req));
 GLOBAL bool IRC_QUIT_HTTP PARAMS((CLIENT *Client, REQUEST *Req));
+GLOBAL bool IRC_SVSNICK PARAMS(( CLIENT *Client, REQUEST *Req ));
 
 
 #endif
 #endif
 
 

+ 109 - 0
src/ngircd/irc-metadata.c

@@ -0,0 +1,109 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ * Copyright (c)2001-2012 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * Please read the file COPYING, README and AUTHORS for more information.
+ */
+
+#define __irc_metadata_c__
+
+#include "portab.h"
+
+/**
+ * @file
+ * IRC metadata commands
+ */
+
+#include "imp.h"
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "conn-func.h"
+#include "channel.h"
+#include "conn-encoding.h"
+#include "irc-write.h"
+#include "log.h"
+#include "messages.h"
+#include "parse.h"
+#include "tool.h"
+
+#include "exp.h"
+#include "irc-metadata.h"
+
+/**
+ * Handler for the IRC+ "METADATA" command.
+ *
+ * @param Client The client from which this command has been received.
+ * @param Req Request structure with prefix and all parameters.
+ * @returns CONNECTED or DISCONNECTED.
+ */
+GLOBAL bool
+IRC_METADATA(CLIENT *Client, REQUEST *Req)
+{
+	CLIENT *prefix, *target;
+	char new_flags[COMMAND_LEN];
+
+	assert(Client != NULL);
+	assert(Req != NULL);
+
+	if (Req->argc != 3)
+		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+					  Client_ID(Client), Req->command);
+
+	prefix = Client_Search(Req->prefix);
+	if (!prefix)
+		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
+					  Client_ID(Client), Req->prefix);
+
+	target = Client_Search(Req->argv[0]);
+	if (!target)
+		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
+					  Client_ID(Client), Req->argv[0]);
+
+	LogDebug("Got \"METADATA\" command from \"%s\" for client \"%s\": \"%s=%s\".",
+		 Client_ID(prefix), Client_ID(target),
+		 Req->argv[1], Req->argv[2]);
+
+	/* Mark client: it has receiveda a METADATA command */
+	if (!strchr(Client_Flags(target), 'M')) {
+		snprintf(new_flags, sizeof new_flags, "%sM",
+			 Client_Flags(target));
+		Client_SetFlags(target, new_flags);
+	}
+
+	if (strcasecmp(Req->argv[1], "cloakhost") == 0) {
+		Client_UpdateCloakedHostname(target, prefix, Req->argv[2]);
+		if (Client_Conn(target) > NONE && Client_HasMode(target, 'x'))
+			IRC_WriteStrClientPrefix(target, prefix,
+					RPL_HOSTHIDDEN_MSG, Client_ID(target),
+					Client_HostnameDisplayed(target));
+		/* The Client_UpdateCloakedHostname() function already
+		 * forwarded the METADATA command, don't do it twice: */
+		return CONNECTED;
+	}
+	else if (*Req->argv[2] && strcasecmp(Req->argv[1], "host") == 0) {
+		Client_SetHostname(target, Req->argv[2]);
+		if (Client_Conn(target) > NONE && !Client_HasMode(target, 'x'))
+			IRC_WriteStrClientPrefix(target, prefix,
+						 RPL_HOSTHIDDEN_MSG, Client_ID(target),
+						 Client_HostnameDisplayed(target));
+	} else if (strcasecmp(Req->argv[1], "info") == 0)
+		Client_SetInfo(target, Req->argv[2]);
+	else if (*Req->argv[2] && strcasecmp(Req->argv[1], "user") == 0)
+		Client_SetUser(target, Req->argv[2], true);
+	else
+		Log(LOG_WARNING,
+		    "Ignored metadata update from \"%s\" for client \"%s\": \"%s=%s\" - unknown key!",
+		    Client_ID(Client), Client_ID(target),
+		    Req->argv[1], Req->argv[2]);
+
+	/* Forward the METADATA command to peers that support it: */
+	IRC_WriteStrServersPrefixFlag(Client, prefix, 'M', "METADATA %s %s :%s",
+				Client_ID(target), Req->argv[1], Req->argv[2]);
+	return CONNECTED;
+}

+ 24 - 0
src/ngircd/irc-metadata.h

@@ -0,0 +1,24 @@
+/*
+ * ngIRCd -- The Next Generation IRC Daemon
+ * Copyright (c)2001-2012 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * Please read the file COPYING, README and AUTHORS for more information.
+ */
+
+#ifndef __irc_metadata_h__
+#define __irc_metadata_h__
+
+/**
+ * @file
+ * IRC metadata commands (header)
+ */
+
+GLOBAL bool IRC_METADATA PARAMS((CLIENT *Client, REQUEST *Req));
+
+#endif
+
+/* -eof- */

+ 149 - 40
src/ngircd/irc-mode.c

@@ -138,6 +138,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 {
 {
 	char the_modes[COMMAND_LEN], x[2], *mode_ptr;
 	char the_modes[COMMAND_LEN], x[2], *mode_ptr;
 	bool ok, set;
 	bool ok, set;
+	bool send_RPL_HOSTHIDDEN_MSG = false;
 	int mode_arg;
 	int mode_arg;
 	size_t len;
 	size_t len;
 
 
@@ -153,7 +154,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 	/* Mode request: let's answer it :-) */
 	/* Mode request: let's answer it :-) */
 	if (Req->argc == 1)
 	if (Req->argc == 1)
 		return IRC_WriteStrClient(Origin, RPL_UMODEIS_MSG,
 		return IRC_WriteStrClient(Origin, RPL_UMODEIS_MSG,
-					  Client_ID(Origin),
+					  Client_ID(Target),
 					  Client_Modes(Target));
 					  Client_Modes(Target));
 
 
 	mode_arg = 1;
 	mode_arg = 1;
@@ -214,6 +215,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 		/* Validate modes */
 		/* Validate modes */
 		x[0] = '\0';
 		x[0] = '\0';
 		switch (*mode_ptr) {
 		switch (*mode_ptr) {
+		case 'b': /* Block private msgs */
 		case 'C': /* Only messages from clients sharing a channel */
 		case 'C': /* Only messages from clients sharing a channel */
 		case 'i': /* Invisible */
 		case 'i': /* Invisible */
 		case 's': /* Server messages */
 		case 's': /* Server messages */
@@ -229,6 +231,14 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 							ERR_NOPRIVILEGES_MSG,
 							ERR_NOPRIVILEGES_MSG,
 							Client_ID(Origin));
 							Client_ID(Origin));
 			break;
 			break;
+		case 'B': /* Bot */
+			if (Client_HasMode(Client, 'r'))
+				ok = IRC_WriteStrClient(Origin,
+							ERR_RESTRICTED_MSG,
+							Client_ID(Origin));
+			else
+				x[0] = 'B';
+			break;
 		case 'c': /* Receive connect notices
 		case 'c': /* Receive connect notices
 			   * (only settable by IRC operators!) */
 			   * (only settable by IRC operators!) */
 			if (!set || Client_Type(Client) == CLIENT_SERVER
 			if (!set || Client_Type(Client) == CLIENT_SERVER
@@ -248,6 +258,15 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 							ERR_NOPRIVILEGES_MSG,
 							ERR_NOPRIVILEGES_MSG,
 							Client_ID(Origin));
 							Client_ID(Origin));
 			break;
 			break;
+		case 'q': /* KICK-protected user */
+			if (!set || Client_Type(Client) == CLIENT_SERVER
+			    || Client_OperByMe(Origin))
+				x[0] = 'q';
+			else
+				ok = IRC_WriteStrClient(Origin,
+							ERR_NOPRIVILEGES_MSG,
+							Client_ID(Origin));
+			break;
 		case 'r': /* Restricted (only settable) */
 		case 'r': /* Restricted (only settable) */
 			if (set || Client_Type(Client) == CLIENT_SERVER)
 			if (set || Client_Type(Client) == CLIENT_SERVER)
 				x[0] = 'r';
 				x[0] = 'r';
@@ -256,13 +275,28 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 							ERR_RESTRICTED_MSG,
 							ERR_RESTRICTED_MSG,
 							Client_ID(Origin));
 							Client_ID(Origin));
 			break;
 			break;
+		case 'R': /* Registered (not [un]settable by clients) */
+			if (Client_Type(Client) == CLIENT_SERVER)
+				x[0] = 'R';
+			else
+				ok = IRC_WriteStrClient(Origin,
+							ERR_NICKREGISTER_MSG,
+							Client_ID(Origin));
+			break;
 		case 'x': /* Cloak hostname */
 		case 'x': /* Cloak hostname */
 			if (Client_HasMode(Client, 'r'))
 			if (Client_HasMode(Client, 'r'))
 				ok = IRC_WriteStrClient(Origin,
 				ok = IRC_WriteStrClient(Origin,
 							ERR_RESTRICTED_MSG,
 							ERR_RESTRICTED_MSG,
 							Client_ID(Origin));
 							Client_ID(Origin));
-			else
+			else if (!set || Conf_CloakHostModeX[0]
+				 || Client_Type(Client) == CLIENT_SERVER
+				 || Client_OperByMe(Client)) {
 				x[0] = 'x';
 				x[0] = 'x';
+				send_RPL_HOSTHIDDEN_MSG = true;
+			} else
+				ok = IRC_WriteStrClient(Origin,
+							ERR_NOPRIVILEGES_MSG,
+							Client_ID(Origin));
 			break;
 			break;
 		default:
 		default:
 			if (Client_Type(Client) != CLIENT_SERVER) {
 			if (Client_Type(Client) != CLIENT_SERVER) {
@@ -333,6 +367,16 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 						  Client_ID(Target),
 						  Client_ID(Target),
 						  the_modes);
 						  the_modes);
 		}
 		}
+
+		if (send_RPL_HOSTHIDDEN_MSG && Client_Conn(Target) > NONE) {
+			/* A new (cloaked) hostname must be annoucned */
+			IRC_WriteStrClientPrefix(Target, Origin,
+						 RPL_HOSTHIDDEN_MSG,
+						 Client_ID(Target),
+						 Client_HostnameDisplayed(Target));
+
+		}
+
 		LogDebug("%s \"%s\": Mode change, now \"%s\".",
 		LogDebug("%s \"%s\": Mode change, now \"%s\".",
 			 Client_TypeText(Target), Client_Mask(Target),
 			 Client_TypeText(Target), Client_Mask(Target),
 			 Client_Modes(Target));
 			 Client_Modes(Target));
@@ -396,13 +440,16 @@ static bool
 Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 {
 {
 	char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2],
 	char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2],
-	    argadd[CLIENT_PASS_LEN], *mode_ptr;
-	bool connected, set, skiponce, retval, onchannel, modeok, use_servermode;
+	    argadd[CLIENT_PASS_LEN], *mode_ptr, *o_mode_ptr;
+	bool connected, set, skiponce, retval, use_servermode,
+	     is_halfop, is_op, is_admin, is_owner, is_machine, is_oper;
 	int mode_arg, arg_arg, mode_arg_count = 0;
 	int mode_arg, arg_arg, mode_arg_count = 0;
 	CLIENT *client;
 	CLIENT *client;
 	long l;
 	long l;
 	size_t len;
 	size_t len;
 
 
+	is_halfop = is_op = is_admin = is_owner = is_machine = is_oper = false;
+
 	if (Channel_IsModeless(Channel))
 	if (Channel_IsModeless(Channel))
 		return IRC_WriteStrClient(Client, ERR_NOCHANMODES_MSG,
 		return IRC_WriteStrClient(Client, ERR_NOCHANMODES_MSG,
 				Client_ID(Client), Channel_Name(Channel));
 				Client_ID(Client), Channel_Name(Channel));
@@ -411,10 +458,20 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 	if (Req->argc <= 1)
 	if (Req->argc <= 1)
 		return Channel_Mode_Answer_Request(Origin, Channel);
 		return Channel_Mode_Answer_Request(Origin, Channel);
 
 
-	Channel_CheckAdminRights(Channel, Client, Origin,
-				 &onchannel, &modeok, &use_servermode);
+	/* Check if origin is oper and opers can use mode */
+	use_servermode = Conf_OperServerMode;
+	if(Client_OperByMe(Client) && Conf_OperCanMode) {
+		is_oper = true;
+	}
+
+	/* Check if client is a server/service */
+	if(Client_Type(Client) == CLIENT_SERVER ||
+	   Client_Type(Client) == CLIENT_SERVICE) {
+		is_machine = true;
+	}
 
 
-	if (!onchannel && !modeok)
+	/* Check if client is member of channel or an oper or an server/service */
+	if(!Channel_IsMemberOf(Channel, Client) && !is_oper && !is_machine)
 		return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG,
 		return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG,
 					  Client_ID(Origin),
 					  Client_ID(Origin),
 					  Channel_Name(Channel));
 					  Channel_Name(Channel));
@@ -493,20 +550,46 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 		if (arg_arg >= Req->argc)
 		if (arg_arg >= Req->argc)
 			arg_arg = -1;
 			arg_arg = -1;
 
 
+		if(!is_machine) {
+			o_mode_ptr = Channel_UserModes(Channel, Client);
+			while( *o_mode_ptr ) {
+				if ( *o_mode_ptr == 'q')
+					is_owner = true;
+				if ( *o_mode_ptr == 'a')
+					is_admin = true;
+				if ( *o_mode_ptr == 'o')
+					is_op = true;
+				if ( *o_mode_ptr == 'h')
+					is_halfop = true;
+				o_mode_ptr++;
+			}
+		}
+
 		/* Validate modes */
 		/* Validate modes */
 		x[0] = '\0';
 		x[0] = '\0';
 		argadd[0] = '\0';
 		argadd[0] = '\0';
 		client = NULL;
 		client = NULL;
 		switch (*mode_ptr) {
 		switch (*mode_ptr) {
 		/* --- Channel modes --- */
 		/* --- Channel modes --- */
+		case 'R': /* Registered users only */
+		case 's': /* Secret channel */
+		case 'z': /* Secure connections only */
+			if(!is_oper && !is_machine && !is_owner &&
+			   !is_admin && !is_op) {
+				connected = IRC_WriteStrClient(Origin,
+					ERR_CHANOPRIVSNEEDED_MSG,
+					Client_ID(Origin), Channel_Name(Channel));
+				goto chan_exit;
+			}
 		case 'i': /* Invite only */
 		case 'i': /* Invite only */
+		case 'V': /* Invite disallow */
+		case 'M': /* Only identified nicks can write */
 		case 'm': /* Moderated */
 		case 'm': /* Moderated */
 		case 'n': /* Only members can write */
 		case 'n': /* Only members can write */
-		case 'R': /* Registered users only */
-		case 's': /* Secret channel */
+		case 'Q': /* No kicks */
 		case 't': /* Topic locked */
 		case 't': /* Topic locked */
-		case 'z': /* Secure connections only */
-			if (modeok)
+			if(is_oper || is_machine || is_owner ||
+			   is_admin || is_op || is_halfop)
 				x[0] = *mode_ptr;
 				x[0] = *mode_ptr;
 			else
 			else
 				connected = IRC_WriteStrClient(Origin,
 				connected = IRC_WriteStrClient(Origin,
@@ -517,7 +600,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 			if (Mode_Limit_Reached(Client, mode_arg_count++))
 			if (Mode_Limit_Reached(Client, mode_arg_count++))
 				goto chan_exit;
 				goto chan_exit;
 			if (!set) {
 			if (!set) {
-				if (modeok)
+				if (is_oper || is_machine || is_owner ||
+				    is_admin || is_op || is_halfop)
 					x[0] = *mode_ptr;
 					x[0] = *mode_ptr;
 				else
 				else
 					connected = IRC_WriteStrClient(Origin,
 					connected = IRC_WriteStrClient(Origin,
@@ -527,7 +611,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 				break;
 				break;
 			}
 			}
 			if (arg_arg > mode_arg) {
 			if (arg_arg > mode_arg) {
-				if (modeok) {
+				if (is_oper || is_machine || is_owner ||
+				    is_admin || is_op || is_halfop) {
 					Channel_ModeDel(Channel, 'k');
 					Channel_ModeDel(Channel, 'k');
 					Channel_SetKey(Channel,
 					Channel_SetKey(Channel,
 						       Req->argv[arg_arg]);
 						       Req->argv[arg_arg]);
@@ -553,7 +638,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 			if (Mode_Limit_Reached(Client, mode_arg_count++))
 			if (Mode_Limit_Reached(Client, mode_arg_count++))
 				goto chan_exit;
 				goto chan_exit;
 			if (!set) {
 			if (!set) {
-				if (modeok)
+				if (is_oper || is_machine || is_owner ||
+				    is_admin || is_op || is_halfop)
 					x[0] = *mode_ptr;
 					x[0] = *mode_ptr;
 				else
 				else
 					connected = IRC_WriteStrClient(Origin,
 					connected = IRC_WriteStrClient(Origin,
@@ -563,7 +649,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 				break;
 				break;
 			}
 			}
 			if (arg_arg > mode_arg) {
 			if (arg_arg > mode_arg) {
-				if (modeok) {
+				if (is_oper || is_machine || is_owner ||
+				    is_admin || is_op || is_halfop) {
 					l = atol(Req->argv[arg_arg]);
 					l = atol(Req->argv[arg_arg]);
 					if (l > 0 && l < 0xFFFF) {
 					if (l > 0 && l < 0xFFFF) {
 						Channel_ModeDel(Channel, 'l');
 						Channel_ModeDel(Channel, 'l');
@@ -588,61 +675,82 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 			}
 			}
 			break;
 			break;
 		case 'O': /* IRC operators only */
 		case 'O': /* IRC operators only */
-			if (modeok) {
+			if (set) {
 				/* Only IRC operators are allowed to
 				/* Only IRC operators are allowed to
 				 * set the 'O' channel mode! */
 				 * set the 'O' channel mode! */
-				if (set && !(Client_OperByMe(Client)
-				    || Client_Type(Client) == CLIENT_SERVER))
+				if(is_oper || is_machine)
+					x[0] = 'O';
+				else
 					connected = IRC_WriteStrClient(Origin,
 					connected = IRC_WriteStrClient(Origin,
 						ERR_NOPRIVILEGES_MSG,
 						ERR_NOPRIVILEGES_MSG,
 						Client_ID(Origin));
 						Client_ID(Origin));
-				else
-					x[0] = 'O';
-			} else
+			} else if(is_oper || is_machine || is_owner ||
+				  is_admin || is_op)
+				x[0] = 'O';
+			else
 				connected = IRC_WriteStrClient(Origin,
 				connected = IRC_WriteStrClient(Origin,
-						ERR_CHANOPRIVSNEEDED_MSG,
-						Client_ID(Origin),
-						Channel_Name(Channel));
-				break;
+					ERR_CHANOPRIVSNEEDED_MSG,
+					Client_ID(Origin),
+					Channel_Name(Channel));
+			break;
 		case 'P': /* Persistent channel */
 		case 'P': /* Persistent channel */
-			if (modeok) {
+			if (set) {
 				/* Only IRC operators are allowed to
 				/* Only IRC operators are allowed to
 				 * set the 'P' channel mode! */
 				 * set the 'P' channel mode! */
-				if (set && !(Client_OperByMe(Client)
-				    || Client_Type(Client) == CLIENT_SERVER))
+				if(is_oper || is_machine)
+					x[0] = 'P';
+				else
 					connected = IRC_WriteStrClient(Origin,
 					connected = IRC_WriteStrClient(Origin,
 						ERR_NOPRIVILEGES_MSG,
 						ERR_NOPRIVILEGES_MSG,
 						Client_ID(Origin));
 						Client_ID(Origin));
-				else
-					x[0] = 'P';
-			} else
+			} else if(is_oper || is_machine || is_owner ||
+				  is_admin || is_op)
+				x[0] = 'P';
+			else
 				connected = IRC_WriteStrClient(Origin,
 				connected = IRC_WriteStrClient(Origin,
 					ERR_CHANOPRIVSNEEDED_MSG,
 					ERR_CHANOPRIVSNEEDED_MSG,
 					Client_ID(Origin),
 					Client_ID(Origin),
 					Channel_Name(Channel));
 					Channel_Name(Channel));
 			break;
 			break;
 		/* --- Channel user modes --- */
 		/* --- Channel user modes --- */
-		case 'a':
-		case 'h':
-		case 'q':
-			if (Client_Type(Client) != CLIENT_SERVER) {
+		case 'q': /* Owner */
+		case 'a': /* Channel admin */
+			if(!is_oper && !is_machine && !is_owner && !is_admin) {
 				connected = IRC_WriteStrClient(Origin,
 				connected = IRC_WriteStrClient(Origin,
-					ERR_CHANOPRIVSNEEDED_MSG,
+					ERR_CHANOPPRIVTOOLOW_MSG,
 					Client_ID(Origin),
 					Client_ID(Origin),
 					Channel_Name(Channel));
 					Channel_Name(Channel));
 				goto chan_exit;
 				goto chan_exit;
 			}
 			}
 		case 'o': /* Channel operator */
 		case 'o': /* Channel operator */
+			if(!is_oper && !is_machine && !is_owner &&
+			   !is_admin && !is_op) {
+				connected = IRC_WriteStrClient(Origin,
+					ERR_CHANOPRIVSNEEDED_MSG,
+					Client_ID(Origin),
+					Channel_Name(Channel));
+				goto chan_exit;
+			}
+		case 'h': /* Half Op */
+			if(!is_oper && !is_machine && !is_owner &&
+			   !is_admin && !is_op) {
+				connected = IRC_WriteStrClient(Origin,
+					ERR_CHANOPRIVSNEEDED_MSG,
+					Client_ID(Origin),
+					Channel_Name(Channel));
+				goto chan_exit;
+			}
 		case 'v': /* Voice */
 		case 'v': /* Voice */
 			if (arg_arg > mode_arg) {
 			if (arg_arg > mode_arg) {
-				if (modeok) {
+				if (is_oper || is_machine || is_owner ||
+				    is_admin || is_op || is_halfop) {
 					client = Client_Search(Req->argv[arg_arg]);
 					client = Client_Search(Req->argv[arg_arg]);
 					if (client)
 					if (client)
 						x[0] = *mode_ptr;
 						x[0] = *mode_ptr;
 					else
 					else
-						connected = IRC_WriteStrClient(Client,
+						connected = IRC_WriteStrClient(Origin,
 							ERR_NOSUCHNICK_MSG,
 							ERR_NOSUCHNICK_MSG,
-							Client_ID(Client),
+							Client_ID(Origin),
 							Req->argv[arg_arg]);
 							Req->argv[arg_arg]);
 				} else {
 				} else {
 					connected = IRC_WriteStrClient(Origin,
 					connected = IRC_WriteStrClient(Origin,
@@ -667,7 +775,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 				goto chan_exit;
 				goto chan_exit;
 			if (arg_arg > mode_arg) {
 			if (arg_arg > mode_arg) {
 				/* modify list */
 				/* modify list */
-				if (modeok) {
+				if (is_oper || is_machine || is_owner ||
+				    is_admin || is_op || is_halfop) {
 					connected = set
 					connected = set
 					   ? Add_To_List(*mode_ptr, Origin,
 					   ? Add_To_List(*mode_ptr, Origin,
 						Client, Channel,
 						Client, Channel,

+ 10 - 2
src/ngircd/irc-op.c

@@ -164,10 +164,18 @@ IRC_INVITE(CLIENT *Client, REQUEST *Req)
 		if (!Channel_IsMemberOf(chan, from))
 		if (!Channel_IsMemberOf(chan, from))
 			return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG, Client_ID(Client), Req->argv[1]);
 			return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG, Client_ID(Client), Req->argv[1]);
 
 
+		/* Is the channel "invite-disallow"? */
+		if (strchr(Channel_Modes(chan), 'V'))
+			return IRC_WriteStrClient(from, ERR_NOINVITE_MSG,
+				Client_ID(from), Channel_Name(chan));
+
 		/* Is the channel "invite-only"? */
 		/* Is the channel "invite-only"? */
 		if (strchr(Channel_Modes(chan), 'i')) {
 		if (strchr(Channel_Modes(chan), 'i')) {
-			/* Yes. The user must be channel operator! */
-			if (!strchr(Channel_UserModes(chan, from), 'o'))
+			/* Yes. The user must be channel owner/admin/operator/halfop! */
+			if (!strchr(Channel_UserModes(chan, from), 'q') &&
+			    !strchr(Channel_UserModes(chan, from), 'a') &&
+			    !strchr(Channel_UserModes(chan, from), 'o') &&
+			    !strchr(Channel_UserModes(chan, from), 'h'))
 				return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
 				return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
 						Client_ID(from), Channel_Name(chan));
 						Client_ID(from), Channel_Name(chan));
 			remember = true;
 			remember = true;

+ 2 - 0
src/ngircd/irc-oper.c

@@ -183,6 +183,8 @@ IRC_REHASH( CLIENT *Client, REQUEST *Req )
 
 
 	Log(LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...",
 	Log(LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...",
 	    Client_Mask(Client));
 	    Client_Mask(Client));
+	IRC_WriteStrClient(Client, RPL_REHASHING_MSG, Client_ID(Client));
+
 	raise(SIGHUP);
 	raise(SIGHUP);
 
 
 	return CONNECTED;
 	return CONNECTED;

+ 61 - 34
src/ngircd/irc-server.c

@@ -53,8 +53,7 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
 	char str[LINE_LEN];
 	char str[LINE_LEN];
 	CLIENT *from, *c;
 	CLIENT *from, *c;
 	int i;
 	int i;
-	CONN_ID con;
-	
+
 	assert( Client != NULL );
 	assert( Client != NULL );
 	assert( Req != NULL );
 	assert( Req != NULL );
 
 
@@ -70,26 +69,44 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
 		LogDebug("Connection %d: got SERVER command (new server link) ...",
 		LogDebug("Connection %d: got SERVER command (new server link) ...",
 			Client_Conn(Client));
 			Client_Conn(Client));
 
 
-		if(( Req->argc != 2 ) && ( Req->argc != 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
-
-		/* Ist this server configured on out side? */
-		for( i = 0; i < MAX_SERVERS; i++ ) if( strcasecmp( Req->argv[0], Conf_Server[i].name ) == 0 ) break;
-		if( i >= MAX_SERVERS )
-		{
-			Log( LOG_ERR, "Connection %d: Server \"%s\" not configured here!", Client_Conn( Client ), Req->argv[0] );
-			Conn_Close( Client_Conn( Client ), NULL, "Server not configured here", true);
+		if (Req->argc != 2 && Req->argc != 3)
+			return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+						  Client_ID(Client),
+						  Req->command);
+
+		/* Get configuration index of new remote server ... */
+		for (i = 0; i < MAX_SERVERS; i++)
+			if (strcasecmp(Req->argv[0], Conf_Server[i].name) == 0)
+				break;
+
+		/* Makre sure the remote server is configured here */
+		if (i >= MAX_SERVERS) {
+			Log(LOG_ERR,
+			    "Connection %d: Server \"%s\" not configured here!",
+			    Client_Conn(Client), Req->argv[0]);
+			Conn_Close(Client_Conn(Client), NULL,
+				   "Server not configured here", true);
 			return DISCONNECTED;
 			return DISCONNECTED;
 		}
 		}
-		if( strcmp( Client_Password( Client ), Conf_Server[i].pwd_in ) != 0 )
-		{
-			/* wrong password */
-			Log( LOG_ERR, "Connection %d: Got bad password from server \"%s\"!", Client_Conn( Client ), Req->argv[0] );
-			Conn_Close( Client_Conn( Client ), NULL, "Bad password", true);
+
+		/* Check server password */
+		if (strcmp(Conn_Password(Client_Conn(Client)),
+		    Conf_Server[i].pwd_in) != 0) {
+			Log(LOG_ERR,
+			    "Connection %d: Got bad password from server \"%s\"!",
+			    Client_Conn(Client), Req->argv[0]);
+			Conn_Close(Client_Conn(Client), NULL,
+				   "Bad password", true);
 			return DISCONNECTED;
 			return DISCONNECTED;
 		}
 		}
-		
+
 		/* Is there a registered server with this ID? */
 		/* Is there a registered server with this ID? */
-		if( ! Client_CheckID( Client, Req->argv[0] )) return DISCONNECTED;
+		if (!Client_CheckID(Client, Req->argv[0]))
+			return DISCONNECTED;
+
+		/* Mark this connection as belonging to an configured server */
+		if (!Conf_SetServer(i, Client_Conn(Client)))
+			return DISCONNECTED;
 
 
 		Client_SetID( Client, Req->argv[0] );
 		Client_SetID( Client, Req->argv[0] );
 		Client_SetHops( Client, 1 );
 		Client_SetHops( Client, 1 );
@@ -97,7 +114,6 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
 
 
 		/* Is this server registering on our side, or are we connecting to
 		/* Is this server registering on our side, or are we connecting to
 		 * a remote server? */
 		 * a remote server? */
-		con = Client_Conn(Client);
 		if (Client_Token(Client) != TOKEN_OUTBOUND) {
 		if (Client_Token(Client) != TOKEN_OUTBOUND) {
 			/* Incoming connection, send user/pass */
 			/* Incoming connection, send user/pass */
 			if (!IRC_WriteStrClient(Client, "PASS %s %s",
 			if (!IRC_WriteStrClient(Client, "PASS %s %s",
@@ -106,7 +122,8 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
 			    || !IRC_WriteStrClient(Client, "SERVER %s 1 :%s",
 			    || !IRC_WriteStrClient(Client, "SERVER %s 1 :%s",
 						   Conf_ServerName,
 						   Conf_ServerName,
 						   Conf_ServerInfo)) {
 						   Conf_ServerInfo)) {
-				    Conn_Close(con, "Unexpected server behavior!",
+				    Conn_Close(Client_Conn(Client),
+					       "Unexpected server behavior!",
 					       NULL, false);
 					       NULL, false);
 				    return DISCONNECTED;
 				    return DISCONNECTED;
 			}
 			}
@@ -118,25 +135,25 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
 			Client_SetToken(Client, atoi(Req->argv[1]));
 			Client_SetToken(Client, atoi(Req->argv[1]));
 		}
 		}
 
 
-		/* Mark this connection as belonging to an configured server */
-		Conf_SetServer(i, con);
-
 		/* Check protocol level */
 		/* Check protocol level */
 		if (Client_Type(Client) == CLIENT_GOTPASS) {
 		if (Client_Type(Client) == CLIENT_GOTPASS) {
 			/* We got a "simple" PASS command, so the peer is
 			/* We got a "simple" PASS command, so the peer is
 			 * using the protocol as defined in RFC 1459. */
 			 * using the protocol as defined in RFC 1459. */
-			if (! (Conn_Options(con) & CONN_RFC1459))
+			if (! (Conn_Options(Client_Conn(Client)) & CONN_RFC1459))
 				Log(LOG_INFO,
 				Log(LOG_INFO,
 				    "Switching connection %d (\"%s\") to RFC 1459 compatibility mode.",
 				    "Switching connection %d (\"%s\") to RFC 1459 compatibility mode.",
-				    con, Client_ID(Client));
-			Conn_SetOption(con, CONN_RFC1459);
+				    Client_Conn(Client), Client_ID(Client));
+			Conn_SetOption(Client_Conn(Client), CONN_RFC1459);
 		}
 		}
 
 
 		Client_SetType(Client, CLIENT_UNKNOWNSERVER);
 		Client_SetType(Client, CLIENT_UNKNOWNSERVER);
 
 
 #ifdef ZLIB
 #ifdef ZLIB
-		if (strchr(Client_Flags(Client), 'Z') && !Zip_InitConn(con)) {
-			Conn_Close( con, "Can't inizialize compression (zlib)!", NULL, false );
+		if (strchr(Client_Flags(Client), 'Z')
+		    && !Zip_InitConn(Client_Conn(Client))) {
+			Conn_Close(Client_Conn(Client),
+				   "Can't inizialize compression (zlib)!",
+				   NULL, false );
 			return DISCONNECTED;
 			return DISCONNECTED;
 		}
 		}
 #endif
 #endif
@@ -202,10 +219,10 @@ GLOBAL bool
 IRC_NJOIN( CLIENT *Client, REQUEST *Req )
 IRC_NJOIN( CLIENT *Client, REQUEST *Req )
 {
 {
 	char nick_in[COMMAND_LEN], nick_out[COMMAND_LEN], *channame, *ptr, modes[8];
 	char nick_in[COMMAND_LEN], nick_out[COMMAND_LEN], *channame, *ptr, modes[8];
-	bool is_op, is_voiced;
+	bool is_owner, is_chanadmin, is_op, is_halfop, is_voiced;
 	CHANNEL *chan;
 	CHANNEL *chan;
 	CLIENT *c;
 	CLIENT *c;
-	
+
 	assert( Client != NULL );
 	assert( Client != NULL );
 	assert( Req != NULL );
 	assert( Req != NULL );
 
 
@@ -218,12 +235,16 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
 	ptr = strtok( nick_in, "," );
 	ptr = strtok( nick_in, "," );
 	while( ptr )
 	while( ptr )
 	{
 	{
-		is_op = is_voiced = false;
-		
+		is_owner = is_chanadmin = is_op = is_halfop = is_voiced = false;
+
 		/* cut off prefixes */
 		/* cut off prefixes */
-		while(( *ptr == '@' ) || ( *ptr == '+' ))
+		while(( *ptr == '~') || ( *ptr == '&' ) || ( *ptr == '@' ) ||
+			( *ptr == '%') || ( *ptr == '+' ))
 		{
 		{
+			if( *ptr == '~' ) is_owner = true;
+			if( *ptr == '&' ) is_chanadmin = true;
 			if( *ptr == '@' ) is_op = true;
 			if( *ptr == '@' ) is_op = true;
+			if( *ptr == 'h' ) is_halfop = true;
 			if( *ptr == '+' ) is_voiced = true;
 			if( *ptr == '+' ) is_voiced = true;
 			ptr++;
 			ptr++;
 		}
 		}
@@ -234,8 +255,11 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
 			Channel_Join( c, channame );
 			Channel_Join( c, channame );
 			chan = Channel_Search( channame );
 			chan = Channel_Search( channame );
 			assert( chan != NULL );
 			assert( chan != NULL );
-			
+
+			if( is_owner ) Channel_UserModeAdd( chan, c, 'q' );
+			if( is_chanadmin ) Channel_UserModeAdd( chan, c, 'a' );
 			if( is_op ) Channel_UserModeAdd( chan, c, 'o' );
 			if( is_op ) Channel_UserModeAdd( chan, c, 'o' );
+			if( is_halfop ) Channel_UserModeAdd( chan, c, 'h' );
 			if( is_voiced ) Channel_UserModeAdd( chan, c, 'v' );
 			if( is_voiced ) Channel_UserModeAdd( chan, c, 'v' );
 
 
 			/* announce to channel... */
 			/* announce to channel... */
@@ -250,12 +274,15 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
 			}
 			}
 
 
 			if( nick_out[0] != '\0' ) strlcat( nick_out, ",", sizeof( nick_out ));
 			if( nick_out[0] != '\0' ) strlcat( nick_out, ",", sizeof( nick_out ));
+			if( is_owner ) strlcat( nick_out, "~", sizeof( nick_out ));
+			if( is_chanadmin ) strlcat( nick_out, "&", sizeof( nick_out ));
 			if( is_op ) strlcat( nick_out, "@", sizeof( nick_out ));
 			if( is_op ) strlcat( nick_out, "@", sizeof( nick_out ));
+			if( is_halfop ) strlcat( nick_out, "%", sizeof( nick_out ));
 			if( is_voiced ) strlcat( nick_out, "+", sizeof( nick_out ));
 			if( is_voiced ) strlcat( nick_out, "+", sizeof( nick_out ));
 			strlcat( nick_out, ptr, sizeof( nick_out ));
 			strlcat( nick_out, ptr, sizeof( nick_out ));
 		}
 		}
 		else Log( LOG_ERR, "Got NJOIN for unknown nick \"%s\" for channel \"%s\"!", ptr, channame );
 		else Log( LOG_ERR, "Got NJOIN for unknown nick \"%s\" for channel \"%s\"!", ptr, channame );
-		
+
 		/* search for next Nick */
 		/* search for next Nick */
 		ptr = strtok( NULL, "," );
 		ptr = strtok( NULL, "," );
 	}
 	}

+ 32 - 6
src/ngircd/irc.c

@@ -25,6 +25,7 @@
 #include "conn-func.h"
 #include "conn-func.h"
 #include "conf.h"
 #include "conf.h"
 #include "channel.h"
 #include "channel.h"
+#include "conn-encoding.h"
 #include "defines.h"
 #include "defines.h"
 #include "irc-write.h"
 #include "irc-write.h"
 #include "log.h"
 #include "log.h"
@@ -327,12 +328,18 @@ IRC_HELP( CLIENT *Client, REQUEST *Req )
 
 
 
 
 static char *
 static char *
-Option_String( CONN_ID Idx )
+#ifdef ZLIB
+Option_String(CONN_ID Idx)
+#else
+Option_String(UNUSED CONN_ID Idx)
+#endif
 {
 {
 	static char option_txt[8];
 	static char option_txt[8];
+#ifdef ZLIB
 	UINT16 options;
 	UINT16 options;
 
 
 	options = Conn_Options(Idx);
 	options = Conn_Options(Idx);
+#endif
 
 
 	strcpy(option_txt, "F");	/* No idea what this means, but the
 	strcpy(option_txt, "F");	/* No idea what this means, but the
 					 * original ircd sends it ... */
 					 * original ircd sends it ... */
@@ -353,6 +360,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 	CHANNEL *chan;
 	CHANNEL *chan;
 	char *currentTarget = Req->argv[0];
 	char *currentTarget = Req->argv[0];
 	char *lastCurrentTarget = NULL;
 	char *lastCurrentTarget = NULL;
+	char *message = NULL;
 
 
 	assert(Client != NULL);
 	assert(Client != NULL);
 	assert(Req != NULL);
 	assert(Req != NULL);
@@ -384,6 +392,13 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
 		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
 					  Client_ID(Client), Req->prefix);
 					  Client_ID(Client), Req->prefix);
 
 
+#ifdef ICONV
+	if (Client_Conn(Client) > NONE)
+		message = Conn_EncodingFrom(Client_Conn(Client), Req->argv[1]);
+	else
+#endif
+		message = Req->argv[1];
+
 	/* handle msgtarget = msgto *("," msgto) */
 	/* handle msgtarget = msgto *("," msgto) */
 	currentTarget = strtok_r(currentTarget, ",", &lastCurrentTarget);
 	currentTarget = strtok_r(currentTarget, ",", &lastCurrentTarget);
 	ngt_UpperStr(Req->command);
 	ngt_UpperStr(Req->command);
@@ -442,7 +457,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 				if (nick != NULL && host != NULL) {
 				if (nick != NULL && host != NULL) {
 					if (strcasecmp(nick, Client_ID(cl)) == 0 &&
 					if (strcasecmp(nick, Client_ID(cl)) == 0 &&
 					    strcasecmp(user, Client_User(cl)) == 0 &&
 					    strcasecmp(user, Client_User(cl)) == 0 &&
-					    strcasecmp(host, Client_HostnameCloaked(cl)) == 0)
+					    strcasecmp(host, Client_HostnameDisplayed(cl)) == 0)
 						break;
 						break;
 					else
 					else
 						continue;
 						continue;
@@ -450,7 +465,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 				if (strcasecmp(user, Client_User(cl)) != 0)
 				if (strcasecmp(user, Client_User(cl)) != 0)
 					continue;
 					continue;
 				if (host != NULL && strcasecmp(host,
 				if (host != NULL && strcasecmp(host,
-						Client_HostnameCloaked(cl)) != 0)
+						Client_HostnameDisplayed(cl)) != 0)
 					continue;
 					continue;
 				if (server != NULL && strcasecmp(server,
 				if (server != NULL && strcasecmp(server,
 						Client_ID(Client_Introducer(cl))) != 0)
 						Client_ID(Client_Introducer(cl))) != 0)
@@ -485,6 +500,17 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 				Req->command = "PRIVMSG";
 				Req->command = "PRIVMSG";
 			}
 			}
 #endif
 #endif
+			if (Client_HasMode(cl, 'b') &&
+			    !Client_HasMode(from, 'R') &&
+			    !Client_HasMode(from, 'o') &&
+			    !(Client_Type(from) == CLIENT_SERVER) &&
+			    !(Client_Type(from) == CLIENT_SERVICE)) {
+				if (SendErrors && !IRC_WriteStrClient(from,
+						ERR_NONONREG_MSG,
+						Client_ID(from), Client_ID(cl)))
+					return DISCONNECTED;
+				goto send_next_target;
+			}
 
 
 			if (Client_HasMode(cl, 'C')) {
 			if (Client_HasMode(cl, 'C')) {
 				cl2chan = Channel_FirstChannelOf(cl);
 				cl2chan = Channel_FirstChannelOf(cl);
@@ -517,12 +543,12 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 			}
 			}
 			if (!IRC_WriteStrClientPrefix(cl, from, "%s %s :%s",
 			if (!IRC_WriteStrClientPrefix(cl, from, "%s %s :%s",
 						      Req->command, Client_ID(cl),
 						      Req->command, Client_ID(cl),
-						      Req->argv[1]))
+						      message))
 				return DISCONNECTED;
 				return DISCONNECTED;
 		} else if (ForceType != CLIENT_SERVICE
 		} else if (ForceType != CLIENT_SERVICE
 			   && (chan = Channel_Search(currentTarget))) {
 			   && (chan = Channel_Search(currentTarget))) {
 			if (!Channel_Write(chan, from, Client, Req->command,
 			if (!Channel_Write(chan, from, Client, Req->command,
-					   SendErrors, Req->argv[1]))
+					   SendErrors, message))
 					return DISCONNECTED;
 					return DISCONNECTED;
 		} else if (ForceType != CLIENT_SERVICE
 		} else if (ForceType != CLIENT_SERVICE
 			/* $#: server/target mask, RFC 2812, sec. 3.3.1 */
 			/* $#: server/target mask, RFC 2812, sec. 3.3.1 */
@@ -530,7 +556,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 			   && strchr(currentTarget, '.')) {
 			   && strchr(currentTarget, '.')) {
 			/* targetmask */
 			/* targetmask */
 			if (!Send_Message_Mask(from, Req->command, currentTarget,
 			if (!Send_Message_Mask(from, Req->command, currentTarget,
-					       Req->argv[1], SendErrors))
+					       message, SendErrors))
 				return DISCONNECTED;
 				return DISCONNECTED;
 		} else {
 		} else {
 			if (!SendErrors)
 			if (!SendErrors)

+ 0 - 0
src/ngircd/lists.c


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