Browse Source

Import upstream version 17.1

Alexander Barton 13 years ago
parent
commit
c01f25a3cd
100 changed files with 3711 additions and 1503 deletions
  1. BIN
      ._INSTALL
  2. BIN
      ._README
  3. 138 1
      ChangeLog
  4. 24 2
      INSTALL
  5. 2 2
      Makefile.am
  6. 28 22
      Makefile.in
  7. 65 1
      NEWS
  8. 7 7
      README
  9. 22 16
      aclocal.m4
  10. 1021 240
      configure
  11. 63 10
      configure.in
  12. BIN
      contrib/._ngindent
  13. BIN
      contrib/._ngircd-bsd.sh
  14. BIN
      contrib/._ngircd-redhat.init
  15. 2 2
      contrib/Debian/Makefile.am
  16. 4 4
      contrib/Debian/Makefile.in
  17. 55 0
      contrib/Debian/changelog
  18. 2 2
      contrib/Debian/control
  19. 2 2
      contrib/Debian/ngircd.init
  20. 4 0
      contrib/Debian/ngircd.pam
  21. 6 2
      contrib/Debian/rules
  22. BIN
      contrib/MacOSX/._Makefile.am
  23. 8 9
      contrib/MacOSX/Makefile.in
  24. 17 1
      contrib/MacOSX/config.h
  25. 2 2
      contrib/MacOSX/ngIRCd.pmdoc/Makefile.in
  26. 2 2
      contrib/MacOSX/ngIRCd.pmdoc/index.xml
  27. 2 2
      contrib/MacOSX/ngIRCd.xcodeproj/Makefile.in
  28. 34 7
      contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj
  29. 14 0
      contrib/MacOSX/postinstall.sh
  30. 8 9
      contrib/Makefile.in
  31. 1 1
      contrib/ngircd-redhat.init
  32. 1 1
      contrib/ngircd.spec
  33. 30 17
      contrib/platformtest.sh
  34. 19 14
      depcomp
  35. 53 0
      doc/Bopm.txt
  36. 17 10
      doc/FAQ.txt
  37. 77 0
      doc/HowToRelease.txt
  38. 28 11
      doc/Makefile.am
  39. 35 21
      doc/Makefile.in
  40. 36 0
      doc/PAM.txt
  41. 18 16
      doc/Platforms.txt
  42. 37 0
      doc/README-Interix.txt
  43. 2 4
      doc/SSL.txt
  44. 28 9
      doc/sample-ngircd.conf
  45. 2 2
      doc/src/Makefile.in
  46. 120 108
      install-sh
  47. 2 2
      man/Makefile.in
  48. 15 8
      man/ngircd.8.tmpl
  49. 35 10
      man/ngircd.conf.5.tmpl
  50. BIN
      src/._Makefile.am
  51. 8 9
      src/Makefile.in
  52. 23 2
      src/config.h.in
  53. 9 10
      src/ipaddr/Makefile.in
  54. 6 2
      src/ipaddr/ng_ipaddr.h
  55. BIN
      src/ngircd/._client.h
  56. BIN
      src/ngircd/._conn-func.c
  57. BIN
      src/ngircd/._irc-channel.c
  58. BIN
      src/ngircd/._irc-op.c
  59. BIN
      src/ngircd/._irc-op.h
  60. BIN
      src/ngircd/._irc.c
  61. BIN
      src/ngircd/._irc.h
  62. BIN
      src/ngircd/._log.h
  63. BIN
      src/ngircd/._parse.h
  64. 4 6
      src/ngircd/Makefile.am
  65. 28 19
      src/ngircd/Makefile.in
  66. 11 2
      src/ngircd/channel.c
  67. 2 0
      src/ngircd/channel.h
  68. 162 29
      src/ngircd/client.c
  69. 16 1
      src/ngircd/client.h
  70. 2 1
      src/ngircd/conf-ssl.h
  71. 202 61
      src/ngircd/conf.c
  72. 29 14
      src/ngircd/conf.h
  73. 10 0
      src/ngircd/conn-func.c
  74. 1 0
      src/ngircd/conn-func.h
  75. 3 2
      src/ngircd/conn-ssl.c
  76. 386 180
      src/ngircd/conn.c
  77. 21 6
      src/ngircd/conn.h
  78. 3 8
      src/ngircd/defines.h
  79. 50 15
      src/ngircd/io.c
  80. 3 0
      src/ngircd/io.h
  81. 57 29
      src/ngircd/irc-channel.c
  82. 150 120
      src/ngircd/irc-info.c
  83. 151 11
      src/ngircd/irc-login.c
  84. 2 1
      src/ngircd/irc-login.h
  85. 55 17
      src/ngircd/irc-mode.c
  86. 0 1
      src/ngircd/irc-op.c
  87. 14 14
      src/ngircd/irc-oper.c
  88. 0 2
      src/ngircd/irc-server.c
  89. 68 60
      src/ngircd/irc-write.c
  90. 9 8
      src/ngircd/irc-write.h
  91. 17 11
      src/ngircd/irc.c
  92. 0 1
      src/ngircd/lists.c
  93. 56 91
      src/ngircd/log.c
  94. 6 7
      src/ngircd/log.h
  95. 6 2
      src/ngircd/messages.h
  96. 51 175
      src/ngircd/ngircd.c
  97. 2 4
      src/ngircd/ngircd.h
  98. 0 2
      src/ngircd/numeric.c
  99. 0 1
      src/ngircd/op.c
  100. 0 0
      src/ngircd/pam.c

BIN
._INSTALL


BIN
._README


+ 138 - 1
ChangeLog

@@ -1,7 +1,7 @@
 
                      ngIRCd - Next Generation IRC Server
 
-                        (c)2001-2009 Alexander Barton,
+                        (c)2001-2010 Alexander Barton,
                     alex@barton.de, http://www.barton.de/
 
                ngIRCd is free software and published under the
@@ -10,6 +10,143 @@
                                -- ChangeLog --
 
 
+ngIRCd Release 17.1 (2010-12-19)
+
+  - --configtest: remember if MOTD is configured by file or phrase
+  - Enhance log messages when establishing server links a little bit
+  - Reset ID of outgoing server link on DNS error correctly
+  - Don't log critical (or worse) messages to stderr
+  - Manual page ngircd(8): add SIGNALS section
+  - Manual pages: update and simplyfy AUTHORS section
+  - Remove "error file" when compiled with debug code enabled
+  - README: Updated list of implemented commands
+  - add doc/README-Interix.txt and doc/Bopm.txt to distribution tarball
+  - Merge branch 'numeric-329'
+  - add doc/PAM.txt to distribution tarball
+  - New numeric 329: get channel creation time on "MODE #chan" commands
+  - Save channel creation time; new function Channel_CreationTime()
+
+ngIRCd Release 17 (2010-11-07)
+
+  - doc: change path names in sample-ngircd.conf depending on sysconfdir
+  - Fix up generation and distribution of sample-ngircd.conf
+  - contrib/ngircd-redhat.init: updated email address of Naoya Nakazawa
+  - contrib/platformtest.sh: make command name quoting consistent
+
+  ngIRCd 17~rc3 (2010-10-27)
+  - Xcode builds: detect version number correctly, updateed project file
+    to use the Mac OS X 10.5.x SDK, disable pam_fail_delay() because it
+    is only available starting with Mac OS X 10.6, and generate a default
+    PAM configuration for the Mac OS X Installer.app package of ngIRCd.
+  - Debian: updated standards version to 3.9.1, added libpam0g-dev to the
+    dependencies, and install a default /etc/pam.d/ngircd allowing all logins.
+  - Make contrib/platformtest.sh more portable.
+  - Fix connect attempts to further IP addresses of outgoing server links.
+
+  ngIRCd 17~rc2 (2010-10-25)
+  - ZeroConf: include header files missing since commit a988bbc86a.
+  - Generate ngIRCd version number from GIT tag.
+  - Make sourcecode compatible with ansi2knr again. This allows to compile
+    ngIRCd using a pre-ANSI K&R C compiler again.
+  - ./configure: check if C compiler can compile ISO Standard C.
+  - ./configure: check support for C prototypes again.
+  - Don't use PARAMS() macro for function implementations.
+  - Added m68k/apple/aux3.0.1 (gcc 2.7.2) to doc/Platforms.txt.
+  - Only try to set FD_CLOEXEC if this flag is defined.
+  - Only use "__attribute__ ((unused))" if GCC >=2.8 is used.
+  - doc/Makefile.am: don't set docdir, automake handles it already.
+
+  ngIRCd 17~rc1 (2010-10-11)
+  - New configuration option "NoZeroConf" to disable service registration at
+    runtime even if ngIRCd is compiled with support for ZeroConf (e.g. using
+    Howl, Avahi or on Mac OS X).
+  - New configuration option "SyslogFacility" to define the syslog "facility"
+    (the "target"), to which ngIRCd should send its log messages.
+    Possible values are system dependant, but most probably "auth", "daemon",
+    "user" and "local1" through "local7" are possible values; see syslog(3).
+    Default is "local5" for historical reasons.
+  - Dump the "internal server state" (configured servers, established
+    connections and known clients) to the console or syslog when receiving
+    the SIGUSR2 signal and debug mode is enabled.
+  - Enable the daemon to disable and enable "debug mode" on runtime using
+    signal SIGUSR1, when debug code is compiled in, not only on startup
+    using the command line parameters.
+  - Signal handler: added new 'delayed' signal handlers, including fallback
+    to deprecated sysv API. And removed global NGIRCd_SignalRehash variable.
+  - IO: add io_cloexec() to set close-on-exec flag.
+  - ng_ipaddr.h: include required assert.h header.
+  - Conn_SyncServerStruct(): test all connections; and work case insensitive
+  - configure script: correctly indent IPv6 yes/no summary output.
+  - Don't reset My_Connections[Idx].lastping when reading data, so the
+    client lag debug-output is working again.
+  - Implement user mode "x": hostname cloaking (closes: #102).
+  - Make configure switch "--docdir" work (closes: #108).
+  - Reformat and update FAQ.txt a little bit.
+  - INSTALL: mention SSL, IPv6, and changed handling of MotdFile.
+  - Change MOTD file handling: ngIRCd now caches the contens of the MOTD
+    file, so the daemon now requires a HUP signal or REHASH command to
+    re-read the MOTD file when its content changed.
+  - Startup: open /dev/null before chroot'ing the daemon.
+  - Allow IRC ops to change channel modes even without OperServerMode set.
+  - Allow IRC operators to use MODE command on any channel (closes: #100).
+  - Added mailmap file for git-[short]log and git-blame.
+  - Authenticated users should be registered without the "~" mark.
+  - Set NoPAM=yes in configuration files used for the testsuite.
+  - New configuration option "NoPAM" to disable PAM.
+  - Implement asynchronous user authentication using PAM, please see the
+    file doc/PAM.txt for details.
+  - Resolver: Implement signal handler and catch TERM signals.
+  - Don't set a penalty time when doing DNS lookups.
+  - Add some documentation for using BOPM with ngIRCd, see doc/Bopm.txt.
+  - Implement user mode "c": receive connect/disconnect NOTICEs. Note that
+    this new mode requires the user to be an IRC operator.
+  - ngircd.init: require "$network" and "$remote_fs" when stopping ngircd.
+  - Show SSL status in WHOIS output, numeric 275.
+  - Include correct header files when testing for arpa/inet.h (Closes: #105).
+  - Don't access already freed memory in IRC_KILL().
+  - Fix "beeing" typo ...
+  - SSL/TLS: fix bogus "socket closed" error message.
+
+ngIRCd Release 16 (2010-05-02)
+
+  - doc/SSL: remove line continuation marker
+
+  ngIRCd 16~rc2 (2010-04-25)
+  - Updated some more copyright notices, it's 2010 already :-)
+  - Only compile in Get_Error() if really needed
+  - Fix gcc warning "ignoring return value of ..."
+  - Include netinet/in_systm.h alongside netinet/ip.h
+  - Include netinet/{in.h, in_systm.h} when checking for netinet/ip.h
+  - Only include <netinet/in_systm.h> if it exists
+  - Updated doc/Platforms.txt
+  - Enhace connection statistics counters: display total number of served
+    connections on daemon shutdown and when a new client connects using
+    the new numeric RPL_STATSCONN (250).
+
+  ngIRCd 16~rc1 (2010-03-25)
+  - Various fixes to the build system and code cleanups.
+  - contrib/platformtest.sh: Only show latest commit.
+  - Updatet doc/Platforms.txt, added new README-Interix.txt documenting
+    how to tun ngIRCd on Microsoft Services for UNIX (MS SFU, MS SUA).
+  - Updated links to the ngIRCd homepage (bug tracker, mailing list).
+  - Added missing modes to USERMODES #define
+  - Show our name (IRCD=ngIRCd) in ISUPPORT (005) numeric
+  - Quote received messages of ERROR commands in log output.
+  - ngircd.conf manual page: document missing "Password" variable.
+  - Implement WEBIRC command used by some Web-IRC frontends. The password
+    required to secure this command must be configured using the new
+    "WebircPassword" variable in the ngircd.conf file.
+  - Don't use port 6668 as example for both "Ports" and "SSLPorts".
+  - Remove limit on max number of configured irc operators.
+  - Only link "nsl" library when really needed.
+  - A new channel mode "secure connections only" (+z) has been implemented:
+    Only clients using a SSL encrypted connection to the server are allowed
+    to join such a channel.
+    But please note three things: a) already joined clients are not checked
+    when setting this mode, b) IRC operators are always allowed to join
+    every channel, and c) remote clients using a server not supporting this
+    mode are not checked either and therefore always allowed to join.
+
 ngIRCd Release 15 (2009-11-07)
 
   - "ngircd --configtest": print SSL configuration options even when unset.

+ 24 - 2
INSTALL

@@ -1,7 +1,7 @@
 
                      ngIRCd - Next Generation IRC Server
 
-                        (c)2001-2007 Alexander Barton,
+                        (c)2001-2010 Alexander Barton,
                     alex@barton.de, http://www.barton.de/
 
                ngIRCd is free software and published under the
@@ -9,11 +9,15 @@
 
                                 -- INSTALL --
 
-                         
 
 I. Upgrade Information
 ~~~~~~~~~~~~~~~~~~~~~~
 
+Differences to version 16
+
+- Changes to the "MotdFile" specified in ngircd.conf now require a ngircd
+  configuration reload to take effect (HUP signal, REHASH command).
+
 Differences to version 0.9.x
 
 - The option of the configure script to enable support for Zeroconf/Bonjour/
@@ -184,6 +188,24 @@ standard locations.
   to the daemon, for example by using "/etc/hosts.{allow|deny}".
   The "libwrap" is required for this option.
 
+* PAM:
+  --with-pam[=<path>]
+
+  Enable support for PAM, the Pluggable Authentication Modules library.
+  See doc/PAM.txt for details.
+
+* SSL:
+  --with-openssl[=<path>]
+  --with-gnutls[=<path>]
+
+  Enable support for SSL/TLS using OpenSSL or gnutls libraries.
+  See doc/SSL.txt for details.
+
+* IPv6:
+  --enable-ipv6
+
+  Adds support for version 6 of the Internet Protocol.
+
 
 IV. Useful make-targets
 ~~~~~~~~~~~~~~~~~~~~~~~

+ 2 - 2
Makefile.am

@@ -1,6 +1,6 @@
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
+# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -38,7 +38,7 @@ have-xcodebuild:
 	 || ( echo; echo "Error: \"xcodebuild\" not found!"; echo; exit 1 )
 
 xcode: have-xcodebuild
-	rel=`grep AC_INIT configure.in | cut -d' ' -f2 | cut -d')' -f1`; \
+	rel=`git describe|sed -e 's/rel-//g'|sed -e 's/-/~/'`; \
 	 def="GCC_PREPROCESSOR_DEFINITIONS=\"VERSION=\\\"$$rel\\\"\""; \
 	 xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -alltargets \
 	 -configuration Default $$def build

+ 28 - 22
Makefile.in

@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -16,7 +16,7 @@
 
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
+# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -295,8 +295,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	mkid -fID $$unique
 tags: TAGS
 
@@ -321,8 +321,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
 	  test -n "$$unique" || unique=$$empty_fix; \
 	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -332,13 +332,12 @@ ctags: CTAGS
 CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
 	tags=; \
-	here=`pwd`; \
 	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	test -z "$(CTAGS_ARGS)$$tags$$unique" \
 	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
 	     $$tags $$unique
@@ -409,6 +408,10 @@ dist-bzip2: distdir
 	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
 	$(am__remove_distdir)
 
+dist-lzma: distdir
+	tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+	$(am__remove_distdir)
+
 dist-tarZ: distdir
 	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
 	$(am__remove_distdir)
@@ -435,6 +438,8 @@ distcheck: dist
 	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
 	*.tar.bz2*) \
 	  bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lzma*) \
+	  unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
 	*.tar.Z*) \
 	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
 	*.shar.gz*) \
@@ -586,17 +591,18 @@ uninstall-am:
 .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
 	all all-am am--refresh check check-am clean clean-generic \
 	clean-local ctags ctags-recursive dist dist-all dist-bzip2 \
-	dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \
-	distclean-generic distclean-tags distcleancheck distdir \
-	distuninstallcheck 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 \
-	installdirs-am maintainer-clean maintainer-clean-generic \
-	maintainer-clean-local mostlyclean mostlyclean-generic pdf \
-	pdf-am ps ps-am tags tags-recursive uninstall uninstall-am
+	dist-gzip dist-lzma dist-shar dist-tarZ dist-zip distcheck \
+	distclean distclean-generic distclean-tags distcleancheck \
+	distdir distuninstallcheck 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 installdirs-am maintainer-clean \
+	maintainer-clean-generic maintainer-clean-local mostlyclean \
+	mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \
+	uninstall uninstall-am
 
 
 clean-local:
@@ -624,7 +630,7 @@ have-xcodebuild:
 	 || ( echo; echo "Error: \"xcodebuild\" not found!"; echo; exit 1 )
 
 xcode: have-xcodebuild
-	rel=`grep AC_INIT configure.in | cut -d' ' -f2 | cut -d')' -f1`; \
+	rel=`git describe|sed -e 's/rel-//g'|sed -e 's/-/~/'`; \
 	 def="GCC_PREPROCESSOR_DEFINITIONS=\"VERSION=\\\"$$rel\\\"\""; \
 	 xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -alltargets \
 	 -configuration Default $$def build

+ 65 - 1
NEWS

@@ -1,7 +1,7 @@
 
                      ngIRCd - Next Generation IRC Server
 
-                        (c)2001-2009 Alexander Barton,
+                        (c)2001-2010 Alexander Barton,
                     alex@barton.de, http://www.barton.de/
 
                ngIRCd is free software and published under the
@@ -10,6 +10,70 @@
                                   -- NEWS --
 
 
+ngIRCd Release 17.1 (2010-12-19)
+
+  - Don't log critical (or worse) messages to stderr
+  - Remove "error file" when compiled with debug code enabled
+  - New numeric 329: get channel creation time on "MODE #chan" commands
+
+ngIRCd Release 17 (2010-11-07)
+
+  - doc: change path names in sample-ngircd.conf depending on sysconfdir
+
+  ngIRCd 17~rc2 (2010-10-25)
+  - Generate ngIRCd version number from GIT tag.
+  - Make sourcecode compatible with ansi2knr again. This allows to compile
+    ngIRCd using a pre-ANSI K&R C compiler again.
+
+  ngIRCd 17~rc1 (2010-10-11)
+  - New configuration option "NoZeroConf" to disable service registration at
+    runtime even if ngIRCd is compiled with support for ZeroConf (e.g. using
+    Howl, Avahi or on Mac OS X).
+  - New configuration option "SyslogFacility" to define the syslog "facility"
+    (the "target"), to which ngIRCd should send its log messages.
+    Possible values are system dependant, but most probably "auth", "daemon",
+    "user" and "local1" through "local7" are possible values; see syslog(3).
+    Default is "local5" for historical reasons.
+  - Dump the "internal server state" (configured servers, established
+    connections and known clients) to the console or syslog when receiving
+    the SIGUSR2 signal and debug mode is enabled.
+  - Enable the daemon to disable and enable "debug mode" on runtime using
+    signal SIGUSR1, when debug code is compiled in, not only on startup
+    using the command line parameters.
+  - Implement user mode "x": hostname cloaking (closes: #102).
+  - Change MOTD file handling: ngIRCd now caches the contens of the MOTD
+    file, so the daemon now requires a HUP signal or REHASH command to
+    re-read the MOTD file when its content changed.
+  - Allow IRC ops to change channel modes even without OperServerMode set.
+  - Allow IRC operators to use MODE command on any channel (closes: #100).
+  - New configuration option "NoPAM" to disable PAM.
+  - Implement asynchronous user authentication using PAM, please see the
+    file doc/PAM.txt for details.
+  - Add some documentation for using BOPM with ngIRCd, see doc/Bopm.txt.
+  - Implement user mode "c": receive connect/disconnect NOTICEs. Note that
+    this new mode requires the user to be an IRC operator.
+  - Show SSL status in WHOIS output, numeric 275.
+
+ngIRCd Release 16 (2010-05-02)
+
+  ngIRCd 16~rc2 (2010-04-25)
+  - Enhace connection statistics counters: display total number of served
+    connections on daemon shutdown and when a new client connects using
+    the new numeric RPL_STATSCONN (250).
+
+  ngIRCd 16~rc1 (2010-03-25)
+  - Implement WEBIRC command used by some Web-IRC frontends. The password
+    required to secure this command must be configured using the new
+    "WebircPassword" variable in the ngircd.conf file.
+  - Remove limit on max number of configured irc operators.
+  - A new channel mode "secure connections only" (+z) has been implemented:
+    Only clients using a SSL encrypted connection to the server are allowed
+    to join such a channel.
+    But please note three things: a) already joined clients are not checked
+    when setting this mode, b) IRC operators are always allowed to join
+    every channel, and c) remote clients using a server not supporting this
+    mode are not checked either and therefore always allowed to join.
+
 ngIRCd Release 15 (2009-11-07)
 
   ngIRCd 15~rc1 (2009-10-15)

+ 7 - 7
README

@@ -34,11 +34,11 @@ used in real IRC networks.
 
 Implemented IRC-commands are:
 
-ADMIN, AWAY, CHANINFO, CONNECT, DIE, DISCONNECT, ERROR, HELP, INVITE, ISON,
-JOIN, KICK, KILL, LINKS, LIST, LUSERS, MODE, MOTD, NAMES, NICK, NJOIN, NOTICE,
-OPER, PART, PASS, PING, PONG, PRIVMSG, QUIT, REHASH, RESTART, SERVER, SQUIT,
-STATS, TIME, TOPIC, TRACE, USER, USERHOST, VERSION, WALLOPS, WHO, WHOIS,
-WHOWAS.
+ADMIN, AWAY, CHANINFO, CONNECT, DIE, DISCONNECT, ERROR, HELP, INFO, INVITE,
+ISON, JOIN, KICK, KILL, LINKS, LIST, LUSERS, MODE, MOTD, NAMES, NICK, NJOIN,
+NOTICE, OPER, PART, PASS, PING, PONG, PRIVMSG, QUIT, REHASH, RESTART, SERVER,
+SERVICE, SERVLIST, SQUERY, SQUIT,  STATS, SUMMON, TIME, TOPIC, TRACE, USER,
+USERHOST, USERS, VERSION, WALLOPS, WEBIRC, WHO, WHOIS, WHOWAS.
 
 
 III. Features (or: why use ngIRCd?)
@@ -78,10 +78,10 @@ VI. Bugs
 If you find bugs in the ngIRCd (which might be there :-), please report
 them at the following URL:
 
-<http://ngircd.barton.de/#bugs>
+<http://ngircd.barton.de/bugtracker.php>
 
 There you can read about known bugs and limitations, too.
 
 If you have critics, patches or something else, please feel free to post a
 mail to the ngIRCd mailing list: <ngircd-ml@arthur.ath.cx> (please see
-<http://ngircd.barton.de/#ml> for details).
+<http://ngircd.barton.de/support.php#ml> for details).

+ 22 - 16
aclocal.m4

@@ -1,7 +1,7 @@
-# generated automatically by aclocal 1.10 -*- Autoconf -*-
+# generated automatically by aclocal 1.10.1 -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006  Free Software Foundation, Inc.
+# 2005, 2006, 2007, 2008  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.
@@ -11,12 +11,15 @@
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
-m4_if(m4_PACKAGE_VERSION, [2.61],,
-[m4_fatal([this file was generated for autoconf 2.61.
-You have another version of autoconf.  If you want to use that,
-you should regenerate the build system entirely.], [63])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(AC_AUTOCONF_VERSION, [2.61],,
+[m4_warning([this file was generated for autoconf 2.61.
+You have another version of autoconf.  It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
 
-# Copyright (C) 2002, 2003, 2005, 2006  Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2005, 2006, 2007  Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -31,7 +34,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
 [am__api_version='1.10'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.10], [],
+m4_if([$1], [1.10.1], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -47,8 +50,10 @@ m4_define([_AM_AUTOCONF_VERSION], [])
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.10])dnl
-_AM_AUTOCONF_VERSION(m4_PACKAGE_VERSION)])
+[AM_AUTOMAKE_VERSION([1.10.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
@@ -320,7 +325,7 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
   # each Makefile.in and add a new line on top of each file to say so.
   # Grep'ing the whole file is not good either: AIX grep has a line
   # limit of 2048, but all sed's we know have understand at least 4000.
-  if sed 10q "$mf" | grep '^#.*generated by automake' > /dev/null 2>&1; then
+  if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
     dirpart=`AS_DIRNAME("$mf")`
   else
     continue
@@ -380,13 +385,13 @@ AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
 # Do all the work for Automake.                             -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006 Free Software Foundation, Inc.
+# 2005, 2006, 2008 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 12
+# serial 13
 
 # This macro actually does too much.  Some checks are only needed if
 # your package does certain things.  But this isn't really a big deal.
@@ -491,16 +496,17 @@ AC_PROVIDE_IFELSE([AC_PROG_OBJC],
 # our stamp files there.
 AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
 [# Compute $1's index in $config_headers.
+_am_arg=$1
 _am_stamp_count=1
 for _am_header in $config_headers :; do
   case $_am_header in
-    $1 | $1:* )
+    $_am_arg | $_am_arg:* )
       break ;;
     * )
       _am_stamp_count=`expr $_am_stamp_count + 1` ;;
   esac
 done
-echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
 # Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
 #
@@ -798,7 +804,7 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
 # _AM_SUBST_NOTMAKE(VARIABLE)
 # ---------------------------
-# Prevent Automake from outputing VARIABLE = @VARIABLE@ in Makefile.in.
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
 # This macro is traced by Automake.
 AC_DEFUN([_AM_SUBST_NOTMAKE])
 

File diff suppressed because it is too large
+ 1021 - 240
configure


+ 63 - 10
configure.in

@@ -1,6 +1,6 @@
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2009 Alexander Barton <alex@barton.de>
+# Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -9,10 +9,12 @@
 # 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))
+
 # -- Initialisation --
 
 AC_PREREQ(2.50)
-AC_INIT(ngircd, 15)
+AC_INIT(ngircd, VERSION_ID)
 AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
 AC_CANONICAL_TARGET
 AM_INIT_AUTOMAKE(1.6)
@@ -33,6 +35,7 @@ AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used])
 AH_TEMPLATE([WANT_IPV6], [Define if IPV6 protocol should be enabled])
 AH_TEMPLATE([ZEROCONF], [Define if support for Zeroconf should be included])
 AH_TEMPLATE([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([TARGET_OS], [Target operating system name])
@@ -42,6 +45,8 @@ AH_TEMPLATE([TARGET_CPU], [Target CPU name])
 # -- C Compiler --
 
 AC_PROG_CC
+AC_PROG_CC_STDC
+AC_C_PROTOTYPES
 
 # -- Helper programs --
 
@@ -101,11 +106,24 @@ AC_HEADER_TIME
 AC_HEADER_SYS_WAIT
 
 AC_CHECK_HEADERS([ \
-	ctype.h errno.h fcntl.h netdb.h netinet/in.h stdlib.h string.h \
-	strings.h sys/socket.h sys/time.h unistd.h \
+	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 \
 	],,AC_MSG_ERROR([required C header missing!]))
 
-AC_CHECK_HEADERS([arpa/inet.h ctype.h malloc.h stdbool.h stddef.h varargs.h])
+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
+	]]
+)
 
 # -- Datatypes --
 
@@ -130,9 +148,11 @@ AC_CHECK_MEMBER([struct sockaddr_in.sin_len], AC_DEFINE(HAVE_sockaddr_in_len),,
 
 # -- 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)
-AC_CHECK_LIB(nsl,gethostent)
 
 # -- Functions --
 
@@ -143,7 +163,7 @@ AC_CHECK_FUNCS([ \
 	bind gethostbyaddr gethostbyname gethostname inet_ntoa \
 	setsid setsockopt socket strcasecmp waitpid],,AC_MSG_ERROR([required function missing!]))
 
-AC_CHECK_FUNCS(getaddrinfo getnameinfo inet_aton isdigit sigaction snprintf \
+AC_CHECK_FUNCS(getaddrinfo getnameinfo inet_aton isdigit sigaction sigprocmask snprintf \
  vsnprintf strdup strlcpy strlcat strtok_r)
 
 # -- Configuration options --
@@ -464,6 +484,33 @@ if test "$x_identauth_on" = "yes"; then
 	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,
+	[  --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
@@ -573,7 +620,7 @@ 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 ${datadir}/doc/${PACKAGE}` ; D=`eval echo ${D}`
+D=`eval echo ${docdir}` ; D=`eval echo ${D}`
 
 echo "             Target: ${target}"
 test "$target" != "$host" && echo "               Host: ${host}"
@@ -641,11 +688,17 @@ echo $ECHO_N "        I/O backend: $ECHO_C"
 	echo "\"$x_io_backend\""
 
 echo $ECHO_N "      IPv6 protocol: $ECHO_C"
-echo $ECHO_N "$x_ipv6_on    $ECHO_C"
-
+test "$x_ipv6_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 "        PAM support: $ECHO_C"
+test "$x_pam_on" = "yes" \
+	&& echo "yes" \
+	|| echo "no"
+
 echo
 
 # -eof-

BIN
contrib/._ngindent


BIN
contrib/._ngircd-bsd.sh


BIN
contrib/._ngircd-redhat.init


+ 2 - 2
contrib/Debian/Makefile.am

@@ -1,6 +1,6 @@
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2009 Alexander Barton (alex@barton.de)
+# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -10,7 +10,7 @@
 #
 
 EXTRA_DIST = rules changelog compat control copyright \
-	ngircd.init ngircd.default ngircd.postinst
+	ngircd.init ngircd.default ngircd.pam ngircd.postinst
 
 maintainer-clean-local:
 	rm -f Makefile Makefile.in

+ 4 - 4
contrib/Debian/Makefile.in

@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -16,7 +16,7 @@
 
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2009 Alexander Barton (alex@barton.de)
+# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -155,7 +155,7 @@ target_vendor = @target_vendor@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 EXTRA_DIST = rules changelog compat control copyright \
-	ngircd.init ngircd.default ngircd.postinst
+	ngircd.init ngircd.default ngircd.pam ngircd.postinst
 
 all: all-am
 

+ 55 - 0
contrib/Debian/changelog

@@ -1,3 +1,58 @@
+ngircd (17.1-0ab1) unstable; urgency=low
+
+  * New "upstream" release: ngIRCd 17.1.
+
+ -- Alexander Barton <alex@barton.de>  Sun, 19 Dec 2010 15:56:42 +0100
+
+ngircd (17-0ab1) unstable; urgency=low
+
+  * New "upstream" release: ngIRCd 17.
+
+ -- Alexander Barton <alex@barton.de>  Sun, 07 Nov 2010 17:23:07 +0100
+
+ngircd (17~rc3-0ab1) unstable; urgency=low
+
+  * New "upstream" release candidate 3 for ngIRCd Release 17.
+
+ -- Alexander Barton <alex@barton.de>  Wed, 27 Oct 2010 22:30:08 +0200
+
+ngircd (17~rc2-0ab2) unstable; urgency=low
+
+  * Install /etc/pam.d/ngircd including "auth required pam_permit.so" when
+    installing -full or -full-dbg variant to keep backwards compatibility.
+
+ -- Alexander Barton <alex@barton.de>  Tue, 26 Oct 2010 23:34:56 +0200
+
+ngircd (17~rc2-0ab1) unstable; urgency=low
+
+  * New "upstream" release candidate 2 for ngIRCd Release 17.
+
+ -- Alexander Barton <alex@barton.de>  Mon, 25 Oct 2010 18:51:15 +0200
+
+ngircd (17~rc1-0ab1) unstable; urgency=low
+
+  * New "upstream" release candidate 1 for ngIRCd Release 17.
+
+ -- Alexander Barton <alex@barton.de>  Mon, 11 Oct 2010 16:57:47 +0200
+
+ngircd (16-0ab1) unstable; urgency=low
+
+  * New "upstream" release: ngIRCd 16.
+
+ -- Alexander Barton <alex@barton.de>  Sun, 02 May 2010 13:32:41 +0200
+
+ngircd (16~rc2-0ab1) unstable; urgency=low
+
+  * New "upstream" release candidate 2 for ngIRCd Release 16.
+
+ -- Alexander Barton <alex@barton.de>  Sun, 25 Apr 2010 13:12:42 +0200
+
+ngircd (16~rc1-0ab1) unstable; urgency=low
+
+  * New "upstream" release candidate 1 for ngIRCd Release 16.
+
+ -- Alexander Barton <alex@barton.de>  Thu, 25 Mar 2010 15:56:03 +0200
+
 ngircd (15-0ab1) unstable; urgency=low
 
   * New "upstream" release: ngIRCd 15.

+ 2 - 2
contrib/Debian/control

@@ -2,8 +2,8 @@ Source: ngircd
 Section: net
 Priority: optional
 Maintainer: Alexander Barton <alex@barton.de>
-Build-Depends: debhelper (>> 4.0.0), libz-dev, libwrap0-dev, libident-dev, libgnutls-dev
-Standards-Version: 3.8.0
+Build-Depends: debhelper (>> 4.0.0), libz-dev, libwrap0-dev, libident-dev, libgnutls-dev, libpam0g-dev
+Standards-Version: 3.9.1
 
 Package: ngircd
 Architecture: any

+ 2 - 2
contrib/Debian/ngircd.init

@@ -1,13 +1,13 @@
 #!/bin/sh
 #
 # ngIRCd start and stop script for Debian-based systems
-# Copyright 2008,2009 Alexander Barton <alex@barton.de>
+# Copyright 2008-2010 Alexander Barton <alex@barton.de>
 #
 
 ### BEGIN INIT INFO
 # Provides:		ngircd
 # Required-Start:	$network $remote_fs
-# Required-Stop:
+# Required-Stop:	$network $remote_fs
 # Should-Start:		$syslog $named
 # Should-Stop:		$syslog
 # Default-Start:	2 3 4 5

+ 4 - 0
contrib/Debian/ngircd.pam

@@ -0,0 +1,4 @@
+# /etc/pam.d/ngircd
+
+# allow all connections to ngIRCd
+auth required pam_permit.so

+ 6 - 2
contrib/Debian/rules

@@ -53,7 +53,7 @@ configure-ngircd-full: configure
 	  --sysconfdir=/etc/ngircd \
 	  --mandir=\$${prefix}/share/man \
 	  --with-syslog --with-zlib \
-	  --with-gnutls --with-ident --with-tcp-wrappers \
+	  --with-gnutls --with-ident --with-tcp-wrappers --with-pam \
 	  --enable-ipv6
 
 configure-ngircd-full-dbg: configure
@@ -66,7 +66,7 @@ configure-ngircd-full-dbg: configure
 	  --mandir=\$${prefix}/share/man \
 	  --enable-debug --enable-sniffer \
 	  --with-syslog --with-zlib \
-	  --with-gnutls --with-ident --with-tcp-wrappers \
+	  --with-gnutls --with-ident --with-tcp-wrappers --with-pam \
 	  --enable-ipv6
 
 build:
@@ -163,6 +163,8 @@ install-ngircd-full: build-ngircd-full
 	 sed -e "s/;PidFile = \/var\/run\/ngircd\/ngircd.pid/PidFile = \/var\/run\/ircd\/ngircd.pid/g" \
 	 >$(CURDIR)/debian/ngircd-full/etc/ngircd/ngircd.conf
 	touch $(CURDIR)/debian/ngircd-full/etc/ngircd/ngircd.motd
+	mkdir -p $(CURDIR)/debian/ngircd-full/etc/pam.d
+	cp $(CURDIR)/debian/ngircd.pam $(CURDIR)/debian/ngircd-full/etc/pam.d/ngircd
 
 install-ngircd-full-dbg: build-ngircd-full-dbg
 	dh_testdir
@@ -183,6 +185,8 @@ install-ngircd-full-dbg: build-ngircd-full-dbg
 	 sed -e "s/;PidFile = \/var\/run\/ngircd\/ngircd.pid/PidFile = \/var\/run\/ircd\/ngircd.pid/g" \
 	 >$(CURDIR)/debian/ngircd-full-dbg/etc/ngircd/ngircd.conf
 	touch $(CURDIR)/debian/ngircd-full-dbg/etc/ngircd/ngircd.motd
+	mkdir -p $(CURDIR)/debian/ngircd-full-dbg/etc/pam.d
+	cp $(CURDIR)/debian/ngircd.pam $(CURDIR)/debian/ngircd-full-dbg/etc/pam.d/ngircd
 
 # Build architecture-independent files here.
 binary-indep:

BIN
contrib/MacOSX/._Makefile.am


+ 8 - 9
contrib/MacOSX/Makefile.in

@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -278,8 +278,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	mkid -fID $$unique
 tags: TAGS
 
@@ -304,8 +304,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
 	  test -n "$$unique" || unique=$$empty_fix; \
 	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -315,13 +315,12 @@ ctags: CTAGS
 CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
 	tags=; \
-	here=`pwd`; \
 	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	test -z "$(CTAGS_ARGS)$$tags$$unique" \
 	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
 	     $$tags $$unique

+ 17 - 1
contrib/MacOSX/config.h

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2009 Alexander Barton (alex@barton.de).
+ * Copyright (c)2001-2010 Alexander Barton (alex@barton.de).
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -51,6 +51,9 @@
 /* Define if IPV6 protocol should be enabled */
 #define WANT_IPV6 1
 
+/* Define if PAM should be used */
+#define PAM 1
+
 /* -- Supported features -- */
 
 /* Define if SSP C support is enabled. */
@@ -71,6 +74,8 @@
 #define HAVE_STDBOOL_H 1
 /* Define to 1 if you have the <arpa/inet.h> header file. */
 #define HAVE_ARPA_INET_H 1
+/* Define to 1 if you have the <netinet/ip.h> header file. */
+#define HAVE_NETINET_IP_H 1
 
 /* Define to 1 if you have the `kqueue' function. */
 #define HAVE_KQUEUE 1
@@ -92,6 +97,8 @@
 #define HAVE_GETADDRINFO 1
 /* Define to 1 if you have the `getnameinfo' function. */
 #define HAVE_GETNAMEINFO 1
+/* Define to 1 if you have the `sigaction' function. */
+#define HAVE_SIGACTION 1
 
 /* Define if socklen_t exists */
 #define HAVE_socklen_t 1
@@ -103,4 +110,13 @@
 #define HAVE_DNSSERVICEREGISTRATIONCREATE 1
 #endif
 
+#ifdef PAM
+/* Define to 1 if you have the `pam_authenticate' function. */
+#define HAVE_PAM_AUTHENTICATE 1
+/* Define to 1 if you have the <pam/pam_appl.h> header file. */
+#define HAVE_PAM_PAM_APPL_H 1
+/* Mac OS X <10.6 doesn't have pam_fail_delay() */
+#define NO_PAM_FAIL_DELAY 1
+#endif
+
 /* -eof- */

+ 2 - 2
contrib/MacOSX/ngIRCd.pmdoc/Makefile.in

@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.

+ 2 - 2
contrib/MacOSX/ngIRCd.pmdoc/index.xml

@@ -4,7 +4,7 @@
 \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\qc\pardirnatural
 
 \f0\i\fs24 \cf0 ngIRCd -- The Next Generation IRC Daemon\
-Copyright (c)2001-2009 Alexander Barton and Contributors.\
+Copyright (c)2001-2010 Alexander Barton and Contributors.\
 \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural
 
 \i0 \cf0 \
@@ -187,4 +187,4 @@ To disable automatic starting of ngIRCd, use this command:\
 \ls2\ilvl0
 \f1\fs24 \cf0 	sudo launchctl unload -w \\\
 		/Library/LaunchDaemons/de.barton.ngircd.plist\
-}]]></resource></locale></resources><flags/><item type="file">01ngircd.xml</item><item type="file">02de.xml</item><mod>properties.customizeOption</mod><mod>properties.title</mod><mod>description</mod><mod>properties.anywhereDomain</mod><mod>properties.systemDomain</mod></pkmkdoc>
+}]]></resource></locale></resources><flags/><item type="file">01ngircd.xml</item><item type="file">02de.xml</item><mod>properties.customizeOption</mod><mod>properties.title</mod><mod>description</mod><mod>properties.anywhereDomain</mod><mod>properties.systemDomain</mod></pkmkdoc>

+ 2 - 2
contrib/MacOSX/ngIRCd.xcodeproj/Makefile.in

@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.

+ 34 - 7
contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj

@@ -7,6 +7,8 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		FA2D564A11EA158B00D37A35 /* pam.c in Sources */ = {isa = PBXBuildFile; fileRef = FA2D564911EA158B00D37A35 /* pam.c */; };
+		FA2D567B11EA1AB300D37A35 /* libpam.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA2D567A11EA1AB300D37A35 /* libpam.dylib */; };
 		FA322D350CEF74B1001761B3 /* array.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322CD90CEF74B1001761B3 /* array.c */; };
 		FA322D360CEF74B1001761B3 /* channel.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322CDB0CEF74B1001761B3 /* channel.c */; };
 		FA322D370CEF74B1001761B3 /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322CDD0CEF74B1001761B3 /* client.c */; };
@@ -36,7 +38,9 @@
 		FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA322DC00CEF77CB001761B3 /* libz.dylib */; };
 		FA407F2E0DB159F400271AF1 /* ng_ipaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */; };
 		FA85178C0FA061EC006A1F5A /* op.c in Sources */ = {isa = PBXBuildFile; fileRef = FA85178B0FA061EC006A1F5A /* op.c */; };
+		FA99428C10E82A27007F27ED /* proc.c in Sources */ = {isa = PBXBuildFile; fileRef = FA99428B10E82A27007F27ED /* proc.c */; };
 		FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA3D2790F139CDC00B2447E /* conn-ssl.c */; };
+		FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA97C55124A271400D5BBA9 /* sighandlers.c */; };
 		FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */ = {isa = PBXBuildFile; fileRef = FAE5CC2D0CF2308A007D69B6 /* numeric.c */; };
 /* End PBXBuildFile section */
 
@@ -55,6 +59,9 @@
 /* Begin PBXFileReference section */
 		FA1A6BBC0D6857BB00AA8F71 /* misc-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "misc-test.e"; sourceTree = "<group>"; };
 		FA1A6BBD0D6857D900AA8F71 /* who-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "who-test.e"; sourceTree = "<group>"; };
+		FA2D564811EA158B00D37A35 /* pam.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pam.h; sourceTree = "<group>"; };
+		FA2D564911EA158B00D37A35 /* pam.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pam.c; sourceTree = "<group>"; };
+		FA2D567A11EA1AB300D37A35 /* libpam.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpam.dylib; path = usr/lib/libpam.dylib; sourceTree = SDKROOT; };
 		FA322BBA0CEF72E4001761B3 /* ngIRCd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ngIRCd; sourceTree = BUILT_PRODUCTS_DIR; };
 		FA322CD60CEF74B1001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
 		FA322CD90CEF74B1001761B3 /* array.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = array.c; sourceTree = "<group>"; };
@@ -196,6 +203,8 @@
 		FA407F380DB15AC700271AF1 /* GIT.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = GIT.txt; sourceTree = "<group>"; };
 		FA85178A0FA061EC006A1F5A /* op.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = op.h; sourceTree = "<group>"; };
 		FA85178B0FA061EC006A1F5A /* op.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = op.c; sourceTree = "<group>"; };
+		FA99428A10E82A27007F27ED /* proc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = proc.h; sourceTree = "<group>"; };
+		FA99428B10E82A27007F27ED /* proc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = proc.c; sourceTree = "<group>"; };
 		FAA3D2700F139CB300B2447E /* invite-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "invite-test.e"; sourceTree = "<group>"; };
 		FAA3D2710F139CB300B2447E /* join-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "join-test.e"; sourceTree = "<group>"; };
 		FAA3D2720F139CB300B2447E /* kick-test.e */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = "kick-test.e"; sourceTree = "<group>"; };
@@ -218,6 +227,8 @@
 		FAA3D2880F139D2E00B2447E /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
 		FAA3D28A0F139D2E00B2447E /* postinstall.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = postinstall.sh; sourceTree = "<group>"; };
 		FAA3D28B0F139D2E00B2447E /* preinstall.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = preinstall.sh; sourceTree = "<group>"; };
+		FAA97C55124A271400D5BBA9 /* sighandlers.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = sighandlers.c; sourceTree = "<group>"; };
+		FAA97C56124A271400D5BBA9 /* sighandlers.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = sighandlers.h; sourceTree = "<group>"; };
 		FAE5CC2C0CF2308A007D69B6 /* numeric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = numeric.h; sourceTree = "<group>"; };
 		FAE5CC2D0CF2308A007D69B6 /* numeric.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = numeric.c; sourceTree = "<group>"; };
 /* End PBXFileReference section */
@@ -228,6 +239,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */,
+				FA2D567B11EA1AB300D37A35 /* libpam.dylib in Frameworks */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -254,6 +266,7 @@
 				FA322D630CEF750F001761B3 /* Makefile.am */,
 				1AB674ADFE9D54B511CA2CBB /* Products */,
 				FA322DC00CEF77CB001761B3 /* libz.dylib */,
+				FA2D567A11EA1AB300D37A35 /* libpam.dylib */,
 			);
 			name = ngIRCd;
 			sourceTree = "<group>";
@@ -339,10 +352,16 @@
 				FA85178B0FA061EC006A1F5A /* op.c */,
 				FA322D080CEF74B1001761B3 /* parse.c */,
 				FA322D090CEF74B1001761B3 /* parse.h */,
+				FA99428B10E82A27007F27ED /* proc.c */,
+				FA99428A10E82A27007F27ED /* proc.h */,
 				FA322D0A0CEF74B1001761B3 /* rendezvous.c */,
 				FA322D0B0CEF74B1001761B3 /* rendezvous.h */,
 				FA322D0C0CEF74B1001761B3 /* resolve.c */,
 				FA322D0D0CEF74B1001761B3 /* resolve.h */,
+				FAA97C55124A271400D5BBA9 /* sighandlers.c */,
+				FAA97C56124A271400D5BBA9 /* sighandlers.h */,
+				FA2D564811EA158B00D37A35 /* pam.h */,
+				FA2D564911EA158B00D37A35 /* pam.c */,
 			);
 			path = ngircd;
 			sourceTree = "<group>";
@@ -631,7 +650,14 @@
 			isa = PBXProject;
 			buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "ngIRCd" */;
 			compatibilityVersion = "Xcode 3.0";
+			developmentRegion = English;
 			hasScannedForEncodings = 1;
+			knownRegions = (
+				English,
+				Japanese,
+				French,
+				German,
+			);
 			mainGroup = 08FB7794FE84155DC02AAC07 /* ngIRCd */;
 			projectDirPath = "";
 			projectReferences = (
@@ -682,6 +708,9 @@
 				FA407F2E0DB159F400271AF1 /* ng_ipaddr.c in Sources */,
 				FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */,
 				FA85178C0FA061EC006A1F5A /* op.c in Sources */,
+				FA99428C10E82A27007F27ED /* proc.c in Sources */,
+				FA2D564A11EA158B00D37A35 /* pam.c in Sources */,
+				FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -711,7 +740,6 @@
 				GCC_WARN_UNUSED_VALUE = YES;
 				INSTALL_PATH = /usr/local/bin;
 				PRODUCT_NAME = ngIRCd;
-				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
 			};
 			name = Default;
 		};
@@ -724,22 +752,22 @@
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
 				PREBINDING = NO;
-				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
+				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
 			};
 			name = Default;
 		};
 		FAB0570C105D917F006AF9E2 /* Debug */ = {
 			isa = XCBuildConfiguration;
 			buildSettings = {
-				ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
-				ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
+				ARCHS = "$(NATIVE_ARCH_ACTUAL)";
 				GCC_DEBUGGING_SYMBOLS = full;
 				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_VERSION = 4.0;
 				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
+				ONLY_ACTIVE_ARCH = YES;
 				PREBINDING = NO;
-				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
+				SDKROOT = "";
 			};
 			name = Debug;
 		};
@@ -758,7 +786,7 @@
 				GCC_WARN_SHADOW = YES;
 				GCC_WARN_SIGN_COMPARE = YES;
 				GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
-				GCC_WARN_UNINITIALIZED_AUTOS = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = NO;
 				GCC_WARN_UNKNOWN_PRAGMAS = YES;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_LABEL = YES;
@@ -766,7 +794,6 @@
 				GCC_WARN_UNUSED_VALUE = YES;
 				INSTALL_PATH = /usr/local/bin;
 				PRODUCT_NAME = ngIRCd;
-				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
 			};
 			name = Debug;
 		};

+ 14 - 0
contrib/MacOSX/postinstall.sh

@@ -19,6 +19,20 @@ else
 fi
 chmod o-rwx /opt/ngircd/etc/ngircd.conf
 
+if [ ! -e /opt/ngircd/etc/ngircd.pam ]; then
+	echo "Creating default PAM configuration: /opt/ngircd/etc/ngircd.pam"
+	echo "# PAM configuration for ngIRCd" >/opt/ngircd/etc/ngircd.pam
+	echo "" >>/opt/ngircd/etc/ngircd.pam
+	echo "auth required pam_permit.so" >>/opt/ngircd/etc/ngircd.pam
+	echo "#auth required pam_opendirectory.so" >>/opt/ngircd/etc/ngircd.pam
+fi
+chmod 644 /opt/ngircd/etc/ngircd.pam
+
+if [ ! -e /etc/pam.d/ngircd ]; then
+	echo "Linkint /opt/ngircd/etc/ngircd.pam to /etc/pam.d/ngircd"
+	ln -s /opt/ngircd/etc/ngircd.pam /etc/pam.d/ngircd || exit 1
+fi
+
 if [ -f "$LDPLIST" ]; then
 	echo "Fixing ownership and permissions of LaunchDaemon script ..."
 	chown root:wheel "$LDPLIST" || exit 1

+ 8 - 9
contrib/Makefile.in

@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -278,8 +278,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	mkid -fID $$unique
 tags: TAGS
 
@@ -304,8 +304,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
 	  test -n "$$unique" || unique=$$empty_fix; \
 	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -315,13 +315,12 @@ ctags: CTAGS
 CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
 	tags=; \
-	here=`pwd`; \
 	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	test -z "$(CTAGS_ARGS)$$tags$$unique" \
 	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
 	     $$tags $$unique

+ 1 - 1
contrib/ngircd-redhat.init

@@ -1,7 +1,7 @@
 #!/bin/sh
 #
 # ngIRCd start and stop script for RedHat based distributions.
-# Written by Naoya Nakazawa <naoya@sanow.net> for CentOS 5.2, 2009.
+# Written by Naoya Nakazawa <naoya.n@gmail.com> for CentOS 5.2, 2009.
 #
 # chkconfig: 2345 01
 # description: ngIRCd is an Open Source server for \

+ 1 - 1
contrib/ngircd.spec

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

+ 30 - 17
contrib/platformtest.sh

@@ -1,7 +1,7 @@
 #!/bin/sh
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2009 Alexander Barton <alex@barton.de>
+# Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -51,16 +51,16 @@ if [ $? -ne 0 ]; then
 	cd ..
 fi
 
-echo "$NAME: Checking for ./configure script ..."
-if [ ! -e ./configure ]; then
-	echo "$NAME: Not found. Running ./autogen.sh ..."
+echo "$NAME: Checking for \"./autogen.sh\" script ..."
+if [ -r ./autogen.sh ]; then
+	echo "$NAME: Running \"./autogen.sh\" ..."
 	[ -n "$VERBOSE" ] && ./autogen.sh || ./autogen.sh >/dev/null
 fi
 
-if [ -e ./configure ]; then
+if [ -r ./configure ]; then
 	echo "$NAME: Running \"./configure\" script ..."
 	[ -n "$VERBOSE" ] && ./configure || ./configure >/dev/null
-	if [ $? -eq 0 -a -e ./Makefile ]; then
+	if [ $? -eq 0 -a -r ./Makefile ]; then
 		CONFIGURE=1
 		echo "$NAME: Running \"make\" ..."
 		[ -n "$VERBOSE" ] && make || make >/dev/null
@@ -93,22 +93,29 @@ fi
 
 # Get compiler information
 if [ -r "Makefile" ]; then
-	eval $(grep "^CC = " Makefile | sed -e 's/ //g')
+	CC=$(grep "^CC = " Makefile | cut -d' ' -f3)
 	$CC --version 2>&1 | grep -i "GCC" >/dev/null
 	if [ $? -eq 0 ]; then
-		COMPILER=$($CC --version | head -n 1 | awk "{ print \$3 }" \
+		COMPILER=$($CC --version | head -1 | awk "{ print \$3 }" \
 		 | cut -d'-' -f1)
 		COMPILER="gcc $COMPILER"
+	else
+		case "$CC" in
+		  gcc*)
+			v="`$CC --version 2>/dev/null | head -1`"
+			[ -n "$v" ] && COMPILER="gcc $v"
+			;;
+		esac
 	fi
 fi
 
 # Get ngIRCd version information
-if [ -d ".git" ]; then
-	VERSION=`git log --abbrev-commit --pretty=oneline HEAD~1.. \
-	 | cut -d' ' -f1 | tr -d '.'`
-elif [ -r "Makefile" ]; then
-	eval $(grep "^VERSION = " Makefile | sed -e 's/ //g')
-fi
+eval $(grep "^VERSION = " Makefile | sed -e 's/ //g')
+case "$VERSION" in
+	*-*-*)
+		VERSION=`echo "$VERSION" | cut -d'-' -f3 | cut -b2-`
+		;;
+esac
 [ -n "$VERSION" ] || VERSION="unknown"
 
 # Get IO interface information
@@ -137,7 +144,13 @@ echo "                                                ./configure works --+ | |
 echo "                                                                    | | | |"
 echo "Platform                    Compiler     ngIRCd     Date     Tester C M T R See"
 echo "--------------------------- ------------ ---------- -------- ------ - - - - ---"
-printf "%-27s %-12s %-10s %s %-6s %s %s %s %s%s" \
- "$PLATFORM" "$COMPILER" "$VERSION" "$DATE" "$USER" \
- "$C" "$M" "$T" "$R" "$COMMENT"
+type printf >/dev/null 2>&1
+if [ $? -eq 0 ]; then
+	printf "%-27s %-12s %-10s %s %-6s %s %s %s %s%s" \
+	 "$PLATFORM" "$COMPILER" "$VERSION" "$DATE" "$USER" \
+	 "$C" "$M" "$T" "$R" "$COMMENT"
+else
+	echo "$PLATFORM $COMPILER $VERSION $DATE $USER" \
+	 "$C" "$M" "$T" "$R" "$COMMENT"
+fi
 echo; echo

+ 19 - 14
depcomp

@@ -1,9 +1,9 @@
 #! /bin/sh
 # depcomp - compile a program generating dependencies as side-effects
 
-scriptversion=2006-10-15.18
+scriptversion=2007-03-29.01
 
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software
 # Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
@@ -215,34 +215,39 @@ aix)
   # current directory.  Also, the AIX compiler puts `$object:' at the
   # start of each line; $object doesn't have directory information.
   # Version 6 uses the directory in both cases.
-  stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
-  tmpdepfile="$stripped.u"
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
   if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
     "$@" -Wc,-M
   else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
     "$@" -M
   fi
   stat=$?
 
-  if test -f "$tmpdepfile"; then :
-  else
-    stripped=`echo "$stripped" | sed 's,^.*/,,'`
-    tmpdepfile="$stripped.u"
-  fi
-
   if test $stat -eq 0; then :
   else
-    rm -f "$tmpdepfile"
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
     exit $stat
   fi
 
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
   if test -f "$tmpdepfile"; then
-    outname="$stripped.o"
     # Each line is of the form `foo.o: dependent.h'.
     # Do two passes, one to just change these to
     # `$object: dependent.h' and one to simply `dependent.h:'.
-    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
-    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+    sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+    # That's a tab and a space in the [].
+    sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
   else
     # The sourcefile does not contain any dependencies, so just
     # store a dummy comment line, to avoid errors with the Makefile

+ 53 - 0
doc/Bopm.txt

@@ -0,0 +1,53 @@
+
+                     ngIRCd - Next Generation IRC Server
+
+                        (c)2001-2010 Alexander Barton,
+                    alex@barton.de, http://www.barton.de/
+
+               ngIRCd is free software and published under the
+                   terms of the GNU General Public License.
+
+                                -- BOPM.txt --
+
+
+I. Introduction
+~~~~~~~~~~~~~~~~
+
+Citing <http://wiki.blitzed.org/BOPM>: "BOPM is an open source open proxy
+monitor, designed for use with hybrid-based ircds, although it can be used
+with slight modification on any server which has the ability to show connects
+to opers and that supports KLINEs."
+
+And starting with Release 17, ngIRCd supports all required log messages that
+BOPM requires to be useful.
+
+II. Installation
+~~~~~~~~~~~~~~~~~
+
+Install BOPM as usual, please see the BOPM documentation for details.
+Afterwards adjust the following configuration parameters that are important
+for ngIRCd:
+
+a) BOPM "IRC" section:
+
+  1) Set "server" and "port" accordingly,
+
+  2) adjust the "oper" line to match an [Operator] block in ngircd.conf,
+
+  3) change "mode" to "+ci" or "+c".
+
+  4) Set "connregex" to the following string, everything in one line(!):
+     "\\*\\*\\* Notice -- Client connecting: ([^ ]+) \\(([^@]+)@([^\\)]+)\\) \\[([0-9\\.]+)\\].*";
+     and comment all the other "connregex" examples (prepend a "#" character).
+
+  5) Set "kline" to "KILL %n :Open proxy found on your host!"; for example,
+     and comment all the other "kline" examples.
+
+b) BOPM "scanner" section:
+
+  Make sure you configure a valid "target_ip" and "target_port" for the
+  configured scanners to test. And please note that you CAN'T USE the port
+  of ngIRCd, because ngIRCd doesn't send any banner message by default!
+
+  So you need a service what sends a banner, so for example POP3, SMTP,
+  IMAP, or SSH daemons should work ...

+ 17 - 10
doc/FAQ.txt

@@ -1,7 +1,7 @@
 
                      ngIRCd - Next Generation IRC Server
 
-                      (c)2001-2003 by Alexander Barton,
+                      (c)2001-2010 by Alexander Barton,
                     alex@barton.de, http://www.barton.de/
 
                ngIRCd is free software and published under the
@@ -12,9 +12,11 @@
 
 I. General
 ~~~~~~~~~~
+
 Q: Is it possible to link the ngIRCd with non-ngIRCd servers?
 A: Yes. ngIRCd is compatible to the original ircd used by IRCNet. Actually
-   this is being tested with version 2.10.3p3.
+   this is being tested with version 2.10.3p3. Please note that newer
+   versions (2.11.x) aren't compatible any more!
 
 Q: Is there a homepage with further information and downloads?
 A: Yes. Please visit <http://ngircd.barton.de/>.
@@ -26,6 +28,7 @@ A: ngIRCd offers several benefits: no problems with dynamic IPs, easy to
 
 II. Compilation
 ~~~~~~~~~~~~~~~
+
 Q: I did a "CVS checkout" but can't execute ./configure because the script
    is missing in the generated directory!?
 A: When using development versions via CVS, the configure script as well as
@@ -55,27 +58,33 @@ III. Runtime
 ~~~~~~~~~~~~
 
 Q: Where is the log file located?
-A: ngIRCd does not write its own log file. Instead, ngIRCd uses
-   syslog(3). Check the files in /var/log/ and/or consult the
-   documentation for your system logger daemon.
+A: ngIRCd does not write its own log file. Instead, ngIRCd uses syslog(3).
+   Check the files in /var/log/ and/or consult the documentation for your
+   system logger daemon.
+
 Q: I cannot connect to remote peers when I use the chroot option, the
    following is logged: "Can't resolve example.com: unknown error!".
 A: On Linux/glibc with chroot enabled you need to put some libraries inside
    the chroot as well, notably libnss_dns; maybe others. Unfortunately, even
-   linking ngircd statically does not help this. The only known workaround
+   linking ngIRCd statically does not help this. The only known workaround
    is to either disable chroot support or to link against dietlibc instead
    of glibc. (tnx to Sebastian Siewior)
+
 Q: I have added an [Oper] section, how do i log on as IRC operator?
 A: You can use the /OPER command in your IRC client to become an IRC operator.
    ngIRCd will also log all OPER requests (using syslog), if OPER fails you
    can look there to determine why it did not work (bad password, unauthorized
    host mask, etc.)
+
 Q: I am an IRC operator, but MODE doesn't work!
-A: You need to set 'OperCanUseMode = yes' in ngircd.conf to enable MODE for IRC
-   operators.
+A: You need to set 'OperCanUseMode = yes' in ngircd.conf, then IRC operators
+   can use the MODE command for changing modes even when they are not joined
+   to the specific channel.
+
 
 IV. Bugs!?
 ~~~~~~~~~~
+
 Q: Is there a list of known bugs and desired feature enhancements?
 A: Yes. Have a look at the bug tracking system (Bugzilla) for ngIRCd located
    at <http://ngircd.barton.de/bugzilla/index.cgi>. There you can file bug
@@ -85,6 +94,3 @@ Q: What should I do if I found a bug?
 A: Please file a bug report at <http://ngircd.barton.de/bugzilla/index.cgi>!
    The author of the particular component will be notified automagically :-)
 
-
-$Id: FAQ.txt,v 1.12 2008/01/02 22:47:58 alex Exp $

+ 77 - 0
doc/HowToRelease.txt

@@ -0,0 +1,77 @@
+
+                     ngIRCd - Next Generation IRC Server
+
+                        (c)2001-2010 Alexander Barton,
+                    alex@barton.de, http://www.barton.de/
+
+               ngIRCd is free software and published under the
+                   terms of the GNU General Public License.
+
+                            -- HowToRelease.txt --
+
+
+I. Introduction
+~~~~~~~~~~~~~~~
+
+Creating a new ngIRCd release requires a few steps to follow: the source
+tree must be in a releasable state (be up to date, include all required
+patches, be tested on as many platforms as possible), a name for the new
+release must be chosen, and all the files describing the release must be
+updated accordingly.
+
+Since ngIRCd release 13 (2009-12-25) we use "simple" release numbers for
+major releases (e.g. "13", "17", "42", ...) introducing new features and
+sub-releases for bug fixes only (e.g. "14.1", "22.3", ...).
+
+When creating pre-releases or release candidates, please use the tilde ("~")
+character to separate the "postfix" in the release number (e.g. "17~rc2"
+or "123.4~rc6").
+
+The release/version number of a build is automatically generated using the
+GIT "describe" command, see git-describe(1). Therefore it is required that
+a new release is tagged in the GIT tree and that the configure script is
+up-to-date (e.g. using ./autogen.sh) before generating the archives!
+
+
+II. How to prepare a new ngIRCd release?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+a) Make sure the source tree is in a releasable state ;-)
+
+b) Make sure you have working versions of GNU autoconf and GNU automake
+   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
+   which seem to work just fine.
+
+c) Update the files describing the new release:
+    - ChangeLog
+    - NEWS
+
+d) Update the version numbers in the following files:
+    - contrib/ngircd.spec
+
+e) Generate a new Debian change log entry in the following file, e.g. using
+   the Debian "dch" tool of the "devscripts" package:
+    - contrib/Debian/changelog
+
+f) Commit the above changes to GIT: "git add", "git commit"
+
+g) Create a new signed GIT tag for the new release: "git tag -s".
+   Please note that we don't use the tilde ("~") here, instead use a simple
+   hyphen ("-") as delimiter: e.g. "rel-16" "rel-17-rc1", "rel-18-pre2", ...
+
+h) Run "./autogen.sh" to update the ./configure script with the correct
+   release number (autogenerated using "git describe", see above).
+
+i) Run "./configure" to rebuild all generated Makefiles.
+
+j) Run "make distcheck" to generate the distribution archives.
+
+k) Sign the distribution archive(s) using GnuPG: "gpg -b <archivefile>"
+
+l) Upload and distribute the newly generated ngIRCd release archive(s)
+   and GnuPG signatures.
+
+m) Write an announcement to the mailing list, freshmeat, Twitter, ...
+
+n) Relax :-)

+ 28 - 11
doc/Makefile.am

@@ -1,6 +1,6 @@
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
+# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 #
 # Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 # der GNU General Public License (GPL), wie von der Free Software Foundation
@@ -10,29 +10,46 @@
 # der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
 #
 
+.tmpl:
+	sed \
+	    -e s@:ETCDIR:@${sysconfdir}@ \
+	    <$< >$@
+
+SUFFIXES = .tmpl
+
+static_docs = Bopm.txt FAQ.txt GIT.txt HowToRelease.txt PAM.txt Platforms.txt \
+	Protocol.txt README-AUX.txt README-BeOS.txt README-Interix.txt RFC.txt \
+	SSL.txt Services.txt Zeroconf.txt
+
+doc_templates = sample-ngircd.conf.tmpl
+
+generated_docs = sample-ngircd.conf
+
+toplevel_docs = ../AUTHORS ../COPYING ../ChangeLog ../INSTALL ../NEWS ../README
+
 SUBDIRS = src
 
-EXTRA_DIST = FAQ.txt GIT.txt Protocol.txt Platforms.txt README-AUX.txt \
-	README-BeOS.txt RFC.txt Services.txt SSL.txt Zeroconf.txt \
-	sample-ngircd.conf
+EXTRA_DIST = $(static_docs) $(doc_templates)
+
+CLEANFILES = $(generated_docs)
 
 maintainer-clean-local:
 	rm -f Makefile Makefile.in
 
-docdir = $(datadir)/doc/$(PACKAGE)
+all: $(generated_docs)
 
-documents = $(EXTRA_DIST) ../AUTHORS ../COPYING ../ChangeLog ../INSTALL \
-	../NEWS ../README
-
-install-data-hook:
+install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
 	$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
 	if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
-	  $(INSTALL) -m 600 -c $(srcdir)/sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; \
+	  $(INSTALL) -m 600 -c sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; \
 	 fi
 	$(mkinstalldirs) $(DESTDIR)$(docdir)
-	for f in $(documents); do \
+	for f in $(static_docs) $(toplevel_docs); do \
 	  $(INSTALL) -m 644 -c $(srcdir)/$$f $(DESTDIR)$(docdir)/; \
 	 done
+	for f in $(generated_docs); do \
+	  $(INSTALL) -m 644 -c $$f $(DESTDIR)$(docdir)/; \
+	 done
 
 uninstall-hook:
 	rm -rf $(DESTDIR)$(docdir)

+ 35 - 21
doc/Makefile.in

@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -16,7 +16,7 @@
 
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
+# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 #
 # Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 # der GNU General Public License (GPL), wie von der Free Software Foundation
@@ -133,7 +133,7 @@ build_vendor = @build_vendor@
 builddir = @builddir@
 datadir = @datadir@
 datarootdir = @datarootdir@
-docdir = $(datadir)/doc/$(PACKAGE)
+docdir = @docdir@
 dvidir = @dvidir@
 exec_prefix = @exec_prefix@
 host = @host@
@@ -167,17 +167,21 @@ target_os = @target_os@
 target_vendor = @target_vendor@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
+SUFFIXES = .tmpl
+static_docs = Bopm.txt FAQ.txt GIT.txt HowToRelease.txt PAM.txt Platforms.txt \
+	Protocol.txt README-AUX.txt README-BeOS.txt README-Interix.txt RFC.txt \
+	SSL.txt Services.txt Zeroconf.txt
+
+doc_templates = sample-ngircd.conf.tmpl
+generated_docs = sample-ngircd.conf
+toplevel_docs = ../AUTHORS ../COPYING ../ChangeLog ../INSTALL ../NEWS ../README
 SUBDIRS = src
-EXTRA_DIST = FAQ.txt GIT.txt Protocol.txt Platforms.txt README-AUX.txt \
-	README-BeOS.txt RFC.txt Services.txt SSL.txt Zeroconf.txt \
-	sample-ngircd.conf
-
-documents = $(EXTRA_DIST) ../AUTHORS ../COPYING ../ChangeLog ../INSTALL \
-	../NEWS ../README
-
+EXTRA_DIST = $(static_docs) $(doc_templates)
+CLEANFILES = $(generated_docs)
 all: all-recursive
 
 .SUFFIXES:
+.SUFFIXES: .tmpl
 $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
@@ -283,8 +287,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	mkid -fID $$unique
 tags: TAGS
 
@@ -309,8 +313,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
 	  test -n "$$unique" || unique=$$empty_fix; \
 	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -320,13 +324,12 @@ ctags: CTAGS
 CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
 	tags=; \
-	here=`pwd`; \
 	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	test -z "$(CTAGS_ARGS)$$tags$$unique" \
 	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
 	     $$tags $$unique
@@ -404,6 +407,7 @@ install-strip:
 mostlyclean-generic:
 
 clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
 	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
@@ -488,18 +492,28 @@ uninstall-am:
 	uninstall uninstall-am uninstall-hook
 
 
+.tmpl:
+	sed \
+	    -e s@:ETCDIR:@${sysconfdir}@ \
+	    <$< >$@
+
 maintainer-clean-local:
 	rm -f Makefile Makefile.in
 
-install-data-hook:
+all: $(generated_docs)
+
+install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
 	$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
 	if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
-	  $(INSTALL) -m 600 -c $(srcdir)/sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; \
+	  $(INSTALL) -m 600 -c sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; \
 	 fi
 	$(mkinstalldirs) $(DESTDIR)$(docdir)
-	for f in $(documents); do \
+	for f in $(static_docs) $(toplevel_docs); do \
 	  $(INSTALL) -m 644 -c $(srcdir)/$$f $(DESTDIR)$(docdir)/; \
 	 done
+	for f in $(generated_docs); do \
+	  $(INSTALL) -m 644 -c $$f $(DESTDIR)$(docdir)/; \
+	 done
 
 uninstall-hook:
 	rm -rf $(DESTDIR)$(docdir)

+ 36 - 0
doc/PAM.txt

@@ -0,0 +1,36 @@
+
+                     ngIRCd - Next Generation IRC Server
+
+                        (c)2001-2010 Alexander Barton,
+                    alex@barton.de, http://www.barton.de/
+
+               ngIRCd is free software and published under the
+                   terms of the GNU General Public License.
+
+                                 -- PAM.txt --
+
+
+ngIRCd can optionally be compiled to use PAM, the Pluggable Authentication
+Modules library, for user authentication. When compiled with PAM support,
+ngIRCd will authenticate all users connecting to the daemon using the
+configured PAM modules in an asynchronous child process.
+
+To enable PAM, you have to pass the command line parameter "--with-pam" to
+the "configure" script. Please see the PAM documentation ("man 7 pam") for
+details and information about configuring PAM and its individual modules.
+
+A very simple -- and quite useless ;-) -- example would be:
+
+	/etc/pam.d/ngircd:
+	  auth  required  pam_debug.so
+
+Here the "pam_debug" module will be called each time a client connects to
+the ngIRCd and has sent its PASS, NICK, and USER commands.
+
+Please note ONE VERY IMPORTANT THING:
+
+All the PAM modules are executed with the privileges of the user ngIRCd
+is running as. Therefore a lot of PAM modules aren't working as expected,
+because they need root privileges ("pam_unix", for example)!
+Only PAM modules not(!) requiring root privileges (such as "pam_pgsql",
+"pam_mysql", "pam_opendirectory" ...) can be used in conjunction with ngIRCd.

+ 18 - 16
doc/Platforms.txt

@@ -1,7 +1,7 @@
 
                      ngIRCd - Next Generation IRC Server
 
-                        (c)2001-2009 Alexander Barton
+                        (c)2001-2010 Alexander Barton
                     alex@barton.de, http://www.barton.de/
 
                ngIRCd is free software and published under the
@@ -32,40 +32,42 @@ hppa1.1/unknown/linux-gnu   gcc 3.3.3    0.8.0      04-05-30 alex   Y Y Y Y
 hppa2.0/unknown/linux-gnu   gcc 3.3.5    13~rc1     08-12-02 alex   Y Y Y Y
 hppa2.0w-hp-hpux11.11       gcc 4.2.3    14.1       09-07-22 goetz  Y Y Y Y
 i386/apple/darwin9.7.0      gcc 4.0.1    14.1       09-08-04 alex   Y Y Y Y (3)
-i386/apple/darwin10.0.0b2   gcc 4.2.1    14.1       09-07-27 alex   Y Y Y Y (3)
+i386/apple/darwin10.4.0     gcc 4.2.1    17         10-11-07 alex   Y Y Y Y (3)
 i386/pc/solaris2.9          gcc 3.2.2    CVSHEAD    04-02-24 alex   Y Y Y Y
-i386/pc/solaris2.11         gcc 3.4.3    14.1       09-08-03 alex   Y Y Y Y (4)
+i386/pc/solaris2.11         gcc 3.4.3    17         10-11-07 alex   Y Y N Y (4)
 i386/unknown/freebsd5.2.1   gcc 3.3.3    0.8.0      04-05-30 alex   Y Y Y Y
-i386/unknown/freebsd6.0     gcc 3.4.4    0.10.0-p1  06-08-04 alex   Y Y Y Y (3)
-i386/unknown/freebsd6.1     gcc 3.4.4    CVSHEAD    06-05-07 fw     Y Y Y Y (3)
-i386/unknown/freebsd6.2     gcc 3.4.6    14.1       09-07-27 alex   Y Y Y Y (3)
-i386/unknown/freebsd7.0     gcc 4.2.1    14.1       09-07-28 alex   Y Y Y Y (3)
-i386/unknown/freebsd7.2     gcc 4.2.1    14.1       09-08-03 alex   Y Y Y Y (3)
-i386/unknown/gnu0.3         gcc 3.3.3    0.8.0      04-05-30 alex   Y Y n Y
-i686/unknown/gnu0.3         gcc 4.3.1    14.1       09-07-28 alex   Y Y Y Y
+i386/unknown/freebsd6.2     gcc 3.4.6    17         10-11-07 alex   Y Y Y Y (3)
+i386/unknown/freebsd7.3     gcc 4.2.1    17         10-11-07 alex   Y Y Y Y (3)
+i686/unknown/gnu0.3         gcc 4.4.5    17         10-11-07 alex   Y Y Y Y
+i686/unkn./kfreebsd7.2-gnu  gcc 4.3.4    15         09-12-02 alex   Y Y Y Y (3)
 i386/unknown/netbsdelf1.6.1 gcc 2.95.3   CVSHEAD    04-02-24 alex   Y Y Y Y
 i386/unknown/netbsdelf3.0.1 gcc 3.3.3    0.10.0-p1  06-08-30 alex   Y Y Y Y (3)
-i386/unknown/netbsdelf4.0   gcc 4.1.2    14.1       09-07-28 alex   Y Y Y Y (3)
+i386/unknown/netbsdelf4.0   gcc 4.1.2    17         10-11-07 alex   Y Y Y Y (3)
+i386/unknown/netbsdelf5.0.2 gcc 4.1.3    17         10-11-07 alex   Y Y Y Y (3)
 i386/unknown/openbsd3.9     gcc 3.3.5    0.10.0-p1  06-08-30 alex   Y Y Y Y (3)
-i386/unknown/openbsd4.1     gcc 3.3.5    14.1       09-07-28 alex   Y Y Y Y (3)
-i686/pc/cygwin              gcc 3.3.1    0.8.0      04-05-30 alex   Y Y n Y
+i386/unknown/openbsd4.1     gcc 3.3.5    16         10-04-11 alex   Y Y Y Y (3)
+i586/pc/interix3.5          gcc 3.3      15         10-01-22 alex   Y Y N Y
+i686/pc/cygwin              gcc 3.3.1    0.8.0      04-05-30 alex   Y Y N Y
 i686/pc/linux-gnu           gcc 2.95.4   0.8.0      04-05-30 alex   Y Y Y Y (1)
 i686/pc/linux-gnu           gcc 3.3.5    14.1       09-08-04 alex   Y Y Y Y (1)
 i386/pc/linux-gnu           gcc 4.1.2    13~rc1     08-12-05 alex   Y Y Y Y (1)
 i686/pc/linux-gnu           gcc 4.3.2    14.1       09-08-04 alex   Y Y Y Y (1)
+m68k/apple/aux3.0.1         gcc 2.7.2    17         10-11-07 alex   Y Y N Y
+m68k/apple/aux3.0.1         Orig. A/UX   17         10-11-07 alex   Y Y N Y (2)
 m68k/apple/aux3.1.1         Orig. A/UX   0.7.x-CVS  03-04-22 alex   Y Y Y Y (2)
 m68k/hp/hp-ux9.10           Orig. HPUX   0.7.x-CVS  03-04-30 goetz  Y Y Y Y
 m88k/dg/dgux5.4R3.10        gcc 2.5.8    CVSHEAD    04-03-15 alex   Y Y ? ?
 powerpc/apple/darwin6.5     gcc 3.1      0.7.x-CVS  03-04-23 alex   Y Y Y Y
-powerpc/apple/darwin7.4.0   gcc 3.3      0.8.0      04-05-30 alex   Y Y Y Y
 powerpc/apple/darwin7.9.0   gcc 3.3      CVSHEAD    06-05-07 fw     Y Y Y Y (3)
 powerpc/apple/darwin8.1.0   gcc 4.0      0.9.x-CVS  05-06-27 alex   Y Y Y Y
 powerpc/unknown/linux-gnu   gcc 3.3.3    0.8.0      04-05-30 alex   Y Y Y Y
-powerpc/unknown/openbsd3.6  gcc 2.95.3   0.10.0     06-10-08 alex   Y Y n Y
+powerpc/unknown/openbsd3.6  gcc 2.95.3   0.10.0     06-10-08 alex   Y Y N Y
 sparc/sun/solaris2.6        gcc 2.95.3   0.7.x-CVS  03-04-22 alex   Y Y Y Y
 sparc/sun/solaris2.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
-x86_64/unknown/linux-gnu    gcc 4.3.2    14.1       09-08-04 alex   Y Y Y Y (1)
+x86_64/unknown/freebsd8.1   gcc 4.2.1    17         10-11-07 alex   Y Y Y Y (3)
+x86_64/unknown/linux-gnu    gcc 4.3.2    17         10-11-07 alex   Y Y Y Y (1)
+x86_64/unknown/openbsd4.7   gcc 3.3.5    17         10-11-07 alex   Y Y Y Y (3)
 
 
 Notes

+ 37 - 0
doc/README-Interix.txt

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

+ 2 - 4
doc/SSL.txt

@@ -49,8 +49,7 @@ Creating a self-signed certificate
 OpenSSL:
 
 Creating a self-signed certificate and key:
- $ openssl req -newkey rsa:2048 -x509 -keyout server-key.pem \
-	-out server-cert.pem -days 1461
+ $ openssl req -newkey rsa:2048 -x509 -keyout server-key.pem -out server-cert.pem -days 1461
 Create DH parameters (optional):
  $ openssl dhparam -2 -out dhparams.pem 2048
 
@@ -58,8 +57,7 @@ GnuTLS:
 
 Creating a self-signed certificate and key:
  $ certtool --generate-privkey --bits 2048 --outfile server-key.pem
- $ certtool --generate-self-signed --load-privkey server-key.pem \
-	 --outfile server-cert.pem
+ $ certtool --generate-self-signed --load-privkey server-key.pem --outfile server-cert.pem
 Create DH parameters (optional):
  $ certtool  --generate-dh-params --bits 2048 --outfile dhparams.pem
 

+ 28 - 9
doc/sample-ngircd.conf

@@ -28,33 +28,39 @@
 	# LINKS requests for example.
 	Info = Server Info Text
 
-	# Global password for all users needed to connect to the server
+	# Global password for all users needed to connect to the server.
+	# (Default: not set)
 	;Password = abc
 
+	# Password required for using the WEBIRC command used by some
+	# Web-to-IRC gateways. If not set/empty, the WEBIRC command can't
+	# be used. (Default: not set)
+	;WebircPassword = xyz
+
 	# Information about the server and the administrator, used by the
 	# ADMIN command. Not required by server but by RFC!
 	;AdminInfo1 = Description
 	;AdminInfo2 = Location
 	;AdminEMail = admin@irc.server
- 
+
 	# Ports on which the server should listen. There may be more than
 	# one port, separated with ",". (Default: 6667)
 	;Ports = 6667, 6668, 6669
 
 	# Additional Listen Ports that expect SSL/TLS encrypted connections
-	;SSLPorts = 9999,6668
+	;SSLPorts = 6697, 9999
 
 	# SSL Server Key
-        ;SSLKeyFile = /usr/local/etc/ngircd/ssl/server-key.pem
+	;SSLKeyFile = :ETCDIR:/ssl/server-key.pem
 
 	# password to decrypt SSLKeyFile (OpenSSL only)
 	;SSLKeyFilePassword = secret
 
 	# SSL Server Key Certificate
-	;SSLCertFile = /usr/local/etc/ngircd/ssl/server-cert.pem
+	;SSLCertFile = :ETCDIR:/ssl/server-cert.pem
 
 	# Diffie-Hellman parameters
-	;SSLDHFile = /usr/local/etc/ngircd/ssl/dhparams.pem
+	;SSLDHFile = :ETCDIR:/ssl/dhparams.pem
 
 	# comma separated list of IP addresses on which the server should
 	# listen. Default values are:
@@ -62,12 +68,18 @@
 	# so the server listens on all IP addresses of the system by default.
 	;Listen = 127.0.0.1,192.168.0.1
 
+	# Syslog "facility" to which ngIRCd should send log messages.
+	# Possible values are system dependant, but most probably auth, daemon,
+	# user and local1 through local7 are possible values; see syslog(3).
+	# Default is "local5" for historical reasons, you probably want to
+	# change this to "daemon", for example.
+	SyslogFacility = local1
+
 	# Text file with the "message of the day" (MOTD). This message will
 	# be shown to all users connecting to the server:
-	;MotdFile = /usr/local/etc/ngircd.motd
+	;MotdFile = :ETCDIR:/ngircd.motd
 
 	# A simple Phrase (<256 chars) if you don't want to use a motd file.
-	# If it is set no MotdFile will be read at all.
 	;MotdPhrase = "Hello world!"
 
 	# User ID under which the server should run; you can use the name
@@ -129,6 +141,13 @@
 	# with support for it.
 	;NoIdent = no
 
+	# Don't use PAM, even if ngIRCd has been compiled with support for it.
+	;NoPAM = no
+
+	# Don't use ZeroConf service registration, even if ngIRCd has been
+	# compiled with support for it (e.g. Howl, Avahi, Mac OS X).
+	;NoZeroConf = no
+
 	# try to connect to other irc servers using ipv4 and ipv6, if possible
 	;ConnectIPv6 = yes
 	;ConnectIPv4 = yes
@@ -251,7 +270,7 @@
 
 	# Key file, syntax for each line: "<user>:<nick>:<key>".
 	# Default: none.
-	;KeyFile = /etc/ngircd/#chan.key
+	;KeyFile = :ETCDIR:/#chan.key
 
 	# maximum users per channel (mode l)
 	;MaxUsers = 23

+ 2 - 2
doc/src/Makefile.in

@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.

+ 120 - 108
install-sh

@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2006-10-14.15
+scriptversion=2006-12-25.00
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -48,7 +48,7 @@ IFS=" ""	$nl"
 # set DOITPROG to echo to test this script
 
 # Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
+doit=${DOITPROG-}
 if test -z "$doit"; then
   doit_exec=exec
 else
@@ -58,34 +58,49 @@ fi
 # Put in absolute file names if you don't have them in your path;
 # or use environment vars.
 
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
 
-posix_glob=
 posix_mkdir=
 
 # Desired mode of installed file.
 mode=0755
 
+chgrpcmd=
 chmodcmd=$chmodprog
 chowncmd=
-chgrpcmd=
-stripcmd=
+mvcmd=$mvprog
 rmcmd="$rmprog -f"
-mvcmd="$mvprog"
+stripcmd=
+
 src=
 dst=
 dir_arg=
-dstarg=
+dst_arg=
+
+copy_on_change=false
 no_target_directory=
 
-usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
    or: $0 [OPTION]... SRCFILES... DIRECTORY
    or: $0 [OPTION]... -t DIRECTORY SRCFILES...
    or: $0 [OPTION]... -d DIRECTORIES...
@@ -95,65 +110,55 @@ In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
 In the 4th, create DIRECTORIES.
 
 Options:
--c         (ignored)
--d         create directories instead of installing files.
--g GROUP   $chgrpprog installed files to GROUP.
--m MODE    $chmodprog installed files to MODE.
--o USER    $chownprog installed files to USER.
--s         $stripprog installed files.
--t DIRECTORY  install into DIRECTORY.
--T         report an error if DSTFILE is a directory.
---help     display this help and exit.
---version  display version info and exit.
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
 
 Environment variables override the default commands:
-  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
 "
 
 while test $# -ne 0; do
   case $1 in
-    -c) shift
-        continue;;
+    -c) ;;
+
+    -C) copy_on_change=true;;
 
-    -d) dir_arg=true
-        shift
-        continue;;
+    -d) dir_arg=true;;
 
     -g) chgrpcmd="$chgrpprog $2"
-        shift
-        shift
-        continue;;
+	shift;;
 
     --help) echo "$usage"; exit $?;;
 
     -m) mode=$2
-        shift
-        shift
 	case $mode in
 	  *' '* | *'	'* | *'
 '*	  | *'*'* | *'?'* | *'['*)
 	    echo "$0: invalid mode: $mode" >&2
 	    exit 1;;
 	esac
-        continue;;
+	shift;;
 
     -o) chowncmd="$chownprog $2"
-        shift
-        shift
-        continue;;
+	shift;;
 
-    -s) stripcmd=$stripprog
-        shift
-        continue;;
+    -s) stripcmd=$stripprog;;
 
-    -t) dstarg=$2
-	shift
-	shift
-	continue;;
+    -t) dst_arg=$2
+	shift;;
 
-    -T) no_target_directory=true
-	shift
-	continue;;
+    -T) no_target_directory=true;;
 
     --version) echo "$0 $scriptversion"; exit $?;;
 
@@ -165,21 +170,22 @@ while test $# -ne 0; do
 
     *)  break;;
   esac
+  shift
 done
 
-if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
   # When -d is used, all remaining arguments are directories to create.
   # When -t is used, the destination is already specified.
   # Otherwise, the last argument is the destination.  Remove it from $@.
   for arg
   do
-    if test -n "$dstarg"; then
+    if test -n "$dst_arg"; then
       # $@ is not empty: it contains at least $arg.
-      set fnord "$@" "$dstarg"
+      set fnord "$@" "$dst_arg"
       shift # fnord
     fi
     shift # arg
-    dstarg=$arg
+    dst_arg=$arg
   done
 fi
 
@@ -224,7 +230,7 @@ for src
 do
   # Protect names starting with `-'.
   case $src in
-    -*) src=./$src ;;
+    -*) src=./$src;;
   esac
 
   if test -n "$dir_arg"; then
@@ -242,22 +248,22 @@ do
       exit 1
     fi
 
-    if test -z "$dstarg"; then
+    if test -z "$dst_arg"; then
       echo "$0: no destination specified." >&2
       exit 1
     fi
 
-    dst=$dstarg
+    dst=$dst_arg
     # Protect names starting with `-'.
     case $dst in
-      -*) dst=./$dst ;;
+      -*) dst=./$dst;;
     esac
 
     # If destination is a directory, append the input filename; won't work
     # if double slashes aren't ignored.
     if test -d "$dst"; then
       if test -n "$no_target_directory"; then
-	echo "$0: $dstarg: Is a directory" >&2
+	echo "$0: $dst_arg: Is a directory" >&2
 	exit 1
       fi
       dstdir=$dst
@@ -378,26 +384,19 @@ do
       # directory the slow way, step by step, checking for races as we go.
 
       case $dstdir in
-	/*) prefix=/ ;;
-	-*) prefix=./ ;;
-	*)  prefix= ;;
+	/*) prefix='/';;
+	-*) prefix='./';;
+	*)  prefix='';;
       esac
 
-      case $posix_glob in
-        '')
-	  if (set -f) 2>/dev/null; then
-	    posix_glob=true
-	  else
-	    posix_glob=false
-	  fi ;;
-      esac
+      eval "$initialize_posix_glob"
 
       oIFS=$IFS
       IFS=/
-      $posix_glob && set -f
+      $posix_glob set -f
       set fnord $dstdir
       shift
-      $posix_glob && set +f
+      $posix_glob set +f
       IFS=$oIFS
 
       prefixes=
@@ -459,41 +458,54 @@ do
     # ignore errors from any of these, just make sure not to ignore
     # errors from the above "$doit $cpprog $src $dsttmp" command.
     #
-    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
-      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
-      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
-      && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
-
-    # Now rename the file to the real destination.
-    { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
-      || {
-	   # The rename failed, perhaps because mv can't rename something else
-	   # to itself, or perhaps because mv is so ancient that it does not
-	   # support -f.
-
-	   # Now remove or move aside any old file at destination location.
-	   # We try this two ways since rm can't unlink itself on some
-	   # systems and the destination file might be busy for other
-	   # reasons.  In this case, the final cleanup might fail but the new
-	   # file should still install successfully.
-	   {
-	     if test -f "$dst"; then
-	       $doit $rmcmd -f "$dst" 2>/dev/null \
-	       || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
-		     && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
-	       || {
-		 echo "$0: cannot unlink or rename $dst" >&2
-		 (exit 1); exit 1
-	       }
-	     else
-	       :
-	     fi
-	   } &&
-
-	   # Now rename the file to the real destination.
-	   $doit $mvcmd "$dsttmp" "$dst"
-	 }
-    } || exit 1
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
 
     trap '' 0
   fi

+ 2 - 2
man/Makefile.in

@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.

+ 15 - 8
man/ngircd.8.tmpl

@@ -1,7 +1,7 @@
 .\"
 .\" ngircd(8) manual page template
 .\"
-.TH ngircd 8 "Dec 2008" ngircd "ngIRCd Manual"
+.TH ngircd 8 "Dec 2010" ngircd "ngIRCd Manual"
 .SH NAME
 ngIRCd \- the next generation IRC daemon
 .SH SYNOPSIS
@@ -64,17 +64,24 @@ The system wide default configuration file.
 .RS
 Default "message of the day" (MOTD).
 .RE
+.SH SIGNALS
+The daemon understands the following signals:
+.TP
+\fBTERM\fR
+Shut down all conections and terminate the daemon.
+.TP
+\fBHUP\fR
+Shut down all listening sockets, re-read the configuration file and
+re-initialize the daemon.
 .SH HINTS
 It's wise to use "ngircd \-\-configtest" to validate the configuration file
 after changing it.
-.SH AUTHOR
-Alexander Barton,
-.UR mailto:alex@barton.de
-.UE
+.SH AUTHORS
+Alexander Barton, <alex@barton.de>
 .br
-Homepage:
-.UR http://ngircd.barton.de/
-.UE
+Florian Westphal, <fw@strlen.de>
+.PP
+Homepage: http://ngircd.barton.de/
 .SH "SEE ALSO"
 .BR ngircd.conf (5),
 .BR ircd (8)

+ 35 - 10
man/ngircd.conf.5.tmpl

@@ -1,7 +1,7 @@
 .\"
 .\" ngircd.conf(5) manual page template
 .\"
-.TH ngircd.conf 5 "Dec 2008" ngircd "ngIRCd Manual"
+.TH ngircd.conf 5 "Dec 2010" ngircd "ngIRCd Manual"
 .SH NAME
 ngircd.conf \- configuration file of ngIRCd
 .SH SYNOPSIS
@@ -69,6 +69,15 @@ IRC network and must contain at least one dot (".") character.
 Info text of the server. This will be shown by WHOIS and LINKS requests for
 example.
 .TP
+\fBPassword\fR
+Global password for all users needed to connect to the server. The default
+is empty, so no password is required.
+.TP
+\fBWebircPassword\fR
+Password required for using the WEBIRC command used by some Web-to-IRC
+gateways. If not set or empty, the WEBIRC command can't be used.
+Default: not set.
+.TP
 \fBAdminInfo1\fR, \fBAdminInfo2\fR, \fBAdminEMail\fR
 Information about the server and the administrator, used by the ADMIN
 command.
@@ -107,14 +116,20 @@ If unset, the defaults value is "0.0.0.0" or, if ngIRCd was compiled
 with IPv6 support, "::,0.0.0.0". So the server listens on all configured
 IP addresses and interfaces by default.
 .TP
+\fBSyslogFacility\fR
+Syslog "facility" to which ngIRCd should send log messages. Possible
+values are system dependant, but most probably "auth", "daemon", "user"
+and "local1" through "local7" are possible values; see syslog(3).
+Default is "local5" for historical reasons, you probably want to
+change this to "daemon", for example.
+.TP
 \fBMotdFile\fR
 Text file with the "message of the day" (MOTD). This message will be shown
-to all users connecting to the server.
+to all users connecting to the server. Changes made to this file
+take effect when ngircd is instructed to re-read its configuration file.
 .TP
 \fBMotdPhrase\fR
 A simple Phrase (<256 chars) if you don't want to use a MOTD file.
-If this variable is set, no \fBMotdFile\fR will be read at all which can be
-handy if the daemon should run inside a chroot directory.
 .TP
 \fBServerUID\fR
 User ID under which the server should run; you can use the name of the user
@@ -201,6 +216,18 @@ If ngIRCd is compiled with IDENT support this can be used to disable IDENT
 lookups at run time.
 Default: no.
 .TP
+\fBNoPAM\fR
+If ngIRCd is compiled with PAM support this can be used to disable all calls
+to the PAM library at runtime; all users connecting without password are
+allowed to connect, all passwords given will fail.
+Default: no.
+.TP
+\fBNoZeroConf\fR
+If ngIRCd is compiled to register its services using ZeroConf (e.g. using
+Howl, Avahi or on Mac OS X) this parameter can be used to disable service
+registration at runtime.
+Default: no.
+.TP
 \fBConnectIPv4\fR
 Set this to no if you do not want ngIRCd to connect to other IRC servers using
 IPv4. This allows usage of ngIRCd in IPv6-only setups.
@@ -379,13 +406,11 @@ after changing it. See
 .BR ngircd (8)
 for details.
 .SH AUTHOR
-Alexander Barton,
-.UR mailto:alex@barton.de
-.UE
+Alexander Barton, <alex@barton.de>
 .br
-Homepage:
-.UR http://ngircd.barton.de/
-.UE
+Florian Westphal, <fw@strlen.de>
+.PP
+Homepage: http://ngircd.barton.de/
 .SH "SEE ALSO"
 .BR ngircd (8)
 .\"

BIN
src/._Makefile.am


+ 8 - 9
src/Makefile.in

@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -296,8 +296,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	mkid -fID $$unique
 tags: TAGS
 
@@ -322,8 +322,8 @@ TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
 	  test -n "$$unique" || unique=$$empty_fix; \
 	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -333,13 +333,12 @@ ctags: CTAGS
 CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
 	tags=; \
-	here=`pwd`; \
 	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	test -z "$(CTAGS_ARGS)$$tags$$unique" \
 	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
 	     $$tags $$unique

+ 23 - 2
src/config.h.in

@@ -91,8 +91,8 @@
 /* Define to 1 if you have the `ident' library (-lident). */
 #undef HAVE_LIBIDENT
 
-/* Define to 1 if you have the `nsl' library (-lnsl). */
-#undef HAVE_LIBNSL
+/* Define to 1 if you have the `pam' library (-lpam). */
+#undef HAVE_LIBPAM
 
 /* Define to 1 if you have the `pthread' library (-lpthread). */
 #undef HAVE_LIBPTHREAD
@@ -127,12 +127,27 @@
 /* Define to 1 if you have the <netinet/in.h> header file. */
 #undef HAVE_NETINET_IN_H
 
+/* Define to 1 if you have the <netinet/in_systm.h> header file. */
+#undef HAVE_NETINET_IN_SYSTM_H
+
+/* Define to 1 if you have the <netinet/ip.h> header file. */
+#undef HAVE_NETINET_IP_H
+
+/* Define to 1 if you have the `pam_authenticate' function. */
+#undef HAVE_PAM_AUTHENTICATE
+
+/* Define to 1 if you have the <pam/pam_appl.h> header file. */
+#undef HAVE_PAM_PAM_APPL_H
+
 /* Define to 1 if you have the `poll' function. */
 #undef HAVE_POLL
 
 /* Define to 1 if you have the <rendezvous/rendezvous.h> header file. */
 #undef HAVE_RENDEZVOUS_RENDEZVOUS_H
 
+/* Define to 1 if you have the <security/pam_appl.h> header file. */
+#undef HAVE_SECURITY_PAM_APPL_H
+
 /* Define to 1 if you have the `select' function. */
 #undef HAVE_SELECT
 
@@ -145,6 +160,9 @@
 /* Define to 1 if you have the `sigaction' function. */
 #undef HAVE_SIGACTION
 
+/* Define to 1 if you have the `sigprocmask' function. */
+#undef HAVE_SIGPROCMASK
+
 /* Define to 1 if you have the `snprintf' function. */
 #undef HAVE_SNPRINTF
 
@@ -274,6 +292,9 @@
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
 
+/* Define if PAM should be used */
+#undef PAM
+
 /* Define to 1 if the C compiler supports function prototypes. */
 #undef PROTOTYPES
 

+ 9 - 10
src/ipaddr/Makefile.in

@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -52,7 +52,7 @@ libngipaddr_a_AR = $(AR) $(ARFLAGS)
 libngipaddr_a_LIBADD =
 am_libngipaddr_a_OBJECTS = ng_ipaddr$U.$(OBJEXT)
 libngipaddr_a_OBJECTS = $(am_libngipaddr_a_OBJECTS)
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/src@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -249,8 +249,8 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	mkid -fID $$unique
 tags: TAGS
 
@@ -262,8 +262,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
 	  test -n "$$unique" || unique=$$empty_fix; \
 	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -273,13 +273,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
 	tags=; \
-	here=`pwd`; \
 	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	test -z "$(CTAGS_ARGS)$$tags$$unique" \
 	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
 	     $$tags $$unique

+ 6 - 2
src/ipaddr/ng_ipaddr.h

@@ -8,6 +8,7 @@
 #define NG_IPADDR_HDR
 #include "portab.h"
 
+#include <assert.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 
@@ -102,8 +103,11 @@ GLOBAL const char *ng_ipaddr_tostr PARAMS((const ng_ipaddr_t *addr));
 /* convert struct sockaddr to string. dest must be NG_INET_ADDRSTRLEN bytes long */
 GLOBAL bool ng_ipaddr_tostr_r PARAMS((const ng_ipaddr_t *addr, char *dest));
 #else
-static inline const char *
-ng_ipaddr_tostr(const ng_ipaddr_t *addr) { return inet_ntoa(addr->sin4.sin_addr); }
+static inline const char*
+ng_ipaddr_tostr(const ng_ipaddr_t *addr)
+{
+	return inet_ntoa(addr->sin4.sin_addr);
+}
 
 static inline bool
 ng_ipaddr_tostr_r(const ng_ipaddr_t *addr, char *d)

BIN
src/ngircd/._client.h


BIN
src/ngircd/._conn-func.c


BIN
src/ngircd/._irc-channel.c


BIN
src/ngircd/._irc-op.c


BIN
src/ngircd/._irc-op.h


BIN
src/ngircd/._irc.c


BIN
src/ngircd/._irc.h


BIN
src/ngircd/._log.h


BIN
src/ngircd/._parse.h


+ 4 - 6
src/ngircd/Makefile.am

@@ -1,6 +1,6 @@
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
+# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -8,8 +8,6 @@
 # (at your option) any later version.
 # Please read the file COPYING, README and AUTHORS for more information.
 #
-# $Id: Makefile.am,v 1.51 2008/02/26 22:04:17 fw Exp $
-#
 
 AUTOMAKE_OPTIONS = ../portab/ansi2knr
 
@@ -23,7 +21,7 @@ sbin_PROGRAMS = ngircd
 ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.c \
 	conn-ssl.c conn-zip.c hash.c io.c irc.c irc-channel.c irc-info.c irc-login.c \
 	irc-mode.c irc-op.c irc-oper.c irc-server.c irc-write.c lists.c log.c \
-	match.c op.c numeric.c parse.c rendezvous.c resolve.c
+	match.c op.c numeric.c pam.c parse.c proc.c rendezvous.c resolve.c sighandlers.c
 
 ngircd_LDFLAGS = -L../portab -L../tool -L../ipaddr
 
@@ -32,8 +30,8 @@ ngircd_LDADD = -lngportab -lngtool -lngipaddr
 noinst_HEADERS = ngircd.h array.h channel.h client.h conf.h conf-ssl.h conn.h \
 	conn-func.h conn-ssl.h conn-zip.h hash.h io.h irc.h irc-channel.h \
 	irc-info.h irc-login.h irc-mode.h irc-op.h irc-oper.h irc-server.h \
-	irc-write.h lists.h log.h match.h numeric.h op.h parse.h rendezvous.h \
-	resolve.h defines.h messages.h
+	irc-write.h lists.h log.h match.h numeric.h op.h pam.h parse.h proc.h \
+	rendezvous.h resolve.h sighandlers.h defines.h messages.h
 
 clean-local:
 	rm -f check-version check-help lint.out

+ 28 - 19
src/ngircd/Makefile.in

@@ -1,8 +1,8 @@
-# Makefile.in generated by automake 1.10 from Makefile.am.
+# Makefile.in generated by automake 1.10.1 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008  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.
@@ -16,7 +16,7 @@
 
 #
 # ngIRCd -- The Next Generation IRC Daemon
-# Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
+# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -24,8 +24,6 @@
 # (at your option) any later version.
 # Please read the file COPYING, README and AUTHORS for more information.
 #
-# $Id: Makefile.am,v 1.51 2008/02/26 22:04:17 fw Exp $
-#
 
 
 VPATH = @srcdir@
@@ -71,12 +69,14 @@ am_ngircd_OBJECTS = ngircd$U.$(OBJEXT) array$U.$(OBJEXT) \
 	irc-oper$U.$(OBJEXT) irc-server$U.$(OBJEXT) \
 	irc-write$U.$(OBJEXT) lists$U.$(OBJEXT) log$U.$(OBJEXT) \
 	match$U.$(OBJEXT) op$U.$(OBJEXT) numeric$U.$(OBJEXT) \
-	parse$U.$(OBJEXT) rendezvous$U.$(OBJEXT) resolve$U.$(OBJEXT)
+	pam$U.$(OBJEXT) parse$U.$(OBJEXT) proc$U.$(OBJEXT) \
+	rendezvous$U.$(OBJEXT) resolve$U.$(OBJEXT) \
+	sighandlers$U.$(OBJEXT)
 ngircd_OBJECTS = $(am_ngircd_OBJECTS)
 ngircd_DEPENDENCIES =
 ngircd_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(ngircd_LDFLAGS) \
 	$(LDFLAGS) -o $@
-DEFAULT_INCLUDES = -I. -I$(top_builddir)/src@am__isrc@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
@@ -196,15 +196,15 @@ LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN \
 ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.c \
 	conn-ssl.c conn-zip.c hash.c io.c irc.c irc-channel.c irc-info.c irc-login.c \
 	irc-mode.c irc-op.c irc-oper.c irc-server.c irc-write.c lists.c log.c \
-	match.c op.c numeric.c parse.c rendezvous.c resolve.c
+	match.c op.c numeric.c pam.c parse.c proc.c rendezvous.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 client.h conf.h conf-ssl.h conn.h \
 	conn-func.h conn-ssl.h conn-zip.h hash.h io.h irc.h irc-channel.h \
 	irc-info.h irc-login.h irc-mode.h irc-op.h irc-oper.h irc-server.h \
-	irc-write.h lists.h log.h match.h numeric.h op.h parse.h rendezvous.h \
-	resolve.h defines.h messages.h
+	irc-write.h lists.h log.h match.h numeric.h op.h pam.h parse.h proc.h \
+	rendezvous.h resolve.h sighandlers.h defines.h messages.h
 
 TESTS = check-version check-help
 all: all-am
@@ -303,9 +303,12 @@ mostlyclean-kr:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ngircd$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/numeric$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/op$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proc$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rendezvous$U.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resolve$U.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sighandlers$U.Po@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -370,12 +373,18 @@ numeric_.c: numeric.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/numeric.c; then echo $(srcdir)/numeric.c; else echo numeric.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 op_.c: op.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/op.c; then echo $(srcdir)/op.c; else echo op.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+pam_.c: pam.c $(ANSI2KNR)
+	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/pam.c; then echo $(srcdir)/pam.c; else echo pam.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 parse_.c: parse.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/parse.c; then echo $(srcdir)/parse.c; else echo parse.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+proc_.c: proc.c $(ANSI2KNR)
+	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/proc.c; then echo $(srcdir)/proc.c; else echo proc.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 rendezvous_.c: rendezvous.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/rendezvous.c; then echo $(srcdir)/rendezvous.c; else echo rendezvous.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
 resolve_.c: resolve.c $(ANSI2KNR)
 	$(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) `if test -f $(srcdir)/resolve.c; then echo $(srcdir)/resolve.c; else echo resolve.c; fi` | sed 's/^# \([0-9]\)/#line \1/' | $(ANSI2KNR) > $@ || rm -f $@
+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 $@
 array_.$(OBJEXT) channel_.$(OBJEXT) client_.$(OBJEXT) conf_.$(OBJEXT) \
 conn_.$(OBJEXT) conn-func_.$(OBJEXT) conn-ssl_.$(OBJEXT) \
 conn-zip_.$(OBJEXT) hash_.$(OBJEXT) io_.$(OBJEXT) irc_.$(OBJEXT) \
@@ -383,16 +392,17 @@ irc-channel_.$(OBJEXT) irc-info_.$(OBJEXT) irc-login_.$(OBJEXT) \
 irc-mode_.$(OBJEXT) irc-op_.$(OBJEXT) irc-oper_.$(OBJEXT) \
 irc-server_.$(OBJEXT) irc-write_.$(OBJEXT) lists_.$(OBJEXT) \
 log_.$(OBJEXT) match_.$(OBJEXT) ngircd_.$(OBJEXT) numeric_.$(OBJEXT) \
-op_.$(OBJEXT) parse_.$(OBJEXT) rendezvous_.$(OBJEXT) \
-resolve_.$(OBJEXT) : $(ANSI2KNR)
+op_.$(OBJEXT) pam_.$(OBJEXT) parse_.$(OBJEXT) proc_.$(OBJEXT) \
+rendezvous_.$(OBJEXT) resolve_.$(OBJEXT) sighandlers_.$(OBJEXT) : \
+$(ANSI2KNR)
 
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	mkid -fID $$unique
 tags: TAGS
 
@@ -404,8 +414,8 @@ TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
 	  test -n "$$unique" || unique=$$empty_fix; \
 	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
@@ -415,13 +425,12 @@ ctags: CTAGS
 CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
 		$(TAGS_FILES) $(LISP)
 	tags=; \
-	here=`pwd`; \
 	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
 	unique=`for i in $$list; do \
 	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
 	  done | \
-	  $(AWK) '    { files[$$0] = 1; } \
-	       END { for (i in files) print i; }'`; \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
 	test -z "$(CTAGS_ARGS)$$tags$$unique" \
 	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
 	     $$tags $$unique

+ 11 - 2
src/ngircd/channel.c

@@ -27,14 +27,12 @@
 
 #include "defines.h"
 #include "conn-func.h"
-#include "client.h"
 
 #include "exp.h"
 #include "channel.h"
 
 #include "imp.h"
 #include "irc-write.h"
-#include "resolve.h"
 #include "conf.h"
 #include "hash.h"
 #include "lists.h"
@@ -699,6 +697,14 @@ Channel_TopicWho(CHANNEL *Chan)
 	return Chan->topic_who;
 } /* Channel_TopicWho */
 
+
+GLOBAL unsigned int
+Channel_CreationTime(CHANNEL *Chan)
+{
+	assert(Chan != NULL);
+	return (unsigned int) Chan->creation_time;
+} /* Channel_CreationTime */
+
 #endif
 
 
@@ -836,6 +842,9 @@ Channel_Create( const char *Name )
 	strlcpy( c->name, Name, sizeof( c->name ));
 	c->hash = Hash( c->name );
 	c->next = My_Channels;
+#ifndef STRICT_RFC
+	c->creation_time = time(NULL);
+#endif
 	My_Channels = c;
 	LogDebug("Created new channel structure for \"%s\".", Name);
 	return c;

+ 2 - 0
src/ngircd/channel.h

@@ -30,6 +30,7 @@ typedef struct _CHANNEL
 	char modes[CHANNEL_MODE_LEN];	/* Channel modes */
 	array topic;			/* Topic of the channel */
 #ifndef STRICT_RFC
+	time_t creation_time;		/* Channel creation time */
 	time_t topic_time;		/* Time when topic was set */
 	char topic_who[CLIENT_NICK_LEN];/* Nickname of user that set topic */
 #endif
@@ -118,6 +119,7 @@ GLOBAL CHANNEL *Channel_Create PARAMS(( const char *Name ));
 #ifndef STRICT_RFC
 GLOBAL unsigned int Channel_TopicTime PARAMS(( CHANNEL *Chan ));
 GLOBAL char *Channel_TopicWho PARAMS(( CHANNEL *Chan ));
+GLOBAL unsigned int Channel_CreationTime PARAMS(( CHANNEL *Chan ));
 #endif
 
 GLOBAL bool Channel_AddInvite PARAMS((CHANNEL *c, const char *Mask, bool OnlyOnce ));

+ 162 - 29
src/ngircd/client.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -35,7 +35,6 @@
 #include <imp.h>
 #include "ngircd.h"
 #include "channel.h"
-#include "resolve.h"
 #include "conf.h"
 #include "hash.h"
 #include "irc-write.h"
@@ -181,39 +180,48 @@ Client_NewRemoteUser(CLIENT *Introducer, const char *Nick, int Hops, const char
  */
 static CLIENT *
 Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer,
- int Type, const char *ID, const char *User, const char *Hostname, const char *Info, int Hops,
- int Token, const char *Modes, bool Idented)
+  int Type, const char *ID, const char *User, const char *Hostname,
+  const char *Info, int Hops, int Token, const char *Modes, bool Idented)
 {
 	CLIENT *client;
 
-	assert( Idx >= NONE );
-	assert( Introducer != NULL );
-	assert( Hostname != NULL );
+	assert(Idx >= NONE);
+	assert(Introducer != NULL);
+	assert(Hostname != NULL);
 
-	client = New_Client_Struct( );
-	if( ! client ) return NULL;
+	client = New_Client_Struct();
+	if (!client)
+		return NULL;
 
 	client->starttime = time(NULL);
 	client->conn_id = Idx;
 	client->introducer = Introducer;
 	client->topserver = TopServer;
 	client->type = Type;
-	if( ID ) Client_SetID( client, ID );
-	if( User ) Client_SetUser( client, User, Idented );
-	if( Hostname ) Client_SetHostname( client, Hostname );
-	if( Info ) Client_SetInfo( client, Info );
+	if (ID)
+		Client_SetID(client, ID);
+	if (User) {
+		Client_SetUser(client, User, Idented);
+		Client_SetOrigUser(client, User);
+	}
+	if (Hostname)
+		Client_SetHostname(client, Hostname);
+	if (Info)
+		Client_SetInfo(client, Info);
 	client->hops = Hops;
 	client->token = Token;
-	if( Modes ) Client_SetModes( client, Modes );
-	if( Type == CLIENT_SERVER ) Generate_MyToken( client );
+	if (Modes)
+		Client_SetModes(client, Modes);
+	if (Type == CLIENT_SERVER)
+		Generate_MyToken(client);
 
-	if( strchr( client->modes, 'a' ))
-		strlcpy( client->away, DEFAULT_AWAY_MSG, sizeof( client->away ));
+	if (strchr(client->modes, 'a'))
+		strlcpy(client->away, DEFAULT_AWAY_MSG, sizeof(client->away));
 
 	client->next = (POINTER *)My_Clients;
 	My_Clients = client;
 
-	Adjust_Counters( client );
+	Adjust_Counters(client);
 
 	return client;
 } /* Init_New_Client */
@@ -346,6 +354,26 @@ Client_SetUser( CLIENT *Client, const char *User, bool Idented )
 } /* Client_SetUser */
 
 
+/**
+ * Set "original" user name of a client.
+ * This function saves the "original" user name, the user name specified by
+ * the peer using the USER command, into the CLIENT structure. This user
+ * name may be used for authentication, for example.
+ * @param Client The client.
+ * @param User User name to set.
+ */
+GLOBAL void
+Client_SetOrigUser(CLIENT UNUSED *Client, const char UNUSED *User)
+{
+	assert(Client != NULL);
+	assert(User != NULL);
+
+#if defined(PAM) && defined(IDENTAUTH)
+	strlcpy(Client->orig_user, User, sizeof(Client->orig_user));
+#endif
+} /* Client_SetOrigUser */
+
+
 GLOBAL void
 Client_SetInfo( CLIENT *Client, const char *Info )
 {
@@ -595,14 +623,61 @@ Client_User( CLIENT *Client )
 } /* Client_User */
 
 
+#ifdef PAM
+
+/**
+ * Get the "original" user name as supplied by the USER command.
+ * The user name as given by the client is used for authentication instead
+ * of the one detected using IDENT requests.
+ * @param Client The client.
+ * @return Original user name.
+ */
+GLOBAL char *
+Client_OrigUser(CLIENT *Client) {
+#ifndef IDENTAUTH
+	char *user = Client->user;
+
+	if (user[0] == '~')
+		user++;
+	return user;
+#else
+	return Client->orig_user;
+#endif
+} /* Client_OrigUser */
+
+#endif
+
+
+/**
+ * Return the hostname of a client.
+ * @param Client Pointer to client structure
+ * @return Pointer to client hostname
+ */
 GLOBAL char *
-Client_Hostname( CLIENT *Client )
+Client_Hostname(CLIENT *Client)
 {
-	assert( Client != NULL );
+	assert (Client != NULL);
 	return Client->host;
 } /* Client_Hostname */
 
 
+/**
+ * Get potentially cloaked hostname of a client.
+ * If the client has not enabled cloaking, the real hostname is used.
+ * @param Client Pointer to client structure
+ * @return Pointer to client hostname
+ */
+GLOBAL char *
+Client_HostnameCloaked(CLIENT *Client)
+{
+	assert(Client != NULL);
+	if (Client_HasMode(Client, 'x'))
+		return Client_ID(Client->introducer);
+	else
+		return Client_Hostname(Client);
+} /* Client_HostnameCloaked */
+
+
 GLOBAL char *
 Client_Password( CLIENT *Client )
 {
@@ -675,23 +750,56 @@ Client_NextHop( CLIENT *Client )
 
 
 /**
- * return Client-ID ("client!user@host"), this ID is needed for e.g.
- * prefixes.  Returnes pointer to static buffer.
+ * Return ID of a client: "client!user@host"
+ * This client ID is used for IRC prefixes, for example.
+ * Please note that this function uses a global static buffer, so you can't
+ * nest invocations without overwriting erlier results!
+ * @param Client Pointer to client structure
+ * @return Pointer to global buffer containing the client ID
  */
 GLOBAL char *
 Client_Mask( CLIENT *Client )
 {
-	static char GetID_Buffer[GETID_LEN];
+	static char Mask_Buffer[GETID_LEN];
 
-	assert( Client != NULL );
+	assert (Client != NULL);
 
-	if( Client->type == CLIENT_SERVER ) return Client->id;
+	/* Servers: return name only, there is no "mask" */
+	if (Client->type == CLIENT_SERVER)
+		return Client->id;
 
-	snprintf(GetID_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user, Client->host);
-	return GetID_Buffer;
+	snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s",
+		 Client->id, Client->user, Client->host);
+	return Mask_Buffer;
 } /* Client_Mask */
 
 
+/**
+ * Return ID of a client with cloaked hostname: "client!user@server-name"
+ * This client ID is used for IRC prefixes, for example.
+ * Please note that this function uses a global static buffer, so you can't
+ * nest invocations without overwriting erlier results!
+ * If the client has not enabled cloaking, the real hostname is used.
+ * @param Client Pointer to client structure
+ * @return Pointer to global buffer containing the client ID
+ */
+GLOBAL char *
+Client_MaskCloaked(CLIENT *Client)
+{
+	static char Mask_Buffer[GETID_LEN];
+
+	assert (Client != NULL);
+
+	/* Is the client using cloaking at all? */
+	if (!Client_HasMode(Client, 'x'))
+	    return Client_Mask(Client);
+
+	snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s",
+		 Client->id, Client->user, Client_ID(Client->introducer));
+	return Mask_Buffer;
+} /* Client_MaskCloaked */
+
+
 GLOBAL CLIENT *
 Client_Introducer( CLIENT *Client )
 {
@@ -1086,7 +1194,7 @@ Client_RegisterWhowas( CLIENT *Client )
 		 sizeof( My_Whowas[slot].id ));
 	strlcpy( My_Whowas[slot].user, Client_User( Client ),
 		 sizeof( My_Whowas[slot].user ));
-	strlcpy( My_Whowas[slot].host, Client_Hostname( Client ),
+	strlcpy( My_Whowas[slot].host, Client_HostnameCloaked( Client ),
 		 sizeof( My_Whowas[slot].host ));
 	strlcpy( My_Whowas[slot].info, Client_Info( Client ),
 		 sizeof( My_Whowas[slot].info ));
@@ -1097,7 +1205,7 @@ Client_RegisterWhowas( CLIENT *Client )
 } /* Client_RegisterWhowas */
 
 
-GLOBAL char *
+GLOBAL const char *
 Client_TypeText(CLIENT *Client)
 {
 	assert(Client != NULL);
@@ -1129,6 +1237,9 @@ Destroy_UserOrService(CLIENT *Client, const char *Txt, const char *FwdMsg, bool
 		    "%s \"%s\" unregistered (connection %d): %s",
 		    Client_TypeText(Client), Client_Mask(Client),
 		    Client->conn_id, Txt);
+		Log_ServerNotice('c', "Client exiting: %s (%s@%s) [%s]",
+			         Client_ID(Client), Client_User(Client),
+				 Client_Hostname(Client), Txt);
 
 		if (SendQuit) {
 			/* Inforam all the other servers */
@@ -1164,4 +1275,26 @@ Destroy_UserOrService(CLIENT *Client, const char *Txt, const char *FwdMsg, bool
 } /* Destroy_UserOrService */
 
 
+#ifdef DEBUG
+
+GLOBAL void
+Client_DebugDump(void)
+{
+	CLIENT *c;
+
+	Log(LOG_DEBUG, "Client status:");
+	c = My_Clients;
+	while (c) {
+		Log(LOG_DEBUG,
+		    " - %s: type=%d, host=%s, user=%s, conn=%d, start=%ld, flags=%s",
+                   Client_ID(c), Client_Type(c), Client_Hostname(c),
+                   Client_User(c), Client_Conn(c), Client_StartTime(c),
+                   Client_Flags(c));
+		c = (CLIENT *)c->next;
+	}
+} /* Client_DumpClients */
+
+#endif
+
+
 /* -eof- */

+ 16 - 1
src/ngircd/client.h

@@ -43,6 +43,9 @@ typedef struct _CLIENT
 	char pwd[CLIENT_PASS_LEN];	/* password received of the client */
 	char host[CLIENT_HOST_LEN];	/* hostname of the client */
 	char user[CLIENT_USER_LEN];	/* user name ("login") */
+#if defined(PAM) && defined(IDENTAUTH)
+	char orig_user[CLIENT_USER_LEN];/* user name supplied by USER command */
+#endif
 	char info[CLIENT_INFO_LEN];	/* long user name (user) / info text (server) */
 	char modes[CLIENT_MODE_LEN];	/* client modes */
 	int hops, token, mytoken;	/* "hops" and "Token" (see SERVER command) */
@@ -90,9 +93,14 @@ GLOBAL int Client_Type PARAMS(( CLIENT *Client ));
 GLOBAL CONN_ID Client_Conn PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_ID PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_Mask PARAMS(( CLIENT *Client ));
+GLOBAL char *Client_MaskCloaked PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_Info PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_User PARAMS(( CLIENT *Client ));
+#ifdef PAM
+GLOBAL char *Client_OrigUser PARAMS(( CLIENT *Client ));
+#endif
 GLOBAL char *Client_Hostname PARAMS(( CLIENT *Client ));
+GLOBAL char *Client_HostnameCloaked PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_Password PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_Modes PARAMS(( CLIENT *Client ));
 GLOBAL char *Client_Flags PARAMS(( CLIENT *Client ));
@@ -111,6 +119,7 @@ GLOBAL bool Client_HasMode PARAMS(( CLIENT *Client, char Mode ));
 GLOBAL void Client_SetHostname PARAMS(( CLIENT *Client, const char *Hostname ));
 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_SetOrigUser PARAMS(( CLIENT *Client, const char *User ));
 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 ));
@@ -146,8 +155,14 @@ GLOBAL int Client_GetLastWhowasIndex PARAMS(( void ));
 
 GLOBAL void Client_RegisterWhowas PARAMS(( CLIENT *Client ));
 
-GLOBAL char * Client_TypeText PARAMS((CLIENT *Client));
+GLOBAL const char *Client_TypeText PARAMS((CLIENT *Client));
+
+#ifdef DEBUG
+GLOBAL void Client_DebugDump PARAMS((void));
+#endif
+
 
 #endif
 
+
 /* -eof- */

+ 2 - 1
src/ngircd/conf-ssl.h

@@ -39,7 +39,8 @@ bool
 ConnSSL_InitLibrary(void);
 #else
 static inline bool
-ConnSSL_InitLibrary(void) { return true; }
+ConnSSL_InitLibrary(void)
+{ return true; }
 #endif /* SSL_SUPPORT */
 
 #endif /* conf_ssl_h */

+ 202 - 61
src/ngircd/conf.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2009 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -39,23 +39,24 @@
 #include "array.h"
 #include "ngircd.h"
 #include "conn.h"
-#include "client.h"
 #include "channel.h"
 #include "defines.h"
 #include "log.h"
 #include "match.h"
-#include "resolve.h"
 #include "tool.h"
 
 #include "exp.h"
 #include "conf.h"
 
 
-static bool Use_Log = true;
+static bool Use_Log = true, Using_MotdFile = true;
 static CONF_SERVER New_Server;
 static int New_Server_Idx;
 
+static size_t Conf_Oper_Count;
 static size_t Conf_Channel_Count;
+static char Conf_MotdFile[FNAME_LEN];
+
 static void Set_Defaults PARAMS(( bool InitServers ));
 static bool Read_Config PARAMS(( bool ngircd_starting ));
 static bool Validate_Config PARAMS(( bool TestOnly, bool Rehash ));
@@ -226,6 +227,41 @@ yesno_to_str(int boolean_value)
 }
 
 
+static void
+opers_free(void)
+{
+	struct Conf_Oper *op;
+	size_t len;
+	
+	len = array_length(&Conf_Opers, sizeof(*op));
+	op = array_start(&Conf_Opers);
+	while (len--) {
+		free(op->mask);
+		op++;
+	}
+	array_free(&Conf_Opers);
+}
+
+static void
+opers_puts(void)
+{
+	struct Conf_Oper *op;
+	size_t len;
+	
+	len = array_length(&Conf_Opers, sizeof(*op));
+	op = array_start(&Conf_Opers);
+	while (len--) {
+		assert(op->name[0]);
+
+		puts("[OPERATOR]");
+		printf("  Name = %s\n", op->name);
+		printf("  Password = %s\n", op->pwd);
+		printf("  Mask = %s\n\n", op->mask ? op->mask : "");
+		op++;
+	}
+}
+
+
 GLOBAL int
 Conf_Test( void )
 {
@@ -255,16 +291,25 @@ Conf_Test( void )
 	}
 
 	puts( "[GLOBAL]" );
-	printf( "  Name = %s\n", Conf_ServerName );
-	printf( "  Info = %s\n", Conf_ServerInfo );
-	printf( "  Password = %s\n", Conf_ServerPwd );
-	printf( "  AdminInfo1 = %s\n", Conf_ServerAdmin1 );
-	printf( "  AdminInfo2 = %s\n", Conf_ServerAdmin2 );
-	printf( "  AdminEMail = %s\n", Conf_ServerAdminMail );
-	printf( "  MotdFile = %s\n", Conf_MotdFile );
-	printf( "  MotdPhrase = %s\n", Conf_MotdPhrase );
-	printf( "  ChrootDir = %s\n", Conf_Chroot );
-	printf( "  PidFile = %s\n", Conf_PidFile);
+	printf("  Name = %s\n", Conf_ServerName);
+	printf("  Info = %s\n", Conf_ServerInfo);
+#ifndef PAM
+	printf("  Password = %s\n", Conf_ServerPwd);
+#endif
+	printf("  WebircPassword = %s\n", Conf_WebircPwd);
+	printf("  AdminInfo1 = %s\n", Conf_ServerAdmin1);
+	printf("  AdminInfo2 = %s\n", Conf_ServerAdmin2);
+	printf("  AdminEMail = %s\n", Conf_ServerAdminMail);
+	if (Using_MotdFile) {
+		printf("  MotdFile = %s\n", Conf_MotdFile);
+		printf("  MotdPhrase =\n");
+	} else {
+		printf("  MotdFile = \n");
+		printf("  MotdPhrase = %s\n", array_bytes(&Conf_Motd)
+		       ? (const char*) array_start(&Conf_Motd) : "");
+	}
+	printf("  ChrootDir = %s\n", Conf_Chroot);
+	printf("  PidFile = %s\n", Conf_PidFile);
 	printf("  Listen = %s\n", Conf_ListenAddress);
 	fputs("  Ports = ", stdout);
 	ports_puts(&Conf_ListenPorts);
@@ -285,6 +330,10 @@ Conf_Test( void )
 		printf("  ServerGID = %s\n", grp->gr_name);
 	else
 		printf("  ServerGID = %ld\n", (long)Conf_GID);
+#ifdef SYSLOG
+	printf("  SyslogFacility = %s\n",
+	       ngt_SyslogFacilityName(Conf_SyslogFacility));
+#endif
 	printf("  PingTimeout = %d\n", Conf_PingTimeout);
 	printf("  PongTimeout = %d\n", Conf_PongTimeout);
 	printf("  ConnectRetry = %d\n", Conf_ConnectRetry);
@@ -294,6 +343,8 @@ Conf_Test( void )
 	printf("  PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly));
 	printf("  NoDNS = %s\n", yesno_to_str(Conf_NoDNS));
 	printf("  NoIdent = %s\n", yesno_to_str(Conf_NoIdent));
+	printf("  NoPAM = %s\n", yesno_to_str(Conf_NoPAM));
+	printf("  NoZeroConf = %s\n", yesno_to_str(Conf_NoZeroConf));
 
 #ifdef WANT_IPV6
 	printf("  ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
@@ -304,16 +355,7 @@ Conf_Test( void )
 	printf("  MaxJoins = %d\n", Conf_MaxJoins > 0 ? Conf_MaxJoins : -1);
 	printf("  MaxNickLength = %u\n\n", Conf_MaxNickLength - 1);
 
-	for( i = 0; i < Conf_Oper_Count; i++ ) {
-		if( ! Conf_Oper[i].name[0] ) continue;
-
-		/* Valid "Operator" section */
-		puts( "[OPERATOR]" );
-		printf( "  Name = %s\n", Conf_Oper[i].name );
-		printf( "  Password = %s\n", Conf_Oper[i].pwd );
-		if ( Conf_Oper[i].mask ) printf( "  Mask = %s\n", Conf_Oper[i].mask );
-		puts( "" );
-	}
+	opers_puts();
 
 	for( i = 0; i < MAX_SERVERS; i++ ) {
 		if( ! Conf_Server[i].name[0] ) continue;
@@ -538,7 +580,6 @@ Set_Defaults(bool InitServers)
 
 	strlcpy(Conf_MotdFile, SYSCONFDIR, sizeof(Conf_MotdFile));
 	strlcat(Conf_MotdFile, MOTD_FILE, sizeof(Conf_MotdFile));
-	strlcpy(Conf_MotdPhrase, MOTD_PHRASE, sizeof(Conf_MotdPhrase));
 
 	Conf_UID = Conf_GID = 0;
 	strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot));
@@ -552,6 +593,8 @@ Set_Defaults(bool InitServers)
 	Conf_ConnectRetry = 60;
 	Conf_NoDNS = false;
 	Conf_NoIdent = false;
+	Conf_NoPAM = false;
+	Conf_NoZeroConf = false;
 
 	Conf_Oper_Count = 0;
 	Conf_Channel_Count = 0;
@@ -569,6 +612,14 @@ Set_Defaults(bool InitServers)
 	Conf_MaxJoins = 10;
 	Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
 
+#ifdef SYSLOG
+#ifdef LOG_LOCAL5
+	Conf_SyslogFacility = LOG_LOCAL5;
+#else
+	Conf_SyslogFacility = 0;
+#endif
+#endif
+
 	/* Initialize server configuration structures */
 	if (InitServers) {
 		for (i = 0; i < MAX_SERVERS;
@@ -587,6 +638,37 @@ no_listenports(void)
 	return cnt == 0;
 }
 
+static void
+Read_Motd(const char *filename)
+{
+	char line[127];
+	FILE *fp;
+
+	if (*filename == '\0')
+		return;
+
+	fp = fopen(filename, "r");
+	if (!fp) {
+		Log(LOG_WARNING, "Can't read MOTD file \"%s\": %s",
+					filename, strerror(errno));
+		return;
+	}
+
+	array_free(&Conf_Motd);
+	Using_MotdFile = true;
+
+	while (fgets(line, (int)sizeof line, fp)) {
+		ngt_TrimLastChr( line, '\n');
+
+		/* add text including \0 */
+		if (!array_catb(&Conf_Motd, line, strlen(line) + 1)) {
+			Log(LOG_WARNING, "Cannot add MOTD text: %s", strerror(errno));
+			break;
+		}
+	}
+	fclose(fp);
+}
+
 static bool
 Read_Config( bool ngircd_starting )
 {
@@ -609,6 +691,7 @@ Read_Config( bool ngircd_starting )
 		exit( 1 );
 	}
 
+	opers_free();
 	Set_Defaults( ngircd_starting );
 
 	Config_Error( LOG_INFO, "Reading configuration from \"%s\" ...", NGIRCd_ConfFile );
@@ -667,21 +750,6 @@ Read_Config( bool ngircd_starting )
 			if( strcasecmp( section, "[GLOBAL]" ) == 0 )
 				continue;
 
-			if( strcasecmp( section, "[OPERATOR]" ) == 0 ) {
-				if( Conf_Oper_Count + 1 > MAX_OPERATORS )
-					Config_Error( LOG_ERR, "Too many operators configured.");
-				else {
-					/* Initialize new operator structure */
-					Conf_Oper[Conf_Oper_Count].name[0] = '\0';
-					Conf_Oper[Conf_Oper_Count].pwd[0] = '\0';
-					if (Conf_Oper[Conf_Oper_Count].mask) {
-						free(Conf_Oper[Conf_Oper_Count].mask );
-						Conf_Oper[Conf_Oper_Count].mask = NULL;
-					}
-					Conf_Oper_Count++;
-				}
-				continue;
-			}
 			if( strcasecmp( section, "[SERVER]" ) == 0 ) {
 				/* Check if there is already a server to add */
 				if( New_Server.name[0] ) {
@@ -710,6 +778,10 @@ Read_Config( bool ngircd_starting )
 				Conf_Channel_Count++;
 				continue;
 			}
+			if (strcasecmp(section, "[OPERATOR]") == 0) {
+				Conf_Oper_Count++;
+				continue;
+			}
 
 			Config_Error( LOG_ERR, "%s, line %d: Unknown section \"%s\"!", NGIRCd_ConfFile, line, section );
 			section[0] = 0x1;
@@ -760,6 +832,10 @@ Read_Config( bool ngircd_starting )
 		Config_Error(LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME);
 		exit(1);
 	}
+
+	/* No MOTD phrase configured? (re)try motd file. */
+	if (array_bytes(&Conf_Motd) == 0)
+		Read_Motd(Conf_MotdFile);
 	return true;
 } /* Read_Config */
 
@@ -775,7 +851,8 @@ Check_ArgIsTrue( const char *Arg )
 } /* Check_ArgIsTrue */
 
 
-static unsigned int Handle_MaxNickLength(int Line, const char *Arg)
+static unsigned int
+Handle_MaxNickLength(int Line, const char *Arg)
 {
 	unsigned new;
 
@@ -796,6 +873,7 @@ static unsigned int Handle_MaxNickLength(int Line, const char *Arg)
 } /* Handle_MaxNickLength */
 
 
+
 static void
 Handle_GLOBAL( int Line, char *Var, char *Arg )
 {
@@ -828,6 +906,13 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 			Config_Error_TooLong( Line, Var );
 		return;
 	}
+	if (strcasecmp(Var, "WebircPassword") == 0) {
+		/* Password required for WEBIRC command */
+		len = strlcpy(Conf_WebircPwd, Arg, sizeof(Conf_WebircPwd));
+		if (len >= sizeof(Conf_WebircPwd))
+			Config_Error_TooLong(Line, Var);
+		return;
+	}
 	if( strcasecmp( Var, "AdminInfo1" ) == 0 ) {
 		/* Administrative info #1 */
 		len = strlcpy( Conf_ServerAdmin1, Arg, sizeof( Conf_ServerAdmin1 ));
@@ -855,17 +940,25 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 		return;
 	}
 	if( strcasecmp( Var, "MotdFile" ) == 0 ) {
-		/* "Message of the day" (MOTD) file */
 		len = strlcpy( Conf_MotdFile, Arg, sizeof( Conf_MotdFile ));
 		if (len >= sizeof( Conf_MotdFile ))
 			Config_Error_TooLong( Line, Var );
+		Read_Motd(Arg);
 		return;
 	}
 	if( strcasecmp( Var, "MotdPhrase" ) == 0 ) {
 		/* "Message of the day" phrase (instead of file) */
-		len = strlcpy( Conf_MotdPhrase, Arg, sizeof( Conf_MotdPhrase ));
-		if (len >= sizeof( Conf_MotdPhrase ))
+		len = strlen(Arg);
+		if (len == 0)
+			return;
+		if (len >= LINE_LEN) {
 			Config_Error_TooLong( Line, Var );
+			return;
+		}
+		if (!array_copyb(&Conf_Motd, Arg, len + 1))
+			Config_Error(LOG_WARNING, "%s, line %d: Could not append MotdPhrase: %s",
+							NGIRCd_ConfFile, Line, strerror(errno));
+		Using_MotdFile = false;
 		return;
 	}
 	if( strcasecmp( Var, "ChrootDir" ) == 0 ) {
@@ -961,6 +1054,16 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 #endif
 		return;
 	}
+	if(strcasecmp(Var, "NoPAM") == 0) {
+		/* don't use PAM library to authenticate users */
+		Conf_NoPAM = Check_ArgIsTrue(Arg);
+		return;
+	}
+	if(strcasecmp(Var, "NoZeroConf") == 0) {
+		/* don't register services using ZeroConf */
+		Conf_NoZeroConf = Check_ArgIsTrue(Arg);
+		return;
+	}
 #ifdef WANT_IPV6
 	/* the default setting for all the WANT_IPV6 special options is 'true' */
 	if( strcasecmp( Var, "ConnectIPv6" ) == 0 ) {
@@ -1073,6 +1176,13 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
                 return;
         }
 #endif
+#ifdef SYSLOG
+	if (strcasecmp(Var, "SyslogFacility") == 0) {
+		Conf_SyslogFacility = ngt_SyslogFacilityID(Arg,
+							   Conf_SyslogFacility);
+		return;
+	}
+#endif
 	Config_Error(LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!",
 								NGIRCd_ConfFile, Line, Var);
 } /* Handle_GLOBAL */
@@ -1081,36 +1191,38 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 static void
 Handle_OPERATOR( int Line, char *Var, char *Arg )
 {
-	unsigned int opercount;
 	size_t len;
+	struct Conf_Oper *op;
+
 	assert( Line > 0 );
 	assert( Var != NULL );
 	assert( Arg != NULL );
 	assert( Conf_Oper_Count > 0 );
 
-	if ( Conf_Oper_Count == 0 )
+	op = array_alloc(&Conf_Opers, sizeof(*op), Conf_Oper_Count - 1);
+	if (!op) {
+		Config_Error(LOG_ERR, "Could not allocate memory for operator (%d:%s = %s)", Line, Var, Arg);
 		return;
+	}
 
-	opercount = Conf_Oper_Count - 1;
-
-	if( strcasecmp( Var, "Name" ) == 0 ) {
+	if (strcasecmp(Var, "Name") == 0) {
 		/* Name of IRC operator */
-		len = strlcpy( Conf_Oper[opercount].name, Arg, sizeof( Conf_Oper[opercount].name ));
-		if (len >= sizeof( Conf_Oper[opercount].name ))
-				Config_Error_TooLong( Line, Var );
+		len = strlcpy(op->name, Arg, sizeof(op->name));
+		if (len >= sizeof(op->name))
+				Config_Error_TooLong(Line, Var);
 		return;
 	}
-	if( strcasecmp( Var, "Password" ) == 0 ) {
+	if (strcasecmp(Var, "Password") == 0) {
 		/* Password of IRC operator */
-		len = strlcpy( Conf_Oper[opercount].pwd, Arg, sizeof( Conf_Oper[opercount].pwd ));
-		if (len >= sizeof( Conf_Oper[opercount].pwd ))
-				Config_Error_TooLong( Line, Var );
+		len = strlcpy(op->pwd, Arg, sizeof(op->pwd));
+		if (len >= sizeof(op->pwd))
+				Config_Error_TooLong(Line, Var);
 		return;
 	}
-	if( strcasecmp( Var, "Mask" ) == 0 ) {
-		if (Conf_Oper[opercount].mask) return; /* Hostname already configured */
-
-		Conf_Oper[opercount].mask = strdup_warn( Arg );
+	if (strcasecmp(Var, "Mask") == 0) {
+		if (op->mask)
+			return; /* Hostname already configured */
+		op->mask = strdup_warn( Arg );
 		return;
 	}
 	Config_Error( LOG_ERR, "%s, line %d (section \"Operator\"): Unknown variable \"%s\"!",
@@ -1376,6 +1488,12 @@ Validate_Config(bool Configtest, bool Rehash)
 			     "No administrative information configured but required by RFC!");
 	}
 
+#ifdef PAM
+	if (Conf_ServerPwd[0])
+		Config_Error(LOG_ERR,
+			     "This server uses PAM, \"Password\" will be ignored!");
+#endif
+
 #ifdef DEBUG
 	servers = servers_once = 0;
 	for (i = 0; i < MAX_SERVERS; i++) {
@@ -1441,6 +1559,29 @@ va_dcl
 } /* Config_Error */
 
 
+#ifdef DEBUG
+
+GLOBAL void
+Conf_DebugDump(void)
+{
+	int i;
+
+	Log(LOG_DEBUG, "Configured servers:");
+	for (i = 0; i < MAX_SERVERS; i++) {
+		if (! Conf_Server[i].name[0])
+			continue;
+		Log(LOG_DEBUG,
+		    " - %s: %s:%d, last=%ld, group=%d, flags=%d, conn=%d",
+		    Conf_Server[i].name, Conf_Server[i].host,
+		    Conf_Server[i].port, Conf_Server[i].lasttry,
+		    Conf_Server[i].group, Conf_Server[i].flags,
+		    Conf_Server[i].conn_id);
+	}
+} /* Conf_DebugDump */
+
+#endif
+
+
 static void
 Init_Server_Struct( CONF_SERVER *Server )
 {
@@ -1455,7 +1596,7 @@ Init_Server_Struct( CONF_SERVER *Server )
 
 	if( NGIRCd_Passive ) Server->flags = CONF_SFLAG_DISABLED;
 
-	Resolve_Init(&Server->res_stat);
+	Proc_InitStruct(&Server->res_stat);
 	Server->conn_id = NONE;
 	memset(&Server->bind_addr, 0, sizeof(&Server->bind_addr));
 } /* Init_Server_Struct */

+ 29 - 14
src/ngircd/conf.h

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,16 +22,15 @@
 #include "portab.h"
 #include "tool.h"
 #include "ng_ipaddr.h"
-#include "resolve.h"
+#include "proc.h"
 #include "conf-ssl.h"
 
 
-typedef struct _Conf_Oper
-{
+struct Conf_Oper {
 	char name[CLIENT_PASS_LEN];	/* Name (ID) of IRC operator */
 	char pwd[CLIENT_PASS_LEN];	/* Password */
-	char *mask;
-} CONF_OPER;
+	char *mask;			/* allowed host mask */
+};
 
 typedef struct _Conf_Server
 {
@@ -42,7 +41,7 @@ typedef struct _Conf_Server
 	UINT16 port;			/* Server port */
 	int group;			/* Group of server */
 	time_t lasttry;			/* Last connect attempt */
-	RES_STAT res_stat;		/* Status of the resolver */
+	PROC_STAT res_stat;		/* Status of the resolver */
 	int flags;			/* Flags */
 	CONN_ID conn_id;		/* ID of server connection or NONE */
 	ng_ipaddr_t bind_addr;		/* source address to use for outgoing
@@ -95,11 +94,8 @@ GLOBAL char Conf_ServerAdmin1[CLIENT_INFO_LEN];
 GLOBAL char Conf_ServerAdmin2[CLIENT_INFO_LEN];
 GLOBAL char Conf_ServerAdminMail[CLIENT_INFO_LEN];
 
-/* File with MOTD text */
-GLOBAL char Conf_MotdFile[FNAME_LEN];
-
-/* Phrase with MOTD text */
-GLOBAL char Conf_MotdPhrase[LINE_LEN];
+/* Message of the Day */
+GLOBAL array Conf_Motd;
 
 /* Ports the server should listen on */
 GLOBAL array Conf_ListenPorts;
@@ -125,8 +121,7 @@ GLOBAL int Conf_PongTimeout;
 GLOBAL int Conf_ConnectRetry;
 
 /* Operators */
-GLOBAL CONF_OPER Conf_Oper[MAX_OPERATORS];
-GLOBAL unsigned int Conf_Oper_Count;
+GLOBAL array Conf_Opers;
 
 /* Servers */
 GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS];
@@ -154,6 +149,12 @@ GLOBAL bool Conf_NoDNS;
 /* Disable IDENT lookups, even when compiled with support for it */
 GLOBAL bool Conf_NoIdent;
 
+/* Disable all usage of PAM, even when compiled with support for it */
+GLOBAL bool Conf_NoPAM;
+
+/* Disable service registration using "ZeroConf" */
+GLOBAL bool Conf_NoZeroConf;
+
 /*
  * try to connect to remote systems using the ipv6 protocol,
  * if they have an ipv6 address? (default yes)
@@ -175,6 +176,13 @@ GLOBAL int Conf_MaxConnectionsIP;
 /* Maximum length of a nick name */
 GLOBAL unsigned int Conf_MaxNickLength;
 
+#ifdef SYSLOG
+
+/* Syslog "facility" */
+GLOBAL int Conf_SyslogFacility;
+
+#endif
+
 GLOBAL void Conf_Init PARAMS((void));
 GLOBAL bool Conf_Rehash PARAMS((void));
 GLOBAL int Conf_Test PARAMS((void));
@@ -190,6 +198,13 @@ GLOBAL bool Conf_AddServer PARAMS(( const char *Name, UINT16 Port, const char *H
 
 GLOBAL bool Conf_IsService PARAMS((int ConfServer, const char *Nick));
 
+/* Password required by WEBIRC command */
+GLOBAL char Conf_WebircPwd[CLIENT_PASS_LEN];
+
+#ifdef DEBUG
+GLOBAL void Conf_DebugDump PARAMS((void));
+#endif
+
 
 #endif
 

+ 10 - 0
src/ngircd/conn-func.c

@@ -273,6 +273,16 @@ Conn_RecvBytes( CONN_ID Idx )
 	return My_Connections[Idx].bytes_in;
 } /* Conn_RecvBytes */
 
+/**
+ * Return the remote IP address of this connection as string.
+ */
+GLOBAL const char *
+Conn_IPA(CONN_ID Idx)
+{
+	assert (Idx > NONE);
+	return ng_ipaddr_tostr(&My_Connections[Idx].addr);
+}
+
 
 GLOBAL void
 Conn_ResetWCounter( void )

+ 1 - 0
src/ngircd/conn-func.h

@@ -39,6 +39,7 @@ GLOBAL long Conn_SendMsg PARAMS(( CONN_ID Idx ));
 GLOBAL long Conn_RecvMsg PARAMS(( CONN_ID Idx ));
 GLOBAL long Conn_SendBytes PARAMS(( CONN_ID Idx ));
 GLOBAL long Conn_RecvBytes PARAMS(( CONN_ID Idx ));
+GLOBAL const char *Conn_IPA PARAMS(( CONN_ID Idx ));
 
 GLOBAL void Conn_SetPenalty PARAMS(( CONN_ID Idx, time_t Seconds ));
 GLOBAL void Conn_ResetPenalty PARAMS(( CONN_ID Idx ));

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

@@ -383,9 +383,10 @@ ConnSSL_Init_SSL(CONNECTION *c)
 	int ret;
 	assert(c != NULL);
 #ifdef HAVE_LIBSSL
-	if (!ssl_ctx)	/* NULL when library initialization failed */
+	if (!ssl_ctx) {
+		Log(LOG_ERR, "Cannot init ssl_ctx: OpenSSL initialization failed at startup");
 		return false;
-
+	}
 	assert(c->ssl_state.ssl == NULL);
 
 	c->ssl_state.ssl = SSL_new(ssl_ctx);

File diff suppressed because it is too large
+ 386 - 180
src/ngircd/conn.c


+ 21 - 6
src/ngircd/conn.h

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2009 by Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -44,11 +44,11 @@
 typedef long CONN_ID;
 
 #include "client.h"
+#include "proc.h"
 
 #ifdef CONN_MODULE
 
 #include "defines.h"
-#include "resolve.h"
 #include "array.h"
 #include "tool.h"
 #include "ng_ipaddr.h"
@@ -69,7 +69,7 @@ typedef struct _Connection
 {
 	int sock;			/* Socket handle */
 	ng_ipaddr_t addr;		/* Client address */
-	RES_STAT res_stat;		/* Status of resolver process */
+	PROC_STAT proc_stat;		/* Status of resolver process */
 	char host[HOST_LEN];		/* Hostname */
 	array rbuf;			/* Read buffer */
 	array wbuf;			/* Write buffer */
@@ -88,7 +88,7 @@ typedef struct _Connection
 	ZIPDATA zip;			/* Compression information */
 #endif  /* ZLIB */
 #ifdef SSL_SUPPORT
-	struct ConnSSL_State	ssl_state;	/* SSL/GNUTLS state information */
+	struct ConnSSL_State ssl_state;	/* SSL/GNUTLS state information */
 #endif
 } CONNECTION;
 
@@ -102,24 +102,39 @@ GLOBAL long WCounter;
 GLOBAL void Conn_Init PARAMS((void ));
 GLOBAL void Conn_Exit PARAMS(( void ));
 
+GLOBAL void Conn_CloseAllSockets PARAMS((void));
+
 GLOBAL unsigned int Conn_InitListeners PARAMS(( void ));
 GLOBAL void Conn_ExitListeners PARAMS(( void ));
 
 GLOBAL void Conn_Handler PARAMS(( void ));
 
-GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, char *Format, ... ));
+GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, const char *Format, ... ));
 
 GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient ));
 
 GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
 
+GLOBAL CONN_ID Conn_GetFromProc PARAMS((int fd));
 GLOBAL CLIENT* Conn_GetClient PARAMS((CONN_ID i));
+GLOBAL PROC_STAT* Conn_GetProcStat PARAMS((CONN_ID i));
 #ifdef SSL_SUPPORT
 GLOBAL bool Conn_GetCipherInfo PARAMS((CONN_ID Idx, char *buf, size_t len));
 GLOBAL bool Conn_UsesSSL PARAMS((CONN_ID Idx));
 #else
-static inline bool Conn_UsesSSL(UNUSED CONN_ID Idx) { return false; }
+static inline bool
+Conn_UsesSSL(UNUSED CONN_ID Idx)
+{ return false; }
 #endif
+
+GLOBAL long Conn_Count PARAMS((void));
+GLOBAL long Conn_CountMax PARAMS((void));
+GLOBAL long Conn_CountAccepted PARAMS((void));
+
+#ifdef DEBUG
+GLOBAL void Conn_DebugDump PARAMS((void));
+#endif
+
 #endif
 
 

+ 3 - 8
src/ngircd/defines.h

@@ -1,14 +1,12 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2007 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  * Please read the file COPYING, README and AUTHORS for more information.
- *
- * $Id: defines.h,v 1.62 2007/11/21 12:16:36 alex Exp $
  */
 
 
@@ -30,8 +28,6 @@
 #define HOST_LEN 256			/* Max. lenght of fully qualified host
 					   names (e. g. "abc.domain.tld") */
 
-#define MAX_OPERATORS 16		/* Max. count of configurable IRC Ops */
-
 #define MAX_SERVERS 16			/* Max. count of configurable servers */
 
 #define MAX_WHOWAS 64			/* Max. number of WHOWAS items */
@@ -84,8 +80,8 @@
 #define RECONNECT_DELAY 3		/* Time to delay re-connect attempts
 					   in seconds. */
 
-#define USERMODES "aios"		/* Supported user modes. */
-#define CHANMODES "biIklmnoPstv"	/* Supported channel modes. */
+#define USERMODES "aciorswx"		/* Supported user modes. */
+#define CHANMODES "biIklmnoPstvz"	/* Supported channel modes. */
 
 #define CONNECTED true			/* Internal status codes. */
 #define DISCONNECTED false
@@ -97,7 +93,6 @@
 
 #define CONFIG_FILE "/ngircd.conf"	/* Configuration file name. */
 #define MOTD_FILE "/ngircd.motd"	/* Name of the MOTD file. */
-#define MOTD_PHRASE ""			/* Default MOTD phrase string. */
 #define CHROOT_DIR ""			/* Default chroot() directory. */
 #define PID_FILE ""			/* Default file for the process ID. */
 

+ 50 - 15
src/ngircd/io.c

@@ -104,8 +104,8 @@ static bool io_event_change_devpoll(int fd, short what);
 
 #ifdef IO_USE_SELECT
 #include "defines.h"	/* for conn.h */
-#include "conn.h"	/* for CONN_IDX (needed by resolve.h) */
-#include "resolve.h"	/* for RES_STAT (needed by conf.h) */
+#include "proc.h"	/* for PROC_STAT (needed by conf.h) */
+#include "conn.h"	/* for CONN_ID (needed by conf.h) */
 #include "conf.h"	/* for Conf_MaxConnections */
 
 static fd_set readers;
@@ -115,7 +115,7 @@ static fd_set writers;
  * the largest fd registered, plus one.
  */
 static int select_maxfd;
-static int io_dispatch_select(struct timeval *tv);
+static int io_dispatch_select PARAMS((struct timeval *tv));
 
 #ifndef IO_USE_EPOLL
 #define io_masterfd -1
@@ -127,12 +127,15 @@ static array io_events;
 static void io_docallback PARAMS((int fd, short what));
 
 #ifdef DEBUG_IO
-static void io_debug(const char *s, int fd, int what)
+static void
+io_debug(const char *s, int fd, int what)
 {
 	Log(LOG_DEBUG, "%s: %d, %d\n", s, fd, what);
 }
 #else
-static inline void io_debug(const char UNUSED *s,int UNUSED a, int UNUSED b) {/*NOTHING*/}
+static inline void
+io_debug(const char UNUSED *s,int UNUSED a, int UNUSED b)
+{ /* NOTHING */ }
 #endif
 
 static io_event *
@@ -227,8 +230,12 @@ io_library_init_devpoll(unsigned int eventsize)
 		eventsize, io_masterfd);
 }
 #else
-static inline void io_close_devpoll(int UNUSED x) {/* NOTHING */}
-static inline void io_library_init_devpoll(unsigned int UNUSED ev) {/*NOTHING*/}
+static inline void
+io_close_devpoll(int UNUSED x)
+{ /* NOTHING */ }
+static inline void
+io_library_init_devpoll(unsigned int UNUSED ev)
+{ /* NOTHING */ }
 #endif
 
 
@@ -331,8 +338,12 @@ io_library_init_poll(unsigned int eventsize)
 	}
 }
 #else
-static inline void io_close_poll(int UNUSED x) {/* NOTHING */}
-static inline void io_library_init_poll(unsigned int UNUSED ev) {/*NOTHING*/}
+static inline void
+io_close_poll(int UNUSED x)
+{ /* NOTHING */ }
+static inline void
+io_library_init_poll(unsigned int UNUSED ev)
+{ /* NOTHING */ }
 #endif
 
 
@@ -340,11 +351,15 @@ static inline void io_library_init_poll(unsigned int UNUSED ev) {/*NOTHING*/}
 static int
 io_dispatch_select(struct timeval *tv)
 {
-	fd_set readers_tmp = readers;
-	fd_set writers_tmp = writers;
+	fd_set readers_tmp;
+	fd_set writers_tmp;
 	short what;
 	int ret, i;
 	int fds_ready;
+
+	readers_tmp = readers;
+	writers_tmp = writers;
+
 	ret = select(select_maxfd + 1, &readers_tmp, &writers_tmp, NULL, tv);
 	if (ret <= 0)
 		return ret;
@@ -418,8 +433,12 @@ io_close_select(int fd)
 	}
 }
 #else
-static inline void io_library_init_select(int UNUSED x) {/* NOTHING */}
-static inline void io_close_select(int UNUSED x) {/* NOTHING */}
+static inline void
+io_library_init_select(int UNUSED x)
+{ /* NOTHING */ }
+static inline void
+io_close_select(int UNUSED x)
+{ /* NOTHING */ }
 #endif /* SELECT */
 
 
@@ -494,7 +513,9 @@ io_library_init_epoll(unsigned int eventsize)
 #endif
 }
 #else
-static inline void io_library_init_epoll(unsigned int UNUSED ev) {/* NOTHING */}
+static inline void
+io_library_init_epoll(unsigned int UNUSED ev)
+{ /* NOTHING */ }
 #endif /* IO_USE_EPOLL */
 
 
@@ -620,7 +641,9 @@ io_library_init_kqueue(unsigned int eventsize)
 		library_initialized = true;
 }
 #else
-static inline void io_library_init_kqueue(unsigned int UNUSED ev) {/* NOTHING */}
+static inline void
+io_library_init_kqueue(unsigned int UNUSED ev)
+{ /* NOTHING */ }
 #endif
 
 
@@ -785,6 +808,18 @@ io_setnonblock(int fd)
 	return fcntl(fd, F_SETFL, flags) == 0;
 }
 
+bool
+io_setcloexec(int fd)
+{
+	int flags = fcntl(fd, F_GETFD);
+	if (flags == -1)
+		return false;
+#ifdef FD_CLOEXEC
+	flags |= FD_CLOEXEC;
+#endif
+
+	return fcntl(fd, F_SETFD, flags) == 0;
+}
 
 bool
 io_close(int fd)

+ 3 - 0
src/ngircd/io.h

@@ -45,6 +45,9 @@ bool io_close PARAMS((int fd));
 /* set O_NONBLOCK */
 bool io_setnonblock PARAMS((int fd));
 
+/* set O_CLOEXEC */
+bool io_setcloexec PARAMS((int fd));
+
 /* watch fds for activity */
 int io_dispatch PARAMS((struct timeval *tv));
 

+ 57 - 29
src/ngircd/irc-channel.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,7 +22,6 @@
 
 #include "defines.h"
 #include "conn.h"
-#include "client.h"
 #include "channel.h"
 #include "conn-func.h"
 #include "lists.h"
@@ -32,7 +31,6 @@
 #include "parse.h"
 #include "irc-info.h"
 #include "irc-write.h"
-#include "resolve.h"
 #include "conf.h"
 
 #include "exp.h"
@@ -62,9 +60,18 @@ part_from_all_channels(CLIENT* client, CLIENT *target)
 }
 
 
+/**
+ * Check weather a local client is allowed to join an already existing
+ * channel or not.
+ * @param Client Client that sent the JOIN command
+ * @param chan Channel to check
+ * @param channame Name of the channel
+ * @param key Provided channel key (or NULL if none has been provided)
+ * @return true if client is allowed to join channel, false otherwise
+ */
 static bool
-join_allowed(CLIENT *Client, CLIENT *target, CHANNEL *chan,
-			const char *channame, const char *key)
+join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
+	     const char *key)
 {
 	bool is_invited, is_banned;
 	const char *channel_modes;
@@ -73,32 +80,48 @@ join_allowed(CLIENT *Client, CLIENT *target, CHANNEL *chan,
 	if (strchr(Client_Modes(Client), 'o'))
 		return true;
 
-	is_banned = Lists_Check(Channel_GetListBans(chan), target);
-	is_invited = Lists_Check(Channel_GetListInvites(chan), target);
+	is_banned = Lists_Check(Channel_GetListBans(chan), Client);
+	is_invited = Lists_Check(Channel_GetListInvites(chan), Client);
 
 	if (is_banned && !is_invited) {
-		IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG, Client_ID(Client), channame);
+		/* Client is banned from channel (and not on invite list) */
+		IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG,
+				   Client_ID(Client), channame);
 		return false;
 	}
 
 	channel_modes = Channel_Modes(chan);
-	if ((strchr(channel_modes, 'i')) && !is_invited) {
-		/* Channel is "invite-only" (and Client wasn't invited) */
-		IRC_WriteStrClient(Client, ERR_INVITEONLYCHAN_MSG, Client_ID(Client), channame);
+	if (strchr(channel_modes, 'i') && !is_invited) {
+		/* Channel is "invite-only" and client is not on invite list */
+		IRC_WriteStrClient(Client, ERR_INVITEONLYCHAN_MSG,
+				   Client_ID(Client), channame);
 		return false;
 	}
 
-	/* Is the channel protected by a key? */
-	if (!Channel_CheckKey(chan, target, key ? key : "")) {
+	if (!Channel_CheckKey(chan, Client, key ? key : "")) {
+		/* Channel is protected by a channel key and the client
+		 * didn't specify the correct one */
 		IRC_WriteStrClient(Client, ERR_BADCHANNELKEY_MSG,
 				   Client_ID(Client), channame);
 		return false;
 	}
-	/* Are there already too many members? */
-	if ((strchr(channel_modes, 'l')) && (Channel_MaxUsers(chan) <= Channel_MemberCount(chan))) {
-		IRC_WriteStrClient(Client, ERR_CHANNELISFULL_MSG, Client_ID(Client), channame);
+
+	if (strchr(channel_modes, 'l') &&
+	    (Channel_MaxUsers(chan) <= Channel_MemberCount(chan))) {
+		/* There are more clints joined to this channel than allowed */
+		IRC_WriteStrClient(Client, ERR_CHANNELISFULL_MSG,
+				   Client_ID(Client), channame);
+		return false;
+	}
+
+	if (strchr(channel_modes, 'z') && !Conn_UsesSSL(Client_Conn(Client))) {
+		/* Only "secure" clients are allowed, but clients doesn't
+		 * use SSL encryption */
+		IRC_WriteStrClient(Client, ERR_SECURECHANNEL_MSG,
+				   Client_ID(Client), channame);
 		return false;
 	}
+
 	return true;
 }
 
@@ -270,20 +293,23 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 
 		/* Local client? */
 		if (Client_Type(Client) == CLIENT_USER) {
-			/* Test if the user has reached his maximum channel count */
-			if ((Conf_MaxJoins > 0) && (Channel_CountForUser(Client) >= Conf_MaxJoins))
-				return IRC_WriteStrClient(Client, ERR_TOOMANYCHANNELS_MSG,
-							Client_ID(Client), channame);
-			if (!chan) {
-				/*
-				 * New Channel: first user will be channel operator
-				 * unless this is a modeless channel.
-				 */
+			/* Test if the user has reached the channel limit */
+			if ((Conf_MaxJoins > 0) &&
+			    (Channel_CountForUser(Client) >= Conf_MaxJoins))
+				return IRC_WriteStrClient(Client,
+						ERR_TOOMANYCHANNELS_MSG,
+						Client_ID(Client), channame);
+			if (chan) {
+				/* Already existing channel: check if the
+				 * client is allowed to join */
+				if (!join_allowed(Client, chan, channame, key))
+					break;
+			} else {
+				/* New channel: first user will become channel
+				 * operator unless this is a modeless channel */
 				if (*channame != '+')
 					flags = "o";
-			} else
-				if (!join_allowed(Client, target, chan, channame, key))
-					break;
+			}
 
 			/* Local client: update idle time */
 			Conn_UpdateIdle(Client_Conn(Client));
@@ -293,7 +319,9 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 			 * that the "one shot" entries (generated by INVITE
 			 * commands) in this list become deleted when a user
 			 * joins a channel this way. */
-			if (chan) (void)Lists_Check(Channel_GetListInvites(chan), target);
+			if (chan)
+				(void)Lists_Check(Channel_GetListInvites(chan),
+						  target);
 		}
 
 		/* Join channel (and create channel if it doesn't exist) */

+ 150 - 120
src/ngircd/irc-info.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2009 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,9 +25,7 @@
 #include "ngircd.h"
 #include "conn-func.h"
 #include "conn-zip.h"
-#include "client.h"
 #include "channel.h"
-#include "resolve.h"
 #include "conf.h"
 #include "defines.h"
 #include "log.h"
@@ -465,6 +463,10 @@ uptime_mins(time_t *now)
 }
 
 
+/**
+ * Handler for the IRC command "STATS".
+ * See RFC 2812 section 3.4.4.
+ */
 GLOBAL bool
 IRC_STATS( CLIENT *Client, REQUEST *Req )
 {
@@ -475,11 +477,12 @@ IRC_STATS( CLIENT *Client, REQUEST *Req )
 	time_t time_now;
 	unsigned int days, hrs, mins;
 
-	assert( Client != NULL );
-	assert( Req != NULL );
+	assert(Client != NULL);
+	assert(Req != NULL);
 
 	if (Req->argc > 2)
-		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
+		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+					  Client_ID(Client), Req->command);
 
 	/* use prefix to determine "From" */
 	if (Client_Type(Client) == CLIENT_SERVER)
@@ -487,18 +490,21 @@ IRC_STATS( CLIENT *Client, REQUEST *Req )
 	else
 		from = Client;
 
-	if (! from)
-		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix);
+	if (!from)
+		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
+					  Client_ID(Client), Req->prefix);
 
 	if (Req->argc == 2) {
 		/* forward to another server? */
-		target = Client_Search( Req->argv[1] );
-		if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER ))
-			return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[1] );
+		target = Client_Search(Req->argv[1]);
+		if ((!target) || (Client_Type(target) != CLIENT_SERVER))
+			return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
+						 Client_ID(from), Req->argv[1]);
 
-		if( target != Client_ThisServer()) {
+		if (target != Client_ThisServer()) {
 			/* forward to another server */
-			return IRC_WriteStrClientPrefix( target, from, "STATS %s %s", Req->argv[0], Req->argv[1] );
+			return IRC_WriteStrClientPrefix(target, from,
+				     "STATS %s %s", Req->argv[0], Req->argv[1]);
 		}
 	}
 
@@ -508,57 +514,70 @@ IRC_STATS( CLIENT *Client, REQUEST *Req )
 		query = '*';
 
 	switch (query) {
-		case 'l':	/* Links */
-		case 'L':
-			time_now = time(NULL);
-			for (con = Conn_First(); con != NONE ;con = Conn_Next(con)) {
-				cl = Conn_GetClient(con);
-				if (!cl)
-					continue;
-				if ((Client_Type(cl) == CLIENT_SERVER) || (cl == Client)) {
-					/* Server link or our own connection */
+	case 'l':	/* Link status (servers and own link) */
+	case 'L':
+		time_now = time(NULL);
+		for (con = Conn_First(); con != NONE; con = Conn_Next(con)) {
+			cl = Conn_GetClient(con);
+			if (!cl)
+				continue;
+			if ((Client_Type(cl) == CLIENT_SERVER)
+			    || (cl == Client)) {
+				/* Server link or our own connection */
 #ifdef ZLIB
-					if (Conn_Options(con) & CONN_ZIP) {
-						if (!IRC_WriteStrClient(from, RPL_STATSLINKINFOZIP_MSG,
-							Client_ID(from), Client_Mask(cl), Conn_SendQ(con),
-							Conn_SendMsg(con), Zip_SendBytes(con), Conn_SendBytes(con),
-							Conn_RecvMsg(con), Zip_RecvBytes(con), Conn_RecvBytes(con), (long)(time_now - Conn_StartTime(con))))
-								return DISCONNECTED;
-						continue;
-					}
-#endif
-					if (!IRC_WriteStrClient(from, RPL_STATSLINKINFO_MSG, Client_ID(from),
-						Client_Mask(cl), Conn_SendQ(con), Conn_SendMsg(con), Conn_SendBytes(con),
-						Conn_RecvMsg(con), Conn_RecvBytes(con), (long)(time_now - Conn_StartTime(con))))
-							return DISCONNECTED;
-				}
-			}
-			break;
-		case 'm':	/* IRC-Commands */
-		case 'M':
-			cmd = Parse_GetCommandStruct( );
-			for (; cmd->name ; cmd++) {
-				if (cmd->lcount == 0 && cmd->rcount == 0)
+				if (Conn_Options(con) & CONN_ZIP) {
+					if (!IRC_WriteStrClient
+					    (from, RPL_STATSLINKINFOZIP_MSG,
+					     Client_ID(from), Client_Mask(cl),
+					     Conn_SendQ(con), Conn_SendMsg(con),
+					     Zip_SendBytes(con),
+					     Conn_SendBytes(con),
+					     Conn_RecvMsg(con),
+					     Zip_RecvBytes(con),
+					     Conn_RecvBytes(con),
+					     (long)(time_now - Conn_StartTime(con))))
+						return DISCONNECTED;
 					continue;
-				if (!IRC_WriteStrClient(from, RPL_STATSCOMMANDS_MSG, Client_ID(from),
-						cmd->name, cmd->lcount, cmd->bytes, cmd->rcount))
-							return DISCONNECTED;
+				}
+#endif
+				if (!IRC_WriteStrClient
+				    (from, RPL_STATSLINKINFO_MSG,
+				     Client_ID(from), Client_Mask(cl),
+				     Conn_SendQ(con), Conn_SendMsg(con),
+				     Conn_SendBytes(con), Conn_RecvMsg(con),
+				     Conn_RecvBytes(con),
+				     (long)(time_now - Conn_StartTime(con))))
+					return DISCONNECTED;
 			}
-			break;
-		case 'u':	/* server uptime */
-		case 'U':
-			time_now = time(NULL) - NGIRCd_Start;
-			days = uptime_days(&time_now);
-			hrs = uptime_hrs(&time_now);
-			mins = uptime_mins(&time_now);
-			if (!IRC_WriteStrClient(from, RPL_STATSUPTIME, Client_ID(from),
-					days, hrs, mins, (unsigned int) time_now))
-						return DISCONNECTED;
-			break;
+		}
+		break;
+	case 'm':	/* IRC command status (usage count) */
+	case 'M':
+		cmd = Parse_GetCommandStruct();
+		for (; cmd->name; cmd++) {
+			if (cmd->lcount == 0 && cmd->rcount == 0)
+				continue;
+			if (!IRC_WriteStrClient
+			    (from, RPL_STATSCOMMANDS_MSG, Client_ID(from),
+			     cmd->name, cmd->lcount, cmd->bytes, cmd->rcount))
+				return DISCONNECTED;
+		}
+		break;
+	case 'u':	/* Server uptime */
+	case 'U':
+		time_now = time(NULL) - NGIRCd_Start;
+		days = uptime_days(&time_now);
+		hrs = uptime_hrs(&time_now);
+		mins = uptime_mins(&time_now);
+		if (!IRC_WriteStrClient(from, RPL_STATSUPTIME, Client_ID(from),
+				       days, hrs, mins, (unsigned int)time_now))
+			return DISCONNECTED;
+		break;
 	}
 
 	IRC_SetPenalty(from, 2);
-	return IRC_WriteStrClient(from, RPL_ENDOFSTATS_MSG, Client_ID(from), query);
+	return IRC_WriteStrClient(from, RPL_ENDOFSTATS_MSG,
+				  Client_ID(from), query);
 } /* IRC_STATS */
 
 
@@ -608,42 +627,51 @@ IRC_TIME( CLIENT *Client, REQUEST *Req )
 } /* IRC_TIME */
 
 
+/**
+ * Handler for the IRC command "USERHOST".
+ * See RFC 2812 section 4.8.
+ */
 GLOBAL bool
-IRC_USERHOST( CLIENT *Client, REQUEST *Req )
+IRC_USERHOST(CLIENT *Client, REQUEST *Req)
 {
 	char rpl[COMMAND_LEN];
 	CLIENT *c;
 	int max, i;
 
-	assert( Client != NULL );
-	assert( Req != NULL );
+	assert(Client != NULL);
+	assert(Req != NULL);
 
-	if(( Req->argc < 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
+	if ((Req->argc < 1))
+		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+					  Client_ID(Client), Req->command);
 
-	if( Req->argc > 5 ) max = 5;
-	else max = Req->argc;
+	if (Req->argc > 5)
+		max = 5;
+	else
+		max = Req->argc;
 
-	strlcpy( rpl, RPL_USERHOST_MSG, sizeof rpl );
-	for( i = 0; i < max; i++ )
-	{
-		c = Client_Search( Req->argv[i] );
-		if( c && ( Client_Type( c ) == CLIENT_USER ))
-		{
+	strlcpy(rpl, RPL_USERHOST_MSG, sizeof rpl);
+	for (i = 0; i < max; i++) {
+		c = Client_Search(Req->argv[i]);
+		if (c && (Client_Type(c) == CLIENT_USER)) {
 			/* This Nick is "online" */
-			strlcat( rpl, Client_ID( c ), sizeof( rpl ));
-			if( Client_HasMode( c, 'o' )) strlcat( rpl, "*", sizeof( rpl ));
-			strlcat( rpl, "=", sizeof( rpl ));
-			if( Client_HasMode( c, 'a' )) strlcat( rpl, "-", sizeof( rpl ));
-			else strlcat( rpl, "+", sizeof( rpl ));
-			strlcat( rpl, Client_User( c ), sizeof( rpl ));
-			strlcat( rpl, "@", sizeof( rpl ));
-			strlcat( rpl, Client_Hostname( c ), sizeof( rpl ));
-			strlcat( rpl, " ", sizeof( rpl ));
+			strlcat(rpl, Client_ID(c), sizeof(rpl));
+			if (Client_HasMode(c, 'o'))
+				strlcat(rpl, "*", sizeof(rpl));
+			strlcat(rpl, "=", sizeof(rpl));
+			if (Client_HasMode(c, 'a'))
+				strlcat(rpl, "-", sizeof(rpl));
+			else
+				strlcat(rpl, "+", sizeof(rpl));
+			strlcat(rpl, Client_User(c), sizeof(rpl));
+			strlcat(rpl, "@", sizeof(rpl));
+			strlcat(rpl, Client_HostnameCloaked(c), sizeof(rpl));
+			strlcat(rpl, " ", sizeof(rpl));
 		}
 	}
-	ngt_TrimLastChr( rpl, ' ');
+	ngt_TrimLastChr(rpl, ' ');
 
-	return IRC_WriteStrClient( Client, rpl, Client_ID( Client ) );
+	return IRC_WriteStrClient(Client, rpl, Client_ID(Client));
 } /* IRC_USERHOST */
 
 
@@ -700,9 +728,11 @@ IRC_VERSION( CLIENT *Client, REQUEST *Req )
 static bool
 write_whoreply(CLIENT *Client, CLIENT *c, const char *channelname, const char *flags)
 {
-	return IRC_WriteStrClient(Client, RPL_WHOREPLY_MSG, Client_ID(Client), channelname,
-			Client_User(c), Client_Hostname(c), Client_ID(Client_Introducer(c)), Client_ID(c),
-			flags, Client_Hops(c), Client_Info(c));
+	return IRC_WriteStrClient(Client, RPL_WHOREPLY_MSG, Client_ID(Client),
+				  channelname, Client_User(c),
+				  Client_HostnameCloaked(c),
+				  Client_ID(Client_Introducer(c)), Client_ID(c),
+				  flags, Client_Hops(c), Client_Info(c));
 }
 
 
@@ -920,8 +950,11 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
 
 	if(( Client_NextHop( target ) != Client_ThisServer( )) && ( Client_Type( Client_NextHop( target )) == CLIENT_SERVER )) return IRC_WriteStrClientPrefix( target, from, "WHOIS %s :%s", Req->argv[0], Req->argv[1] );
 
-	/* Nick, user and name */
-	if( ! IRC_WriteStrClient( from, RPL_WHOISUSER_MSG, Client_ID( from ), Client_ID( c ), Client_User( c ), Client_Hostname( c ), Client_Info( c ))) return DISCONNECTED;
+	/* Nick, user, hostname and client info */
+	if (!IRC_WriteStrClient(from, RPL_WHOISUSER_MSG, Client_ID(from),
+				Client_ID(c), Client_User(c),
+				Client_HostnameCloaked(c), Client_Info(c)))
+		return DISCONNECTED;
 
 	/* Server */
 	if( ! IRC_WriteStrClient( from, RPL_WHOISSERVER_MSG, Client_ID( from ), Client_ID( c ), Client_ID( Client_Introducer( c )), Client_Info( Client_Introducer( c )))) return DISCONNECTED;
@@ -972,6 +1005,13 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
 		if( ! IRC_WriteStrClient( from, RPL_WHOISOPERATOR_MSG, Client_ID( from ), Client_ID( c ))) return DISCONNECTED;
 	}
 
+	/* Connected using SSL? */
+	if (Conn_UsesSSL(Client_Conn(c))) {
+		if (!IRC_WriteStrClient
+		    (from, RPL_WHOISSSL_MSG, Client_ID(from), Client_ID(c)))
+			return DISCONNECTED;
+	}
+
 	/* Idle and signon time (local clients only!) */
 	if (Client_Conn(c) > NONE ) {
 		if (! IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG,
@@ -1155,6 +1195,10 @@ IRC_Send_LUSERS( CLIENT *Client )
 	if(! IRC_WriteStrClient(Client, RPL_NETUSERS_MSG, Client_ID(Client),
 			cnt, max, cnt, max))
 		return DISCONNECTED;
+	/* Connection counters */
+	if (! IRC_WriteStrClient(Client, RPL_STATSCONN_MSG, Client_ID(Client),
+			Conn_CountMax(), Conn_CountAccepted()))
+		return DISCONNECTED;
 #endif
 	
 	return CONNECTED;
@@ -1195,51 +1239,38 @@ static bool Show_MOTD_SSLInfo(CLIENT *Client)
 	return ret;
 }
 #else
-static inline bool Show_MOTD_SSLInfo(UNUSED CLIENT *c) { return true; }
+static inline bool
+Show_MOTD_SSLInfo(UNUSED CLIENT *c)
+{ return true; }
 #endif
 
 GLOBAL bool
 IRC_Show_MOTD( CLIENT *Client )
 {
-	char line[127];
-	FILE *fd;
+	const char *line;
+	size_t len_tot, len_str;
 
 	assert( Client != NULL );
 
-	if (Conf_MotdPhrase[0]) {
-		if (!Show_MOTD_Start(Client))
-			return DISCONNECTED;
-		if (!Show_MOTD_Sendline(Client, Conf_MotdPhrase))
-			return DISCONNECTED;
-		goto out;
-	}
+	len_tot = array_bytes(&Conf_Motd);
+	if (len_tot == 0 && !Conn_UsesSSL(Client_Conn(Client)))
+		return IRC_WriteStrClient(Client, ERR_NOMOTD_MSG, Client_ID(Client));
 
-	fd = fopen( Conf_MotdFile, "r" );
-	if( ! fd ) {
-		Log( LOG_WARNING, "Can't read MOTD file \"%s\": %s", Conf_MotdFile, strerror( errno ));
-		if (Conn_UsesSSL(Client_Conn(Client))) {
-			if (!Show_MOTD_Start(Client))
-				return DISCONNECTED;
-			goto out;
-		}
-		return IRC_WriteStrClient( Client, ERR_NOMOTD_MSG, Client_ID( Client ) );
-	}
+	if (!Show_MOTD_Start(Client))
+		return DISCONNECTED;
 
-	if (!Show_MOTD_Start( Client )) {
-		fclose(fd);
-		return false;
-	}
+	line = array_start(&Conf_Motd);
+	while (len_tot > 0) {
+		len_str = strlen(line) + 1;
 
-	while (fgets( line, (int)sizeof line, fd )) {
-		ngt_TrimLastChr( line, '\n');
+		assert(len_tot >= len_str);
+		len_tot -= len_str;
 
-		if( ! Show_MOTD_Sendline( Client, line)) {
-			fclose( fd );
-			return false;
-		}
+		if (!Show_MOTD_Sendline(Client, line))
+			return DISCONNECTED;
+		line += len_str;
 	}
-	fclose(fd);
-out:
+
 	if (!Show_MOTD_SSLInfo(Client))
 		return DISCONNECTED;
 	return Show_MOTD_End(Client);
@@ -1302,14 +1333,13 @@ IRC_Send_NAMES( CLIENT *Client, CHANNEL *Chan )
 } /* IRC_Send_NAMES */
 
 
-
 /**
  * Send the ISUPPORT numeric (005).
  * This numeric indicates the features that are supported by this server.
  * See <http://www.irc.org/tech_docs/005.html> for details.
  */
 GLOBAL bool
-IRC_Send_ISUPPORT PARAMS((CLIENT * Client))
+IRC_Send_ISUPPORT(CLIENT * Client)
 {
 	if (!IRC_WriteStrClient(Client, RPL_ISUPPORT1_MSG, Client_ID(Client),
 				Conf_MaxJoins))

+ 151 - 11
src/ngircd/irc-login.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,15 +20,17 @@
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
+#include <signal.h>
+#include <unistd.h>
 
 #include "ngircd.h"
-#include "resolve.h"
 #include "conn-func.h"
 #include "conf.h"
-#include "client.h"
 #include "channel.h"
+#include "io.h"
 #include "log.h"
 #include "messages.h"
+#include "pam.h"
 #include "parse.h"
 #include "irc.h"
 #include "irc-info.h"
@@ -39,11 +41,17 @@
 
 
 static bool Hello_User PARAMS(( CLIENT *Client ));
+static bool Hello_User_PostAuth PARAMS(( CLIENT *Client ));
 static void Kill_Nick PARAMS(( char *Nick, char *Reason ));
 static void Introduce_Client PARAMS((CLIENT *To, CLIENT *Client, int Type));
+static void Reject_Client PARAMS((CLIENT *Client));
+
 static void cb_introduceClient PARAMS((CLIENT *Client, CLIENT *Prefix,
 				       void *i));
 
+#ifdef PAM
+static void cb_Read_Auth_Result PARAMS((int r_fd, UNUSED short events));
+#endif
 
 /**
  * Handler for the IRC command "PASS".
@@ -356,7 +364,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
 		 * RFC 1459: announce the new client only after receiving the
 		 * USER command, first we need more information! */
 		if (Req->argc < 7) {
-			LogDebug("Client \"%s\" is beeing registered (RFC 1459) ...",
+			LogDebug("Client \"%s\" is being registered (RFC 1459) ...",
 				 Client_Mask(c));
 			Client_SetType(c, CLIENT_GOTNICK);
 		} else
@@ -403,6 +411,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
 #else
 		Client_SetUser(Client, Req->argv[0], false);
 #endif
+		Client_SetOrigUser(Client, Req->argv[0]);
 
 		/* "Real name" or user info text: Don't set it to the empty
 		 * string, the original ircd can't deal with such "real names"
@@ -435,6 +444,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
 						  Req->prefix);
 
 		Client_SetUser(c, Req->argv[0], true);
+		Client_SetOrigUser(c, Req->argv[0]);
 		Client_SetHostname(c, Req->argv[1]);
 		Client_SetInfo(c, Req->argv[3]);
 
@@ -557,6 +567,32 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req)
 } /* IRC_SERVICE */
 
 
+/**
+ * Handler for the IRC command "WEBIRC".
+ * Syntax: WEBIRC <password> <username> <real-hostname> <real-IP-address>
+ */
+GLOBAL bool
+IRC_WEBIRC(CLIENT *Client, REQUEST *Req)
+{
+	/* Exactly 4 parameters are requited */
+	if (Req->argc != 4)
+		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+					  Client_ID(Client), Req->command);
+
+	if (!Conf_WebircPwd[0] || strcmp(Req->argv[0], Conf_WebircPwd) != 0)
+		return IRC_WriteStrClient(Client, ERR_PASSWDMISMATCH_MSG,
+					  Client_ID(Client));
+
+	LogDebug("Connection %d: got valid WEBIRC command: user=%s, host=%s, ip=%s",
+		 Client_Conn(Client), Req->argv[1], Req->argv[2], Req->argv[3]);
+
+	Client_SetUser(Client, Req->argv[1], true);
+	Client_SetOrigUser(Client, Req->argv[1]);
+	Client_SetHostname(Client, Req->argv[2]);
+	return CONNECTED;
+} /* IRC_WEBIRC */
+
+
 GLOBAL bool
 IRC_QUIT( CLIENT *Client, REQUEST *Req )
 {
@@ -734,18 +770,116 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
 static bool
 Hello_User(CLIENT * Client)
 {
+#ifdef PAM
+	int pipefd[2], result;
+	CONN_ID conn;
+	pid_t pid;
+
+	assert(Client != NULL);
+	conn = Client_Conn(Client);
+
+	if (Conf_NoPAM) {
+		/* Don't do any PAM authentication at all, instead emulate
+		 * the beahiour of the daemon compiled without PAM support:
+		 * because there can't be any "server password", all
+		 * passwords supplied are classified as "wrong". */
+		if(Client_Password(Client)[0] == '\0')
+			return Hello_User_PostAuth(Client);
+		Reject_Client(Client);
+		return DISCONNECTED;
+	}
+
+	/* Fork child process for PAM authentication; and make sure that the
+	 * process timeout is set higher than the login timeout! */
+	pid = Proc_Fork(Conn_GetProcStat(conn), pipefd,
+			cb_Read_Auth_Result, Conf_PongTimeout + 1);
+	if (pid > 0) {
+		LogDebug("Authenticator for connection %d created (PID %d).",
+			 conn, pid);
+		return CONNECTED;
+	} else {
+		/* Sub process */
+		Log_Init_Subprocess("Auth");
+		result = PAM_Authenticate(Client);
+		write(pipefd[1], &result, sizeof(result));
+		Log_Exit_Subprocess("Auth");
+		exit(0);
+	}
+#else
 	assert(Client != NULL);
 
-	/* Check password ... */
+	/* Check global server password ... */
 	if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
 		/* Bad password! */
-		Log(LOG_ERR,
-		    "Client \"%s\" rejected (connection %d): Bad password!",
-		    Client_Mask(Client), Client_Conn(Client));
-		Conn_Close(Client_Conn(Client), NULL, "Bad password", true);
+		Reject_Client(Client);
 		return DISCONNECTED;
 	}
+	return Hello_User_PostAuth(Client);
+#endif
+}
+
+
+#ifdef PAM
+
+/**
+ * Read result of the authenticatior sub-process from pipe
+ */
+static void
+cb_Read_Auth_Result(int r_fd, UNUSED short events)
+{
+	CONN_ID conn;
+	CLIENT *client;
+	int result;
+	size_t len;
+	PROC_STAT *proc;
+
+	LogDebug("Auth: Got callback on fd %d, events %d", r_fd, events);
+	conn = Conn_GetFromProc(r_fd);
+	if (conn == NONE) {
+		/* Ops, none found? Probably the connection has already
+		 * been closed!? We'll ignore that ... */
+		io_close(r_fd);
+		LogDebug("Auth: Got callback for unknown connection!?");
+		return;
+	}
+	proc = Conn_GetProcStat(conn);
+	client = Conn_GetClient(conn);
+
+	/* Read result from pipe */
+	len = Proc_Read(proc, &result, sizeof(result));
+	if (len == 0)
+		return;
+
+	if (len != sizeof(result)) {
+		Log(LOG_CRIT, "Auth: Got malformed result!");
+		Reject_Client(client);
+		return;
+	}
+
+	if (result == true) {
+		Client_SetUser(client, Client_OrigUser(client), true);
+		(void)Hello_User_PostAuth(client);
+	} else
+		Reject_Client(client);
+}
 
+#endif
+
+
+static void
+Reject_Client(CLIENT *Client)
+{
+	Log(LOG_ERR,
+	    "User \"%s\" rejected (connection %d): Access denied!",
+	    Client_Mask(Client), Client_Conn(Client));
+	Conn_Close(Client_Conn(Client), NULL,
+		   "Access denied! Bad password?", true);
+}
+
+
+static bool
+Hello_User_PostAuth(CLIENT *Client)
+{
 	Introduce_Client(NULL, Client, CLIENT_USER);
 
 	if (!IRC_WriteStrClient
@@ -779,7 +913,7 @@ Hello_User(CLIENT * Client)
 	IRC_SetPenalty(Client, 1);
 
 	return CONNECTED;
-} /* Hello_User */
+}
 
 
 static void
@@ -815,10 +949,16 @@ Introduce_Client(CLIENT *From, CLIENT *Client, int Type)
 			 Client_Modes(Client), Client_ID(From),
 			 Client_ID(Client_Introducer(Client)),
 			 Client_Hops(Client), Client_Hops(Client) > 1 ? "s": "");
-	} else
+	} else {
 		Log(LOG_NOTICE, "%s \"%s\" registered (connection %d).",
 		    Client_TypeText(Client), Client_Mask(Client),
 		    Client_Conn(Client));
+		Log_ServerNotice('c', "Client connecting: %s (%s@%s) [%s] - %s",
+			         Client_ID(Client), Client_User(Client),
+				 Client_Hostname(Client),
+				 Conn_IPA(Client_Conn(Client)),
+				 Client_TypeText(Client));
+	}
 
 	/* Inform other servers */
 	IRC_WriteStrServersPrefixFlag_CB(From,

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

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

+ 55 - 17
src/ngircd/irc-mode.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,27 +22,30 @@
 
 #include "defines.h"
 #include "conn.h"
-#include "client.h"
 #include "channel.h"
 #include "irc-write.h"
 #include "lists.h"
 #include "log.h"
 #include "parse.h"
 #include "messages.h"
-#include "resolve.h"
 #include "conf.h"
 
 #include "exp.h"
 #include "irc-mode.h"
 
 
-static bool Client_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ));
-static bool Channel_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ));
+static bool Client_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin,
+	CLIENT *Target ));
+static bool Channel_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin,
+	CHANNEL *Channel ));
 
-static bool Add_Ban_Invite PARAMS((int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Pattern));
-static bool Del_Ban_Invite PARAMS((int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Pattern));
+static bool Add_Ban_Invite PARAMS((int what, CLIENT *Prefix, CLIENT *Client,
+	CHANNEL *Channel, const char *Pattern));
+static bool Del_Ban_Invite PARAMS((int what, CLIENT *Prefix, CLIENT *Client,
+	CHANNEL *Channel, const char *Pattern));
 
-static bool Send_ListChange PARAMS(( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Mask ));
+static bool Send_ListChange PARAMS((const char *Mode, CLIENT *Prefix,
+	CLIENT *Client, CHANNEL *Channel, const char *Mask));
 
 
 GLOBAL bool
@@ -172,6 +175,17 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 				else ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin ));
 				break;
 
+			case 'c': /* Receive connect notices
+				   * (only settable by IRC operators!) */
+				if(!set || Client_OperByMe(Origin)
+				   || Client_Type(Client) == CLIENT_SERVER)
+					x[0] = 'c';
+				else
+					ok = IRC_WriteStrClient(Origin,
+							ERR_NOPRIVILEGES_MSG,
+							Client_ID(Origin));
+				break;
+
 			case 'o': /* IRC operator (only unsettable!) */
 				if(( ! set ) || ( Client_Type( Client ) == CLIENT_SERVER ))
 				{
@@ -186,6 +200,15 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 				else ok = IRC_WriteStrClient( Origin, ERR_RESTRICTED_MSG, Client_ID( Origin ));
 				break;
 
+			case 'x': /* Cloak hostname */
+				if (Client_HasMode(Client, 'r'))
+					IRC_WriteStrClient(Origin,
+							   ERR_RESTRICTED_MSG,
+							   Client_ID(Origin));
+				else
+					x[0] = 'x';
+				break;
+
 			default:
 				Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\"!?", set ? '+' : '-', *mode_ptr, Client_ID( Origin ));
 				if( Client_Type( Client ) != CLIENT_SERVER ) ok = IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Origin ), set ? '+' : '-', *mode_ptr );
@@ -271,8 +294,17 @@ Channel_Mode_Answer_Request(CLIENT *Origin, CHANNEL *Channel)
 	if (the_args[0])
 		strlcat(the_modes, the_args, sizeof(the_modes));
 
-	return IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG,
-		Client_ID(Origin), Channel_Name(Channel), the_modes);
+	if (!IRC_WriteStrClient(Origin, RPL_CHANNELMODEIS_MSG,
+				Client_ID(Origin), Channel_Name(Channel),
+				the_modes))
+		return DISCONNECTED;
+#ifndef STRICT_RFC
+	if (!IRC_WriteStrClient(Origin, RPL_CREATIONTIME_MSG,
+				  Client_ID(Origin), Channel_Name(Channel),
+				  Channel_CreationTime(Channel)))
+		return DISCONNECTED;
+#endif
+	return CONNECTED;
 }
 
 
@@ -284,7 +316,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 {
 	char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2],
 	    argadd[CLIENT_PASS_LEN], *mode_ptr;
-	bool connected, set, modeok = true, skiponce, use_servermode = false, retval;
+	bool connected, set, skiponce, retval, onchannel;
+	bool modeok = true, use_servermode = false;
 	int mode_arg, arg_arg;
 	CLIENT *client;
 	long l;
@@ -301,14 +334,13 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 	/* Is the user allowed to change modes? */
 	if (Client_Type(Client) == CLIENT_USER) {
 		/* Is the originating user on that channel? */
-		if (!Channel_IsMemberOf(Channel, Origin))
-			return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG,
-				Client_ID(Origin), Channel_Name(Channel));
+		onchannel = Channel_IsMemberOf(Channel, Origin);
 		modeok = false;
 		/* channel operator? */
-		if (strchr(Channel_UserModes(Channel, Origin), 'o'))
+		if (onchannel &&
+		    strchr(Channel_UserModes(Channel, Origin), 'o')) {
 			modeok = true;
-		else if (Conf_OperCanMode) {
+		} else if (Conf_OperCanMode) {
 			/* IRC-Operators can use MODE as well */
 			if (Client_OperByMe(Origin)) {
 				modeok = true;
@@ -316,6 +348,10 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 					use_servermode = true; /* Change Origin to Server */
 			}
 		}
+
+		if (!onchannel && !modeok)
+			return IRC_WriteStrClient(Origin, ERR_NOTONCHANNEL_MSG,
+				Client_ID(Origin), Channel_Name(Channel));
 	}
 
 	mode_arg = 1;
@@ -401,6 +437,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 		case 'n': /* Only members can write */
 		case 's': /* Secret channel */
 		case 't': /* Topic locked */
+		case 'z': /* Secure connections only */
 			if (modeok)
 				x[0] = *mode_ptr;
 			else
@@ -747,7 +784,8 @@ Del_Ban_Invite(int what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const
 
 
 static bool
-Send_ListChange( char *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, const char *Mask )
+Send_ListChange(const char *Mode, CLIENT *Prefix, CLIENT *Client,
+		CHANNEL *Channel, const char *Mask)
 {
 	bool ok;
 

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

@@ -21,7 +21,6 @@
 
 #include "defines.h"
 #include "conn.h"
-#include "client.h"
 #include "channel.h"
 #include "irc-write.h"
 #include "lists.h"

+ 14 - 14
src/ngircd/irc-oper.c

@@ -19,12 +19,11 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <signal.h>
 
 #include "ngircd.h"
-#include "resolve.h"
 #include "conn-func.h"
 #include "conf.h"
-#include "client.h"
 #include "channel.h"
 #include "irc-write.h"
 #include "log.h"
@@ -55,25 +54,26 @@ Bad_OperPass(CLIENT *Client, char *errtoken, char *errmsg)
 GLOBAL bool
 IRC_OPER( CLIENT *Client, REQUEST *Req )
 {
-	unsigned int i;
+	struct Conf_Oper *op;
+	size_t len, i;
 
 	assert( Client != NULL );
 	assert( Req != NULL );
 
 	if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 
-	for( i = 0; i < Conf_Oper_Count; i++)
-	{
-		if( Conf_Oper[i].name[0] && Conf_Oper[i].pwd[0] && ( strcmp( Conf_Oper[i].name, Req->argv[0] ) == 0 )) break;
-	}
-	if( i >= Conf_Oper_Count )
+	len = array_length(&Conf_Opers, sizeof(*op));
+	op = array_start(&Conf_Opers);
+	for (i = 0; i < len && strcmp(op[i].name, Req->argv[0]); i++)
+		;
+	if (i >= len)
 		return Bad_OperPass(Client, Req->argv[0], "not configured");
 
-	if( strcmp( Conf_Oper[i].pwd, Req->argv[1] ) != 0 )
-		return Bad_OperPass(Client, Conf_Oper[i].name, "bad password");
+	if (strcmp(op[i].pwd, Req->argv[1]) != 0)
+		return Bad_OperPass(Client, op[i].name, "bad password");
 
-	if( Conf_Oper[i].mask && (! Match( Conf_Oper[i].mask, Client_Mask( Client ) )))
-		return Bad_OperPass(Client, Conf_Oper[i].mask, "hostmask check failed" );
+	if (op[i].mask && (!Match(op[i].mask, Client_Mask(Client))))
+		return Bad_OperPass(Client, op[i].mask, "hostmask check failed");
 
 	if( ! Client_HasMode( Client, 'o' ))
 	{
@@ -147,8 +147,8 @@ IRC_REHASH( CLIENT *Client, REQUEST *Req )
 	if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 
 	Log( LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...", Client_Mask( Client ));
-	NGIRCd_SignalRehash = true;
-	
+	raise(SIGHUP);
+
 	return CONNECTED;
 } /* IRC_REHASH */
 

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

@@ -22,12 +22,10 @@
 #include <strings.h>
 
 #include "defines.h"
-#include "resolve.h"
 #include "conn.h"
 #include "conn-func.h"
 #include "conn-zip.h"
 #include "conf.h"
-#include "client.h"
 #include "channel.h"
 #include "irc-write.h"
 #include "lists.h"

+ 68 - 60
src/ngircd/irc-write.c

@@ -26,7 +26,6 @@
 
 #include "defines.h"
 #include "conn-func.h"
-#include "client.h"
 #include "channel.h"
 
 #include "exp.h"
@@ -37,19 +36,20 @@
 #define SEND_TO_SERVER 2
 
 
-static char *Get_Prefix PARAMS((CLIENT *Target, CLIENT *Client));
+static const char *Get_Prefix PARAMS((CLIENT *Target, CLIENT *Client));
 static void cb_writeStrServersPrefixFlag PARAMS((CLIENT *Client,
 					 CLIENT *Prefix, void *Buffer));
+static bool Send_Marked_Connections PARAMS((CLIENT *Prefix, const char *Buffer));
 
 
 #ifdef PROTOTYPES
 GLOBAL bool
-IRC_WriteStrClient( CLIENT *Client, char *Format, ... )
+IRC_WriteStrClient( CLIENT *Client, const char *Format, ... )
 #else
 GLOBAL bool
 IRC_WriteStrClient( Client, Format, va_alist )
 CLIENT *Client;
-char *Format;
+const char *Format;
 va_dcl
 #endif
 {
@@ -77,13 +77,13 @@ va_dcl
 
 #ifdef PROTOTYPES
 GLOBAL bool
-IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, char *Format, ... )
+IRC_WriteStrClientPrefix(CLIENT *Client, CLIENT *Prefix, const char *Format, ...)
 #else
 GLOBAL bool
-IRC_WriteStrClientPrefix( Client, Prefix, Format, va_alist )
+IRC_WriteStrClientPrefix(Client, Prefix, Format, va_alist)
 CLIENT *Client;
 CLIENT *Prefix;
-char *Format;
+const char *Format;
 va_dcl
 #endif
 {
@@ -104,20 +104,22 @@ va_dcl
 	vsnprintf( buffer, 1000, Format, ap );
 	va_end( ap );
 
-	return Conn_WriteStr( Client_Conn( Client_NextHop( Client )), ":%s %s", Get_Prefix( Client_NextHop( Client ), Prefix ), buffer );
+	return Conn_WriteStr(Client_Conn(Client_NextHop(Client)), ":%s %s",
+			Get_Prefix(Client_NextHop(Client), Prefix), buffer);
 } /* IRC_WriteStrClientPrefix */
 
 
 #ifdef PROTOTYPES
 GLOBAL bool
-IRC_WriteStrChannel( CLIENT *Client, CHANNEL *Chan, bool Remote, char *Format, ... )
+IRC_WriteStrChannel(CLIENT *Client, CHANNEL *Chan, bool Remote,
+		    const char *Format, ...)
 #else
 GLOBAL bool
-IRC_WriteStrChannel( Client, Chan, Remote, Format, va_alist )
+IRC_WriteStrChannel(Client, Chan, Remote, Format, va_alist)
 CLIENT *Client;
 CHANNEL *Chan;
 bool Remote;
-char *Format;
+const char *Format;
 va_dcl
 #endif
 {
@@ -146,19 +148,19 @@ va_dcl
  */
 #ifdef PROTOTYPES
 GLOBAL bool
-IRC_WriteStrChannelPrefix( CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, bool Remote, char *Format, ... )
+IRC_WriteStrChannelPrefix(CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix,
+			  bool Remote, const char *Format, ...)
 #else
 GLOBAL bool
-IRC_WriteStrChannelPrefix( Client, Chan, Prefix, Remote, Format, va_alist )
+IRC_WriteStrChannelPrefix(Client, Chan, Prefix, Remote, Format, va_alist)
 CLIENT *Client;
 CHANNEL *Chan;
 CLIENT *Prefix;
 bool Remote;
-char *Format;
+const char *Format;
 va_dcl
 #endif
 {
-	bool ok = CONNECTED;
 	char buffer[1000];
 	CL2CHAN *cl2chan;
 	CONN_ID conn;
@@ -200,30 +202,18 @@ va_dcl
 		}
 		cl2chan = Channel_NextMember( Chan, cl2chan );
 	}
-
-	conn = Conn_First( );
-	while( conn != NONE )
-	{
-		/* do we need to send data via this connection? */
-		if( Conn_Flag( conn ) == SEND_TO_SERVER) ok = Conn_WriteStr( conn, ":%s %s", Client_ID( Prefix ), buffer );
-		else if( Conn_Flag( conn ) == SEND_TO_USER ) ok = Conn_WriteStr( conn, ":%s %s", Client_Mask( Prefix ), buffer );
-		if( ! ok ) break;
-
-		conn = Conn_Next( conn );
-	}
-
-	return ok;
+	return Send_Marked_Connections(Prefix, buffer);
 } /* IRC_WriteStrChannelPrefix */
 
 
 #ifdef PROTOTYPES
 GLOBAL void
-IRC_WriteStrServers( CLIENT *ExceptOf, char *Format, ... )
+IRC_WriteStrServers(CLIENT *ExceptOf, const char *Format, ...)
 #else
 GLOBAL void
-IRC_WriteStrServers( ExceptOf, Format, va_alist )
+IRC_WriteStrServers(ExceptOf, Format, va_alist)
 CLIENT *ExceptOf;
-char *Format;
+const char *Format;
 va_dcl
 #endif
 {
@@ -246,13 +236,14 @@ va_dcl
 
 #ifdef PROTOTYPES
 GLOBAL void
-IRC_WriteStrServersPrefix( CLIENT *ExceptOf, CLIENT *Prefix, char *Format, ... )
+IRC_WriteStrServersPrefix(CLIENT *ExceptOf, CLIENT *Prefix,
+			  const char *Format, ...)
 #else
 GLOBAL void
-IRC_WriteStrServersPrefix( ExceptOf, Prefix, Format, va_alist )
+IRC_WriteStrServersPrefix(ExceptOf, Prefix, Format, va_alist)
 CLIENT *ExceptOf;
 CLIENT *Prefix;
-char *Format;
+const char *Format;
 va_dcl
 #endif
 {
@@ -276,14 +267,15 @@ va_dcl
 
 #ifdef PROTOTYPES
 GLOBAL void
-IRC_WriteStrServersPrefixFlag( CLIENT *ExceptOf, CLIENT *Prefix, char Flag, char *Format, ... )
+IRC_WriteStrServersPrefixFlag(CLIENT *ExceptOf, CLIENT *Prefix, char Flag,
+			      const char *Format, ...)
 #else
 GLOBAL void
-IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, Flag, Format, va_alist )
+IRC_WriteStrServersPrefixFlag(ExceptOf, Prefix, Flag, Format, va_alist)
 CLIENT *ExceptOf;
 CLIENT *Prefix;
 char Flag;
-char *Format;
+const char *Format;
 va_dcl
 #endif
 {
@@ -331,18 +323,18 @@ IRC_WriteStrServersPrefixFlag_CB(CLIENT *ExceptOf, CLIENT *Prefix, char Flag,
  */
 #ifdef PROTOTYPES
 GLOBAL bool
-IRC_WriteStrRelatedPrefix( CLIENT *Client, CLIENT *Prefix, bool Remote, char *Format, ... )
+IRC_WriteStrRelatedPrefix(CLIENT *Client, CLIENT *Prefix, bool Remote,
+			  const char *Format, ...)
 #else
 GLOBAL bool
-IRC_WriteStrRelatedPrefix( Client, Prefix, Remote, Format, va_alist )
+IRC_WriteStrRelatedPrefix(Client, Prefix, Remote, Format, va_alist)
 CLIENT *Client;
 CLIENT *Prefix;
 bool Remote;
-char *Format;
+const char *Format;
 va_dcl
 #endif
 {
-	bool ok = CONNECTED;
 	CL2CHAN *chan_cl2chan, *cl2chan;
 	char buffer[1000];
 	CHANNEL *chan;
@@ -390,18 +382,7 @@ va_dcl
 
 		chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan );
 	}
-
-	conn = Conn_First( );
-	while( conn != NONE )
-	{
-		/* send data via this connection? */
-		if( Conn_Flag( conn ) == SEND_TO_SERVER ) ok = Conn_WriteStr( conn, ":%s %s", Client_ID( Prefix ), buffer );
-		else if( Conn_Flag( conn ) == SEND_TO_USER ) ok = Conn_WriteStr( conn, ":%s %s", Client_Mask( Prefix ), buffer );
-		if( ! ok ) break;
-
-		conn = Conn_Next( conn );
-	}
-	return ok;
+	return Send_Marked_Connections(Prefix, buffer);
 } /* IRC_WriteStrRelatedPrefix */
 
 
@@ -416,7 +397,7 @@ GLOBAL void
 IRC_SendWallops(Client, From, Format, va_alist )
 CLIENT *Client;
 CLIENT *From;
-char *Format;
+const char *Format;
 va_dcl
 #endif
 {
@@ -468,14 +449,16 @@ IRC_SetPenalty( CLIENT *Client, time_t Seconds )
 } /* IRC_SetPenalty */
 
 
-static char *
-Get_Prefix( CLIENT *Target, CLIENT *Client )
+static const char *
+Get_Prefix(CLIENT *Target, CLIENT *Client)
 {
-	assert( Target != NULL );
-	assert( Client != NULL );
+	assert (Target != NULL);
+	assert (Client != NULL);
 
-	if( Client_Type( Target ) == CLIENT_SERVER ) return Client_ID( Client );
-	else return Client_Mask( Client );
+	if (Client_Type(Target) == CLIENT_SERVER)
+		return Client_ID(Client);
+	else
+		return Client_MaskCloaked(Client);
 } /* Get_Prefix */
 
 
@@ -486,4 +469,29 @@ cb_writeStrServersPrefixFlag(CLIENT *Client, CLIENT *Prefix, void *Buffer)
 } /* cb_writeStrServersPrefixFlag */
 
 
+static bool
+Send_Marked_Connections(CLIENT *Prefix, const char *Buffer)
+{
+	CONN_ID conn;
+	bool ok = CONNECTED;
+
+	assert(Prefix != NULL);
+	assert(Buffer != NULL);
+
+	conn = Conn_First();
+	while (conn != NONE) {
+		if (Conn_Flag(conn) == SEND_TO_SERVER)
+			ok = Conn_WriteStr(conn, ":%s %s",
+					   Client_ID(Prefix), Buffer);
+		else if (Conn_Flag(conn) == SEND_TO_USER)
+			ok = Conn_WriteStr(conn, ":%s %s",
+					   Client_MaskCloaked(Prefix), Buffer);
+		if (!ok)
+			break;
+		conn = Conn_Next( conn );
+	}
+	return ok;
+}
+
+
 /* -eof- */

+ 9 - 8
src/ngircd/irc-write.h

@@ -14,26 +14,27 @@
 #ifndef __irc_write_h__
 #define __irc_write_h__
 
-GLOBAL bool IRC_WriteStrClient PARAMS((CLIENT *Client, char *Format, ...));
+GLOBAL bool IRC_WriteStrClient PARAMS((CLIENT *Client, const char *Format, ...));
 GLOBAL bool IRC_WriteStrClientPrefix PARAMS((CLIENT *Client, CLIENT *Prefix,
-		char *Format, ...));
+		const char *Format, ...));
 
 GLOBAL bool IRC_WriteStrChannel PARAMS((CLIENT *Client, CHANNEL *Chan,
-		bool Remote, char *Format, ...));
+		bool Remote, const char *Format, ...));
 GLOBAL bool IRC_WriteStrChannelPrefix PARAMS((CLIENT *Client, CHANNEL *Chan,
-		CLIENT *Prefix, bool Remote, char *Format, ...));
+		CLIENT *Prefix, bool Remote, const char *Format, ...));
 
-GLOBAL void IRC_WriteStrServers PARAMS((CLIENT *ExceptOf, char *Format, ...));
+GLOBAL void IRC_WriteStrServers PARAMS((CLIENT *ExceptOf,
+		const char *Format, ...));
 GLOBAL void IRC_WriteStrServersPrefix PARAMS((CLIENT *ExceptOf, CLIENT *Prefix,
-		char *Format, ...));
+		const char *Format, ...));
 GLOBAL void IRC_WriteStrServersPrefixFlag PARAMS((CLIENT *ExceptOf,
-		CLIENT *Prefix, char Flag, char *Format, ...));
+		CLIENT *Prefix, char Flag, const char *Format, ...));
 GLOBAL void IRC_WriteStrServersPrefixFlag_CB PARAMS((CLIENT *ExceptOf,
 		CLIENT *Prefix, char Flag,
 		void (*callback)(CLIENT *, CLIENT *, void *), void *cb_data));
 
 GLOBAL bool IRC_WriteStrRelatedPrefix PARAMS((CLIENT *Client, CLIENT *Prefix,
-		bool Remote, char *Format, ...));
+		bool Remote, const char *Format, ...));
 
 GLOBAL void IRC_SendWallops PARAMS((CLIENT *Client, CLIENT *From,
 		const char *Format, ...));

+ 17 - 11
src/ngircd/irc.c

@@ -22,10 +22,8 @@ static char UNUSED id[] = "$Id: irc.c,v 1.132 2008/01/15 22:28:14 fw Exp $";
 #include <string.h>
 
 #include "ngircd.h"
-#include "resolve.h"
 #include "conn-func.h"
 #include "conf.h"
-#include "client.h"
 #include "channel.h"
 #include "defines.h"
 #include "irc-write.h"
@@ -53,8 +51,12 @@ IRC_ERROR( CLIENT *Client, REQUEST *Req )
 	assert( Client != NULL );
 	assert( Req != NULL );
 
-	if( Req->argc < 1 ) Log( LOG_NOTICE, "Got ERROR from \"%s\"!", Client_Mask( Client ));
-	else Log( LOG_NOTICE, "Got ERROR from \"%s\": %s!", Client_Mask( Client ), Req->argv[0] );
+	if (Req->argc < 1)
+		Log(LOG_NOTICE, "Got ERROR from \"%s\"!",
+		    Client_Mask(Client));
+	else
+		Log(LOG_NOTICE, "Got ERROR from \"%s\": \"%s\"!",
+		    Client_Mask(Client), Req->argv[0]);
 
 	return CONNECTED;
 } /* IRC_ERROR */
@@ -66,7 +68,7 @@ IRC_ERROR( CLIENT *Client, REQUEST *Req )
  * disconnect clients. It can be used by IRC operators and servers, for example
  * to "solve" nick collisions after netsplits.
  * Please note that this function is also called internally, without a real
- * KILL command beeing received over the network! Client is Client_ThisServer()
+ * KILL command being received over the network! Client is Client_ThisServer()
  * in this case. */
 GLOBAL bool
 IRC_KILL( CLIENT *Client, REQUEST *Req )
@@ -156,11 +158,15 @@ IRC_KILL( CLIENT *Client, REQUEST *Req )
 			     Client_Type( c ), Req->argv[0] );
 		}
 
-		/* Kill client NOW! */
+		/* Kill the client NOW:
+		 *  - Close the local connection (if there is one),
+		 *  - Destroy the CLIENT structure for remote clients.
+		 * Note: Conn_Close() removes the CLIENT structure as well. */
 		conn = Client_Conn( c );
-		Client_Destroy( c, NULL, reason, false );
-		if( conn > NONE )
-			Conn_Close( conn, NULL, reason, true );
+		if(conn > NONE)
+			Conn_Close(conn, NULL, reason, true);
+		else
+			Client_Destroy(c, NULL, reason, false);
 	}
 	else
 		Log( LOG_NOTICE, "Client with nick \"%s\" is unknown here.", Req->argv[0] );
@@ -406,7 +412,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 				if (nick != NULL && host != NULL) {
 					if (strcmp(nick, Client_ID(cl)) == 0 &&
 					    strcmp(user, Client_User(cl)) == 0 &&
-					    strcasecmp(host, Client_Hostname(cl)) == 0)
+					    strcasecmp(host, Client_HostnameCloaked(cl)) == 0)
 						break;
 					else
 						continue;
@@ -414,7 +420,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 				if (strcasecmp(user, Client_User(cl)) != 0)
 					continue;
 				if (host != NULL && strcasecmp(host,
-						Client_Hostname(cl)) != 0)
+						Client_HostnameCloaked(cl)) != 0)
 					continue;
 				if (server != NULL && strcasecmp(server,
 						Client_ID(Client_Introducer(cl))) != 0)

+ 0 - 1
src/ngircd/lists.c

@@ -19,7 +19,6 @@
 
 #include "defines.h"
 #include "conn.h"
-#include "client.h"
 #include "channel.h"
 #include "log.h"
 #include "match.h"

+ 56 - 91
src/ngircd/log.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2005 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,9 +34,9 @@
 #include "ngircd.h"
 #include "defines.h"
 #include "conn.h"
-#include "client.h"
 #include "channel.h"
 #include "irc-write.h"
+#include "conf.h"
 
 #include "exp.h"
 #include "log.h"
@@ -45,12 +45,6 @@
 static char Init_Txt[127];
 static bool Is_Daemon;
 
-#ifdef DEBUG
-static char Error_File[FNAME_LEN];
-#endif
-
-
-static void Wall_ServerNotice PARAMS(( char *Msg ));
 
 static void
 Log_Message(int Level, const char *msg)
@@ -75,13 +69,10 @@ Log_Init( bool Daemon_Mode )
 	Is_Daemon = Daemon_Mode;
 	
 #ifdef SYSLOG
-#ifndef LOG_CONS     /* Kludge: mips-dec-ultrix4.5 has no LOG_CONS/LOG_LOCAL5 */
+#ifndef LOG_CONS     /* Kludge: mips-dec-ultrix4.5 has no LOG_CONS */
 #define LOG_CONS 0
 #endif
-#ifndef LOG_LOCAL5
-#define LOG_LOCAL5 0
-#endif
-	openlog( PACKAGE_NAME, LOG_CONS|LOG_PID, LOG_LOCAL5 );
+	openlog(PACKAGE_NAME, LOG_CONS|LOG_PID, Conf_SyslogFacility);
 #endif
 
 	Log( LOG_NOTICE, "%s started.", NGIRCd_Version );
@@ -112,51 +103,14 @@ Log_Init( bool Daemon_Mode )
 	}
 #endif
 	if( Init_Txt[0] ) Log( LOG_INFO, "Activating: %s.", Init_Txt );
-
-#ifdef DEBUG
-	Error_File[0] = '\0';
-#endif
 } /* Log_Init */
 
 
-#ifdef DEBUG
-GLOBAL void
-Log_InitErrorfile( void )
-{
-	snprintf( Error_File, sizeof Error_File, "%s/%s-%ld.err", ERROR_DIR, PACKAGE_NAME, (long)getpid( ));
-
-	fflush( stderr );
-	if( ! freopen( Error_File, "w", stderr ))
-	{
-		Log( LOG_ERR, "Can't reopen stderr (\"%s\"): %s", Error_File, strerror( errno ));
-		return;
-	}
-
-	fputs( ctime( &NGIRCd_Start ), stderr );
-	fprintf( stderr, "%s started.\n", NGIRCd_Version );
-	fprintf( stderr, "Activating: %s\n\n", Init_Txt[0] ? Init_Txt : "-" );
-	fflush( stderr );
-
-	Log(LOG_DEBUG, "Redirected stderr to \"%s\".", Error_File);
-} /* Log_InitErrfile */
-#endif
-
-
 GLOBAL void
 Log_Exit( void )
 {
-	/* Good Bye! */
-	if( NGIRCd_SignalRestart ) Log( LOG_NOTICE, "%s done (restarting).", PACKAGE_NAME );
-	else Log( LOG_NOTICE, "%s done.", PACKAGE_NAME );
-
-#ifdef DEBUG
-	if( Error_File[0] )
-	{
-		/* Error-File (stderr) loeschen */
-		if( unlink( Error_File ) != 0 ) Log( LOG_ERR, "Can't delete \"%s\": %s", Error_File, strerror( errno ));
-	}
-#endif
-
+	Log(LOG_NOTICE, "%s done%s, served %lu connections.", PACKAGE_NAME,
+	    NGIRCd_SignalRestart ? " (restarting)" : "", Conn_CountAccepted());
 #ifdef SYSLOG
 	closelog();
 #endif
@@ -251,102 +205,113 @@ va_dcl
 
 	Log_Message(Level, msg);
 
-	if (Level <= LOG_CRIT) {
-		/* log critical messages to stderr */
-		fprintf(stderr, "%s\n", msg);
-		fflush(stderr);
-	}
-
 	if (snotice) {
 		/* Send NOTICE to all local users with mode +s and to the
 		 * local &SERVER channel */
-		Wall_ServerNotice(msg);
+		Log_ServerNotice('s', "%s", msg);
 		Channel_LogServer(msg);
 	}
 } /* Log */
 
 
 GLOBAL void
-Log_Init_Resolver( void )
+Log_Init_Subprocess(char UNUSED *Name)
 {
 #ifdef SYSLOG
-	openlog( PACKAGE_NAME, LOG_CONS|LOG_PID, LOG_LOCAL5 );
+	openlog(PACKAGE_NAME, LOG_CONS|LOG_PID, Conf_SyslogFacility);
 #endif
 #ifdef DEBUG
-	Log_Resolver(LOG_DEBUG, "Resolver sub-process starting, PID %ld.", (long)getpid());
+	Log_Subprocess(LOG_DEBUG, "%s sub-process starting, PID %ld.",
+		     Name, (long)getpid());
 #endif
-} /* Log_Init_Resolver */
+}
 
 
 GLOBAL void
-Log_Exit_Resolver( void )
+Log_Exit_Subprocess(char UNUSED *Name)
 {
 #ifdef DEBUG
-	Log_Resolver(LOG_DEBUG, "Resolver sub-process %ld done.", (long)getpid());
+	Log_Subprocess(LOG_DEBUG, "%s sub-process %ld done.",
+		     Name, (long)getpid());
 #endif
 #ifdef SYSLOG
 	closelog( );
 #endif
-} /* Log_Exit_Resolver */
+}
 
 
 #ifdef PROTOTYPES
 GLOBAL void
-Log_Resolver( const int Level, const char *Format, ... )
+Log_Subprocess(const int Level, const char *Format, ...)
 #else
 GLOBAL void
-Log_Resolver( Level, Format, va_alist )
+Log_Subprocess(Level, Format, va_alist)
 const int Level;
 const char *Format;
 va_dcl
 #endif
 {
-	/* Eintrag des Resolver in Logfile(s) schreiben */
-
 	char msg[MAX_LOG_MSG_LEN];
 	va_list ap;
 
-	assert( Format != NULL );
+	assert(Format != NULL);
 
 #ifdef DEBUG
-	if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
+	if ((Level == LOG_DEBUG) && (!NGIRCd_Debug))
+		return;
 #else
-	if( Level == LOG_DEBUG ) return;
+	if (Level == LOG_DEBUG)
+		return;
 #endif
 
-	/* String mit variablen Argumenten zusammenbauen ... */
 #ifdef PROTOTYPES
-	va_start( ap, Format );
+	va_start(ap, Format);
 #else
-	va_start( ap );
+	va_start(ap);
 #endif
-	vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
-	va_end( ap );
+	vsnprintf(msg, MAX_LOG_MSG_LEN, Format, ap);
+	va_end(ap);
 
 	Log_Message(Level, msg);
-} /* Log_Resolver */
+}
 
 
 /**
- * Send log messages to users flagged with the "s" mode.
- * @param Msg The message to send.
+ * Send a log message to all local users flagged with the given user mode.
+ * @param UserMode User mode which the target user must have set,
+ * @param Format The format string.
  */
-static void
-Wall_ServerNotice( char *Msg )
+#ifdef PROTOTYPES
+GLOBAL void
+Log_ServerNotice(const char UserMode, const char *Format, ... )
+#else
+GLOBAL void
+Log_ServerNotice(UserMode, Format, va_alist)
+const char UserMode;
+const char *Format;
+va_dcl
+#endif
 {
 	CLIENT *c;
+	char msg[MAX_LOG_MSG_LEN];
+	va_list ap;
 
-	assert( Msg != NULL );
+	assert(Format != NULL);
 
-	c = Client_First( );
-	while(c) {
-		if (Client_Conn(c) > NONE && Client_HasMode(c, 's'))
-			IRC_WriteStrClient(c, "NOTICE %s :%s%s", Client_ID(c),
-							NOTICE_TXTPREFIX, Msg);
+#ifdef PROTOTYPES
+	va_start(ap, Format);
+#else
+	va_start(ap);
+#endif
+	vsnprintf(msg, MAX_LOG_MSG_LEN, Format, ap);
+	va_end(ap);
 
-		c = Client_Next( c );
+	for(c=Client_First(); c != NULL; c=Client_Next(c)) {
+		if (Client_Conn(c) > NONE && Client_HasMode(c, UserMode))
+			IRC_WriteStrClient(c, "NOTICE %s :%s%s", Client_ID(c),
+							NOTICE_TXTPREFIX, msg);
 	}
-} /* Wall_ServerNotice */
+} /* Log_ServerNotice */
 
 
 /* -eof- */

+ 6 - 7
src/ngircd/log.h

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -8,8 +8,6 @@
  * (at your option) any later version.
  * Please read the file COPYING, README and AUTHORS for more information.
  *
- * $Id: log.h,v 1.20 2006/08/05 09:16:21 fw Exp $
- *
  * Logging functions (header)
  */
 
@@ -40,17 +38,18 @@ GLOBAL void Log_Exit PARAMS(( void ));
 
 GLOBAL void Log PARAMS(( int Level, const char *Format, ... ));
 
+GLOBAL void Log_ServerNotice PARAMS((char UserMode, const char *Format, ...));
+
 #ifdef DEBUG
 GLOBAL void LogDebug PARAMS(( const char *Format, ... ));
 #else
 static inline void LogDebug PARAMS(( UNUSED const char *Format, ... )){/* Do nothing. The compiler should optimize this out, please ;-) */}
 #endif
 
+GLOBAL void Log_Init_Subprocess PARAMS((char *Name));
+GLOBAL void Log_Exit_Subprocess PARAMS((char *Name));
 
-GLOBAL void Log_Init_Resolver PARAMS(( void ));
-GLOBAL void Log_Exit_Resolver PARAMS(( void ));
-
-GLOBAL void Log_Resolver PARAMS(( const int Level, const char *Format, ... ));
+GLOBAL void Log_Subprocess PARAMS((const int Level, const char *Format, ...));
 
 #ifdef DEBUG
 GLOBAL void Log_InitErrorfile PARAMS(( void ));

+ 6 - 2
src/ngircd/messages.h

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
+ * Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
 #define RPL_YOURHOST_MSG		"002 %s :Your host is %s, running version ngircd-%s (%s/%s/%s)"
 #define RPL_CREATED_MSG			"003 %s :This server has been started %s"
 #define RPL_MYINFO_MSG			"004 %s %s ngircd-%s %s %s"
-#define RPL_ISUPPORT1_MSG		"005 %s RFC2812 CASEMAPPING=ascii PREFIX=(ov)@+ CHANTYPES=#&+ CHANMODES=bI,k,l,imnPst CHANLIMIT=#&+:%d :are supported on this server"
+#define RPL_ISUPPORT1_MSG		"005 %s RFC2812 IRCD=ngIRCd CASEMAPPING=ascii PREFIX=(ov)@+ CHANTYPES=#&+ CHANMODES=bI,k,l,imnPst CHANLIMIT=#&+:%d :are supported on this server"
 #define RPL_ISUPPORT2_MSG		"005 %s CHANNELLEN=%d NICKLEN=%d TOPICLEN=%d AWAYLEN=%d KICKLEN=%d PENALTY :are supported on this server"
 
 #define RPL_TRACELINK_MSG		"200 %s Link %s-%s %s %s V%s %ld %d %d"
@@ -46,6 +46,8 @@
 #define RPL_TRACEEND_MSG		"262 %s %s %s-%s.%s :End of TRACE"
 #define RPL_LOCALUSERS_MSG		"265 %s %lu %lu :Current local users: %lu, Max: %lu"
 #define RPL_NETUSERS_MSG		"266 %s %lu %lu :Current global users: %lu, Max: %lu"
+#define RPL_STATSCONN_MSG		"250 %s :Highest connection count: %lu (%lu connections received)"
+#define RPL_WHOISSSL_MSG		"275 %s %s :is connected via SSL (secure link)"
 
 #define RPL_AWAY_MSG			"301 %s %s :%s"
 #define RPL_USERHOST_MSG		"302 %s :"
@@ -63,6 +65,7 @@
 #define RPL_LIST_MSG			"322 %s %s %ld :%s"
 #define RPL_LISTEND_MSG			"323 %s :End of LIST"
 #define RPL_CHANNELMODEIS_MSG		"324 %s %s +%s"
+#define RPL_CREATIONTIME_MSG		"329 %s %s %ld"
 #define RPL_NOTOPIC_MSG			"331 %s %s :No topic is set"
 #define RPL_TOPIC_MSG			"332 %s %s :%s"
 #define RPL_TOPICSETBY_MSG		"333 %s %s %s %u"
@@ -113,6 +116,7 @@
 #define ERR_ALREADYREGISTRED_MSG	"462 %s :Connection already registered"
 #define ERR_PASSWDMISMATCH_MSG		"464 %s :Invalid password"
 #define ERR_CHANNELISFULL_MSG		"471 %s %s :Cannot join channel (+l)"
+#define ERR_SECURECHANNEL_MSG		"471 %s %s :Cannot join channel (+z)"
 #define ERR_UNKNOWNMODE_MSG		"472 %s: %c :is unknown mode char for %s"
 #define ERR_INVITEONLYCHAN_MSG		"473 %s %s :Cannot join channel (+i)"
 #define ERR_BANNEDFROMCHAN_MSG		"474 %s %s :Cannot join channel (+b)"

+ 51 - 175
src/ngircd/ngircd.c

@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2009 Alexander Barton (alex@barton.de).
+ * Copyright (c)2001-2010 Alexander Barton (alex@barton.de).
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,7 +29,6 @@
 #include <time.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/wait.h>
 #include <fcntl.h>
 #include <pwd.h>
 #include <grp.h>
@@ -39,15 +38,15 @@
 #endif
 
 #include "defines.h"
-#include "resolve.h"
 #include "conn.h"
 #include "conf-ssl.h"
-#include "client.h"
 #include "channel.h"
 #include "conf.h"
 #include "lists.h"
 #include "log.h"
 #include "parse.h"
+#include "sighandlers.h"
+#include "io.h"
 #include "irc.h"
 
 #ifdef ZEROCONF
@@ -58,9 +57,6 @@
 #include "ngircd.h"
 
 
-static void Initialize_Signal_Handler PARAMS(( void ));
-static void Signal_Handler PARAMS(( int Signal ));
-
 static void Show_Version PARAMS(( void ));
 static void Show_Help PARAMS(( void ));
 
@@ -69,10 +65,11 @@ static void Pidfile_Delete PARAMS(( void ));
 
 static void Fill_Version PARAMS(( void ));
 
-static void Setup_FDStreams PARAMS(( void ));
+static void Setup_FDStreams PARAMS(( int fd ));
 
 static bool NGIRCd_Init PARAMS(( bool ));
 
+
 /**
  * The main() function of ngIRCd.
  * Here all starts: this function is called by the operating system loader,
@@ -97,7 +94,7 @@ main( int argc, const char *argv[] )
 
 	umask( 0077 );
 
-	NGIRCd_SignalQuit = NGIRCd_SignalRestart = NGIRCd_SignalRehash = false;
+	NGIRCd_SignalQuit = NGIRCd_SignalRestart = false;
 	NGIRCd_Passive = false;
 #ifdef DEBUG
 	NGIRCd_Debug = false;
@@ -265,7 +262,6 @@ main( int argc, const char *argv[] )
 		NGIRCd_Start = time( NULL );
 		(void)strftime( NGIRCd_StartStr, 64, "%a %b %d %Y at %H:%M:%S (%Z)", localtime( &NGIRCd_Start ));
 
-		NGIRCd_SignalRehash = false;
 		NGIRCd_SignalRestart = false;
 		NGIRCd_SignalQuit = false;
 
@@ -289,13 +285,15 @@ main( int argc, const char *argv[] )
 #endif
 		Conn_Init( );
 
-#ifdef DEBUG
-		/* Redirect stderr handle to "error file" for debugging
-		 * when not running in "no daemon" mode: */
-		if( ! NGIRCd_NoDaemon ) Log_InitErrorfile( );
-#endif
+		if (!io_library_init(CONNECTION_POOL)) {
+			Log(LOG_ALERT, "Fatal: Cannot initialize IO routines: %s", strerror(errno));
+			exit(1);
+		}
 
-		Initialize_Signal_Handler( );
+		if (!Signals_Init()) {
+			Log(LOG_ALERT, "Fatal: Could not set up signal handlers: %s", strerror(errno));
+			exit(1);
+		}
 
 		/*
 		 * create protocol and server identification.
@@ -362,7 +360,6 @@ Fill_Version( void )
 #ifdef ZLIB
 	if( NGIRCd_VersionAddition[0] )
 		strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
-
 	strlcat( NGIRCd_VersionAddition, "ZLIB", sizeof NGIRCd_VersionAddition );
 #endif
 #ifdef SSL_SUPPORT
@@ -372,49 +369,46 @@ Fill_Version( void )
 #ifdef TCPWRAP
 	if( NGIRCd_VersionAddition[0] )
 			strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
-
 	strlcat( NGIRCd_VersionAddition, "TCPWRAP", sizeof NGIRCd_VersionAddition );
 #endif
 #ifdef ZEROCONF
 	if( NGIRCd_VersionAddition[0] )
 		strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
-
 	strlcat( NGIRCd_VersionAddition, "ZEROCONF", sizeof NGIRCd_VersionAddition );
 #endif
 #ifdef IDENTAUTH
 	if( NGIRCd_VersionAddition[0] )
 		strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
-
 	strlcat( NGIRCd_VersionAddition, "IDENT", sizeof NGIRCd_VersionAddition );
 #endif
+#ifdef PAM
+	if (NGIRCd_VersionAddition[0])
+		strlcat(NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition);
+	strlcat(NGIRCd_VersionAddition, "PAM", sizeof NGIRCd_VersionAddition);
+#endif
 #ifdef DEBUG
 	if( NGIRCd_VersionAddition[0] )
 		strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
-
 	strlcat( NGIRCd_VersionAddition, "DEBUG", sizeof NGIRCd_VersionAddition );
 #endif
 #ifdef SNIFFER
 	if( NGIRCd_VersionAddition[0] )
 		strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
-
 	strlcat( NGIRCd_VersionAddition, "SNIFFER", sizeof NGIRCd_VersionAddition );
 #endif
 #ifdef STRICT_RFC
 	if( NGIRCd_VersionAddition[0] )
 		strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
-
 	strlcat( NGIRCd_VersionAddition, "RFC", sizeof NGIRCd_VersionAddition );
 #endif
 #ifdef IRCPLUS
 	if( NGIRCd_VersionAddition[0] )
 		strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
-
 	strlcat( NGIRCd_VersionAddition, "IRCPLUS", sizeof NGIRCd_VersionAddition );
 #endif
 #ifdef WANT_IPV6
 	if (NGIRCd_VersionAddition[0])
 		strlcat(NGIRCd_VersionAddition, "+", sizeof(NGIRCd_VersionAddition));
-
 	strlcat(NGIRCd_VersionAddition, "IPv6", sizeof(NGIRCd_VersionAddition));
 #endif
 	if( NGIRCd_VersionAddition[0] )
@@ -432,137 +426,13 @@ Fill_Version( void )
 
 
 /**
- * Reload the server configuration file.
- */
-GLOBAL void
-NGIRCd_Rehash( void )
-{
-	char old_name[CLIENT_ID_LEN];
-	unsigned old_nicklen;
-
-	Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" );
-	NGIRCd_SignalRehash = false;
-
-	/* Remember old server name and nick name length */
-	strlcpy( old_name, Conf_ServerName, sizeof old_name );
-	old_nicklen = Conf_MaxNickLength;
-
-	/* Re-read configuration ... */
-	if (!Conf_Rehash( ))
-		return;
-
-	/* Close down all listening sockets */
-	Conn_ExitListeners( );
-
-	/* Recover old server name and nick name length: these values can't
-	 * be changed during run-time */
-	if (strcmp(old_name, Conf_ServerName) != 0 ) {
-		strlcpy(Conf_ServerName, old_name, sizeof Conf_ServerName);
-		Log(LOG_ERR, "Can't change \"ServerName\" on runtime! Ignored new name.");
-	}
-	if (old_nicklen != Conf_MaxNickLength) {
-		Conf_MaxNickLength = old_nicklen;
-		Log(LOG_ERR, "Can't change \"MaxNickLength\" on runtime! Ignored new value.");
-	}
-
-	/* Create new pre-defined channels */
-	Channel_InitPredefined( );
-
-	if (!ConnSSL_InitLibrary())
-		Log(LOG_WARNING, "Re-Initializing SSL failed, using old keys");
-
-	/* Start listening on sockets */
-	Conn_InitListeners( );
-
-	/* Sync configuration with established connections */
-	Conn_SyncServerStruct( );
-
-	Log( LOG_NOTICE|LOG_snotice, "Re-reading of configuration done." );
-} /* NGIRCd_Rehash */
-
-
-/**
- * Initialize the signal handler.
- */
-static void
-Initialize_Signal_Handler( void )
-{
-#ifdef HAVE_SIGACTION
-	struct sigaction saction;
-
-	memset( &saction, 0, sizeof( saction ));
-	saction.sa_handler = Signal_Handler;
-#ifdef SA_RESTART
-	saction.sa_flags |= SA_RESTART;
-#endif
-#ifdef SA_NOCLDWAIT
-	saction.sa_flags |= SA_NOCLDWAIT;
-#endif
-
-	sigaction(SIGINT, &saction, NULL);
-	sigaction(SIGQUIT, &saction, NULL);
-	sigaction(SIGTERM, &saction, NULL);
-	sigaction(SIGHUP, &saction, NULL);
-	sigaction(SIGCHLD, &saction, NULL);
-
-	/* we handle write errors properly; ignore SIGPIPE */
-	saction.sa_handler = SIG_IGN;
-	sigaction(SIGPIPE, &saction, NULL);
-#else
-	signal(SIGINT, Signal_Handler);
-	signal(SIGQUIT, Signal_Handler);
-	signal(SIGTERM, Signal_Handler);
-	signal(SIGHUP, Signal_Handler);
-	signal(SIGCHLD, Signal_Handler);
-
-	signal(SIGPIPE, SIG_IGN);
-#endif
-} /* Initialize_Signal_Handler */
-
-
-/**
- * Signal handler of ngIRCd.
- * This function is called whenever ngIRCd catches a signal sent by the
- * user and/or the system to it. For example SIGTERM and SIGHUP.
- * @param Signal Number of the signal to handle.
- */
-static void
-Signal_Handler( int Signal )
-{
-	switch( Signal )
-	{
-		case SIGTERM:
-		case SIGINT:
-		case SIGQUIT:
-			/* shut down sever */
-			NGIRCd_SignalQuit = true;
-			break;
-		case SIGHUP:
-			/* re-read configuration */
-			NGIRCd_SignalRehash = true;
-			break;
-		case SIGCHLD:
-			/* child-process exited, avoid zombies */
-			while (waitpid( -1, NULL, WNOHANG) > 0)
-				;
-			break;
-#ifdef DEBUG
-		default:
-			/* unbekanntes bzw. unbehandeltes Signal */
-			Log( LOG_DEBUG, "Got signal %d! Ignored.", Signal );
-#endif
-	}
-} /* Signal_Handler */
-
-
-/**
  * Display copyright and version information of ngIRCd on the console.
  */
 static void
 Show_Version( void )
 {
 	puts( NGIRCd_Version );
-	puts( "Copyright (c)2001-2009 Alexander Barton (<alex@barton.de>) and Contributors." );
+	puts( "Copyright (c)2001-2010 Alexander Barton (<alex@barton.de>) and Contributors." );
 	puts( "Homepage: <http://ngircd.barton.de/>\n" );
 	puts( "This is free software; see the source for copying conditions. There is NO" );
 	puts( "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." );
@@ -652,27 +522,16 @@ Pidfile_Create(pid_t pid)
  * Redirect stdin, stdout and stderr to apropriate file handles.
  */
 static void
-Setup_FDStreams( void )
+Setup_FDStreams(int fd)
 {
-	int fd;
-
-	/* Test if we can open /dev/null for reading and writing. If not
-	 * we are most probably chrooted already and the server has been
-	 * restarted. So we simply don't try to redirect stdXXX ... */
-	fd = open( "/dev/null", O_RDWR );
-	if ( fd < 0 ) {
-		Log(LOG_WARNING, "Could not open /dev/null: %s", strerror(errno));	
+	if (fd < 0)
 		return;
-	} 
 
 	fflush(stdout);
 	fflush(stderr);
 
 	/* Create new stdin(0), stdout(1) and stderr(2) descriptors */
 	dup2( fd, 0 ); dup2( fd, 1 ); dup2( fd, 2 );
-
-	/* Close newly opened file descriptor if not stdin/out/err */
-	if( fd > 2 ) close( fd );
 } /* Setup_FDStreams */
 
 
@@ -715,12 +574,19 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
 	bool chrooted = false;
 	struct passwd *pwd;
 	struct group *grp;
-	int real_errno;
+	int real_errno, fd = -1;
 	pid_t pid;
 
 	if (initialized)
 		return true;
 
+	if (!NGIRCd_NoDaemon) {
+		/* open /dev/null before chroot() */
+		fd = open( "/dev/null", O_RDWR);
+		if (fd < 0)
+			Log(LOG_WARNING, "Could not open /dev/null: %s", strerror(errno));
+	}
+
 	if (!ConnSSL_InitLibrary())
 		Log(LOG_WARNING,
 		    "Warning: Error during SSL initialization, continuing ...");
@@ -728,15 +594,14 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
 	if( Conf_Chroot[0] ) {
 		if( chdir( Conf_Chroot ) != 0 ) {
 			Log( LOG_ERR, "Can't chdir() in ChrootDir (%s): %s", Conf_Chroot, strerror( errno ));
-			return false;
+			goto out;
 		}
 
 		if( chroot( Conf_Chroot ) != 0 ) {
 			if (errno != EPERM) {
 				Log( LOG_ERR, "Can't change root directory to \"%s\": %s",
 								Conf_Chroot, strerror( errno ));
-
-				return false;
+				goto out;
 			}
 		} else {
 			chrooted = true;
@@ -750,7 +615,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
   		if (! NGIRCd_getNobodyID(&Conf_UID, &Conf_GID)) {
 			Log(LOG_WARNING, "Could not get user/group ID of user \"nobody\": %s",
 					errno ? strerror(errno) : "not found" );
-			return false;
+			goto out;
 		}
 	}
 
@@ -760,7 +625,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
 			real_errno = errno;
 			Log( LOG_ERR, "Can't change group ID to %u: %s", Conf_GID, strerror( errno ));
 			if (real_errno != EPERM) 
-				return false;
+				goto out;
 		}
 	}
 
@@ -770,7 +635,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
 			real_errno = errno;
 			Log(LOG_ERR, "Can't change user ID to %u: %s", Conf_UID, strerror(errno));
 			if (real_errno != EPERM) 
-				return false;
+				goto out;
 		}
 	}
 
@@ -798,10 +663,16 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
 #else
 		setpgrp(0, getpid());
 #endif
-		chdir( "/" );
+		if (chdir( "/" ) != 0)
+			Log(LOG_ERR, "Can't change directory to '/': %s",
+				     strerror(errno));
 
 		/* Detach stdin, stdout and stderr */
-		Setup_FDStreams( );
+		Setup_FDStreams(fd);
+		if (fd > 2) {
+			close(fd);
+			fd = -1;
+		}
 	}
 	pid = getpid();
 
@@ -828,8 +699,8 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
 
 	/* Change working directory to home directory of the user
 	 * we are running as (only when running in daemon mode and not in chroot) */
-	
-	if ( pwd ) {
+
+	if (pwd) {
 		if (!NGIRCd_NoDaemon ) {
 			if( chdir( pwd->pw_dir ) == 0 ) 
 				Log( LOG_DEBUG, "Changed working directory to \"%s\" ...", pwd->pw_dir );
@@ -841,7 +712,12 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
 		Log( LOG_ERR, "Can't get user informaton for UID %d!?", Conf_UID );
 	}
 
-return true;
+	return true;
+ out:
+	if (fd > 2)
+		close(fd);
+	return false;
 }
 
+
 /* -eof- */

+ 2 - 4
src/ngircd/ngircd.h

@@ -21,6 +21,8 @@
 
 #include "defines.h"
 
+#define C_ARRAY_SIZE(x)	(sizeof(x)/sizeof((x)[0]))
+
 
 GLOBAL time_t NGIRCd_Start;		/* Startzeitpunkt des Daemon */
 GLOBAL char NGIRCd_StartStr[64];
@@ -39,7 +41,6 @@ GLOBAL bool NGIRCd_Passive;		/* nicht zu anderen Servern connecten */
 
 GLOBAL bool NGIRCd_SignalQuit;	/* true: quit server*/
 GLOBAL bool NGIRCd_SignalRestart;	/* true: restart server */
-GLOBAL bool NGIRCd_SignalRehash;	/* true: reload configuration */
 
 GLOBAL char NGIRCd_DebugLevel[2];	/* Debug-Level fuer IRC_VERSION() */
 
@@ -48,9 +49,6 @@ GLOBAL char NGIRCd_ConfFile[FNAME_LEN];	/* Konfigurationsdatei */
 GLOBAL char NGIRCd_ProtoID[COMMAND_LEN];/* Protokoll- und Server-Identifikation */
 
 
-GLOBAL void NGIRCd_Rehash PARAMS(( void ));
-
-
 #endif
 
 

+ 0 - 2
src/ngircd/numeric.c

@@ -20,12 +20,10 @@
 #include <string.h>
 
 #include "defines.h"
-#include "resolve.h"
 #include "conn.h"
 #include "conf.h"
 #include "conn.h"
 #include "conn-func.h"
-#include "client.h"
 #include "channel.h"
 #include "irc-write.h"
 #include "lists.h"

+ 0 - 1
src/ngircd/op.c

@@ -19,7 +19,6 @@
 #include <string.h>
 
 #include "conn.h"
-#include "client.h"
 #include "channel.h"
 #include "conf.h"
 #include "log.h"

+ 0 - 0
src/ngircd/pam.c


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