mirror of
				https://github.com/osmarks/ngircd.git
				synced 2025-11-03 23:43:00 +00:00 
			
		
		
		
	Compare commits
	
		
			160 Commits
		
	
	
		
			rel-15
			...
			rel-17-rc2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					8449e08245 | ||
| 
						 | 
					05d1df97c3 | ||
| 
						 | 
					01c39ba001 | ||
| 
						 | 
					0c0cac641d | ||
| 
						 | 
					8288878122 | ||
| 
						 | 
					596bc096b0 | ||
| 
						 | 
					5700329f8c | ||
| 
						 | 
					3b74280879 | ||
| 
						 | 
					f1267ca375 | ||
| 
						 | 
					ccb175dce6 | ||
| 
						 | 
					99e08eaced | ||
| 
						 | 
					5f2bc55d36 | ||
| 
						 | 
					1fa5b11995 | ||
| 
						 | 
					d00a0f1e7c | ||
| 
						 | 
					a988bbc86a | ||
| 
						 | 
					4226db873f | ||
| 
						 | 
					f579043671 | ||
| 
						 | 
					50cb321bb1 | ||
| 
						 | 
					ade8902b88 | ||
| 
						 | 
					3a826b774a | ||
| 
						 | 
					c51cc88eb0 | ||
| 
						 | 
					5e82a91d13 | ||
| 
						 | 
					4943bbb066 | ||
| 
						 | 
					e2ba7e08b4 | ||
| 
						 | 
					b1a117cd98 | ||
| 
						 | 
					4a770e8e2d | ||
| 
						 | 
					ba720fcbae | ||
| 
						 | 
					b3cfbc3d28 | ||
| 
						 | 
					74578890b7 | ||
| 
						 | 
					212311efc5 | ||
| 
						 | 
					fe5c7cb22d | ||
| 
						 | 
					cdae82413d | ||
| 
						 | 
					3600dc60fc | ||
| 
						 | 
					cd954ee7e9 | ||
| 
						 | 
					355828e64f | ||
| 
						 | 
					755f54b150 | ||
| 
						 | 
					ef3dbf96eb | ||
| 
						 | 
					1fe17e246c | ||
| 
						 | 
					c135d0dded | ||
| 
						 | 
					1e281a8baa | ||
| 
						 | 
					6349ec8bb3 | ||
| 
						 | 
					8d68fe3f86 | ||
| 
						 | 
					4f6c19712e | ||
| 
						 | 
					4833f9e5c8 | ||
| 
						 | 
					90a186158b | ||
| 
						 | 
					b52d5e2a78 | ||
| 
						 | 
					04e38f17ae | ||
| 
						 | 
					32188d821b | ||
| 
						 | 
					6f4a348b75 | ||
| 
						 | 
					a51670005f | ||
| 
						 | 
					0263fa4c66 | ||
| 
						 | 
					31ea0f8ee9 | ||
| 
						 | 
					fd4dfccc30 | ||
| 
						 | 
					2a4bf67aac | ||
| 
						 | 
					575485eb82 | ||
| 
						 | 
					3fd4f320b7 | ||
| 
						 | 
					6fdd3479f1 | ||
| 
						 | 
					617640e0a3 | ||
| 
						 | 
					f72e22d361 | ||
| 
						 | 
					c65bf5d2ce | ||
| 
						 | 
					9c6230e177 | ||
| 
						 | 
					479a43b1c6 | ||
| 
						 | 
					056de78e31 | ||
| 
						 | 
					a02bc9cc6f | ||
| 
						 | 
					01e40f4b55 | ||
| 
						 | 
					acb66d6463 | ||
| 
						 | 
					63a304755a | ||
| 
						 | 
					6ebb31ab35 | ||
| 
						 | 
					cf93881dfb | ||
| 
						 | 
					560492a4a4 | ||
| 
						 | 
					9cd3494de9 | ||
| 
						 | 
					6131822af6 | ||
| 
						 | 
					57a2faf4a7 | ||
| 
						 | 
					41034950d9 | ||
| 
						 | 
					6faf44bc6d | ||
| 
						 | 
					f369177617 | ||
| 
						 | 
					37ee0a3313 | ||
| 
						 | 
					03457135b7 | ||
| 
						 | 
					28424d013d | ||
| 
						 | 
					583c50476b | ||
| 
						 | 
					808d4f6e85 | ||
| 
						 | 
					fb4b5acfb8 | ||
| 
						 | 
					77870ddf2d | ||
| 
						 | 
					1995af0ed6 | ||
| 
						 | 
					761b2284b9 | ||
| 
						 | 
					79be1c477e | ||
| 
						 | 
					7b5e2fe38e | ||
| 
						 | 
					bf8b646304 | ||
| 
						 | 
					e4ffcd00bd | ||
| 
						 | 
					4cc4c29e38 | ||
| 
						 | 
					0db9a31e50 | ||
| 
						 | 
					5462c6c50f | ||
| 
						 | 
					3d49fa5bff | ||
| 
						 | 
					2d4ea28835 | ||
| 
						 | 
					d4632a727f | ||
| 
						 | 
					60f5dd5b29 | ||
| 
						 | 
					89e73ad4b4 | ||
| 
						 | 
					54e67ea9ee | ||
| 
						 | 
					cc336b7558 | ||
| 
						 | 
					ae55d4f500 | ||
| 
						 | 
					edfa215481 | ||
| 
						 | 
					c6742192a6 | ||
| 
						 | 
					0c0d4af55a | ||
| 
						 | 
					8605e9c0fe | ||
| 
						 | 
					a68103771c | ||
| 
						 | 
					8ad1c23ae4 | ||
| 
						 | 
					f76e0a1db6 | ||
| 
						 | 
					51ed742054 | ||
| 
						 | 
					60eac5e952 | ||
| 
						 | 
					139d6303e7 | ||
| 
						 | 
					28f8b50174 | ||
| 
						 | 
					e2930f3f5e | ||
| 
						 | 
					059e707249 | ||
| 
						 | 
					b849e63fbf | ||
| 
						 | 
					55190f2d3d | ||
| 
						 | 
					6dc80bd195 | ||
| 
						 | 
					df359835d1 | ||
| 
						 | 
					defd7e09af | ||
| 
						 | 
					29d448ed63 | ||
| 
						 | 
					bdec5ac1f3 | ||
| 
						 | 
					73fd26e9fa | ||
| 
						 | 
					79e1ec2b1e | ||
| 
						 | 
					615d09459e | ||
| 
						 | 
					1338ade650 | ||
| 
						 | 
					21140500f1 | ||
| 
						 | 
					77ceb9f8ab | ||
| 
						 | 
					b042363e88 | ||
| 
						 | 
					6b0bb665c3 | ||
| 
						 | 
					1caa3fb94b | ||
| 
						 | 
					025342fe46 | ||
| 
						 | 
					628c6c962b | ||
| 
						 | 
					1ed49de83a | ||
| 
						 | 
					bb914b93e9 | ||
| 
						 | 
					50e8a62c5c | ||
| 
						 | 
					aa32fec1b6 | ||
| 
						 | 
					cbe41ec875 | ||
| 
						 | 
					20276f7cc9 | ||
| 
						 | 
					6e8cf51bb2 | ||
| 
						 | 
					53fc0ebff6 | ||
| 
						 | 
					9b3e143a26 | ||
| 
						 | 
					f1bbc92b39 | ||
| 
						 | 
					1da3e25e65 | ||
| 
						 | 
					e1de769ab9 | ||
| 
						 | 
					9f58418765 | ||
| 
						 | 
					ef157715a0 | ||
| 
						 | 
					ecad9f32c8 | ||
| 
						 | 
					f58c8b94d9 | ||
| 
						 | 
					3a2ac66f7f | ||
| 
						 | 
					cf05bf31a7 | ||
| 
						 | 
					a4d7c6f145 | ||
| 
						 | 
					1ddc74f13e | ||
| 
						 | 
					75dabcaae5 | ||
| 
						 | 
					1b73e68e6e | ||
| 
						 | 
					03cde2efd3 | ||
| 
						 | 
					cb6faed61c | ||
| 
						 | 
					c62c2d349b | ||
| 
						 | 
					60137a7139 | ||
| 
						 | 
					513a75c919 | ||
| 
						 | 
					4f1b5400e9 | ||
| 
						 | 
					28ca31e576 | 
							
								
								
									
										4
									
								
								.mailmap
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.mailmap
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
# mailmap file for git-[short]log and git-blame
 | 
			
		||||
 | 
			
		||||
Alexander Barton <anonymous>
 | 
			
		||||
Ali Shemiran <ashemira@ucsd.edu>
 | 
			
		||||
							
								
								
									
										108
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										108
									
								
								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,112 @@
 | 
			
		||||
                               -- ChangeLog --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ngIRCd Release 17
 | 
			
		||||
 | 
			
		||||
  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.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								INSTALL
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								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
 | 
			
		||||
@@ -10,10 +10,14 @@
 | 
			
		||||
                                -- 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
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										58
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								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,62 @@
 | 
			
		||||
                                  -- NEWS --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ngIRCd Release 17
 | 
			
		||||
 | 
			
		||||
  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)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								README
									
									
									
									
									
								
							@@ -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).
 | 
			
		||||
 
 | 
			
		||||
@@ -150,20 +150,23 @@ echo "Generating files ..."
 | 
			
		||||
$ACLOCAL && \
 | 
			
		||||
	$AUTOHEADER && \
 | 
			
		||||
	$AUTOMAKE --add-missing && \
 | 
			
		||||
	$AUTOCONF
 | 
			
		||||
	$AUTOCONF --force
 | 
			
		||||
 | 
			
		||||
if [ $? -eq 0 -a -x ./configure ]; then
 | 
			
		||||
	# Success: if we got some parameters we call ./configure and pass
 | 
			
		||||
	# all of them to it.
 | 
			
		||||
	NAME=`grep PACKAGE_STRING= configure | cut -d"'" -f2`
 | 
			
		||||
	if [ "$GO" = "1" ]; then
 | 
			
		||||
		[ -n "$PREFIX" ] && p=" --prefix=$PREFIX" || p=""
 | 
			
		||||
		[ -n "$*" ] && a=" $*" || a=""
 | 
			
		||||
		c="./configure${p}${a}"
 | 
			
		||||
		echo "Okay, autogen.sh for $NAME done."
 | 
			
		||||
		echo "Calling \"$c\" ..."
 | 
			
		||||
		$c
 | 
			
		||||
		exit $?
 | 
			
		||||
	else
 | 
			
		||||
		echo "Okay, autogen.sh done; now run the \"configure\" script."
 | 
			
		||||
		echo "Okay, autogen.sh for $NAME done."
 | 
			
		||||
		echo "Now run the \"./configure\" script."
 | 
			
		||||
		exit 0
 | 
			
		||||
	fi
 | 
			
		||||
else
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										73
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								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-
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,33 @@
 | 
			
		||||
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.
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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:
 | 
			
		||||
 
 | 
			
		||||
@@ -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,11 @@
 | 
			
		||||
#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
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -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 \
 | 
			
		||||
 
 | 
			
		||||
@@ -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>";
 | 
			
		||||
@@ -682,6 +701,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;
 | 
			
		||||
		};
 | 
			
		||||
@@ -746,6 +768,7 @@
 | 
			
		||||
		FAB0570D105D917F006AF9E2 /* Debug */ = {
 | 
			
		||||
			isa = XCBuildConfiguration;
 | 
			
		||||
			buildSettings = {
 | 
			
		||||
				ARCHS = "$(NATIVE_ARCH_ACTUAL)";
 | 
			
		||||
				GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
 | 
			
		||||
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 | 
			
		||||
				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
 | 
			
		||||
@@ -758,13 +781,14 @@
 | 
			
		||||
				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;
 | 
			
		||||
				GCC_WARN_UNUSED_PARAMETER = YES;
 | 
			
		||||
				GCC_WARN_UNUSED_VALUE = YES;
 | 
			
		||||
				INSTALL_PATH = /usr/local/bin;
 | 
			
		||||
				ONLY_ACTIVE_ARCH = YES;
 | 
			
		||||
				PRODUCT_NAME = ngIRCd;
 | 
			
		||||
				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk";
 | 
			
		||||
			};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
%define name    ngircd
 | 
			
		||||
%define version 15
 | 
			
		||||
%define version 17~rc2
 | 
			
		||||
%define release 1
 | 
			
		||||
%define prefix  %{_prefix}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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,9 +51,9 @@ 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 [ -e ./autogen.sh ]; then
 | 
			
		||||
	echo "$NAME: Running ./autogen.sh ..."
 | 
			
		||||
	[ -n "$VERBOSE" ] && ./autogen.sh || ./autogen.sh >/dev/null
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
@@ -93,7 +93,7 @@ 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 }" \
 | 
			
		||||
@@ -103,12 +103,12 @@ if [ -r "Makefile" ]; then
 | 
			
		||||
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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										53
									
								
								doc/Bopm.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								doc/Bopm.txt
									
									
									
									
									
										Normal file
									
								
							@@ -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 ...
 | 
			
		||||
							
								
								
									
										28
									
								
								doc/FAQ.txt
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								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
									
								
								doc/HowToRelease.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								doc/HowToRelease.txt
									
									
									
									
									
										Normal file
									
								
							@@ -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 :-)
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -14,13 +14,11 @@ 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
 | 
			
		||||
	HowToRelease.txt sample-ngircd.conf
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in
 | 
			
		||||
 | 
			
		||||
docdir = $(datadir)/doc/$(PACKAGE)
 | 
			
		||||
 | 
			
		||||
documents = $(EXTRA_DIST) ../AUTHORS ../COPYING ../ChangeLog ../INSTALL \
 | 
			
		||||
	../NEWS ../README
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								doc/PAM.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								doc/PAM.txt
									
									
									
									
									
										Normal file
									
								
							@@ -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.
 | 
			
		||||
@@ -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,27 +32,32 @@ 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-dev     10-10-05 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/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/freebsd6.2     gcc 3.4.6    17-dev     10-10-05 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/freebsd7.3     gcc 4.2.1    17-dev     10-10-05 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
 | 
			
		||||
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-dev     10-10-05 alex   Y Y Y Y (3)
 | 
			
		||||
i386/unknown/netbsdelf5.0.2 gcc 4.1.3    17-dev     10-10-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)
 | 
			
		||||
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~rc1     10-10-12 alex   Y Y Y Y
 | 
			
		||||
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 ? ?
 | 
			
		||||
@@ -65,7 +70,10 @@ 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.0   gcc 4.2.1    16         10-04-23 alex   Y Y Y Y (3)
 | 
			
		||||
x86_64/unknown/freebsd8.1   gcc 4.2.1    17-dev     10-10-05 alex   Y Y Y Y (3)
 | 
			
		||||
x86_64/unknown/linux-gnu    gcc 4.3.2    17-dev     10-10-05 alex   Y Y Y Y (1)
 | 
			
		||||
x86_64/unknown/openbsd4.7   gcc 3.3.5    17-dev     10-10-05 alex   Y Y Y Y (3)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Notes
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								doc/README-Interix.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								doc/README-Interix.txt
									
									
									
									
									
										Normal file
									
								
							@@ -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.
 | 
			
		||||
 | 
			
		||||
@@ -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 +28,15 @@
 | 
			
		||||
	# 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
 | 
			
		||||
@@ -42,7 +48,7 @@
 | 
			
		||||
	;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
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
	# 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
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -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_Hostname( CLIENT *Client )
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
	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- */
 | 
			
		||||
 
 | 
			
		||||
@@ -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- */
 | 
			
		||||
 
 | 
			
		||||
@@ -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 */
 | 
			
		||||
 
 | 
			
		||||
@@ -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,12 +39,10 @@
 | 
			
		||||
#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"
 | 
			
		||||
@@ -55,7 +53,10 @@ static bool Use_Log = 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,19 @@ 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);
 | 
			
		||||
	printf("  MotdFile = %s\n", Conf_MotdFile);
 | 
			
		||||
	printf("  MotdPhrase = %.32s\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 +324,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 +337,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 +349,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 +574,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 +587,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 +606,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 +632,36 @@ 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);
 | 
			
		||||
 | 
			
		||||
	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 +684,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 +743,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 +771,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 +825,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 +844,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 +866,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 +899,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 +933,24 @@ 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));
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if( strcasecmp( Var, "ChrootDir" ) == 0 ) {
 | 
			
		||||
@@ -961,6 +1046,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 ) {
 | 
			
		||||
@@ -1072,6 +1167,13 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 | 
			
		||||
		Conf_SSLOptions.DHFile = strdup_warn( 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);
 | 
			
		||||
@@ -1081,36 +1183,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 +1480,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 +1551,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 +1588,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 */
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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 )
 | 
			
		||||
 
 | 
			
		||||
@@ -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 ));
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -21,9 +21,9 @@
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
#	include <stdarg.h>
 | 
			
		||||
# include <stdarg.h>
 | 
			
		||||
#else
 | 
			
		||||
#	include <varargs.h>
 | 
			
		||||
# include <varargs.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
@@ -37,6 +37,9 @@
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_NETINET_IP_H
 | 
			
		||||
# ifdef HAVE_NETINET_IN_SYSTM_H
 | 
			
		||||
#  include <netinet/in_systm.h>
 | 
			
		||||
# endif
 | 
			
		||||
# include <netinet/ip.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -50,20 +53,22 @@
 | 
			
		||||
 | 
			
		||||
#include "array.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "array.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "conn-ssl.h"
 | 
			
		||||
#include "conn-zip.h"
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "ng_ipaddr.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
#include "tool.h"
 | 
			
		||||
 | 
			
		||||
#ifdef ZEROCONF
 | 
			
		||||
@@ -92,10 +97,12 @@ static bool Init_Socket PARAMS(( int Sock ));
 | 
			
		||||
static void New_Server PARAMS(( int Server, ng_ipaddr_t *dest ));
 | 
			
		||||
static void Simple_Message PARAMS(( int Sock, const char *Msg ));
 | 
			
		||||
static int NewListener PARAMS(( const char *listen_addr, UINT16 Port ));
 | 
			
		||||
static void Account_Connection PARAMS((void));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static array My_Listeners;
 | 
			
		||||
static array My_ConnArray;
 | 
			
		||||
static size_t NumConnections;
 | 
			
		||||
static size_t NumConnections, NumConnectionsMax, NumConnectionsAccepted;
 | 
			
		||||
 | 
			
		||||
#ifdef TCPWRAP
 | 
			
		||||
int allow_severity = LOG_INFO;
 | 
			
		||||
@@ -109,37 +116,51 @@ extern struct SSLOptions Conf_SSLOptions;
 | 
			
		||||
static void cb_connserver_login_ssl PARAMS((int sock, short what));
 | 
			
		||||
static void cb_clientserver_ssl PARAMS((int sock, short what));
 | 
			
		||||
#endif
 | 
			
		||||
static void cb_Read_Resolver_Result PARAMS(( int sock, UNUSED short what));
 | 
			
		||||
static void cb_Connect_to_Server PARAMS(( int sock, UNUSED short what));
 | 
			
		||||
static void cb_Read_Resolver_Result PARAMS((int sock, UNUSED short what));
 | 
			
		||||
static void cb_Connect_to_Server PARAMS((int sock, UNUSED short what));
 | 
			
		||||
static void cb_clientserver PARAMS((int sock, short what));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * IO callback for listening sockets: handle new connections. This callback
 | 
			
		||||
 * gets called when a new non-SSL connection should be accepted.
 | 
			
		||||
 * @param sock Socket descriptor
 | 
			
		||||
 * @param irrelevant (ignored IO specification)
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
cb_listen(int sock, short irrelevant)
 | 
			
		||||
{
 | 
			
		||||
	(void) irrelevant;
 | 
			
		||||
	if (New_Connection( sock ) >= 0)
 | 
			
		||||
		NumConnections++;
 | 
			
		||||
	LogDebug("Total number of connections now %ld.", NumConnections);
 | 
			
		||||
	(void) New_Connection(sock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef SSL_SUPPORT
 | 
			
		||||
/**
 | 
			
		||||
 * IO callback for listening SSL sockets: handle new connections. This callback
 | 
			
		||||
 * gets called when a new SSL-enabled connection should be accepted.
 | 
			
		||||
 * @param sock Socket descriptor
 | 
			
		||||
 * @param irrelevant (ignored IO specification)
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
cb_listen_ssl(int sock, short irrelevant)
 | 
			
		||||
{
 | 
			
		||||
	int fd;
 | 
			
		||||
 | 
			
		||||
	(void) irrelevant;
 | 
			
		||||
	fd = New_Connection(sock);
 | 
			
		||||
	if (fd < 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	NumConnections++;
 | 
			
		||||
	LogDebug("Total number of connections now %ld.", NumConnections);
 | 
			
		||||
	io_event_setcb(My_Connections[fd].sock, cb_clientserver_ssl);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * IO callback for new outgoing non-SSL server connections.
 | 
			
		||||
 * @param sock Socket descriptor
 | 
			
		||||
 * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...)
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
cb_connserver(int sock, UNUSED short what)
 | 
			
		||||
{
 | 
			
		||||
@@ -213,6 +234,10 @@ cb_connserver(int sock, UNUSED short what)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Login to a remote server.
 | 
			
		||||
 * @param idx Connection index
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
server_login(CONN_ID idx)
 | 
			
		||||
{
 | 
			
		||||
@@ -229,6 +254,11 @@ server_login(CONN_ID idx)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef SSL_SUPPORT
 | 
			
		||||
/**
 | 
			
		||||
 * IO callback for new outgoing SSL-enabled server connections.
 | 
			
		||||
 * @param sock Socket descriptor
 | 
			
		||||
 * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...)
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
cb_connserver_login_ssl(int sock, short unused)
 | 
			
		||||
{
 | 
			
		||||
@@ -258,6 +288,11 @@ cb_connserver_login_ssl(int sock, short unused)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * IO callback for established non-SSL client and server connections.
 | 
			
		||||
 * @param sock Socket descriptor
 | 
			
		||||
 * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...)
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
cb_clientserver(int sock, short what)
 | 
			
		||||
{
 | 
			
		||||
@@ -270,18 +305,27 @@ cb_clientserver(int sock, short what)
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
#ifdef SSL_SUPPORT
 | 
			
		||||
	if (what & IO_WANTREAD || (Conn_OPTION_ISSET(&My_Connections[idx], CONN_SSL_WANT_WRITE)))
 | 
			
		||||
		Read_Request( idx ); /* if TLS layer needs to write additional data, call Read_Request instead so SSL/TLS can continue */
 | 
			
		||||
	if (what & IO_WANTREAD
 | 
			
		||||
	    || (Conn_OPTION_ISSET(&My_Connections[idx], CONN_SSL_WANT_WRITE))) {
 | 
			
		||||
		/* if TLS layer needs to write additional data, call
 | 
			
		||||
		 * Read_Request() instead so that SSL/TLS can continue */
 | 
			
		||||
		Read_Request(idx);
 | 
			
		||||
	}
 | 
			
		||||
#else
 | 
			
		||||
	if (what & IO_WANTREAD)
 | 
			
		||||
		Read_Request( idx );
 | 
			
		||||
		Read_Request(idx);
 | 
			
		||||
#endif
 | 
			
		||||
	if (what & IO_WANTWRITE)
 | 
			
		||||
		Handle_Write( idx );
 | 
			
		||||
		Handle_Write(idx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef SSL_SUPPORT
 | 
			
		||||
/**
 | 
			
		||||
 * IO callback for established SSL-enabled client and server connections.
 | 
			
		||||
 * @param sock Socket descriptor
 | 
			
		||||
 * @param what IO specification (IO_WANTREAD/IO_WANTWRITE/...)
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
cb_clientserver_ssl(int sock, short what)
 | 
			
		||||
{
 | 
			
		||||
@@ -295,11 +339,13 @@ cb_clientserver_ssl(int sock, short what)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch (ConnSSL_Accept(&My_Connections[idx])) {
 | 
			
		||||
		case 1: break;	/* OK */
 | 
			
		||||
		case 0: return; /* EAGAIN: this callback will be invoked again by the io layer */
 | 
			
		||||
		default:
 | 
			
		||||
			Conn_Close( idx, "Socket closed!", "SSL accept error", false );
 | 
			
		||||
			return;
 | 
			
		||||
	case 1:
 | 
			
		||||
		break;	/* OK */
 | 
			
		||||
	case 0:
 | 
			
		||||
		return;	/* EAGAIN: callback will be invoked again by IO layer */
 | 
			
		||||
	default:
 | 
			
		||||
		Conn_Close(idx, "SSL accept error, closing socket", "SSL accept error", false);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (what & IO_WANTREAD)
 | 
			
		||||
		Read_Request(idx);
 | 
			
		||||
@@ -312,6 +358,9 @@ cb_clientserver_ssl(int sock, short what)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialite connecion module.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_Init( void )
 | 
			
		||||
{
 | 
			
		||||
@@ -324,8 +373,8 @@ Conn_Init( void )
 | 
			
		||||
			Pool_Size = Conf_MaxConnections;
 | 
			
		||||
 | 
			
		||||
	if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)Pool_Size)) {
 | 
			
		||||
		Log( LOG_EMERG, "Can't allocate memory! [Conn_Init]" );
 | 
			
		||||
		exit( 1 );
 | 
			
		||||
		Log(LOG_EMERG, "Can't allocate memory! [Conn_Init]");
 | 
			
		||||
		exit(1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* FIXME: My_Connetions/Pool_Size is needed by other parts of the
 | 
			
		||||
@@ -333,20 +382,21 @@ Conn_Init( void )
 | 
			
		||||
	My_Connections = (CONNECTION*) array_start(&My_ConnArray);
 | 
			
		||||
 | 
			
		||||
	LogDebug("Allocated connection pool for %d items (%ld bytes).",
 | 
			
		||||
		array_length(&My_ConnArray, sizeof( CONNECTION )), array_bytes(&My_ConnArray));
 | 
			
		||||
		array_length(&My_ConnArray, sizeof(CONNECTION)),
 | 
			
		||||
		array_bytes(&My_ConnArray));
 | 
			
		||||
 | 
			
		||||
	assert( array_length(&My_ConnArray, sizeof( CONNECTION )) >= (size_t) Pool_Size);
 | 
			
		||||
	assert(array_length(&My_ConnArray, sizeof(CONNECTION)) >= (size_t)Pool_Size);
 | 
			
		||||
	
 | 
			
		||||
	array_free( &My_Listeners );
 | 
			
		||||
 | 
			
		||||
	/* Connection-Struktur initialisieren */
 | 
			
		||||
	for( i = 0; i < Pool_Size; i++ ) Init_Conn_Struct( i );
 | 
			
		||||
 | 
			
		||||
	/* Global write counter */
 | 
			
		||||
	WCounter = 0;
 | 
			
		||||
	for (i = 0; i < Pool_Size; i++)
 | 
			
		||||
		Init_Conn_Struct(i);
 | 
			
		||||
} /* Conn_Init */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Clean up connection module.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_Exit( void )
 | 
			
		||||
{
 | 
			
		||||
@@ -369,6 +419,23 @@ Conn_Exit( void )
 | 
			
		||||
} /* Conn_Exit */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Close all sockets (file descriptors) of open connections.
 | 
			
		||||
 * This is useful in forked child processes, for example, to make sure that
 | 
			
		||||
 * they don't hold connections open that the main process wants to close.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_CloseAllSockets(void)
 | 
			
		||||
{
 | 
			
		||||
	CONN_ID idx;
 | 
			
		||||
 | 
			
		||||
	for(idx = 0; idx < Pool_Size; idx++) {
 | 
			
		||||
		if(My_Connections[idx].sock > NONE)
 | 
			
		||||
			close(My_Connections[idx].sock);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static unsigned int
 | 
			
		||||
ports_initlisteners(array *a, const char *listen_addr, void (*func)(int,short))
 | 
			
		||||
{
 | 
			
		||||
@@ -399,6 +466,10 @@ ports_initlisteners(array *a, const char *listen_addr, void (*func)(int,short))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialize all listening sockets.
 | 
			
		||||
 * @return Number of created listening sockets
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL unsigned int
 | 
			
		||||
Conn_InitListeners( void )
 | 
			
		||||
{
 | 
			
		||||
@@ -406,11 +477,6 @@ Conn_InitListeners( void )
 | 
			
		||||
	unsigned int created = 0;
 | 
			
		||||
	char *copy, *listen_addr;
 | 
			
		||||
 | 
			
		||||
	if (!io_library_init(CONNECTION_POOL)) {
 | 
			
		||||
		Log(LOG_EMERG, "Cannot initialize IO routines: %s", strerror(errno));
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	assert(Conf_ListenAddress);
 | 
			
		||||
 | 
			
		||||
	/* can't use Conf_ListenAddress directly, see below */
 | 
			
		||||
@@ -433,13 +499,12 @@ Conn_InitListeners( void )
 | 
			
		||||
		listen_addr = strtok(NULL, ",");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * can't free() Conf_ListenAddress here. On /REHASH, if the config file
 | 
			
		||||
	/* Can't free() Conf_ListenAddress here: on REHASH, if the config file
 | 
			
		||||
	 * cannot be re-loaded, we'd end up with a NULL Conf_ListenAddress.
 | 
			
		||||
	 * Instead, free() takes place in conf.c, before the config file
 | 
			
		||||
	 * is being parsed.
 | 
			
		||||
	 */
 | 
			
		||||
	 * is being parsed. */
 | 
			
		||||
	free(copy);
 | 
			
		||||
 | 
			
		||||
	return created;
 | 
			
		||||
} /* Conn_InitListeners */
 | 
			
		||||
 | 
			
		||||
@@ -582,6 +647,7 @@ NewListener(const char *listen_addr, UINT16 Port)
 | 
			
		||||
	return sock;
 | 
			
		||||
} /* NewListener */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef SSL_SUPPORT
 | 
			
		||||
/*
 | 
			
		||||
 * SSL/TLS connections require extra treatment:
 | 
			
		||||
@@ -615,9 +681,11 @@ SSL_WantWrite(const CONNECTION *c)
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
static inline bool
 | 
			
		||||
SSL_WantRead(UNUSED const CONNECTION *c) { return false; }
 | 
			
		||||
SSL_WantRead(UNUSED const CONNECTION *c)
 | 
			
		||||
{ return false; }
 | 
			
		||||
static inline bool
 | 
			
		||||
SSL_WantWrite(UNUSED const CONNECTION *c) { return false; }
 | 
			
		||||
SSL_WantWrite(UNUSED const CONNECTION *c)
 | 
			
		||||
{ return false; }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -644,10 +712,6 @@ Conn_Handler(void)
 | 
			
		||||
		Rendezvous_Handler();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		/* Should the configuration be reloaded? */
 | 
			
		||||
		if (NGIRCd_SignalRehash)
 | 
			
		||||
			NGIRCd_Rehash();
 | 
			
		||||
 | 
			
		||||
		/* Check configured servers and established links */
 | 
			
		||||
		Check_Servers();
 | 
			
		||||
		Check_Connections();
 | 
			
		||||
@@ -700,8 +764,9 @@ Conn_Handler(void)
 | 
			
		||||
			if (SSL_WantWrite(&My_Connections[i]))
 | 
			
		||||
				continue; /* TLS/SSL layer needs to write data; deal with this first */
 | 
			
		||||
#endif
 | 
			
		||||
			if (Resolve_INPROGRESS(&My_Connections[i].res_stat)) {
 | 
			
		||||
				/* Wait for completion of resolver sub-process ... */
 | 
			
		||||
			if (Proc_InProgress(&My_Connections[i].proc_stat)) {
 | 
			
		||||
				/* Wait for completion of forked subprocess
 | 
			
		||||
				 * and ignore the socket in the meantime ... */
 | 
			
		||||
				io_event_del(My_Connections[i].sock,
 | 
			
		||||
					     IO_WANTREAD);
 | 
			
		||||
				continue;
 | 
			
		||||
@@ -717,6 +782,7 @@ Conn_Handler(void)
 | 
			
		||||
					     IO_WANTREAD);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			io_event_add(My_Connections[i].sock, IO_WANTREAD);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -757,12 +823,12 @@ Conn_Handler(void)
 | 
			
		||||
 */
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Conn_WriteStr( CONN_ID Idx, char *Format, ... )
 | 
			
		||||
Conn_WriteStr(CONN_ID Idx, const char *Format, ...)
 | 
			
		||||
#else
 | 
			
		||||
GLOBAL bool 
 | 
			
		||||
Conn_WriteStr( Idx, Format, va_alist )
 | 
			
		||||
Conn_WriteStr(Idx, Format, va_alist)
 | 
			
		||||
CONN_ID Idx;
 | 
			
		||||
char *Format;
 | 
			
		||||
const char *Format;
 | 
			
		||||
va_dcl
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
@@ -1018,10 +1084,6 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
 | 
			
		||||
		    in_k, out_k);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* cancel running resolver */
 | 
			
		||||
	if (Resolve_INPROGRESS(&My_Connections[Idx].res_stat))
 | 
			
		||||
		Resolve_Shutdown(&My_Connections[Idx].res_stat);
 | 
			
		||||
 | 
			
		||||
	/* Servers: Modify time of next connect attempt? */
 | 
			
		||||
	Conf_UnsetServer( Idx );
 | 
			
		||||
 | 
			
		||||
@@ -1049,32 +1111,53 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
 | 
			
		||||
} /* Conn_Close */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_SyncServerStruct( void )
 | 
			
		||||
GLOBAL long
 | 
			
		||||
Conn_Count(void)
 | 
			
		||||
{
 | 
			
		||||
	/* Synchronize server structures (connection IDs):
 | 
			
		||||
	 * connections <-> configuration */
 | 
			
		||||
	return NumConnections;
 | 
			
		||||
} /* Conn_Count */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL long
 | 
			
		||||
Conn_CountMax(void)
 | 
			
		||||
{
 | 
			
		||||
	return NumConnectionsMax;
 | 
			
		||||
} /* Conn_CountMax */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL long
 | 
			
		||||
Conn_CountAccepted(void)
 | 
			
		||||
{
 | 
			
		||||
	return NumConnectionsAccepted;
 | 
			
		||||
} /* Conn_CountAccepted */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Synchronize established connections and configured server structures
 | 
			
		||||
 * after a configuration update and store the correct connection IDs, if any.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_SyncServerStruct(void)
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *client;
 | 
			
		||||
	CONN_ID i;
 | 
			
		||||
	int c;
 | 
			
		||||
 | 
			
		||||
	for( i = 0; i < Pool_Size; i++ ) {
 | 
			
		||||
		/* Established connection? */
 | 
			
		||||
		if (My_Connections[i].sock < 0)
 | 
			
		||||
	for (i = 0; i < Pool_Size; i++) {
 | 
			
		||||
		if (My_Connections[i].sock == NONE)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* Server connection? */
 | 
			
		||||
		client = Conn_GetClient( i );
 | 
			
		||||
		if(( ! client ) || ( Client_Type( client ) != CLIENT_SERVER )) continue;
 | 
			
		||||
		/* Server link? */
 | 
			
		||||
		client = Conn_GetClient(i);
 | 
			
		||||
		if (!client || Client_Type(client) != CLIENT_SERVER)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		for( c = 0; c < MAX_SERVERS; c++ )
 | 
			
		||||
		{
 | 
			
		||||
		for (c = 0; c < MAX_SERVERS; c++) {
 | 
			
		||||
			/* Configured server? */
 | 
			
		||||
			if( ! Conf_Server[c].host[0] ) continue;
 | 
			
		||||
			if (!Conf_Server[c].host[0])
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			/* Duplicate? */
 | 
			
		||||
			if( strcmp( Conf_Server[c].name, Client_ID( client )) == 0 )
 | 
			
		||||
			if (strcasecmp(Conf_Server[c].name, Client_ID(client)) == 0)
 | 
			
		||||
				Conf_Server[c].conn_id = i;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -1163,12 +1246,14 @@ Count_Connections(ng_ipaddr_t *a)
 | 
			
		||||
} /* Count_Connections */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialize new client connection on a listening socket.
 | 
			
		||||
 * @param Sock Listening socket descriptor
 | 
			
		||||
 * @return Accepted socket descriptor or -1 on error
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
New_Connection( int Sock )
 | 
			
		||||
New_Connection(int Sock)
 | 
			
		||||
{
 | 
			
		||||
	/* Neue Client-Verbindung von Listen-Socket annehmen und
 | 
			
		||||
	 * CLIENT-Struktur anlegen. */
 | 
			
		||||
 | 
			
		||||
#ifdef TCPWRAP
 | 
			
		||||
	struct request_info req;
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1178,16 +1263,16 @@ New_Connection( int Sock )
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	long cnt;
 | 
			
		||||
 | 
			
		||||
	assert( Sock > NONE );
 | 
			
		||||
	/* Connection auf Listen-Socket annehmen */
 | 
			
		||||
	new_sock_len = (int)sizeof(new_addr);
 | 
			
		||||
	assert(Sock > NONE);
 | 
			
		||||
 | 
			
		||||
	new_sock_len = (int)sizeof(new_addr);
 | 
			
		||||
	new_sock = accept(Sock, (struct sockaddr *)&new_addr,
 | 
			
		||||
			  (socklen_t *)&new_sock_len);
 | 
			
		||||
	if (new_sock < 0) {
 | 
			
		||||
		Log(LOG_CRIT, "Can't accept connection: %s!", strerror(errno));
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	NumConnectionsAccepted++;
 | 
			
		||||
 | 
			
		||||
	if (!ng_ipaddr_tostr_r(&new_addr, ip_str)) {
 | 
			
		||||
		Log(LOG_CRIT, "fd %d: Can't convert IP address!", new_sock);
 | 
			
		||||
@@ -1198,49 +1283,56 @@ New_Connection( int Sock )
 | 
			
		||||
 | 
			
		||||
#ifdef TCPWRAP
 | 
			
		||||
	/* Validate socket using TCP Wrappers */
 | 
			
		||||
	request_init( &req, RQ_DAEMON, PACKAGE_NAME, RQ_FILE, new_sock, RQ_CLIENT_SIN, &new_addr, NULL );
 | 
			
		||||
	request_init(&req, RQ_DAEMON, PACKAGE_NAME, RQ_FILE, new_sock,
 | 
			
		||||
		     RQ_CLIENT_SIN, &new_addr, NULL);
 | 
			
		||||
	fromhost(&req);
 | 
			
		||||
	if (!hosts_access(&req)) {
 | 
			
		||||
		Log (deny_severity, "Refused connection from %s (by TCP Wrappers)!", ip_str);
 | 
			
		||||
		Simple_Message( new_sock, "ERROR :Connection refused" );
 | 
			
		||||
		close( new_sock );
 | 
			
		||||
		Log(deny_severity,
 | 
			
		||||
		    "Refused connection from %s (by TCP Wrappers)!", ip_str);
 | 
			
		||||
		Simple_Message(new_sock, "ERROR :Connection refused");
 | 
			
		||||
		close(new_sock);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Socket initialisieren */
 | 
			
		||||
	if (!Init_Socket( new_sock ))
 | 
			
		||||
	if (!Init_Socket(new_sock))
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	/* Check global connection limit */
 | 
			
		||||
	if ((Conf_MaxConnections > 0) &&
 | 
			
		||||
	    (NumConnections >= (size_t) Conf_MaxConnections)) {
 | 
			
		||||
		Log(LOG_ALERT, "Can't accept connection: limit (%d) reached!",
 | 
			
		||||
		    Conf_MaxConnections);
 | 
			
		||||
		Simple_Message(new_sock, "ERROR :Connection limit reached");
 | 
			
		||||
		close(new_sock);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check IP-based connection limit */
 | 
			
		||||
	cnt = Count_Connections(&new_addr);
 | 
			
		||||
	if ((Conf_MaxConnectionsIP > 0) && (cnt >= Conf_MaxConnectionsIP)) {
 | 
			
		||||
		/* Access denied, too many connections from this IP address! */
 | 
			
		||||
		Log( LOG_ERR, "Refused connection from %s: too may connections (%ld) from this IP address!", ip_str, cnt);
 | 
			
		||||
		Simple_Message( new_sock, "ERROR :Connection refused, too many connections from your IP address!" );
 | 
			
		||||
		close( new_sock );
 | 
			
		||||
		Log(LOG_ERR,
 | 
			
		||||
		    "Refused connection from %s: too may connections (%ld) from this IP address!",
 | 
			
		||||
		    ip_str, cnt);
 | 
			
		||||
		Simple_Message(new_sock,
 | 
			
		||||
			       "ERROR :Connection refused, too many connections from your IP address!");
 | 
			
		||||
		close(new_sock);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ((Conf_MaxConnections > 0) &&
 | 
			
		||||
		(NumConnections >= (size_t) Conf_MaxConnections))
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_ALERT, "Can't accept connection: limit (%d) reached!", Conf_MaxConnections);
 | 
			
		||||
		Simple_Message( new_sock, "ERROR :Connection limit reached" );
 | 
			
		||||
		close( new_sock );
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( new_sock >= Pool_Size ) {
 | 
			
		||||
	if (new_sock >= Pool_Size) {
 | 
			
		||||
		if (!array_alloc(&My_ConnArray, sizeof(CONNECTION),
 | 
			
		||||
				 (size_t)new_sock)) {
 | 
			
		||||
			Log( LOG_EMERG, "Can't allocate memory! [New_Connection]" );
 | 
			
		||||
			Simple_Message( new_sock, "ERROR: Internal error" );
 | 
			
		||||
			close( new_sock );
 | 
			
		||||
				 (size_t) new_sock)) {
 | 
			
		||||
			Log(LOG_EMERG,
 | 
			
		||||
			    "Can't allocate memory! [New_Connection]");
 | 
			
		||||
			Simple_Message(new_sock, "ERROR: Internal error");
 | 
			
		||||
			close(new_sock);
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
		LogDebug("Bumped connection pool to %ld items (internal: %ld items, %ld bytes)",
 | 
			
		||||
			new_sock, array_length(&My_ConnArray, sizeof(CONNECTION)), array_bytes(&My_ConnArray));
 | 
			
		||||
			 new_sock, array_length(&My_ConnArray,
 | 
			
		||||
			 sizeof(CONNECTION)), array_bytes(&My_ConnArray));
 | 
			
		||||
 | 
			
		||||
		/* Adjust pointer to new block */
 | 
			
		||||
		My_Connections = array_start(&My_ConnArray);
 | 
			
		||||
@@ -1249,22 +1341,24 @@ New_Connection( int Sock )
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* register callback */
 | 
			
		||||
	if (!io_event_create( new_sock, IO_WANTREAD, cb_clientserver)) {
 | 
			
		||||
		Log(LOG_ALERT, "Can't accept connection: io_event_create failed!");
 | 
			
		||||
	if (!io_event_create(new_sock, IO_WANTREAD, cb_clientserver)) {
 | 
			
		||||
		Log(LOG_ALERT,
 | 
			
		||||
		    "Can't accept connection: io_event_create failed!");
 | 
			
		||||
		Simple_Message(new_sock, "ERROR :Internal error");
 | 
			
		||||
		close(new_sock);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c = Client_NewLocal(new_sock, ip_str, CLIENT_UNKNOWN, false );
 | 
			
		||||
	if( ! c ) {
 | 
			
		||||
		Log(LOG_ALERT, "Can't accept connection: can't create client structure!");
 | 
			
		||||
	c = Client_NewLocal(new_sock, ip_str, CLIENT_UNKNOWN, false);
 | 
			
		||||
	if (!c) {
 | 
			
		||||
		Log(LOG_ALERT,
 | 
			
		||||
		    "Can't accept connection: can't create client structure!");
 | 
			
		||||
		Simple_Message(new_sock, "ERROR :Internal error");
 | 
			
		||||
		io_close(new_sock);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Init_Conn_Struct( new_sock );
 | 
			
		||||
	Init_Conn_Struct(new_sock);
 | 
			
		||||
	My_Connections[new_sock].sock = new_sock;
 | 
			
		||||
	My_Connections[new_sock].addr = new_addr;
 | 
			
		||||
	My_Connections[new_sock].client = c;
 | 
			
		||||
@@ -1290,13 +1384,25 @@ New_Connection( int Sock )
 | 
			
		||||
		identsock = -1;
 | 
			
		||||
#endif
 | 
			
		||||
	if (!Conf_NoDNS)
 | 
			
		||||
		Resolve_Addr(&My_Connections[new_sock].res_stat, &new_addr,
 | 
			
		||||
		Resolve_Addr(&My_Connections[new_sock].proc_stat, &new_addr,
 | 
			
		||||
			     identsock, cb_Read_Resolver_Result);
 | 
			
		||||
	Conn_SetPenalty(new_sock, 4);
 | 
			
		||||
 | 
			
		||||
	Account_Connection();
 | 
			
		||||
	return new_sock;
 | 
			
		||||
} /* New_Connection */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
Account_Connection(void)
 | 
			
		||||
{
 | 
			
		||||
	NumConnections++;
 | 
			
		||||
	if (NumConnections > NumConnectionsMax)
 | 
			
		||||
		NumConnectionsMax = NumConnections;
 | 
			
		||||
	LogDebug("Total number of connections now %lu (max %lu).",
 | 
			
		||||
		 NumConnections, NumConnectionsMax);
 | 
			
		||||
} /* Account_Connection */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static CONN_ID
 | 
			
		||||
Socket2Index( int Sock )
 | 
			
		||||
{
 | 
			
		||||
@@ -1394,7 +1500,7 @@ Read_Request( CONN_ID Idx )
 | 
			
		||||
	 * registered as a user, server or service connection. Don't update
 | 
			
		||||
	 * otherwise, so users have at least Conf_PongTimeout seconds time to
 | 
			
		||||
	 * register with the IRC server -- see Check_Connections().
 | 
			
		||||
	 * Set "lastping", too, so we can handle time shifts backwards ... */
 | 
			
		||||
	 * Update "lastping", too, if time shifted backwards ... */
 | 
			
		||||
	c = Conn_GetClient(Idx);
 | 
			
		||||
	if (c && (Client_Type(c) == CLIENT_USER
 | 
			
		||||
		  || Client_Type(c) == CLIENT_SERVER
 | 
			
		||||
@@ -1404,7 +1510,8 @@ Read_Request( CONN_ID Idx )
 | 
			
		||||
			My_Connections[Idx].bps = 0;
 | 
			
		||||
 | 
			
		||||
		My_Connections[Idx].lastdata = t;
 | 
			
		||||
		My_Connections[Idx].lastping = My_Connections[Idx].lastdata;
 | 
			
		||||
		if (My_Connections[Idx].lastping > t)
 | 
			
		||||
			My_Connections[Idx].lastping = t;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Look at the data in the (read-) buffer of this connection */
 | 
			
		||||
@@ -1572,11 +1679,14 @@ Handle_Buffer(CONN_ID Idx)
 | 
			
		||||
} /* Handle_Buffer */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check whether established connections are still alive or not.
 | 
			
		||||
 * If not, play PING-PONG first; and if that doesn't help either,
 | 
			
		||||
 * disconnect the respective peer.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
Check_Connections(void)
 | 
			
		||||
{
 | 
			
		||||
	/* check if connections are alive. if not, play PING-PONG first.
 | 
			
		||||
	 * if this doesn't help either, disconnect client. */
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	CONN_ID i;
 | 
			
		||||
	char msg[64];
 | 
			
		||||
@@ -1628,42 +1738,47 @@ Check_Connections(void)
 | 
			
		||||
} /* Check_Connections */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if further server links should be established.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
Check_Servers( void )
 | 
			
		||||
Check_Servers(void)
 | 
			
		||||
{
 | 
			
		||||
	/* Check if we can establish further server links */
 | 
			
		||||
 | 
			
		||||
	int i, n;
 | 
			
		||||
	time_t time_now;
 | 
			
		||||
 | 
			
		||||
	time_now = time(NULL);
 | 
			
		||||
 | 
			
		||||
	/* Check all configured servers */
 | 
			
		||||
	for( i = 0; i < MAX_SERVERS; i++ ) {
 | 
			
		||||
		/* Valid outgoing server which isn't already connected or disabled? */
 | 
			
		||||
		if(( ! Conf_Server[i].host[0] ) || ( ! Conf_Server[i].port > 0 ) ||
 | 
			
		||||
			( Conf_Server[i].conn_id > NONE ) || ( Conf_Server[i].flags & CONF_SFLAG_DISABLED ))
 | 
			
		||||
				continue;
 | 
			
		||||
	for (i = 0; i < MAX_SERVERS; i++) {
 | 
			
		||||
		if (Conf_Server[i].conn_id != NONE)
 | 
			
		||||
			continue;	/* Already establishing or connected */
 | 
			
		||||
		if (!Conf_Server[i].host[0] || !Conf_Server[i].port > 0)
 | 
			
		||||
			continue;	/* No host and/or port configured */
 | 
			
		||||
		if (Conf_Server[i].flags & CONF_SFLAG_DISABLED)
 | 
			
		||||
			continue;	/* Disabled configuration entry */
 | 
			
		||||
		if (Conf_Server[i].lasttry > (time_now - Conf_ConnectRetry))
 | 
			
		||||
			continue;	/* We have to wait a little bit ... */
 | 
			
		||||
 | 
			
		||||
		/* Is there already a connection in this group? */
 | 
			
		||||
		if( Conf_Server[i].group > NONE ) {
 | 
			
		||||
		if (Conf_Server[i].group > NONE) {
 | 
			
		||||
			for (n = 0; n < MAX_SERVERS; n++) {
 | 
			
		||||
				if (n == i) continue;
 | 
			
		||||
				if (n == i)
 | 
			
		||||
					continue;
 | 
			
		||||
				if ((Conf_Server[n].conn_id != NONE) &&
 | 
			
		||||
					(Conf_Server[n].group == Conf_Server[i].group))
 | 
			
		||||
						break;
 | 
			
		||||
				    (Conf_Server[n].group == Conf_Server[i].group))
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
			if (n < MAX_SERVERS) continue;
 | 
			
		||||
			if (n < MAX_SERVERS)
 | 
			
		||||
				continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Check last connect attempt? */
 | 
			
		||||
		time_now = time(NULL);
 | 
			
		||||
		if( Conf_Server[i].lasttry > (time_now - Conf_ConnectRetry))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* Okay, try to connect now */
 | 
			
		||||
		Conf_Server[i].lasttry = time_now;
 | 
			
		||||
		Conf_Server[i].conn_id = SERVER_WAIT;
 | 
			
		||||
		assert(Resolve_Getfd(&Conf_Server[i].res_stat) < 0);
 | 
			
		||||
		Resolve_Name(&Conf_Server[i].res_stat, Conf_Server[i].host, cb_Connect_to_Server);
 | 
			
		||||
		assert(Proc_GetPipeFd(&Conf_Server[i].res_stat) < 0);
 | 
			
		||||
		Resolve_Name(&Conf_Server[i].res_stat, Conf_Server[i].host,
 | 
			
		||||
			     cb_Connect_to_Server);
 | 
			
		||||
	}
 | 
			
		||||
} /* Check_Servers */
 | 
			
		||||
 | 
			
		||||
@@ -1736,7 +1851,7 @@ New_Server( int Server , ng_ipaddr_t *dest)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Conn_Close() decrements this counter again */
 | 
			
		||||
	NumConnections++;
 | 
			
		||||
	Account_Connection();
 | 
			
		||||
	Client_SetIntroducer( c, c );
 | 
			
		||||
	Client_SetToken( c, TOKEN_OUTBOUND );
 | 
			
		||||
 | 
			
		||||
@@ -1785,7 +1900,7 @@ Init_Conn_Struct(CONN_ID Idx)
 | 
			
		||||
	My_Connections[Idx].signon = now;
 | 
			
		||||
	My_Connections[Idx].lastdata = now;
 | 
			
		||||
	My_Connections[Idx].lastprivmsg = now;
 | 
			
		||||
	Resolve_Init(&My_Connections[Idx].res_stat);
 | 
			
		||||
	Proc_InitStruct(&My_Connections[Idx].proc_stat);
 | 
			
		||||
} /* Init_Conn_Struct */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1811,12 +1926,13 @@ Init_Socket( int Sock )
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Set type of service (TOS) */
 | 
			
		||||
#if defined(IP_TOS) && defined(IPTOS_LOWDELAY)
 | 
			
		||||
#if defined(IPPROTO_IP) && defined(IPTOS_LOWDELAY)
 | 
			
		||||
	value = IPTOS_LOWDELAY;
 | 
			
		||||
	LogDebug("Setting option IP_TOS on socket %d to IPTOS_LOWDELAY (%d).", Sock, value );
 | 
			
		||||
	if( setsockopt( Sock, SOL_IP, IP_TOS, &value, (socklen_t)sizeof( value )) != 0 )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_ERR, "Can't set socket option IP_TOS: %s!", strerror( errno ));
 | 
			
		||||
	LogDebug("Setting IP_TOS on socket %d to IPTOS_LOWDELAY.", Sock);
 | 
			
		||||
	if (setsockopt(Sock, IPPROTO_IP, IP_TOS, &value,
 | 
			
		||||
		       (socklen_t) sizeof(value))) {
 | 
			
		||||
		Log(LOG_ERR, "Can't set socket option IP_TOS: %s!",
 | 
			
		||||
		    strerror(errno));
 | 
			
		||||
		/* ignore this error */
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1825,7 +1941,6 @@ Init_Socket( int Sock )
 | 
			
		||||
} /* Init_Socket */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cb_Connect_to_Server(int fd, UNUSED short events)
 | 
			
		||||
{
 | 
			
		||||
@@ -1840,7 +1955,7 @@ cb_Connect_to_Server(int fd, UNUSED short events)
 | 
			
		||||
	LogDebug("Resolver: Got forward lookup callback on fd %d, events %d", fd, events);
 | 
			
		||||
 | 
			
		||||
	for (i=0; i < MAX_SERVERS; i++) {
 | 
			
		||||
		  if (Resolve_Getfd(&Conf_Server[i].res_stat) == fd )
 | 
			
		||||
		  if (Proc_GetPipeFd(&Conf_Server[i].res_stat) == fd )
 | 
			
		||||
			  break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1852,7 +1967,7 @@ cb_Connect_to_Server(int fd, UNUSED short events)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Read result from pipe */
 | 
			
		||||
	len = Resolve_Read(&Conf_Server[i].res_stat, dest_addrs, sizeof(dest_addrs));
 | 
			
		||||
	len = Proc_Read(&Conf_Server[i].res_stat, dest_addrs, sizeof(dest_addrs));
 | 
			
		||||
	if (len == 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
@@ -1885,7 +2000,7 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 | 
			
		||||
	 * IDENT user name.*/
 | 
			
		||||
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	int i;
 | 
			
		||||
	CONN_ID i;
 | 
			
		||||
	size_t len;
 | 
			
		||||
	char *identptr;
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
@@ -1895,14 +2010,8 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	LogDebug("Resolver: Got callback on fd %d, events %d", r_fd, events );
 | 
			
		||||
 | 
			
		||||
	/* Search associated connection ... */
 | 
			
		||||
	for( i = 0; i < Pool_Size; i++ ) {
 | 
			
		||||
		if(( My_Connections[i].sock != NONE )
 | 
			
		||||
		  && ( Resolve_Getfd(&My_Connections[i].res_stat) == r_fd ))
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	if( i >= Pool_Size ) {
 | 
			
		||||
	i = Conn_GetFromProc(r_fd);
 | 
			
		||||
	if (i == NONE) {
 | 
			
		||||
		/* Ops, none found? Probably the connection has already
 | 
			
		||||
		 * been closed!? We'll ignore that ... */
 | 
			
		||||
		io_close( r_fd );
 | 
			
		||||
@@ -1911,7 +2020,7 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Read result from pipe */
 | 
			
		||||
	len = Resolve_Read(&My_Connections[i].res_stat, readbuf, sizeof readbuf -1);
 | 
			
		||||
	len = Proc_Read(&My_Connections[i].proc_stat, readbuf, sizeof readbuf -1);
 | 
			
		||||
	if (len == 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
@@ -1933,10 +2042,14 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 | 
			
		||||
	c = Conn_GetClient( i );
 | 
			
		||||
	assert( c != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Only update client information of unregistered clients */
 | 
			
		||||
	if( Client_Type( c ) == CLIENT_UNKNOWN ) {
 | 
			
		||||
		strlcpy(My_Connections[i].host, readbuf, sizeof( My_Connections[i].host));
 | 
			
		||||
		Client_SetHostname( c, readbuf);
 | 
			
		||||
	/* Only update client information of unregistered clients.
 | 
			
		||||
	 * Note: user commands (e. g. WEBIRC) are always read _after_ reading
 | 
			
		||||
	 * the resolver results, so we don't have to worry to override settings
 | 
			
		||||
	 * from these commands here. */
 | 
			
		||||
	if(Client_Type(c) == CLIENT_UNKNOWN) {
 | 
			
		||||
		strlcpy(My_Connections[i].host, readbuf,
 | 
			
		||||
			sizeof(My_Connections[i].host));
 | 
			
		||||
		Client_SetHostname(c, readbuf);
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
		++identptr;
 | 
			
		||||
		if (*identptr) {
 | 
			
		||||
@@ -1950,46 +2063,102 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
		else Log( LOG_DEBUG, "Resolver: discarding result for already registered connection %d.", i );
 | 
			
		||||
#endif
 | 
			
		||||
	/* Reset penalty time */
 | 
			
		||||
	Conn_ResetPenalty( i );
 | 
			
		||||
} /* cb_Read_Resolver_Result */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Write a "simple" (error) message to a socket.
 | 
			
		||||
 * The message is sent without using the connection write buffers, without
 | 
			
		||||
 * compression/encryption, and even without any error reporting. It is
 | 
			
		||||
 * designed for error messages of e.g. New_Connection(). */
 | 
			
		||||
static void
 | 
			
		||||
Simple_Message( int Sock, const char *Msg )
 | 
			
		||||
Simple_Message(int Sock, const char *Msg)
 | 
			
		||||
{
 | 
			
		||||
	char buf[COMMAND_LEN];
 | 
			
		||||
	size_t len;
 | 
			
		||||
	/* Write "simple" message to socket, without using compression
 | 
			
		||||
	 * or even the connection write buffers. Used e.g. for error
 | 
			
		||||
	 * messages by New_Connection(). */
 | 
			
		||||
	assert( Sock > NONE );
 | 
			
		||||
	assert( Msg != NULL );
 | 
			
		||||
 | 
			
		||||
	strlcpy( buf, Msg, sizeof buf - 2);
 | 
			
		||||
	len = strlcat( buf, "\r\n", sizeof buf);
 | 
			
		||||
	(void)write(Sock, buf, len);
 | 
			
		||||
	assert(Sock > NONE);
 | 
			
		||||
	assert(Msg != NULL);
 | 
			
		||||
 | 
			
		||||
	strlcpy(buf, Msg, sizeof buf - 2);
 | 
			
		||||
	len = strlcat(buf, "\r\n", sizeof buf);
 | 
			
		||||
	if (write(Sock, buf, len) < 0) {
 | 
			
		||||
		/* Because this function most probably got called to log
 | 
			
		||||
		 * an error message, any write error is ignored here to
 | 
			
		||||
		 * avoid an endless loop. But casting the result of write()
 | 
			
		||||
		 * to "void" doesn't satisfy the GNU C code attribute
 | 
			
		||||
		 * "warn_unused_result" which is used by some versions of
 | 
			
		||||
		 * glibc (e.g. 2.11.1), therefore this silly error
 | 
			
		||||
		 * "handling" code here :-( */
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
} /* Simple_Error */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get CLIENT structure that belongs to a local connection identified by its
 | 
			
		||||
 * index number. Each connection belongs to a client by definition, so it is
 | 
			
		||||
 * not required that the caller checks for NULL return values.
 | 
			
		||||
 * @param Idx Connection index number
 | 
			
		||||
 * @return Pointer to CLIENT structure
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Conn_GetClient( CONN_ID Idx ) 
 | 
			
		||||
{
 | 
			
		||||
	/* return Client-Structure that belongs to the local Connection Idx.
 | 
			
		||||
	 * If none is found, return NULL.
 | 
			
		||||
	 */
 | 
			
		||||
	CONNECTION *c;
 | 
			
		||||
	assert( Idx >= 0 );
 | 
			
		||||
 | 
			
		||||
	assert(Idx >= 0);
 | 
			
		||||
	c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx);
 | 
			
		||||
 | 
			
		||||
	assert(c != NULL);
 | 
			
		||||
 | 
			
		||||
	return c ? c->client : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get PROC_STAT sub-process structure of a connection.
 | 
			
		||||
 * @param Idx Connection index number
 | 
			
		||||
 * @return PROC_STAT structure
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL PROC_STAT *
 | 
			
		||||
Conn_GetProcStat(CONN_ID Idx)
 | 
			
		||||
{
 | 
			
		||||
	CONNECTION *c;
 | 
			
		||||
 | 
			
		||||
	assert(Idx >= 0);
 | 
			
		||||
	c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx);
 | 
			
		||||
	assert(c != NULL);
 | 
			
		||||
	return &c->proc_stat;
 | 
			
		||||
} /* Conn_GetProcStat */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get CONN_ID from file descriptor associated to a subprocess structure.
 | 
			
		||||
 * @param fd File descriptor
 | 
			
		||||
 * @return CONN_ID or NONE (-1)
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL CONN_ID
 | 
			
		||||
Conn_GetFromProc(int fd)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	assert(fd > 0);
 | 
			
		||||
	for (i = 0; i < Pool_Size; i++) {
 | 
			
		||||
		if ((My_Connections[i].sock != NONE)
 | 
			
		||||
		    && (Proc_GetPipeFd(&My_Connections[i].proc_stat) == fd))
 | 
			
		||||
			return i;
 | 
			
		||||
	}
 | 
			
		||||
	return NONE;
 | 
			
		||||
} /* Conn_GetFromProc */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef SSL_SUPPORT
 | 
			
		||||
/* we cannot access My_Connections in irc-info.c */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get information about used SSL chiper.
 | 
			
		||||
 * @param Idx Connection index number
 | 
			
		||||
 * @param buf Buffer for returned information text
 | 
			
		||||
 * @param len Size of return buffer "buf"
 | 
			
		||||
 * @return true on success, false otherwise
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Conn_GetCipherInfo(CONN_ID Idx, char *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
@@ -2000,6 +2169,11 @@ Conn_GetCipherInfo(CONN_ID Idx, char *buf, size_t len)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a connection is SSL-enabled or not.
 | 
			
		||||
 * @param Idx Connection index number
 | 
			
		||||
 * @return true if connection is SSL-enabled, false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Conn_UsesSSL(CONN_ID Idx)
 | 
			
		||||
{
 | 
			
		||||
@@ -2008,6 +2182,31 @@ Conn_UsesSSL(CONN_ID Idx)
 | 
			
		||||
	assert(Idx < (int) array_length(&My_ConnArray, sizeof(CONNECTION)));
 | 
			
		||||
	return Conn_OPTION_ISSET(&My_Connections[Idx], CONN_SSL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_DebugDump(void)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	Log(LOG_DEBUG, "Connection status:");
 | 
			
		||||
	for (i = 0; i < Pool_Size; i++) {
 | 
			
		||||
		if (My_Connections[i].sock == NONE)
 | 
			
		||||
			continue;
 | 
			
		||||
		Log(LOG_DEBUG,
 | 
			
		||||
		    " - %d: host=%s, lastdata=%ld, lastping=%ld, delaytime=%ld, flag=%d, options=%d, bps=%d, client=%s",
 | 
			
		||||
		    My_Connections[i].sock, My_Connections[i].host,
 | 
			
		||||
		    My_Connections[i].lastdata, My_Connections[i].lastping,
 | 
			
		||||
		    My_Connections[i].delaytime, My_Connections[i].flag,
 | 
			
		||||
		    My_Connections[i].options, My_Connections[i].bps,
 | 
			
		||||
		    My_Connections[i].client ? Client_ID(My_Connections[i].client) : "-");
 | 
			
		||||
	}
 | 
			
		||||
} /* Conn_DumpClients */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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. */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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) */
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
					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))
 | 
			
		||||
				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;
 | 
			
		||||
			break;
 | 
			
		||||
					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 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))
 | 
			
		||||
	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));
 | 
			
		||||
 | 
			
		||||
	if (!Show_MOTD_Start(Client))
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	line = array_start(&Conf_Motd);
 | 
			
		||||
	while (len_tot > 0) {
 | 
			
		||||
		len_str = strlen(line) + 1;
 | 
			
		||||
 | 
			
		||||
		assert(len_tot >= len_str);
 | 
			
		||||
		len_tot -= len_str;
 | 
			
		||||
 | 
			
		||||
		if (!Show_MOTD_Sendline(Client, line))
 | 
			
		||||
			return DISCONNECTED;
 | 
			
		||||
		if (!Show_MOTD_Sendline(Client, Conf_MotdPhrase))
 | 
			
		||||
			return DISCONNECTED;
 | 
			
		||||
		goto out;
 | 
			
		||||
		line += len_str;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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 )) {
 | 
			
		||||
		fclose(fd);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while (fgets( line, (int)sizeof line, fd )) {
 | 
			
		||||
		ngt_TrimLastChr( line, '\n');
 | 
			
		||||
 | 
			
		||||
		if( ! Show_MOTD_Sendline( Client, line)) {
 | 
			
		||||
			fclose( fd );
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	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))
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
{
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
	int pipefd[2], result;
 | 
			
		||||
	CONN_ID conn;
 | 
			
		||||
	pid_t pid;
 | 
			
		||||
 | 
			
		||||
	/* Check 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);
 | 
			
		||||
	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 global server password ... */
 | 
			
		||||
	if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
 | 
			
		||||
		/* Bad password! */
 | 
			
		||||
		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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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));
 | 
			
		||||
 
 | 
			
		||||
@@ -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 );
 | 
			
		||||
@@ -284,7 +307,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 +325,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 +339,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 +428,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 +775,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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,7 +21,6 @@
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "lists.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -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,7 +147,7 @@ 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 */
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -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- */
 | 
			
		||||
 
 | 
			
		||||
@@ -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, ...));
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "match.h"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										100
									
								
								src/ngircd/log.c
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								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"
 | 
			
		||||
@@ -50,8 +50,6 @@ 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 +73,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 );
 | 
			
		||||
@@ -146,8 +141,8 @@ 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 );
 | 
			
		||||
	Log(LOG_NOTICE, "%s done%s, served %lu connections.", PACKAGE_NAME,
 | 
			
		||||
	    NGIRCd_SignalRestart ? " (restarting)" : "", Conn_CountAccepted());
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	if( Error_File[0] )
 | 
			
		||||
@@ -260,93 +255,110 @@ va_dcl
 | 
			
		||||
	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'))
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
	va_start(ap, Format);
 | 
			
		||||
#else
 | 
			
		||||
	va_start(ap);
 | 
			
		||||
#endif
 | 
			
		||||
	vsnprintf(msg, MAX_LOG_MSG_LEN, Format, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
		c = Client_Next( c );
 | 
			
		||||
							NOTICE_TXTPREFIX, msg);
 | 
			
		||||
	}
 | 
			
		||||
} /* Wall_ServerNotice */
 | 
			
		||||
} /* Log_ServerNotice */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -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 ));
 | 
			
		||||
 
 | 
			
		||||
@@ -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 :"
 | 
			
		||||
@@ -113,6 +115,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)"
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 | 
			
		||||
@@ -294,8 +290,15 @@ main( int argc, const char *argv[] )
 | 
			
		||||
		 * 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 +365,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 +374,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] )
 | 
			
		||||
@@ -431,130 +430,6 @@ Fill_Version( void )
 | 
			
		||||
	} /* Fill_Version */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
@@ -562,7 +437,7 @@ 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 +527,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 +579,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 +599,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 +620,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 +630,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 +640,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 +668,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();
 | 
			
		||||
 | 
			
		||||
@@ -829,7 +705,7 @@ 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 +717,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- */
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										139
									
								
								src/ngircd/pam.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								src/ngircd/pam.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,139 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * PAM User Authentification
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_SECURITY_PAM_APPL_H
 | 
			
		||||
#include <security/pam_appl.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_PAM_PAM_APPL_H
 | 
			
		||||
#include <pam/pam_appl.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "pam.h"
 | 
			
		||||
 | 
			
		||||
static char *password;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * PAM "conversation function".
 | 
			
		||||
 * This is a callback function used by the PAM library to get the password.
 | 
			
		||||
 * Please see the PAM documentation for details :-)
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
password_conversation(int num_msg, const struct pam_message **msg,
 | 
			
		||||
		      struct pam_response **resp, void *appdata_ptr) {
 | 
			
		||||
	LogDebug("PAM: conv(%d, %d, '%s', '%s')",
 | 
			
		||||
		 num_msg, msg[0]->msg_style, msg[0]->msg, appdata_ptr);
 | 
			
		||||
 | 
			
		||||
	/* Can we deal with this request? */
 | 
			
		||||
	if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF) {
 | 
			
		||||
		Log(LOG_ERR, "PAM: Unexpected PAM conversation '%d:%s'!",
 | 
			
		||||
		    msg[0]->msg_style, msg[0]->msg);
 | 
			
		||||
		return PAM_CONV_ERR;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!appdata_ptr) {
 | 
			
		||||
		/* Sometimes appdata_ptr gets lost!? */
 | 
			
		||||
		appdata_ptr = password;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Duplicate password ("application data") for the PAM library */
 | 
			
		||||
	*resp = calloc(num_msg, sizeof(struct pam_response));
 | 
			
		||||
	if (!*resp) {
 | 
			
		||||
		Log(LOG_ERR, "PAM: Out of memory!");
 | 
			
		||||
		return PAM_CONV_ERR;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	(*resp)[0].resp = strdup((char *)appdata_ptr);
 | 
			
		||||
	(*resp)[0].resp_retcode = 0;
 | 
			
		||||
 | 
			
		||||
	return ((*resp)[0].resp ? PAM_SUCCESS : PAM_CONV_ERR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * PAM "conversation" structure.
 | 
			
		||||
 */
 | 
			
		||||
static struct pam_conv conv = {
 | 
			
		||||
	&password_conversation,
 | 
			
		||||
	NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Authenticate a connectiong client using PAM.
 | 
			
		||||
 * @param Client The client to authenticate.
 | 
			
		||||
 * @return true when authentication succeeded, false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
PAM_Authenticate(CLIENT *Client) {
 | 
			
		||||
	pam_handle_t *pam;
 | 
			
		||||
	int retval = PAM_SUCCESS;
 | 
			
		||||
 | 
			
		||||
	LogDebug("PAM: Authenticate \"%s\" (%s) ...",
 | 
			
		||||
		 Client_OrigUser(Client), Client_Mask(Client));
 | 
			
		||||
 | 
			
		||||
	/* Set supplied client password */
 | 
			
		||||
	if (password)
 | 
			
		||||
		free(password);
 | 
			
		||||
	password = strdup(Client_Password(Client));
 | 
			
		||||
	conv.appdata_ptr = password;
 | 
			
		||||
 | 
			
		||||
	/* Initialize PAM */
 | 
			
		||||
	retval = pam_start("ngircd", Client_OrigUser(Client), &conv, &pam);
 | 
			
		||||
	if (retval != PAM_SUCCESS) {
 | 
			
		||||
		Log(LOG_ERR, "PAM: Failed to create authenticator! (%d)", retval);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pam_set_item(pam, PAM_RUSER, Client_User(Client));
 | 
			
		||||
	pam_set_item(pam, PAM_RHOST, Client_Hostname(Client));
 | 
			
		||||
#ifdef HAVE_PAM_FAIL_DELAY
 | 
			
		||||
	pam_fail_delay(pam, 0);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* PAM authentication ... */
 | 
			
		||||
	retval = pam_authenticate(pam, 0);
 | 
			
		||||
 | 
			
		||||
	/* Success? */
 | 
			
		||||
	if (retval == PAM_SUCCESS)
 | 
			
		||||
		Log(LOG_INFO, "PAM: Authenticated \"%s\" (%s).",
 | 
			
		||||
		    Client_OrigUser(Client), Client_Mask(Client));
 | 
			
		||||
	else
 | 
			
		||||
		Log(LOG_ERR, "PAM: Error on \"%s\" (%s): %s",
 | 
			
		||||
		    Client_OrigUser(Client), Client_Mask(Client),
 | 
			
		||||
		    pam_strerror(pam, retval));
 | 
			
		||||
 | 
			
		||||
	/* Free PAM structures */
 | 
			
		||||
	if (pam_end(pam, retval) != PAM_SUCCESS)
 | 
			
		||||
		Log(LOG_ERR, "PAM: Failed to release authenticator!");
 | 
			
		||||
 | 
			
		||||
	return (retval == PAM_SUCCESS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* PAM */
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										25
									
								
								src/ngircd/pam.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/ngircd/pam.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * PAM User Authentification (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
 | 
			
		||||
#ifndef __pam_h__
 | 
			
		||||
#define __pam_h__
 | 
			
		||||
 | 
			
		||||
GLOBAL bool PAM_Authenticate PARAMS((CLIENT *Client));
 | 
			
		||||
 | 
			
		||||
#endif	/* __pam_h__ */
 | 
			
		||||
 | 
			
		||||
#endif	/* PAM */
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -26,7 +26,6 @@
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
@@ -103,6 +102,7 @@ static COMMAND My_Commands[] =
 | 
			
		||||
	{ "USERS", IRC_USERS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "VERSION", IRC_VERSION, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "WALLOPS", IRC_WALLOPS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "WEBIRC", IRC_WEBIRC, CLIENT_UNKNOWN, 0, 0, 0 },
 | 
			
		||||
	{ "WHO", IRC_WHO, CLIENT_USER, 0, 0, 0 },
 | 
			
		||||
	{ "WHOIS", IRC_WHOIS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "WHOWAS", IRC_WHOWAS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
@@ -120,8 +120,6 @@ static bool Validate_Args PARAMS(( CONN_ID Idx, REQUEST *Req, bool *Closed ));
 | 
			
		||||
 | 
			
		||||
static bool Handle_Request PARAMS(( CONN_ID Idx, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
#define ARRAY_SIZE(x)	(sizeof(x)/sizeof((x)[0]))
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return the pointer to the global "IRC command structure".
 | 
			
		||||
 * This structure, an array of type "COMMAND" describes all the IRC commands
 | 
			
		||||
@@ -397,7 +395,7 @@ Handle_Numeric(CLIENT *client, REQUEST *Req)
 | 
			
		||||
		/* This server is the target of the numeric */
 | 
			
		||||
		num = atoi(Req->command);
 | 
			
		||||
 | 
			
		||||
		for (i = 0; i < (int) ARRAY_SIZE(Numerics); i++) {
 | 
			
		||||
		for (i = 0; i < (int) C_ARRAY_SIZE(Numerics); i++) {
 | 
			
		||||
			if (num == Numerics[i].numeric) {
 | 
			
		||||
				if (!Numerics[i].function)
 | 
			
		||||
					return CONNECTED;
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ typedef struct _REQUEST			/* vgl. RFC 2812, 2.3 */
 | 
			
		||||
 | 
			
		||||
typedef struct _COMMAND
 | 
			
		||||
{
 | 
			
		||||
	char *name;			/* command name */
 | 
			
		||||
	const char *name;		/* command name */
 | 
			
		||||
	bool (*function) PARAMS(( CLIENT *Client, REQUEST *Request ));
 | 
			
		||||
	CLIENT_TYPE type;		/* valid client types (bit mask) */
 | 
			
		||||
	long lcount, rcount;		/* number of local and remote calls */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										145
									
								
								src/ngircd/proc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								src/ngircd/proc.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,145 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * Process management
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "sighandlers.h"
 | 
			
		||||
#include "proc.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialize process structure.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Proc_InitStruct (PROC_STAT *proc)
 | 
			
		||||
{
 | 
			
		||||
	assert(proc != NULL);
 | 
			
		||||
	proc->pid = 0;
 | 
			
		||||
	proc->pipe_fd = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Fork a child process.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL pid_t
 | 
			
		||||
Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout)
 | 
			
		||||
{
 | 
			
		||||
	pid_t pid;
 | 
			
		||||
 | 
			
		||||
	assert(proc != NULL);
 | 
			
		||||
	assert(pipefds != NULL);
 | 
			
		||||
	assert(cbfunc != NULL);
 | 
			
		||||
 | 
			
		||||
	if (pipe(pipefds) != 0) {
 | 
			
		||||
		Log(LOG_ALERT, "Can't create output pipe for child process: %s!",
 | 
			
		||||
		    strerror(errno));
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pid = fork();
 | 
			
		||||
	switch (pid) {
 | 
			
		||||
	case -1:
 | 
			
		||||
		/* Error on fork: */
 | 
			
		||||
		Log(LOG_CRIT, "Can't fork child process: %s!", strerror(errno));
 | 
			
		||||
		close(pipefds[0]);
 | 
			
		||||
		close(pipefds[1]);
 | 
			
		||||
		return -1;
 | 
			
		||||
	case 0:
 | 
			
		||||
		/* New child process: */
 | 
			
		||||
		Signals_Exit();
 | 
			
		||||
		signal(SIGTERM, Proc_GenericSignalHandler);
 | 
			
		||||
		signal(SIGALRM, Proc_GenericSignalHandler);
 | 
			
		||||
		close(pipefds[0]);
 | 
			
		||||
		alarm(timeout);
 | 
			
		||||
		Conn_CloseAllSockets();
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Old parent process: */
 | 
			
		||||
	close(pipefds[1]);
 | 
			
		||||
 | 
			
		||||
	if (!io_setnonblock(pipefds[0])
 | 
			
		||||
	 || !io_event_create(pipefds[0], IO_WANTREAD, cbfunc)) {
 | 
			
		||||
		Log(LOG_CRIT, "Can't register callback for child process: %s!",
 | 
			
		||||
		    strerror(errno));
 | 
			
		||||
		close(pipefds[0]);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	proc->pid = pid;
 | 
			
		||||
	proc->pipe_fd = pipefds[0];
 | 
			
		||||
	return pid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generic signal handler for forked child processes.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Proc_GenericSignalHandler(int Signal)
 | 
			
		||||
{
 | 
			
		||||
	switch(Signal) {
 | 
			
		||||
	case SIGTERM:
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
		Log_Subprocess(LOG_DEBUG, "Child got TERM signal, exiting.");
 | 
			
		||||
#endif
 | 
			
		||||
		exit(1);
 | 
			
		||||
	case SIGALRM:
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
		Log_Subprocess(LOG_DEBUG, "Child got ALARM signal, exiting.");
 | 
			
		||||
#endif
 | 
			
		||||
		exit(1);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Read bytes from a pipe of a forked child process.
 | 
			
		||||
 * In addition, this function makes sure that the child process is ignored
 | 
			
		||||
 * after all data has been read or a fatal error occurred.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL size_t
 | 
			
		||||
Proc_Read(PROC_STAT *proc, void *buffer, size_t buflen)
 | 
			
		||||
{
 | 
			
		||||
	ssize_t bytes_read = 0;
 | 
			
		||||
 | 
			
		||||
	assert(buffer != NULL);
 | 
			
		||||
	assert(buflen > 0);
 | 
			
		||||
 | 
			
		||||
	bytes_read = read(proc->pipe_fd, buffer, buflen);
 | 
			
		||||
	if (bytes_read < 0) {
 | 
			
		||||
		if (errno == EAGAIN)
 | 
			
		||||
			return 0;
 | 
			
		||||
		Log(LOG_CRIT, "Can't read from child process %ld: %s",
 | 
			
		||||
		    proc->pid, strerror(errno));
 | 
			
		||||
		bytes_read = 0;
 | 
			
		||||
	}
 | 
			
		||||
#if DEBUG
 | 
			
		||||
	else if (bytes_read == 0)
 | 
			
		||||
		LogDebug("Can't read from child process %ld: EOF", proc->pid);
 | 
			
		||||
#endif
 | 
			
		||||
	Proc_InitStruct(proc);
 | 
			
		||||
	return (size_t)bytes_read;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										37
									
								
								src/ngircd/proc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/ngircd/proc.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * Process management (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __proc_h__
 | 
			
		||||
#define __proc_h__
 | 
			
		||||
 | 
			
		||||
/* This struct must not be accessed directly! */
 | 
			
		||||
typedef struct _Proc_Stat {
 | 
			
		||||
	pid_t pid;	/* PID of the child process or 0 if none */
 | 
			
		||||
	int pipe_fd;	/* Pipe file descriptor or -1 if none */
 | 
			
		||||
} PROC_STAT;
 | 
			
		||||
 | 
			
		||||
#define Proc_InProgress(x)	((x)->pid != 0)
 | 
			
		||||
#define Proc_GetPipeFd(x)	((x)->pipe_fd)
 | 
			
		||||
 | 
			
		||||
GLOBAL void Proc_InitStruct PARAMS((PROC_STAT *proc));
 | 
			
		||||
 | 
			
		||||
GLOBAL pid_t Proc_Fork PARAMS((PROC_STAT *proc, int *pipefds,
 | 
			
		||||
			       void (*cbfunc)(int, short), int timeout));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Proc_GenericSignalHandler PARAMS((int Signal));
 | 
			
		||||
 | 
			
		||||
GLOBAL size_t Proc_Read PARAMS((PROC_STAT *proc, void *buffer, size_t buflen));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2004 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2010 by 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
 | 
			
		||||
@@ -21,8 +21,6 @@
 | 
			
		||||
#ifdef ZEROCONF
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: rendezvous.c,v 1.8 2006/05/10 21:24:01 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
@@ -43,6 +41,8 @@ static char UNUSED id[] = "$Id: rendezvous.c,v 1.8 2006/05/10 21:24:01 alex Exp
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
@@ -144,12 +144,16 @@ GLOBAL void Rendezvous_Exit( void )
 | 
			
		||||
} /* Rendezvous_Exit */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Register ZeroConf service
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool Rendezvous_Register( char *Name, char *Type, UINT16 Port )
 | 
			
		||||
{
 | 
			
		||||
	/* Register new service */
 | 
			
		||||
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	if (Conf_NoZeroConf)
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	/* Search free port structure */
 | 
			
		||||
	for( i = 0; i < MAX_RENDEZVOUS; i++ ) if( ! My_Rendezvous[i].Desc[0] ) break;
 | 
			
		||||
	if( i >= MAX_RENDEZVOUS )
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,8 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define RESOLVER_TIMEOUT (Conf_PongTimeout*3)/4
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
@@ -23,6 +25,7 @@
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
#ifdef HAVE_IDENT_H
 | 
			
		||||
@@ -30,9 +33,12 @@
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "array.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "ng_ipaddr.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
@@ -41,46 +47,18 @@
 | 
			
		||||
 | 
			
		||||
static void Do_ResolveAddr PARAMS(( const ng_ipaddr_t *Addr, int Sock, int w_fd ));
 | 
			
		||||
static void Do_ResolveName PARAMS(( const char *Host, int w_fd ));
 | 
			
		||||
static bool register_callback PARAMS((RES_STAT *s, void (*cbfunc)(int, short)));
 | 
			
		||||
 | 
			
		||||
#ifdef WANT_IPV6
 | 
			
		||||
extern bool Conf_ConnectIPv4;
 | 
			
		||||
extern bool Conf_ConnectIPv6;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static pid_t
 | 
			
		||||
Resolver_fork(int *pipefds)
 | 
			
		||||
{
 | 
			
		||||
	pid_t pid;
 | 
			
		||||
 | 
			
		||||
	if (pipe(pipefds) != 0) {
 | 
			
		||||
                Log( LOG_ALERT, "Resolver: Can't create output pipe: %s!", strerror( errno ));
 | 
			
		||||
                return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pid = fork();
 | 
			
		||||
	switch(pid) {
 | 
			
		||||
		case -1:
 | 
			
		||||
			Log( LOG_CRIT, "Resolver: Can't fork: %s!", strerror( errno ));
 | 
			
		||||
			close(pipefds[0]);
 | 
			
		||||
			close(pipefds[1]);
 | 
			
		||||
			return -1;
 | 
			
		||||
		case 0: /* child */
 | 
			
		||||
			close(pipefds[0]);
 | 
			
		||||
			Log_Init_Resolver( );
 | 
			
		||||
			return 0;
 | 
			
		||||
	}
 | 
			
		||||
	/* parent */
 | 
			
		||||
	close(pipefds[1]);
 | 
			
		||||
	return pid; 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Resolve IP (asynchronous!).
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Resolve_Addr(RES_STAT * s, const ng_ipaddr_t *Addr, int identsock,
 | 
			
		||||
Resolve_Addr(PROC_STAT * s, const ng_ipaddr_t *Addr, int identsock,
 | 
			
		||||
	     void (*cbfunc) (int, short))
 | 
			
		||||
{
 | 
			
		||||
	int pipefd[2];
 | 
			
		||||
@@ -88,17 +66,15 @@ Resolve_Addr(RES_STAT * s, const ng_ipaddr_t *Addr, int identsock,
 | 
			
		||||
 | 
			
		||||
	assert(s != NULL);
 | 
			
		||||
 | 
			
		||||
	pid = Resolver_fork(pipefd);
 | 
			
		||||
	pid = Proc_Fork(s, pipefd, cbfunc, RESOLVER_TIMEOUT);
 | 
			
		||||
	if (pid > 0) {
 | 
			
		||||
		LogDebug("Resolver for %s created (PID %d).", ng_ipaddr_tostr(Addr), pid);
 | 
			
		||||
 | 
			
		||||
		s->pid = pid;
 | 
			
		||||
		s->resolver_fd = pipefd[0];
 | 
			
		||||
		return register_callback(s, cbfunc);
 | 
			
		||||
		return true;
 | 
			
		||||
	} else if( pid == 0 ) {
 | 
			
		||||
		/* Sub process */
 | 
			
		||||
		Log_Init_Subprocess("Resolver");
 | 
			
		||||
		Do_ResolveAddr( Addr, identsock, pipefd[1]);
 | 
			
		||||
		Log_Exit_Resolver( );
 | 
			
		||||
		Log_Exit_Subprocess("Resolver");
 | 
			
		||||
		exit(0);
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
@@ -109,43 +85,33 @@ Resolve_Addr(RES_STAT * s, const ng_ipaddr_t *Addr, int identsock,
 | 
			
		||||
 * Resolve hostname (asynchronous!).
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Resolve_Name( RES_STAT *s, const char *Host, void (*cbfunc)(int, short))
 | 
			
		||||
Resolve_Name( PROC_STAT *s, const char *Host, void (*cbfunc)(int, short))
 | 
			
		||||
{
 | 
			
		||||
	int pipefd[2];
 | 
			
		||||
	pid_t pid;
 | 
			
		||||
 | 
			
		||||
	assert(s != NULL);
 | 
			
		||||
 | 
			
		||||
	pid = Resolver_fork(pipefd);
 | 
			
		||||
	pid = Proc_Fork(s, pipefd, cbfunc, RESOLVER_TIMEOUT);
 | 
			
		||||
	if (pid > 0) {
 | 
			
		||||
		/* Main process */
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
		Log( LOG_DEBUG, "Resolver for \"%s\" created (PID %d).", Host, pid );
 | 
			
		||||
#endif
 | 
			
		||||
		s->pid = pid;
 | 
			
		||||
		s->resolver_fd = pipefd[0];
 | 
			
		||||
		return register_callback(s, cbfunc);
 | 
			
		||||
		return true;
 | 
			
		||||
	} else if( pid == 0 ) {
 | 
			
		||||
		/* Sub process */
 | 
			
		||||
		Log_Init_Subprocess("Resolver");
 | 
			
		||||
		Do_ResolveName(Host, pipefd[1]);
 | 
			
		||||
		Log_Exit_Resolver( );
 | 
			
		||||
		Log_Exit_Subprocess("Resolver");
 | 
			
		||||
		exit(0);
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
} /* Resolve_Name */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Resolve_Init(RES_STAT *s)
 | 
			
		||||
{
 | 
			
		||||
	assert(s != NULL);
 | 
			
		||||
	s->resolver_fd = -1;
 | 
			
		||||
	s->pid = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef WANT_IPV6
 | 
			
		||||
#ifdef h_errno
 | 
			
		||||
#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETNAMEINFO)
 | 
			
		||||
#if !defined(WANT_IPV6) && defined(h_errno)
 | 
			
		||||
static char *
 | 
			
		||||
Get_Error( int H_Error )
 | 
			
		||||
{
 | 
			
		||||
@@ -162,8 +128,8 @@ Get_Error( int H_Error )
 | 
			
		||||
	}
 | 
			
		||||
	return "unknown error";
 | 
			
		||||
}
 | 
			
		||||
#endif /* h_errno */
 | 
			
		||||
#endif /* WANT_IPV6 */
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Do "IDENT" (aka "AUTH") lookup and append result to resolved_addr array */
 | 
			
		||||
@@ -177,17 +143,20 @@ Do_IdentQuery(int identsock, array *resolved_addr)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	Log_Resolver(LOG_DEBUG, "Doing IDENT lookup on socket %d ...", identsock);
 | 
			
		||||
	Log_Subprocess(LOG_DEBUG, "Doing IDENT lookup on socket %d ...",
 | 
			
		||||
		       identsock);
 | 
			
		||||
#endif
 | 
			
		||||
	res = ident_id( identsock, 10 );
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	Log_Resolver(LOG_DEBUG, "Ok, IDENT lookup on socket %d done: \"%s\"",
 | 
			
		||||
						identsock, res ? res : "(NULL)" );
 | 
			
		||||
	Log_Subprocess(LOG_DEBUG, "Ok, IDENT lookup on socket %d done: \"%s\"",
 | 
			
		||||
		       identsock, res ? res : "(NULL)");
 | 
			
		||||
#endif
 | 
			
		||||
	if (!res) /* no result */
 | 
			
		||||
		return;
 | 
			
		||||
	if (!array_cats(resolved_addr, res))
 | 
			
		||||
		Log_Resolver(LOG_WARNING, "Resolver: Cannot copy IDENT result: %s!", strerror(errno));
 | 
			
		||||
		Log_Subprocess(LOG_WARNING,
 | 
			
		||||
			       "Resolver: Cannot copy IDENT result: %s!",
 | 
			
		||||
			       strerror(errno));
 | 
			
		||||
 | 
			
		||||
	free(res);
 | 
			
		||||
#else
 | 
			
		||||
@@ -203,7 +172,7 @@ Do_IdentQuery(int identsock, array *resolved_addr)
 | 
			
		||||
 * the IP address in resbuf and returns false.
 | 
			
		||||
 * @param IpAddr ip address to resolve
 | 
			
		||||
 * @param resbuf result buffer to store DNS name/string representation of ip address
 | 
			
		||||
 * @reslen size of result buffer (must be >= NGT_INET_ADDRSTRLEN)
 | 
			
		||||
 * @param reslen size of result buffer (must be >= NGT_INET_ADDRSTRLEN)
 | 
			
		||||
 * @return true if reverse lookup successful, false otherwise
 | 
			
		||||
 */
 | 
			
		||||
static bool
 | 
			
		||||
@@ -249,7 +218,7 @@ ReverseLookup(const ng_ipaddr_t *IpAddr, char *resbuf, size_t reslen)
 | 
			
		||||
	assert(reslen >= NG_INET_ADDRSTRLEN);
 | 
			
		||||
	ng_ipaddr_tostr_r(IpAddr, tmp_ip_str);
 | 
			
		||||
 | 
			
		||||
	Log_Resolver(LOG_WARNING, "%s: Can't resolve address \"%s\": %s",
 | 
			
		||||
	Log_Subprocess(LOG_WARNING, "%s: Can't resolve address \"%s\": %s",
 | 
			
		||||
				funcname, tmp_ip_str, errmsg);
 | 
			
		||||
	strlcpy(resbuf, tmp_ip_str, reslen);
 | 
			
		||||
	return false;
 | 
			
		||||
@@ -297,10 +266,10 @@ ForwardLookup(const char *hostname, array *IpAddr)
 | 
			
		||||
	switch (res) {
 | 
			
		||||
	case 0:	break;
 | 
			
		||||
	case EAI_SYSTEM:
 | 
			
		||||
		Log_Resolver(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, strerror(errno));
 | 
			
		||||
		Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, strerror(errno));
 | 
			
		||||
		return false;
 | 
			
		||||
	default:
 | 
			
		||||
		Log_Resolver(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, gai_strerror(res));
 | 
			
		||||
		Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, gai_strerror(res));
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -323,9 +292,10 @@ ForwardLookup(const char *hostname, array *IpAddr)
 | 
			
		||||
 | 
			
		||||
	if (!h) {
 | 
			
		||||
#ifdef h_errno
 | 
			
		||||
		Log_Resolver(LOG_WARNING, "Can't resolve \"%s\": %s", hostname, Get_Error(h_errno));
 | 
			
		||||
		Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\": %s",
 | 
			
		||||
			       hostname, Get_Error(h_errno));
 | 
			
		||||
#else
 | 
			
		||||
		Log_Resolver(LOG_WARNING, "Can't resolve \"%s\"", hostname);
 | 
			
		||||
		Log_Subprocess(LOG_WARNING, "Can't resolve \"%s\"", hostname);
 | 
			
		||||
#endif
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
@@ -361,7 +331,7 @@ Addr_in_list(const array *resolved_addr, const ng_ipaddr_t *Addr)
 | 
			
		||||
	tmpAddrs = array_start(resolved_addr);
 | 
			
		||||
 | 
			
		||||
	while (len > 0) {
 | 
			
		||||
		Log_Resolver(LOG_WARNING, "Address mismatch: %s != %s",
 | 
			
		||||
		Log_Subprocess(LOG_WARNING, "Address mismatch: %s != %s",
 | 
			
		||||
			tmp_ip_str, ng_ipaddr_tostr(tmpAddrs));
 | 
			
		||||
		tmpAddrs++;
 | 
			
		||||
		len--;
 | 
			
		||||
@@ -374,15 +344,15 @@ Addr_in_list(const array *resolved_addr, const ng_ipaddr_t *Addr)
 | 
			
		||||
static void
 | 
			
		||||
Log_Forgery_NoIP(const char *ip, const char *host)
 | 
			
		||||
{
 | 
			
		||||
	Log_Resolver(LOG_WARNING, "Possible forgery: %s resolved to %s "
 | 
			
		||||
		"(which has no ip address)", ip, host);
 | 
			
		||||
	Log_Subprocess(LOG_WARNING,
 | 
			
		||||
		"Possible forgery: %s resolved to %s (which has no ip address)", ip, host);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
Log_Forgery_WrongIP(const char *ip, const char *host)
 | 
			
		||||
{
 | 
			
		||||
	Log_Resolver(LOG_WARNING,"Possible forgery: %s resolved to %s "
 | 
			
		||||
		"(which points to different address)", ip, host);
 | 
			
		||||
	Log_Subprocess(LOG_WARNING,
 | 
			
		||||
		"Possible forgery: %s resolved to %s (which points to different address)", ip, host);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -395,7 +365,7 @@ ArrayWrite(int fd, const array *a)
 | 
			
		||||
	assert(data);
 | 
			
		||||
 | 
			
		||||
	if( (size_t)write(fd, data, len) != len )
 | 
			
		||||
		Log_Resolver( LOG_CRIT, "Resolver: Can't write to parent: %s!",
 | 
			
		||||
		Log_Subprocess( LOG_CRIT, "Resolver: Can't write to parent: %s!",
 | 
			
		||||
							strerror(errno));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -413,7 +383,7 @@ Do_ResolveAddr(const ng_ipaddr_t *Addr, int identsock, int w_fd)
 | 
			
		||||
	array_init(&resolved_addr);
 | 
			
		||||
	ng_ipaddr_tostr_r(Addr, tmp_ip_str);
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	Log_Resolver(LOG_DEBUG, "Now resolving %s ...", tmp_ip_str);
 | 
			
		||||
	Log_Subprocess(LOG_DEBUG, "Now resolving %s ...", tmp_ip_str);
 | 
			
		||||
#endif
 | 
			
		||||
	if (!ReverseLookup(Addr, hostname, sizeof(hostname)))
 | 
			
		||||
		goto dns_done;
 | 
			
		||||
@@ -428,13 +398,15 @@ Do_ResolveAddr(const ng_ipaddr_t *Addr, int identsock, int w_fd)
 | 
			
		||||
		strlcpy(hostname, tmp_ip_str, sizeof(hostname));
 | 
			
		||||
	}
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	Log_Resolver(LOG_DEBUG, "Ok, translated %s to \"%s\".", tmp_ip_str, hostname);
 | 
			
		||||
	Log_Subprocess(LOG_DEBUG, "Ok, translated %s to \"%s\".", tmp_ip_str, hostname);
 | 
			
		||||
#endif
 | 
			
		||||
 dns_done:
 | 
			
		||||
	len = strlen(hostname);
 | 
			
		||||
	hostname[len] = '\n';
 | 
			
		||||
	if (!array_copyb(&resolved_addr, hostname, ++len)) {
 | 
			
		||||
		Log_Resolver(LOG_CRIT, "Resolver: Can't copy resolved name: %s!", strerror(errno));
 | 
			
		||||
		Log_Subprocess(LOG_CRIT,
 | 
			
		||||
			       "Resolver: Can't copy resolved name: %s!",
 | 
			
		||||
			       strerror(errno));
 | 
			
		||||
		array_free(&resolved_addr);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
@@ -457,7 +429,7 @@ Do_ResolveName( const char *Host, int w_fd )
 | 
			
		||||
	ng_ipaddr_t *addr;
 | 
			
		||||
	size_t len;
 | 
			
		||||
#endif
 | 
			
		||||
	Log_Resolver(LOG_DEBUG, "Now resolving \"%s\" ...", Host);
 | 
			
		||||
	Log_Subprocess(LOG_DEBUG, "Now resolving \"%s\" ...", Host);
 | 
			
		||||
 | 
			
		||||
	array_init(&IpAddrs);
 | 
			
		||||
	/* Resolve hostname */
 | 
			
		||||
@@ -471,7 +443,7 @@ Do_ResolveName( const char *Host, int w_fd )
 | 
			
		||||
	addr = array_start(&IpAddrs);
 | 
			
		||||
	assert(addr);
 | 
			
		||||
	for (; len > 0; --len,addr++) {
 | 
			
		||||
		Log_Resolver(LOG_DEBUG, "translated \"%s\" to %s.",
 | 
			
		||||
		Log_Subprocess(LOG_DEBUG, "translated \"%s\" to %s.",
 | 
			
		||||
					Host, ng_ipaddr_tostr(addr));
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -482,66 +454,4 @@ Do_ResolveName( const char *Host, int w_fd )
 | 
			
		||||
} /* Do_ResolveName */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
register_callback( RES_STAT *s, void (*cbfunc)(int, short))
 | 
			
		||||
{
 | 
			
		||||
	assert(cbfunc != NULL);
 | 
			
		||||
	assert(s != NULL);
 | 
			
		||||
	assert(s->resolver_fd >= 0);
 | 
			
		||||
 | 
			
		||||
	if (io_setnonblock(s->resolver_fd) &&
 | 
			
		||||
		io_event_create(s->resolver_fd, IO_WANTREAD, cbfunc))
 | 
			
		||||
			return true;
 | 
			
		||||
 | 
			
		||||
	Log( LOG_CRIT, "Resolver: Could not register callback function: %s!", strerror(errno));
 | 
			
		||||
	close(s->resolver_fd);
 | 
			
		||||
	Resolve_Init(s);
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Resolve_Shutdown( RES_STAT *s)
 | 
			
		||||
{
 | 
			
		||||
	bool ret = false;
 | 
			
		||||
 | 
			
		||||
	assert(s != NULL);
 | 
			
		||||
	assert(s->resolver_fd >= 0);
 | 
			
		||||
 | 
			
		||||
	if (s->resolver_fd >= 0)
 | 
			
		||||
		ret = io_close(s->resolver_fd);
 | 
			
		||||
 | 
			
		||||
	Resolve_Init(s);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Read result of resolver sub-process from pipe
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL size_t
 | 
			
		||||
Resolve_Read( RES_STAT *s, void* readbuf, size_t buflen)
 | 
			
		||||
{
 | 
			
		||||
	ssize_t bytes_read;
 | 
			
		||||
 | 
			
		||||
	assert(buflen > 0);
 | 
			
		||||
 | 
			
		||||
	/* Read result from pipe */
 | 
			
		||||
	bytes_read = read(s->resolver_fd, readbuf, buflen);
 | 
			
		||||
	if (bytes_read < 0) {
 | 
			
		||||
		if (errno == EAGAIN)
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
		Log( LOG_CRIT, "Resolver: Can't read result: %s!", strerror(errno));
 | 
			
		||||
		bytes_read = 0;
 | 
			
		||||
	}
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	else if (bytes_read == 0)
 | 
			
		||||
		Log( LOG_DEBUG, "Resolver: Can't read result: EOF");
 | 
			
		||||
#endif
 | 
			
		||||
	Resolve_Shutdown(s);
 | 
			
		||||
	return (size_t)bytes_read;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2010 by 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,34 +8,17 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: resolve.h,v 1.14 2008/02/26 22:04:17 fw Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Asynchronous resolver (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __resolve_h__
 | 
			
		||||
#define __resolve_h__
 | 
			
		||||
 | 
			
		||||
#include "array.h"
 | 
			
		||||
#include "tool.h"
 | 
			
		||||
#include "ng_ipaddr.h"
 | 
			
		||||
 | 
			
		||||
/* This struct must not be accessed directly */
 | 
			
		||||
typedef struct _Res_Stat {
 | 
			
		||||
	pid_t pid;			/* PID of resolver process */
 | 
			
		||||
	int resolver_fd;		/* pipe fd for lookup result. */
 | 
			
		||||
} RES_STAT;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define Resolve_Getfd(x)		((x)->resolver_fd)
 | 
			
		||||
#define Resolve_INPROGRESS(x)		((x)->resolver_fd >= 0)
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Resolve_Addr PARAMS(( RES_STAT *s, const ng_ipaddr_t *Addr, int identsock, void (*cbfunc)(int, short)));
 | 
			
		||||
GLOBAL bool Resolve_Name PARAMS(( RES_STAT *s, const char *Host, void (*cbfunc)(int, short) ));
 | 
			
		||||
GLOBAL size_t Resolve_Read PARAMS(( RES_STAT *s, void *buf, size_t buflen));
 | 
			
		||||
GLOBAL void Resolve_Init PARAMS(( RES_STAT *s));
 | 
			
		||||
GLOBAL bool Resolve_Shutdown PARAMS(( RES_STAT *s));
 | 
			
		||||
GLOBAL bool Resolve_Addr PARAMS((PROC_STAT * s, const ng_ipaddr_t * Addr,
 | 
			
		||||
				 int identsock, void (*cbfunc) (int, short)));
 | 
			
		||||
GLOBAL bool Resolve_Name PARAMS((PROC_STAT * s, const char *Host,
 | 
			
		||||
				 void (*cbfunc) (int, short)));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										336
									
								
								src/ngircd/sighandlers.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										336
									
								
								src/ngircd/sighandlers.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,336 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Signal Handlers: Actions to be performed when the program
 | 
			
		||||
 * receives a signal.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "conf-ssl.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "sighandlers.h"
 | 
			
		||||
 | 
			
		||||
static int signalpipe[2];
 | 
			
		||||
 | 
			
		||||
static const int signals_catch[] = {
 | 
			
		||||
       SIGINT, SIGQUIT, SIGTERM, SIGHUP, SIGCHLD, SIGUSR1, SIGUSR2
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
Dump_State(void)
 | 
			
		||||
{
 | 
			
		||||
	Log(LOG_DEBUG, "--- Internal server state: %s ---",
 | 
			
		||||
	    Client_ID(Client_ThisServer()));
 | 
			
		||||
	Log(LOG_DEBUG, "time()=%ld", time(NULL));
 | 
			
		||||
	Conf_DebugDump();
 | 
			
		||||
	Conn_DebugDump();
 | 
			
		||||
	Client_DebugDump();
 | 
			
		||||
	Log(LOG_DEBUG, "--- End of state dump ---");
 | 
			
		||||
} /* Dump_State */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
Signal_Block(int sig)
 | 
			
		||||
{
 | 
			
		||||
#ifdef HAVE_SIGPROCMASK
 | 
			
		||||
	sigset_t set;
 | 
			
		||||
 | 
			
		||||
	sigemptyset(&set);
 | 
			
		||||
	sigaddset(&set, sig);
 | 
			
		||||
 | 
			
		||||
	sigprocmask(SIG_BLOCK, &set, NULL);
 | 
			
		||||
#else
 | 
			
		||||
	sigblock(sig);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
Signal_Unblock(int sig)
 | 
			
		||||
{
 | 
			
		||||
#ifdef HAVE_SIGPROCMASK
 | 
			
		||||
	sigset_t set;
 | 
			
		||||
 | 
			
		||||
	sigemptyset(&set);
 | 
			
		||||
	sigaddset(&set, sig);
 | 
			
		||||
 | 
			
		||||
	sigprocmask(SIG_UNBLOCK, &set, NULL);
 | 
			
		||||
#else
 | 
			
		||||
	int old = sigblock(0) & ~sig;
 | 
			
		||||
	sigsetmask(old);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reload the server configuration file.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
Rehash(void)
 | 
			
		||||
{
 | 
			
		||||
	char old_name[CLIENT_ID_LEN];
 | 
			
		||||
	unsigned old_nicklen;
 | 
			
		||||
 | 
			
		||||
	Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" );
 | 
			
		||||
 | 
			
		||||
	/* 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." );
 | 
			
		||||
} /* Rehash */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * It blocks the signal and queues it for later execution by Signal_Handler_BH.
 | 
			
		||||
 * @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;
 | 
			
		||||
		return;
 | 
			
		||||
	case SIGCHLD:
 | 
			
		||||
		/* child-process exited, avoid zombies */
 | 
			
		||||
		while (waitpid( -1, NULL, WNOHANG) > 0)
 | 
			
		||||
			;
 | 
			
		||||
		return;
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	case SIGUSR1:
 | 
			
		||||
		if (! NGIRCd_Debug) {
 | 
			
		||||
			Log(LOG_INFO|LOG_snotice,
 | 
			
		||||
			    "Got SIGUSR1, debug mode activated.");
 | 
			
		||||
#ifdef SNIFFER
 | 
			
		||||
			strcpy(NGIRCd_DebugLevel, "2");
 | 
			
		||||
			NGIRCd_Debug = true;
 | 
			
		||||
			NGIRCd_Sniffer = true;
 | 
			
		||||
#else
 | 
			
		||||
			strcpy(NGIRCd_DebugLevel, "1");
 | 
			
		||||
			NGIRCd_Debug = true;
 | 
			
		||||
#endif /* SNIFFER */
 | 
			
		||||
		} else {
 | 
			
		||||
			Log(LOG_INFO|LOG_snotice,
 | 
			
		||||
			    "Got SIGUSR1, debug mode deactivated.");
 | 
			
		||||
			strcpy(NGIRCd_DebugLevel, "");
 | 
			
		||||
			NGIRCd_Debug = false;
 | 
			
		||||
#ifdef SNIFFER
 | 
			
		||||
			NGIRCd_Sniffer = false;
 | 
			
		||||
#endif /* SNIFFER */
 | 
			
		||||
		}
 | 
			
		||||
		return;
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * other signal: queue for later execution.
 | 
			
		||||
	 * This has the advantage that we are not restricted
 | 
			
		||||
	 * to functions that can be called safely from signal handlers.
 | 
			
		||||
	 */
 | 
			
		||||
	if (write(signalpipe[1], &Signal, sizeof(Signal)) != -1)
 | 
			
		||||
		Signal_Block(Signal);
 | 
			
		||||
} /* Signal_Handler */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Signal processing handler of ngIRCd.
 | 
			
		||||
 * This function is called from the main conn event loop in (io_dispatch)
 | 
			
		||||
 * whenever ngIRCd has queued a signal.
 | 
			
		||||
 *
 | 
			
		||||
 * This function runs in normal context, not from the real signal handler,
 | 
			
		||||
 * thus its not necessary to only use functions that are signal safe.
 | 
			
		||||
 * @param Signal Number of the signal that was queued.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
Signal_Handler_BH(int Signal)
 | 
			
		||||
{
 | 
			
		||||
	switch (Signal) {
 | 
			
		||||
	case SIGHUP:
 | 
			
		||||
		/* re-read configuration */
 | 
			
		||||
		Rehash();
 | 
			
		||||
		break;
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	case SIGUSR2:
 | 
			
		||||
		if (NGIRCd_Debug)
 | 
			
		||||
			Dump_State();
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		Log(LOG_DEBUG, "Got signal %d! Ignored.", Signal);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
	Signal_Unblock(Signal);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
Signal_Callback(int fd, short UNUSED what)
 | 
			
		||||
{
 | 
			
		||||
	int sig, ret;
 | 
			
		||||
	(void) what;
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		ret = (int)read(fd, &sig, sizeof(sig));
 | 
			
		||||
		if (ret == sizeof(int))
 | 
			
		||||
			Signal_Handler_BH(sig);
 | 
			
		||||
	} while (ret == sizeof(int));
 | 
			
		||||
 | 
			
		||||
	if (ret == -1) {
 | 
			
		||||
		if (errno == EAGAIN || errno == EINTR)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		Log(LOG_EMERG, "read from signal pipe: %s", strerror(errno));
 | 
			
		||||
		exit(1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log(LOG_EMERG, "EOF on signal pipe");
 | 
			
		||||
	exit(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialize the signal handlers, catch
 | 
			
		||||
 * those signals we are interested in and sets SIGPIPE to be ignored.
 | 
			
		||||
 * @return true if initialization was sucessful.
 | 
			
		||||
 */
 | 
			
		||||
bool
 | 
			
		||||
Signals_Init(void)
 | 
			
		||||
{
 | 
			
		||||
	size_t i;
 | 
			
		||||
#ifdef HAVE_SIGACTION
 | 
			
		||||
	struct sigaction saction;
 | 
			
		||||
#endif
 | 
			
		||||
	if (signalpipe[0] > 0 || signalpipe[1] > 0)
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	if (pipe(signalpipe))
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	if (!io_setnonblock(signalpipe[0]) ||
 | 
			
		||||
	    !io_setnonblock(signalpipe[1]))
 | 
			
		||||
		return false;
 | 
			
		||||
	if (!io_setcloexec(signalpipe[0]) ||
 | 
			
		||||
	    !io_setcloexec(signalpipe[1]))
 | 
			
		||||
		return false;
 | 
			
		||||
#ifdef HAVE_SIGACTION
 | 
			
		||||
	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
 | 
			
		||||
 | 
			
		||||
	for (i=0; i < C_ARRAY_SIZE(signals_catch) ; i++)
 | 
			
		||||
		sigaction(signals_catch[i], &saction, NULL);
 | 
			
		||||
 | 
			
		||||
	/* we handle write errors properly; ignore SIGPIPE */
 | 
			
		||||
	saction.sa_handler = SIG_IGN;
 | 
			
		||||
	sigaction(SIGPIPE, &saction, NULL);
 | 
			
		||||
#else
 | 
			
		||||
	for (i=0; i < C_ARRAY_SIZE(signals_catch) ; i++)
 | 
			
		||||
		signal(signals_catch[i], Signal_Handler);
 | 
			
		||||
 | 
			
		||||
	signal(SIGPIPE, SIG_IGN);
 | 
			
		||||
#endif
 | 
			
		||||
	return io_event_create(signalpipe[0], IO_WANTREAD, Signal_Callback);
 | 
			
		||||
} /* Signals_Init */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Restores signals to their default behaviour.
 | 
			
		||||
 *
 | 
			
		||||
 * This should be called after a fork() in the new
 | 
			
		||||
 * child prodcess, especially when we are about to call
 | 
			
		||||
 * 3rd party code (e.g. PAM).
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
Signals_Exit(void)
 | 
			
		||||
{
 | 
			
		||||
	size_t i;
 | 
			
		||||
#ifdef HAVE_SIGACTION
 | 
			
		||||
	struct sigaction saction;
 | 
			
		||||
 | 
			
		||||
	memset(&saction, 0, sizeof(saction));
 | 
			
		||||
	saction.sa_handler = SIG_DFL;
 | 
			
		||||
 | 
			
		||||
	for (i=0; i < C_ARRAY_SIZE(signals_catch) ; i++)
 | 
			
		||||
		sigaction(signals_catch[i], &saction, NULL);
 | 
			
		||||
	sigaction(SIGPIPE, &saction, NULL);
 | 
			
		||||
#else
 | 
			
		||||
	for (i=0; i < C_ARRAY_SIZE(signals_catch) ; i++)
 | 
			
		||||
		signal(signals_catch[i], SIG_DFL);
 | 
			
		||||
	signal(SIGPIPE, SIG_DFL);
 | 
			
		||||
#endif
 | 
			
		||||
	close(signalpipe[1]);
 | 
			
		||||
	close(signalpipe[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										19
									
								
								src/ngircd/sighandlers.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/ngircd/sighandlers.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef signals_included_
 | 
			
		||||
#define signals_included_
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
bool Signals_Init PARAMS((void));
 | 
			
		||||
void Signals_Exit PARAMS((void));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -8,8 +8,6 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: portab.h,v 1.22 2005/07/31 20:13:11 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Portability functions and declarations (header for libngbportab).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@@ -48,7 +46,7 @@
 | 
			
		||||
 | 
			
		||||
/* compiler features */
 | 
			
		||||
 | 
			
		||||
#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))
 | 
			
		||||
#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 7))
 | 
			
		||||
# define PUNUSED(x) __attribute__ ((unused)) x
 | 
			
		||||
# define UNUSED     __attribute__ ((unused))
 | 
			
		||||
#else
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@
 | 
			
		||||
	OperCanUseMode = yes
 | 
			
		||||
	MaxJoins = 4
 | 
			
		||||
	NoIdent = yes
 | 
			
		||||
	NoPAM = yes
 | 
			
		||||
 | 
			
		||||
[Operator]
 | 
			
		||||
	Name = TestOp
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@
 | 
			
		||||
	OperCanUseMode = yes
 | 
			
		||||
	MaxJoins = 4
 | 
			
		||||
	NoIdent = yes
 | 
			
		||||
	NoPAM = yes
 | 
			
		||||
 | 
			
		||||
[Operator]
 | 
			
		||||
	Name = TestOp
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -22,6 +22,11 @@
 | 
			
		||||
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
 | 
			
		||||
#ifdef SYSLOG
 | 
			
		||||
#define SYSLOG_NAMES 1
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "tool.h"
 | 
			
		||||
 | 
			
		||||
@@ -122,4 +127,92 @@ ngt_TrimLastChr( char *String, const char Chr)
 | 
			
		||||
} /* ngt_TrimLastChr */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef SYSLOG
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef INTERNAL_MARK
 | 
			
		||||
 | 
			
		||||
#ifndef _code
 | 
			
		||||
typedef struct _code {
 | 
			
		||||
        char    *c_name;
 | 
			
		||||
        int     c_val;
 | 
			
		||||
} CODE;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
CODE facilitynames[] = {
 | 
			
		||||
#ifdef LOG_AUTH
 | 
			
		||||
	{ "auth",	LOG_AUTH },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef LOG_AUTHPRIV
 | 
			
		||||
	{ "authpriv",	LOG_AUTHPRIV },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef LOG_CRON
 | 
			
		||||
	{ "cron", 	LOG_CRON },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef LOG_DAEMON
 | 
			
		||||
	{ "daemon",	LOG_DAEMON },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef LOG_FTP
 | 
			
		||||
	{ "ftp",	LOG_FTP },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef LOG_LPR
 | 
			
		||||
	{ "lpr",	LOG_LPR },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef LOG_MAIL
 | 
			
		||||
	{ "mail",	LOG_MAIL },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef LOG_NEWS
 | 
			
		||||
	{ "news",	LOG_NEWS },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef LOG_UUCP
 | 
			
		||||
	{ "uucp",	LOG_UUCP },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef LOG_USER
 | 
			
		||||
	{ "user",	LOG_USER },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef LOG_LOCAL7
 | 
			
		||||
	{ "local0",	LOG_LOCAL0 },
 | 
			
		||||
	{ "local1",	LOG_LOCAL1 },
 | 
			
		||||
	{ "local2",	LOG_LOCAL2 },
 | 
			
		||||
	{ "local3",	LOG_LOCAL3 },
 | 
			
		||||
	{ "local4",	LOG_LOCAL4 },
 | 
			
		||||
	{ "local5",	LOG_LOCAL5 },
 | 
			
		||||
	{ "local6",	LOG_LOCAL6 },
 | 
			
		||||
	{ "local7",	LOG_LOCAL7 },
 | 
			
		||||
#endif
 | 
			
		||||
	{ 0,		-1 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL const char*
 | 
			
		||||
ngt_SyslogFacilityName(int Facility)
 | 
			
		||||
{
 | 
			
		||||
	int i = 0;
 | 
			
		||||
	while(facilitynames[i].c_name) {
 | 
			
		||||
		if (facilitynames[i].c_val == Facility)
 | 
			
		||||
			return facilitynames[i].c_name;
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
	return "unknown";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL int
 | 
			
		||||
ngt_SyslogFacilityID(char *Name, int DefaultFacility)
 | 
			
		||||
{
 | 
			
		||||
	int i = 0;
 | 
			
		||||
	while(facilitynames[i].c_name) {
 | 
			
		||||
		if (strcasecmp(facilitynames[i].c_name, Name) == 0)
 | 
			
		||||
			return facilitynames[i].c_val;
 | 
			
		||||
		i++;
 | 
			
		||||
	}
 | 
			
		||||
	return DefaultFacility;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2008 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
 | 
			
		||||
@@ -29,6 +29,11 @@ GLOBAL void ngt_TrimStr PARAMS((char *String ));
 | 
			
		||||
GLOBAL char *ngt_UpperStr PARAMS((char *String ));
 | 
			
		||||
GLOBAL char *ngt_LowerStr PARAMS((char *String ));
 | 
			
		||||
 | 
			
		||||
#ifdef SYSLOG
 | 
			
		||||
GLOBAL const char *ngt_SyslogFacilityName PARAMS((int Facility));
 | 
			
		||||
GLOBAL int ngt_SyslogFacilityID PARAMS((char *Name, int DefaultFacility));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user