mirror of
				https://github.com/osmarks/ngircd.git
				synced 2025-11-03 23:43:00 +00:00 
			
		
		
		
	Compare commits
	
		
			142 Commits
		
	
	
		
			rel-0-10-0
			...
			branch-0-1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					3b69da0c52 | ||
| 
						 | 
					04933f5b8b | ||
| 
						 | 
					45df522bcb | ||
| 
						 | 
					51260c2e9f | ||
| 
						 | 
					55865d7fc6 | ||
| 
						 | 
					082a92beef | ||
| 
						 | 
					e92c889580 | ||
| 
						 | 
					de4676f066 | ||
| 
						 | 
					64a98338d5 | ||
| 
						 | 
					f4709082fe | ||
| 
						 | 
					997abc6889 | ||
| 
						 | 
					b7047f2e3b | ||
| 
						 | 
					e990d96c61 | ||
| 
						 | 
					d986cd372f | ||
| 
						 | 
					762aec0e08 | ||
| 
						 | 
					f8cb8e3f20 | ||
| 
						 | 
					478a8c01f9 | ||
| 
						 | 
					61e6b5c0aa | ||
| 
						 | 
					91a6fffaa0 | ||
| 
						 | 
					2ce5b734bd | ||
| 
						 | 
					f99f9a8f02 | ||
| 
						 | 
					4715ccf9ca | ||
| 
						 | 
					8974e90552 | ||
| 
						 | 
					2fe13f0a45 | ||
| 
						 | 
					20ce56cc5b | ||
| 
						 | 
					47a0379e2b | ||
| 
						 | 
					37563537a9 | ||
| 
						 | 
					82d32ffb28 | ||
| 
						 | 
					024588dbe7 | ||
| 
						 | 
					47ca178a21 | ||
| 
						 | 
					12db0bdc4f | ||
| 
						 | 
					53b98fd7e9 | ||
| 
						 | 
					c7d4d85666 | ||
| 
						 | 
					4659dae6eb | ||
| 
						 | 
					68f896eee0 | ||
| 
						 | 
					06bfb3adfb | ||
| 
						 | 
					2f305331a1 | ||
| 
						 | 
					ad7361dfe0 | ||
| 
						 | 
					e47c9d750f | ||
| 
						 | 
					001c00b273 | ||
| 
						 | 
					b861f536b2 | ||
| 
						 | 
					877bcc55f2 | ||
| 
						 | 
					8f162f4e17 | ||
| 
						 | 
					089ca21b3d | ||
| 
						 | 
					137a139112 | ||
| 
						 | 
					b160f574de | ||
| 
						 | 
					d223b587e4 | ||
| 
						 | 
					77939c382d | ||
| 
						 | 
					f586052f2b | ||
| 
						 | 
					d4ed056147 | ||
| 
						 | 
					9021ea2070 | ||
| 
						 | 
					640367e886 | ||
| 
						 | 
					4b9e52eb4d | ||
| 
						 | 
					69081851ac | ||
| 
						 | 
					efcca62a35 | ||
| 
						 | 
					cd65e0a56e | ||
| 
						 | 
					2275add327 | ||
| 
						 | 
					fd1091541b | ||
| 
						 | 
					5675be4cd9 | ||
| 
						 | 
					f1486e6a53 | ||
| 
						 | 
					22a9ed6694 | ||
| 
						 | 
					ddf56cbe5f | ||
| 
						 | 
					255edf7eab | ||
| 
						 | 
					5930a29197 | ||
| 
						 | 
					07d8da60de | ||
| 
						 | 
					44afe042d1 | ||
| 
						 | 
					a073bc89c4 | ||
| 
						 | 
					63e89ceb21 | ||
| 
						 | 
					09416f36bf | ||
| 
						 | 
					508b55126f | ||
| 
						 | 
					9f65979979 | ||
| 
						 | 
					2e34ddae53 | ||
| 
						 | 
					09deb857ce | ||
| 
						 | 
					8c14d397ba | ||
| 
						 | 
					99eab1e216 | ||
| 
						 | 
					c93d089736 | ||
| 
						 | 
					429f85b77a | ||
| 
						 | 
					ea2a4b3370 | ||
| 
						 | 
					f9b9850662 | ||
| 
						 | 
					1b852fce72 | ||
| 
						 | 
					82aaffe55d | ||
| 
						 | 
					40199e0b56 | ||
| 
						 | 
					95b7dbcc18 | ||
| 
						 | 
					43f8d149bb | ||
| 
						 | 
					949a4ef793 | ||
| 
						 | 
					f74781647a | ||
| 
						 | 
					5c78230283 | ||
| 
						 | 
					ee568cc444 | ||
| 
						 | 
					2d9a3ec484 | ||
| 
						 | 
					262d945284 | ||
| 
						 | 
					f6ce2d557a | ||
| 
						 | 
					4243cae985 | ||
| 
						 | 
					40226d26b2 | ||
| 
						 | 
					d2f7d3087d | ||
| 
						 | 
					3f1e03edd9 | ||
| 
						 | 
					23e7f7f0dd | ||
| 
						 | 
					f36746a4d0 | ||
| 
						 | 
					8cb0e3af68 | ||
| 
						 | 
					eb3ddace46 | ||
| 
						 | 
					5040d56489 | ||
| 
						 | 
					fb0fbe908d | ||
| 
						 | 
					fa7bb2790a | ||
| 
						 | 
					5877bca4bc | ||
| 
						 | 
					37602d1523 | ||
| 
						 | 
					a09034563a | ||
| 
						 | 
					5b35b101f2 | ||
| 
						 | 
					058d3085a9 | ||
| 
						 | 
					74883f57da | ||
| 
						 | 
					018e351630 | ||
| 
						 | 
					6e105bf87e | ||
| 
						 | 
					61966a6088 | ||
| 
						 | 
					27c96632f1 | ||
| 
						 | 
					4108e16be6 | ||
| 
						 | 
					4e02bdc322 | ||
| 
						 | 
					ca5e09865e | ||
| 
						 | 
					fb0c7ad252 | ||
| 
						 | 
					d8950c5dd0 | ||
| 
						 | 
					257312b102 | ||
| 
						 | 
					27d947fb7d | ||
| 
						 | 
					bed98979dc | ||
| 
						 | 
					bddb4914b4 | ||
| 
						 | 
					4c6c6ecf0e | ||
| 
						 | 
					a2f5a05ff8 | ||
| 
						 | 
					639eb40035 | ||
| 
						 | 
					0d6f9d4e3e | ||
| 
						 | 
					147de9dfa9 | ||
| 
						 | 
					f6e729443e | ||
| 
						 | 
					e426c131c7 | ||
| 
						 | 
					b9661ae65d | ||
| 
						 | 
					035f7fb2fe | ||
| 
						 | 
					1b2c228de5 | ||
| 
						 | 
					4d7d1d23be | ||
| 
						 | 
					e2aacff7d4 | ||
| 
						 | 
					0eccdbc137 | ||
| 
						 | 
					939ee6a39b | ||
| 
						 | 
					8423b89996 | ||
| 
						 | 
					7d87318b04 | ||
| 
						 | 
					83caef4598 | ||
| 
						 | 
					7378860aea | ||
| 
						 | 
					6eb3f3055d | ||
| 
						 | 
					c888c81adf | ||
| 
						 | 
					fac4682212 | 
							
								
								
									
										7
									
								
								.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								.cvsignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
aclocal.m4
 | 
			
		||||
autom4te.cache
 | 
			
		||||
config.log
 | 
			
		||||
config.status
 | 
			
		||||
configure
 | 
			
		||||
							
								
								
									
										12
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								AUTHORS
									
									
									
									
									
								
							@@ -1,7 +1,7 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                        (c)2001-2005 Alexander Barton,
 | 
			
		||||
                        (c)2001-2007 Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
@@ -10,9 +10,16 @@
 | 
			
		||||
                       -- AUTHORS and CONTRIBUTORS --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Note: If you have critics, patches or something else, please feel free to
 | 
			
		||||
post a mail to the ngIRCd mailing list: <ngircd-ml@arthur.ath.cx> (please see
 | 
			
		||||
<http://ngircd.barton.de/#ml> for details). Don't mail the contributors
 | 
			
		||||
directly, if possible!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Main Authors
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
Alexander Barton, <alex@barton.de> (alex)
 | 
			
		||||
Florian Westphal, <westphal@foo.fh-furtwangen.de> (fw)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Contributors
 | 
			
		||||
@@ -21,7 +28,6 @@ Goetz Hoffart, <goetz@hoffart.de> (goetz)
 | 
			
		||||
Ilja Osthoff, <i.osthoff@gmx.net> (ilja)
 | 
			
		||||
Benjamin Pineau, <ben@zouh.org>
 | 
			
		||||
Sean Reifschneider, <jafo-rpms@tummy.com>
 | 
			
		||||
Florian Westphal, <westphal@foo.fh-furtwangen.de> (fw)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Code snippets
 | 
			
		||||
@@ -32,4 +38,4 @@ Andrew Tridgell & Martin Pool: strl{cpy|cat}()-functions
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: AUTHORS,v 1.11 2005/03/19 14:24:52 alex Exp $
 | 
			
		||||
$Id: AUTHORS,v 1.13 2007/10/04 15:18:48 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										94
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								ChangeLog
									
									
									
									
									
								
							@@ -1,7 +1,7 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                        (c)2001-2005 Alexander Barton,
 | 
			
		||||
                        (c)2001-2008 Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
@@ -10,8 +10,96 @@
 | 
			
		||||
                               -- ChangeLog --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ngIRCd CVSHEAD
 | 
			
		||||
ngIRCd 0.11.1 (2008-02-26)
 | 
			
		||||
 | 
			
		||||
  - Fix sending of JOIN commands between servers when remote server appended
 | 
			
		||||
    mode flags. (Rolf Eike Beer) [from HEAD]
 | 
			
		||||
  - Send "G" instead of "H" flag in WHO replies. (reported by Dana Dahlstrom)
 | 
			
		||||
  - Under some circumstances ngIRCd issued channel MODE message with a
 | 
			
		||||
    trailing space. (Dana Dahlstrom) [from HEAD]
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.11.0 (2008-01-15)
 | 
			
		||||
 | 
			
		||||
  ngIRCd 0.11.0-pre2 (2008-01-07)
 | 
			
		||||
  - SECURITY: IRC_PART could reference invalid memory, causing
 | 
			
		||||
    ngircd to crash [from HEAD].
 | 
			
		||||
  
 | 
			
		||||
  ngIRCd 0.11.0-pre1 (2008-01-02)
 | 
			
		||||
  - Use dotted-decimal IP address if hostname is >= 64.
 | 
			
		||||
  - Add support for /STAT u (server uptime) command.
 | 
			
		||||
  - New [Server] configuration Option "Bind" allows to specify
 | 
			
		||||
    the source ip adress to use when connecting to remote server.
 | 
			
		||||
  - New configuration option "MaxNickLength" to specify the allowed maximum
 | 
			
		||||
    length of user nick names. Note: must be unique in an IRC network!
 | 
			
		||||
  - Enhanced the IRC+ protocol to support an enhanced "server handshake" and
 | 
			
		||||
    enable server to recognice numeric 005 (ISUPPORT) and 376 (ENDOFMOTD).
 | 
			
		||||
    See doc/Protocol.txt for details.
 | 
			
		||||
  - Re-added doc/SSL.txt to distribution -- got lost somewhere!?
 | 
			
		||||
  - Fixes the wrong logging output when nested servers are introduced
 | 
			
		||||
    to the network as well as the wrong output of the LINKS command.
 | 
			
		||||
  - Update Mac OS X Xcode project file for Xcode 3.
 | 
			
		||||
  - Adjust test suite to be usable on HP/UX 11.11 :-)
 | 
			
		||||
  - Fix code to compile using K&R C compiler and ansi2kr again.
 | 
			
		||||
  - New config option NoDNS: Disables DNS lookups when clients connect.
 | 
			
		||||
  - Fixed propagation of channel mode 'P' on server links.
 | 
			
		||||
  - Numeric 317: implemented "signon time" (displayed in WHOIS result).
 | 
			
		||||
  - Fixed code that prevented GCC 2.95 to compile ngIRCd.
 | 
			
		||||
  - Adjust path names in manual pages according to "./configure" settings.
 | 
			
		||||
  - Added new server configuration option "Passive" for "Server" blocks to
 | 
			
		||||
    disable automatic outgoing connections (similar to -p option to ngircd,
 | 
			
		||||
    but only for the specified server). (Tassilo Schweyer)
 | 
			
		||||
  - Don't connect to a server if a connection to another server within the
 | 
			
		||||
    same group is already in progress.
 | 
			
		||||
  - Added support for the WALLOPS command. Usage is restricted to IRC
 | 
			
		||||
    operators.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.10.4 (2008-01-07)
 | 
			
		||||
 | 
			
		||||
  - SECURITY: IRC_PART could reference invalid memory, causing
 | 
			
		||||
    ngircd to crash [from HEAD].
 | 
			
		||||
  
 | 
			
		||||
ngIRCd 0.10.3 (2007-08-01)
 | 
			
		||||
 | 
			
		||||
  - SECURITY: Fixed a severe bug in handling JOIN commands, which could
 | 
			
		||||
    cause the server to crash. Thanks to Sebastian Vesper, <net@veoson.net>.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.10.2 (2007-06-08)
 | 
			
		||||
 | 
			
		||||
  ngIRCd 0.10.2-pre2 (2007-05-19)
 | 
			
		||||
  - Server links are allowed to use larger write buffers now (up to 50 KB).
 | 
			
		||||
 | 
			
		||||
  ngIRCd 0.10.2-pre1 (2007-05-05)
 | 
			
		||||
  - Fix compressed server links (broken since 0.10.0).
 | 
			
		||||
  - Predefined Channel configuration now allows specification of channel key
 | 
			
		||||
    (mode k) and maximum user count (mode l).
 | 
			
		||||
  - When using epoll() IO interface, compile in the select() interface as
 | 
			
		||||
    well and fall back to it when epoll() isn't available on runtime.
 | 
			
		||||
  - New configure option "--without-select" to disable select() IO API
 | 
			
		||||
    (even when using epoll(), see above).
 | 
			
		||||
  - Added support for IO APIs "poll()" and "/dev/poll".
 | 
			
		||||
  - Reorganized internal handling of invite and ban lists.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.10.1 (2006-12-17)
 | 
			
		||||
 | 
			
		||||
  - Fixed validation of server names containing digits.
 | 
			
		||||
  - Update the "info text" of the local server after re-reading configuration.
 | 
			
		||||
  - Changed Numerics 265 and 266 to follow ircd 2.11.x "standards".
 | 
			
		||||
  - Allow PASS syntax defined in RFC 1459 for server links, too.
 | 
			
		||||
  - Enhanced ISUPPORT message (005 numeric).
 | 
			
		||||
  - New configuration option "PredefChannelsOnly": if set, clients can only
 | 
			
		||||
    join predefined channels.
 | 
			
		||||
  - Code cleanups: use "LogDebug(...)" instead of "Log(LOG_DEBUG, ...)", use
 | 
			
		||||
    "strcspn()", unsigned vs. signed, use "const", fix whitespaces, ...
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.10.0 (2006-10-01)
 | 
			
		||||
 | 
			
		||||
  - Fixed file handle leak when daemon is not able to send MOTD to a client.
 | 
			
		||||
 | 
			
		||||
  ngIRCd 0.10.0-pre2 (2006-09-09)
 | 
			
		||||
  - Fixed build problems with GCC option -fstack-protector.
 | 
			
		||||
  - Minor documentation updates.
 | 
			
		||||
 | 
			
		||||
  ngIRCd 0.10.0-pre1 (2006-08-02)
 | 
			
		||||
  - Validate "ServerName" (see RFC 2812, section 2.3.1).
 | 
			
		||||
  - Enhanced DIE to accept a single parameter ("comment text") which is sent
 | 
			
		||||
    to all locally connected clients before the server goes down.
 | 
			
		||||
@@ -654,4 +742,4 @@ ngIRCd 0.0.1, 31.12.2001
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: ChangeLog,v 1.302 2006/07/23 16:42:45 alex Exp $
 | 
			
		||||
$Id: ChangeLog,v 1.332.2.11 2008/02/26 20:35:05 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								INSTALL
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								INSTALL
									
									
									
									
									
								
							@@ -1,7 +1,7 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001-2004 by Alexander Barton,
 | 
			
		||||
                        (c)2001-2007 Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
@@ -149,14 +149,20 @@ standard locations.
 | 
			
		||||
  The Z compression library ("libz") is required for this option.
 | 
			
		||||
  
 | 
			
		||||
* IO Backend (autodetected by default):
 | 
			
		||||
  --with-select[=<path>] / --without-select
 | 
			
		||||
  --with-poll[=<path>] / --without-poll
 | 
			
		||||
  --with-devpoll[=<path>] / --without-devpoll
 | 
			
		||||
  --with-epoll[=<path>] / --without-epoll
 | 
			
		||||
  --with-kqueue[=<path>] / --without-kqueue  
 | 
			
		||||
 | 
			
		||||
  ngIRCd can use three different IO "backends": the "old school" select()
 | 
			
		||||
  ngIRCd can use different IO "backends": the "old school" select() and poll()
 | 
			
		||||
  API which should be supported by most UNIX-like operating systems, or the
 | 
			
		||||
  more efficient and flexible epoll() (Linux 2.6) or kqueue() (BSD) APIs.
 | 
			
		||||
  more efficient and flexible epoll() (Linux >=2.6), kqueue() (BSD) and
 | 
			
		||||
  /dev/poll APIs.
 | 
			
		||||
  By default the IO backend is autodetected, but you can use "--without-xxx"
 | 
			
		||||
  to disable a more enhanced API and force the daemon to use select().
 | 
			
		||||
  to disable a more enhanced API.
 | 
			
		||||
  When using the epoll() API, support for select() is compiled in as well by
 | 
			
		||||
  default to enable the binary to run on older Linux kernels (<2.6), too.
 | 
			
		||||
 | 
			
		||||
* IDENT-Support:
 | 
			
		||||
  --with-ident[=<path>]
 | 
			
		||||
@@ -241,4 +247,4 @@ number. In both cases the server exits after the output.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: INSTALL,v 1.23 2005/12/30 22:43:23 alex Exp $
 | 
			
		||||
$Id: INSTALL,v 1.26 2007/04/08 11:39:08 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										47
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,7 +1,7 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                        (c)2001-2005 Alexander Barton,
 | 
			
		||||
                        (c)2001-2008 Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
@@ -10,6 +10,49 @@
 | 
			
		||||
                                  -- NEWS --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.11.0 (2008-01-15)
 | 
			
		||||
 | 
			
		||||
  - Add support for /STAT u (server uptime) command.
 | 
			
		||||
  - New [Server] configuration Option "Bind" allows to specify
 | 
			
		||||
    the source ip adress to use when connecting to remote server.
 | 
			
		||||
  - New configuration option "MaxNickLength" to specify the allowed maximum
 | 
			
		||||
    length of user nick names. Note: must be unique in an IRC network!
 | 
			
		||||
  - Numeric 317: implemented "signon time" (displayed in WHOIS result).
 | 
			
		||||
  - Added new server configuration option "Passive" for "Server" blocks to
 | 
			
		||||
    disable automatic outgoing connections (similar to -p option to ngircd,
 | 
			
		||||
    but only for the specified server). (Tassilo Schweyer)
 | 
			
		||||
  - Added support for the WALLOPS command. Usage is restricted to IRC
 | 
			
		||||
    operators.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.10.2 (2007-06-08)
 | 
			
		||||
 | 
			
		||||
  - Predefined channel configuration now allows specification of channel key
 | 
			
		||||
    (mode k) and maximum user count (mode l): variables "Key" and "MaxUsers".
 | 
			
		||||
  - When using the epoll() IO interface, compile in the select() interface as
 | 
			
		||||
    well and fall back to it when epoll() isn't available on runtime.
 | 
			
		||||
  - Added support for IO APIs "poll()" and "/dev/poll".
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.10.1 (2006-12-17)
 | 
			
		||||
 | 
			
		||||
  - Allow PASS syntax defined in RFC 1459 for server links, too.
 | 
			
		||||
  - New configuration option "PredefChannelsOnly": if set, clients can only
 | 
			
		||||
    join predefined channels.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.10.0 (2006-10-01)
 | 
			
		||||
 | 
			
		||||
  ngIRCd 0.10.0-pre1 (2006-08-02)
 | 
			
		||||
  - Enhanced DIE to accept a single parameter ("comment text") which is sent
 | 
			
		||||
    to all locally connected clients before the server goes down.
 | 
			
		||||
  - JOIN now supports more than one channel key at a time.
 | 
			
		||||
  - Implemented numeric "333": Time and user name who set a channel topic.
 | 
			
		||||
  - Channel topics are no longer limited to 127 characters: now the only limit
 | 
			
		||||
    is the maximum length of an IRC command, i. e. 512 bytes (in practice, this
 | 
			
		||||
    limits the topic to about 490 characters due to protocol overhead).
 | 
			
		||||
  - Reverse DNS lookup code now checks the result by doing an additional
 | 
			
		||||
    lookup to prevent spoofing.
 | 
			
		||||
  - Added new IO layer which (optionally) supports epoll() and kqueue() in
 | 
			
		||||
    addition to the select() interface.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.9.0 (2005-07-24)
 | 
			
		||||
 | 
			
		||||
  - Never run with root privileges but always switch the user ID.
 | 
			
		||||
@@ -208,4 +251,4 @@ ngIRCd 0.0.1, 31.12.2001
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: NEWS,v 1.75 2005/07/26 19:41:49 alex Exp $
 | 
			
		||||
$Id: NEWS,v 1.83.2.4 2008/02/26 19:22:07 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								README
									
									
									
									
									
								
							@@ -1,7 +1,7 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                        (c)2001-2005 Alexander Barton,
 | 
			
		||||
                        (c)2001-2007 Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
@@ -19,6 +19,8 @@ Licence (URL: http://www.gnu.org/licenses/gpl.html). ngIRCd means "next
 | 
			
		||||
generation IRC daemon", it's written from scratch and not deduced from the
 | 
			
		||||
"grandfather of IRC daemons", the daemon of the IRCNet.
 | 
			
		||||
 | 
			
		||||
Please see the INSTALL document for installation and upgrade information!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
II. Status
 | 
			
		||||
~~~~~~~~~~~
 | 
			
		||||
@@ -35,7 +37,8 @@ Implemented IRC-commands are:
 | 
			
		||||
ADMIN, AWAY, CHANINFO, CONNECT, DIE, DISCONNECT, ERROR, HELP, INVITE, ISON,
 | 
			
		||||
JOIN, KICK, KILL, LINKS, LIST, LUSERS, MODE, MOTD, NAMES, NICK, NJOIN, NOTICE,
 | 
			
		||||
OPER, PART, PASS, PING, PONG, PRIVMSG, QUIT, REHASH, RESTART, SERVER, SQUIT,
 | 
			
		||||
STATS, TIME, TOPIC, TRACE, USER, USERHOST, VERSION, WHO, WHOIS, WHOWAS.
 | 
			
		||||
STATS, TIME, TOPIC, TRACE, USER, USERHOST, VERSION, WALLOPS, WHO, WHOIS,
 | 
			
		||||
WHOWAS.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
III. Features (or: why use ngIRCd?)
 | 
			
		||||
@@ -80,8 +83,9 @@ them at the following URL:
 | 
			
		||||
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 <alex@barton.de>.
 | 
			
		||||
mail to the ngIRCd mailing list: <ngircd-ml@arthur.ath.cx> (please see
 | 
			
		||||
<http://ngircd.barton.de/#ml> for details).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: README,v 1.21 2005/07/09 14:39:42 alex Exp $
 | 
			
		||||
$Id: README,v 1.25 2007/10/04 15:18:48 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								autogen.sh
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								autogen.sh
									
									
									
									
									
								
							@@ -9,7 +9,7 @@
 | 
			
		||||
# (at your option) any later version.
 | 
			
		||||
# Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
#
 | 
			
		||||
# $Id: autogen.sh,v 1.14 2005/02/21 15:23:23 alex Exp $
 | 
			
		||||
# $Id: autogen.sh,v 1.15 2007/10/07 13:02:15 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
@@ -124,17 +124,22 @@ if [ -z "$EXIST" ]; then
 | 
			
		||||
fi
 | 
			
		||||
[ "$VERBOSE" = "1" ] && echo "Using \"$EXIST\" to test for tools."
 | 
			
		||||
 | 
			
		||||
# We want to use GNU automake 1.7, if available (WANT_AUTOMAKE is used by
 | 
			
		||||
# We want to use GNU automake 1.9, if available (WANT_AUTOMAKE is used by
 | 
			
		||||
# the wrapper scripts of Gentoo Linux, AUTOMAKE_VERSION is used by OpenBSD);
 | 
			
		||||
# same applies for GNU autoconf, we want to use version 2.59.
 | 
			
		||||
AUTOMAKE_VERSION=1.7
 | 
			
		||||
AUTOCONF_VERSION=2.59
 | 
			
		||||
export AUTOMAKE_VERSION AUTOCONF_VERSION
 | 
			
		||||
WANT_AUTOMAKE=1.7
 | 
			
		||||
export WANT_AUTOMAKE
 | 
			
		||||
# same applies for GNU autoconf, we want to use version 2.59. -- But only
 | 
			
		||||
# set these preferences if not already set!
 | 
			
		||||
if [ -z "$AUTOMAKE_VERSION" -a -z "$WANT_AUTOMAKE" ]; then
 | 
			
		||||
	AUTOMAKE_VERSION=1.9
 | 
			
		||||
	WANT_AUTOMAKE=1.9
 | 
			
		||||
fi
 | 
			
		||||
if [ -z "$AUTOCONF_VERSION" -a -z "$WANT_AUTOCONF" ]; then
 | 
			
		||||
	AUTOCONF_VERSION=2.59
 | 
			
		||||
	WANT_AUTOCONF=2.59
 | 
			
		||||
fi
 | 
			
		||||
export AUTOMAKE_VERSION WANT_AUTOMAKE AUTOCONF_VERSION WANT_AUTOCONF
 | 
			
		||||
 | 
			
		||||
# Try to detect the needed tools when no environment variable already
 | 
			
		||||
# spezifies one:
 | 
			
		||||
# specifies one:
 | 
			
		||||
echo "Searching tools ..."
 | 
			
		||||
[ -z "$ACLOCAL" ] && ACLOCAL=`Search aclocal 1`
 | 
			
		||||
[ "$VERBOSE" = "1" ] && echo "ACLOCAL=$ACLOCAL"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										47
									
								
								config.guess
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										47
									
								
								config.guess
									
									
									
									
										vendored
									
									
								
							@@ -1,9 +1,10 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
# Attempt to guess a canonical system name.
 | 
			
		||||
#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 | 
			
		||||
#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 | 
			
		||||
#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
 | 
			
		||||
#   Inc.
 | 
			
		||||
 | 
			
		||||
timestamp='2006-02-23'
 | 
			
		||||
timestamp='2007-03-06'
 | 
			
		||||
 | 
			
		||||
# This file is free software; you can redistribute it and/or modify it
 | 
			
		||||
# under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -160,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 | 
			
		||||
	    arm*) machine=arm-unknown ;;
 | 
			
		||||
	    sh3el) machine=shl-unknown ;;
 | 
			
		||||
	    sh3eb) machine=sh-unknown ;;
 | 
			
		||||
	    sh5el) machine=sh5le-unknown ;;
 | 
			
		||||
	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
 | 
			
		||||
	esac
 | 
			
		||||
	# The Operating System including object format, if it has switched
 | 
			
		||||
@@ -210,7 +212,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    macppc:MirBSD:*:*)
 | 
			
		||||
	echo powerppc-unknown-mirbsd${UNAME_RELEASE}
 | 
			
		||||
	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *:MirBSD:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
 | 
			
		||||
@@ -770,6 +772,8 @@ EOF
 | 
			
		||||
	case ${UNAME_MACHINE} in
 | 
			
		||||
	    pc98)
 | 
			
		||||
		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
 | 
			
		||||
	    amd64)
 | 
			
		||||
		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
 | 
			
		||||
	    *)
 | 
			
		||||
		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
 | 
			
		||||
	esac
 | 
			
		||||
@@ -777,10 +781,7 @@ EOF
 | 
			
		||||
    i*:CYGWIN*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-cygwin
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*:MINGW*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-mingw32
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*:MSYS_NT-*:*:*)
 | 
			
		||||
    *:MINGW*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-mingw32
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*:windows32*:*)
 | 
			
		||||
@@ -790,12 +791,15 @@ EOF
 | 
			
		||||
    i*:PW*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-pw32
 | 
			
		||||
	exit ;;
 | 
			
		||||
    x86:Interix*:[345]*)
 | 
			
		||||
	echo i586-pc-interix${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    EM64T:Interix*:[345]*)
 | 
			
		||||
	echo x86_64-unknown-interix${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *:Interix*:[3456]*)
 | 
			
		||||
    	case ${UNAME_MACHINE} in
 | 
			
		||||
	    x86) 
 | 
			
		||||
		echo i586-pc-interix${UNAME_RELEASE}
 | 
			
		||||
		exit ;;
 | 
			
		||||
	    EM64T | authenticamd)
 | 
			
		||||
		echo x86_64-unknown-interix${UNAME_RELEASE}
 | 
			
		||||
		exit ;;
 | 
			
		||||
	esac ;;
 | 
			
		||||
    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
 | 
			
		||||
	echo i${UNAME_MACHINE}-pc-mks
 | 
			
		||||
	exit ;;
 | 
			
		||||
@@ -831,6 +835,9 @@ EOF
 | 
			
		||||
    arm*:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    avr32*:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    cris:Linux:*:*)
 | 
			
		||||
	echo cris-axis-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
@@ -947,6 +954,9 @@ EOF
 | 
			
		||||
    x86_64:Linux:*:*)
 | 
			
		||||
	echo x86_64-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    xtensa:Linux:*:*)
 | 
			
		||||
    	echo xtensa-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*86:Linux:*:*)
 | 
			
		||||
	# The BFD linker knows what the default object file format is, so
 | 
			
		||||
	# first see if it will tell us. cd to the root directory to prevent
 | 
			
		||||
@@ -989,7 +999,7 @@ EOF
 | 
			
		||||
	LIBC=gnulibc1
 | 
			
		||||
	# endif
 | 
			
		||||
	#else
 | 
			
		||||
	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__sun)
 | 
			
		||||
	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
 | 
			
		||||
	LIBC=gnu
 | 
			
		||||
	#else
 | 
			
		||||
	LIBC=gnuaout
 | 
			
		||||
@@ -1205,6 +1215,15 @@ EOF
 | 
			
		||||
    SX-6:SUPER-UX:*:*)
 | 
			
		||||
	echo sx6-nec-superux${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    SX-7:SUPER-UX:*:*)
 | 
			
		||||
	echo sx7-nec-superux${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    SX-8:SUPER-UX:*:*)
 | 
			
		||||
	echo sx8-nec-superux${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    SX-8R:SUPER-UX:*:*)
 | 
			
		||||
	echo sx8r-nec-superux${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    Power*:Rhapsody:*:*)
 | 
			
		||||
	echo powerpc-apple-rhapsody${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										68
									
								
								config.sub
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										68
									
								
								config.sub
									
									
									
									
										vendored
									
									
								
							@@ -1,9 +1,10 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
# Configuration validation subroutine script.
 | 
			
		||||
#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 | 
			
		||||
#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 | 
			
		||||
#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
 | 
			
		||||
#   Inc.
 | 
			
		||||
 | 
			
		||||
timestamp='2006-02-23'
 | 
			
		||||
timestamp='2007-01-18'
 | 
			
		||||
 | 
			
		||||
# This file is (in principle) common to ALL GNU software.
 | 
			
		||||
# The presence of a machine in this file suggests that SOME GNU software
 | 
			
		||||
@@ -240,15 +241,16 @@ case $basic_machine in
 | 
			
		||||
	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
 | 
			
		||||
	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
 | 
			
		||||
	| am33_2.0 \
 | 
			
		||||
	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
 | 
			
		||||
	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
 | 
			
		||||
	| bfin \
 | 
			
		||||
	| c4x | clipper \
 | 
			
		||||
	| d10v | d30v | dlx | dsp16xx \
 | 
			
		||||
	| fr30 | frv \
 | 
			
		||||
	| fido | fr30 | frv \
 | 
			
		||||
	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 | 
			
		||||
	| i370 | i860 | i960 | ia64 \
 | 
			
		||||
	| ip2k | iq2000 \
 | 
			
		||||
	| m32r | m32rle | m68000 | m68k | m88k | maxq | mb | microblaze | mcore \
 | 
			
		||||
	| m32c | m32r | m32rle | m68000 | m68k | m88k \
 | 
			
		||||
	| maxq | mb | microblaze | mcore | mep \
 | 
			
		||||
	| mips | mipsbe | mipseb | mipsel | mipsle \
 | 
			
		||||
	| mips16 \
 | 
			
		||||
	| mips64 | mips64el \
 | 
			
		||||
@@ -274,21 +276,19 @@ case $basic_machine in
 | 
			
		||||
	| pdp10 | pdp11 | pj | pjl \
 | 
			
		||||
	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
 | 
			
		||||
	| pyramid \
 | 
			
		||||
	| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
 | 
			
		||||
	| score \
 | 
			
		||||
	| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
 | 
			
		||||
	| sh64 | sh64le \
 | 
			
		||||
	| sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \
 | 
			
		||||
	| sparcv8 | sparcv9 | sparcv9b \
 | 
			
		||||
	| strongarm \
 | 
			
		||||
	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
 | 
			
		||||
	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
 | 
			
		||||
	| spu | strongarm \
 | 
			
		||||
	| tahoe | thumb | tic4x | tic80 | tron \
 | 
			
		||||
	| v850 | v850e \
 | 
			
		||||
	| we32k \
 | 
			
		||||
	| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
 | 
			
		||||
	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
 | 
			
		||||
	| z8k)
 | 
			
		||||
		basic_machine=$basic_machine-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	m32c)
 | 
			
		||||
		basic_machine=$basic_machine-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	m6811 | m68hc11 | m6812 | m68hc12)
 | 
			
		||||
		# Motorola 68HC11/12.
 | 
			
		||||
		basic_machine=$basic_machine-unknown
 | 
			
		||||
@@ -318,18 +318,18 @@ case $basic_machine in
 | 
			
		||||
	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
 | 
			
		||||
	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
 | 
			
		||||
	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
 | 
			
		||||
	| avr-* \
 | 
			
		||||
	| avr-* | avr32-* \
 | 
			
		||||
	| bfin-* | bs2000-* \
 | 
			
		||||
	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
 | 
			
		||||
	| clipper-* | craynv-* | cydra-* \
 | 
			
		||||
	| d10v-* | d30v-* | dlx-* \
 | 
			
		||||
	| elxsi-* \
 | 
			
		||||
	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
 | 
			
		||||
	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
 | 
			
		||||
	| h8300-* | h8500-* \
 | 
			
		||||
	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
 | 
			
		||||
	| i*86-* | i860-* | i960-* | ia64-* \
 | 
			
		||||
	| ip2k-* | iq2000-* \
 | 
			
		||||
	| m32r-* | m32rle-* \
 | 
			
		||||
	| m32c-* | m32r-* | m32rle-* \
 | 
			
		||||
	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
 | 
			
		||||
	| m88110-* | m88k-* | maxq-* | mcore-* \
 | 
			
		||||
	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
 | 
			
		||||
@@ -358,23 +358,21 @@ case $basic_machine in
 | 
			
		||||
	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
 | 
			
		||||
	| pyramid-* \
 | 
			
		||||
	| romp-* | rs6000-* \
 | 
			
		||||
	| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | shbe-* \
 | 
			
		||||
	| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
 | 
			
		||||
	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
 | 
			
		||||
	| sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \
 | 
			
		||||
	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
 | 
			
		||||
	| sparclite-* \
 | 
			
		||||
	| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
 | 
			
		||||
	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
 | 
			
		||||
	| tahoe-* | thumb-* \
 | 
			
		||||
	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
 | 
			
		||||
	| tron-* \
 | 
			
		||||
	| v850-* | v850e-* | vax-* \
 | 
			
		||||
	| we32k-* \
 | 
			
		||||
	| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
 | 
			
		||||
	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
 | 
			
		||||
	| xstormy16-* | xtensa-* \
 | 
			
		||||
	| ymp-* \
 | 
			
		||||
	| z8k-*)
 | 
			
		||||
		;;
 | 
			
		||||
	m32c-*)
 | 
			
		||||
		;;
 | 
			
		||||
	# Recognize the various machine names and aliases which stand
 | 
			
		||||
	# for a CPU type and a company and sometimes even an OS.
 | 
			
		||||
	386bsd)
 | 
			
		||||
@@ -912,6 +910,10 @@ case $basic_machine in
 | 
			
		||||
	sb1el)
 | 
			
		||||
		basic_machine=mipsisa64sb1el-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	sde)
 | 
			
		||||
		basic_machine=mipsisa32-sde
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	sei)
 | 
			
		||||
		basic_machine=mips-sei
 | 
			
		||||
		os=-seiux
 | 
			
		||||
@@ -923,6 +925,9 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=sh-hitachi
 | 
			
		||||
		os=-hms
 | 
			
		||||
		;;
 | 
			
		||||
	sh5el)
 | 
			
		||||
		basic_machine=sh5le-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	sh64)
 | 
			
		||||
		basic_machine=sh64-unknown
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1128,7 +1133,7 @@ case $basic_machine in
 | 
			
		||||
	sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
 | 
			
		||||
		basic_machine=sh-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	sparc | sparcv8 | sparcv9 | sparcv9b)
 | 
			
		||||
	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
 | 
			
		||||
		basic_machine=sparc-sun
 | 
			
		||||
		;;
 | 
			
		||||
	cydra)
 | 
			
		||||
@@ -1217,7 +1222,7 @@ case $os in
 | 
			
		||||
	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 | 
			
		||||
	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 | 
			
		||||
	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
 | 
			
		||||
	      | -skyos* | -haiku* | -rdos*)
 | 
			
		||||
	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
 | 
			
		||||
	# Remember, each alternative MUST END IN *, to match a version number.
 | 
			
		||||
		;;
 | 
			
		||||
	-qnx*)
 | 
			
		||||
@@ -1369,6 +1374,12 @@ else
 | 
			
		||||
# system, and we'll never get to this point.
 | 
			
		||||
 | 
			
		||||
case $basic_machine in
 | 
			
		||||
        score-*)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
        spu-*)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	*-acorn)
 | 
			
		||||
		os=-riscix1.2
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1378,9 +1389,9 @@ case $basic_machine in
 | 
			
		||||
	arm*-semi)
 | 
			
		||||
		os=-aout
 | 
			
		||||
		;;
 | 
			
		||||
    c4x-* | tic4x-*)
 | 
			
		||||
        os=-coff
 | 
			
		||||
        ;;
 | 
			
		||||
        c4x-* | tic4x-*)
 | 
			
		||||
        	os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	# This must come before the *-dec entry.
 | 
			
		||||
	pdp10-*)
 | 
			
		||||
		os=-tops20
 | 
			
		||||
@@ -1406,6 +1417,9 @@ case $basic_machine in
 | 
			
		||||
	m68*-cisco)
 | 
			
		||||
		os=-aout
 | 
			
		||||
		;;
 | 
			
		||||
        mep-*)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	mips*-cisco)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										164
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										164
									
								
								configure.in
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001-2005 Alexander Barton <alex@barton.de>
 | 
			
		||||
# Copyright (c)2001-2008 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,13 +8,13 @@
 | 
			
		||||
# (at your option) any later version.
 | 
			
		||||
# Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
#
 | 
			
		||||
# $Id: configure.in,v 1.118 2006/05/17 16:44:14 alex Exp $
 | 
			
		||||
# $Id: configure.in,v 1.125.2.4 2008/02/26 19:37:34 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# -- Initialisation --
 | 
			
		||||
 | 
			
		||||
AC_PREREQ(2.50)
 | 
			
		||||
AC_INIT(ngircd, CVSHEAD)
 | 
			
		||||
AC_INIT(ngircd, 0.11.1)
 | 
			
		||||
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
 | 
			
		||||
AC_CANONICAL_TARGET
 | 
			
		||||
AM_INIT_AUTOMAKE(1.6)
 | 
			
		||||
@@ -53,33 +53,33 @@ AC_PROG_RANLIB
 | 
			
		||||
 | 
			
		||||
AM_C_PROTOTYPES
 | 
			
		||||
AC_C_CONST
 | 
			
		||||
AC_C_INLINE
 | 
			
		||||
 | 
			
		||||
# -- Hard coded system and compiler dependencies/features/options ... --
 | 
			
		||||
 | 
			
		||||
AC_DEFUN([GCC_STACK_PROTECT_CC],[
 | 
			
		||||
  ssp_cc=yes
 | 
			
		||||
  # we use -fstack-protector-all for the test to enfoce the use of the guard variable 
 | 
			
		||||
  AC_MSG_CHECKING([whether ${CC} accepts -fstack-protector])
 | 
			
		||||
  ssp_old_cflags="$CFLAGS"
 | 
			
		||||
  CFLAGS="$CFLAGS -fstack-protector-all"
 | 
			
		||||
  AC_TRY_LINK(,,, ssp_cc=no)
 | 
			
		||||
  echo $ssp_cc
 | 
			
		||||
  CFLAGS="$ssp_old_cflags"
 | 
			
		||||
  if test "X$ssp_cc" = "Xyes"; then
 | 
			
		||||
      CFLAGS="$CFLAGS -fstack-protector"
 | 
			
		||||
      AC_DEFINE([ENABLE_SSP_CC], 1, [Define if SSP C support is enabled.])
 | 
			
		||||
  fi
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if test "$GCC" = "yes"; then
 | 
			
		||||
	# We are using the GNU C compiler. Good!
 | 
			
		||||
	CFLAGS="$CFLAGS -pipe -W -Wall -Wpointer-arith -Wstrict-prototypes"
 | 
			
		||||
 | 
			
		||||
	GCC_STACK_PROTECT_CC
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
AC_DEFUN([GCC_STACK_PROTECT_CC],[
 | 
			
		||||
  ssp_cc=yes
 | 
			
		||||
  if test "X$CC" != "X"; then
 | 
			
		||||
    AC_MSG_CHECKING([whether ${CC} accepts -fstack-protector])
 | 
			
		||||
    ssp_old_cflags="$CFLAGS"
 | 
			
		||||
    CFLAGS="$CFLAGS -fstack-protector"
 | 
			
		||||
    AC_TRY_COMPILE(,,, ssp_cc=no)
 | 
			
		||||
    echo $ssp_cc
 | 
			
		||||
    if test "X$ssp_cc" = "Xno"; then
 | 
			
		||||
      CFLAGS="$ssp_old_cflags"
 | 
			
		||||
    else
 | 
			
		||||
      AC_DEFINE([ENABLE_SSP_CC], 1, [Define if SSP C support is enabled.])
 | 
			
		||||
    fi
 | 
			
		||||
  fi
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
GCC_STACK_PROTECT_CC
 | 
			
		||||
 | 
			
		||||
case "$target_os" in
 | 
			
		||||
	hpux*)
 | 
			
		||||
		# This is HP/UX, we need to define _XOPEN_SOURCE_EXTENDED
 | 
			
		||||
@@ -138,17 +138,15 @@ AC_FUNC_STRFTIME
 | 
			
		||||
 | 
			
		||||
AC_CHECK_FUNCS([ \
 | 
			
		||||
	bind gethostbyaddr gethostbyname gethostname inet_ntoa malloc memmove \
 | 
			
		||||
	memset realloc setsid setsockopt socket strcasecmp strchr strerror \
 | 
			
		||||
	memset realloc setsid setsockopt socket strcasecmp strchr strcspn strerror \
 | 
			
		||||
	strstr waitpid],,AC_MSG_ERROR([required function missing!]))
 | 
			
		||||
 | 
			
		||||
AC_CHECK_FUNCS(inet_aton isdigit sigaction snprintf vsnprintf strdup strlcpy strlcat)
 | 
			
		||||
 | 
			
		||||
AC_CHECK_FUNCS(select,[AC_CHECK_HEADERS(sys/select.h)],
 | 
			
		||||
	AC_MSG_ERROR([required function select() is missing!])
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# -- Configuration options --
 | 
			
		||||
 | 
			
		||||
# use syslog?
 | 
			
		||||
 | 
			
		||||
x_syslog_on=no
 | 
			
		||||
AC_ARG_WITH(syslog,
 | 
			
		||||
	[  --without-syslog        disable syslog (autodetected by default)],
 | 
			
		||||
@@ -174,6 +172,8 @@ if test "$x_syslog_on" = "yes"; then
 | 
			
		||||
	AC_CHECK_HEADERS(syslog.h,,AC_MSG_ERROR([required C header missing!]))
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# use zlib compression?
 | 
			
		||||
 | 
			
		||||
x_zlib_on=no
 | 
			
		||||
AC_ARG_WITH(zlib,
 | 
			
		||||
	[  --without-zlib          disable zlib compression (autodetected by default)],
 | 
			
		||||
@@ -198,44 +198,120 @@ if test "$x_zlib_on" = "yes"; then
 | 
			
		||||
	AC_CHECK_HEADERS(zlib.h,,AC_MSG_ERROR([required C header missing!]))
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# detect which IO API to use:
 | 
			
		||||
 | 
			
		||||
x_io_backend=select
 | 
			
		||||
AC_ARG_WITH(epoll,
 | 
			
		||||
	[  --without-epoll         disable epoll support (autodetected by default)],
 | 
			
		||||
x_io_backend=none
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH(select,
 | 
			
		||||
	[  --without-select        disable select IO support (autodetected by default)],
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
				CPPFLAGS="-I$withval/include $CPPFLAGS"
 | 
			
		||||
				LDFLAGS="-L$withval/lib $LDFLAGS"
 | 
			
		||||
			fi
 | 
			
		||||
			AC_CHECK_FUNCS(epoll_create, x_io_backend=epoll,
 | 
			
		||||
				AC_MSG_ERROR([Can't enable epoll support!])
 | 
			
		||||
			AC_CHECK_FUNCS(select, x_io_select=yes,
 | 
			
		||||
				AC_MSG_ERROR([Can't enable select IO support!])
 | 
			
		||||
			)
 | 
			
		||||
		fi
 | 
			
		||||
	],
 | 
			
		||||
	[
 | 
			
		||||
		AC_CHECK_FUNCS(epoll_create, x_io_backend=epoll)
 | 
			
		||||
		AC_CHECK_FUNCS(select, x_io_select=yes)
 | 
			
		||||
	]
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH(poll,
 | 
			
		||||
	[  --without-poll          disable poll support (autodetected by default)],
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
				CPPFLAGS="-I$withval/include $CPPFLAGS"
 | 
			
		||||
				LDFLAGS="-L$withval/lib $LDFLAGS"
 | 
			
		||||
			fi
 | 
			
		||||
			AC_CHECK_FUNCS(poll, x_io_backend=poll\(\),
 | 
			
		||||
				AC_MSG_ERROR([Can't enable poll IO support!])
 | 
			
		||||
			)
 | 
			
		||||
		fi
 | 
			
		||||
	],
 | 
			
		||||
	[
 | 
			
		||||
		AC_CHECK_FUNCS(poll, x_io_backend=poll\(\))
 | 
			
		||||
	]
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH(devpoll,
 | 
			
		||||
	[  --without-devpoll       disable /dev/poll IO support (autodetected by default)],
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
				CPPFLAGS="-I$withval/include $CPPFLAGS"
 | 
			
		||||
				LDFLAGS="-L$withval/lib $LDFLAGS"
 | 
			
		||||
			fi
 | 
			
		||||
 | 
			
		||||
				AC_CHECK_HEADERS(sys/devpoll.h,,AC_MSG_ERROR([required C header missing!]))
 | 
			
		||||
		fi
 | 
			
		||||
	],
 | 
			
		||||
	[
 | 
			
		||||
		AC_CHECK_HEADERS(sys/devpoll.h, x_io_backend=/dev/poll)
 | 
			
		||||
	]
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH(epoll,
 | 
			
		||||
	[  --without-epoll         disable epoll IO support (autodetected by default)],
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
				CPPFLAGS="-I$withval/include $CPPFLAGS"
 | 
			
		||||
				LDFLAGS="-L$withval/lib $LDFLAGS"
 | 
			
		||||
			fi
 | 
			
		||||
			AC_CHECK_FUNCS(epoll_create, x_io_epoll=yes,
 | 
			
		||||
				AC_MSG_ERROR([Can't enable epoll IO support!])
 | 
			
		||||
			)
 | 
			
		||||
		fi
 | 
			
		||||
	],
 | 
			
		||||
	[
 | 
			
		||||
		AC_CHECK_FUNCS(epoll_create, x_io_epoll=yes)
 | 
			
		||||
	]
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH(kqueue,
 | 
			
		||||
	[  --without-kqueue        disable kqueue support (autodetected by default)],
 | 
			
		||||
	[  --without-kqueue        disable kqueue IO support (autodetected by default)],
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
				CPPFLAGS="-I$withval/include $CPPFLAGS"
 | 
			
		||||
				LDFLAGS="-L$withval/lib $LDFLAGS"
 | 
			
		||||
			fi
 | 
			
		||||
			AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue,
 | 
			
		||||
				AC_MSG_ERROR([Can't enable kqueue support!])
 | 
			
		||||
			AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue\(\),
 | 
			
		||||
				AC_MSG_ERROR([Can't enable kqueue IO support!])
 | 
			
		||||
			)
 | 
			
		||||
		fi
 | 
			
		||||
	],
 | 
			
		||||
	[
 | 
			
		||||
		AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue)
 | 
			
		||||
		AC_CHECK_FUNCS(kqueue, x_io_backend=kqueue\(\))
 | 
			
		||||
	]
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
if test "$x_io_epoll" = "yes" -a "$x_io_select" = "yes"; then
 | 
			
		||||
	# when epoll() and select() are available, we'll use both!
 | 
			
		||||
	x_io_backend="epoll(), select()"
 | 
			
		||||
else
 | 
			
		||||
	if test "$x_io_epoll" = "yes"; then
 | 
			
		||||
		# we prefere epoll() if it is available
 | 
			
		||||
		x_io_backend="epoll()"
 | 
			
		||||
	else
 | 
			
		||||
		if test "$x_io_select" = "yes" -a "$x_io_backend" = "none"; then
 | 
			
		||||
			# we'll use select, when available and no "better"
 | 
			
		||||
			# interface has been detected ...
 | 
			
		||||
			x_io_backend="select()"
 | 
			
		||||
		fi
 | 
			
		||||
	fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test "$x_io_backend" = "none"; then
 | 
			
		||||
	AC_MSG_ERROR([No useabe IO API activated/found!?])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# use TCP wrappers?
 | 
			
		||||
 | 
			
		||||
x_tcpwrap_on=no
 | 
			
		||||
AC_ARG_WITH(tcp-wrappers,
 | 
			
		||||
@@ -266,6 +342,8 @@ int deny_severity = 0;
 | 
			
		||||
	]
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# include support for "zeroconf"?
 | 
			
		||||
 | 
			
		||||
x_zeroconf_on=no
 | 
			
		||||
AC_ARG_WITH(zeroconf,
 | 
			
		||||
	[  --with-zeroconf         enable support for "Zeroconf"],
 | 
			
		||||
@@ -314,6 +392,8 @@ if test "$x_zeroconf_on" = "howl"; then
 | 
			
		||||
	AC_DEFINE(ZEROCONF, 1)
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# do IDENT requests using libident?
 | 
			
		||||
 | 
			
		||||
x_identauth_on=no
 | 
			
		||||
AC_ARG_WITH(ident,
 | 
			
		||||
	[  --with-ident            enable "IDENT" ("AUTH") protocol support],
 | 
			
		||||
@@ -335,6 +415,8 @@ if test "$x_identauth_on" = "yes"; then
 | 
			
		||||
	AC_CHECK_HEADERS(ident.h,,AC_MSG_ERROR([required C header missing!]))
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# compile in IRC+ protocol support?
 | 
			
		||||
 | 
			
		||||
x_ircplus_on=yes
 | 
			
		||||
AC_ARG_ENABLE(ircplus,
 | 
			
		||||
	[  --disable-ircplus       disable IRC+ protocol],
 | 
			
		||||
@@ -344,6 +426,8 @@ if test "$x_ircplus_on" = "yes"; then
 | 
			
		||||
	AC_DEFINE(IRCPLUS, 1)
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# compile in IRC "sniffer"?
 | 
			
		||||
 | 
			
		||||
x_sniffer_on=no; x_debug_on=no
 | 
			
		||||
AC_ARG_ENABLE(sniffer,
 | 
			
		||||
	[  --enable-sniffer        enable IRC traffic sniffer (enables debug mode)],
 | 
			
		||||
@@ -353,6 +437,8 @@ AC_ARG_ENABLE(sniffer,
 | 
			
		||||
	fi
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# enable additional debugging code?
 | 
			
		||||
 | 
			
		||||
AC_ARG_ENABLE(debug,
 | 
			
		||||
	[  --enable-debug          show additional debug output],
 | 
			
		||||
	if test "$enableval" = "yes"; then x_debug_on=yes; fi
 | 
			
		||||
@@ -362,6 +448,8 @@ if test "$x_debug_on" = "yes"; then
 | 
			
		||||
	test "$GCC" = "yes" && CFLAGS="-pedantic $CFLAGS"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# enable "strict RFC rules"?
 | 
			
		||||
 | 
			
		||||
x_strict_rfc_on=no
 | 
			
		||||
AC_ARG_ENABLE(strict-rfc,
 | 
			
		||||
	[  --enable-strict-rfc     strict RFC conformance -- may break clients!],
 | 
			
		||||
@@ -482,7 +570,7 @@ test "$x_identauth_on" = "yes" \
 | 
			
		||||
	&& echo $ECHO_N "yes   $ECHO_C" \
 | 
			
		||||
	|| echo $ECHO_N "no    $ECHO_C"
 | 
			
		||||
echo $ECHO_N "        I/O backend: $ECHO_C"
 | 
			
		||||
	echo "\"$x_io_backend()\""
 | 
			
		||||
	echo "\"$x_io_backend\""
 | 
			
		||||
 | 
			
		||||
echo
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								contrib/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								contrib/.cvsignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
							
								
								
									
										2
									
								
								contrib/Debian/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								contrib/Debian/.cvsignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
@@ -1,3 +1,70 @@
 | 
			
		||||
ngircd (0.11.1-0ab1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New "upstream" release 0.11.1.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Tue, 26 Feb 2008 20:24:55 +0100
 | 
			
		||||
 | 
			
		||||
ngircd (0.11.0-0ab1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New "upstream" release 0.11.0.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Tue, 15 Jan 2008 21:43:46 +0100
 | 
			
		||||
 | 
			
		||||
ngircd (0.11.0-0ab0-pre2) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Second prerelease of upcoming new "upstream release".
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Mon,  7 Jan 2008 15:32:42 +0100
 | 
			
		||||
 | 
			
		||||
ngircd (0.11.0-0ab0-pre1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Prerelease of upcoming new "upstream release".
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Wed,  2 Jan 2008 21:33:15 +0100
 | 
			
		||||
 | 
			
		||||
ngircd (0.10.4-0ab1) unstable; urgency=high
 | 
			
		||||
 | 
			
		||||
  * New "upstream" release: 0.10.4 - fixing a security bug.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Mon,  7 Jan 2008 22:04:44 +0100
 | 
			
		||||
 | 
			
		||||
ngircd (0.10.0-0ab1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New "upstream" release: 0.10.0
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Sun,  1 Oct 2006 18:14:21 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (0.10.0-0ab0-pre2-1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Bumped standards version to 3.7.2.1.
 | 
			
		||||
  * Added "Provides: ircd" to Debian control file.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Sun,  1 Oct 2006 16:25:33 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (0.10.0-0ab0-pre2) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Second "upstream" prerelease of upcoming 0.10.0 release.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Sat,  9 Sep 2006 20:57:52 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (0.10.0-0ab0-pre1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Prerelease of upcoming new "upstream release".
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Wed,  2 Aug 2006 12:01:07 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (0.9.2-0ab1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New "upstream release" fixing a few bugs in 0.9.1.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Sat, 15 Oct 2005 14:10:34 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (0.9.1-0ab1) unstable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * New "upstream release" addressing two problems in ngIRCd 0.9.0.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Wed,  3 Aug 2005 15:10:41 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (0.9.0-0ab2) unstable; urgency=medium
 | 
			
		||||
 | 
			
		||||
  * Init script: fixed a problem with symbolic links in runlevel directories
 | 
			
		||||
 
 | 
			
		||||
@@ -3,11 +3,12 @@ Section: net
 | 
			
		||||
Priority: optional
 | 
			
		||||
Maintainer: Alexander Barton <alex@barton.de>
 | 
			
		||||
Build-Depends: debhelper (>> 4.0.0), libz-dev, libwrap-dev, libident-dev
 | 
			
		||||
Standards-Version: 3.5.8
 | 
			
		||||
Standards-Version: 3.7.2.1
 | 
			
		||||
 | 
			
		||||
Package: ngircd
 | 
			
		||||
Architecture: any
 | 
			
		||||
Depends: ${shlibs:Depends}, ${misc:Depends}
 | 
			
		||||
Provides: ircd
 | 
			
		||||
Description: A lightweight daemon for the Internet Relay Chat (IRC)
 | 
			
		||||
 ngIRCd is a free open source daemon for the Internet Relay Chat (IRC)
 | 
			
		||||
 network. It is written from scratch and is not based upon the original
 | 
			
		||||
@@ -28,6 +29,7 @@ Description: A lightweight daemon for the Internet Relay Chat (IRC)
 | 
			
		||||
Package: ngircd-full
 | 
			
		||||
Architecture: any
 | 
			
		||||
Depends: ${shlibs:Depends}, ${misc:Depends}
 | 
			
		||||
Provides: ircd
 | 
			
		||||
Conflicts: ngircd
 | 
			
		||||
Description: A lightweight daemon for the Internet Relay Chat (IRC)
 | 
			
		||||
 ngIRCd is a free open source daemon for the Internet Relay Chat (IRC)
 | 
			
		||||
 
 | 
			
		||||
@@ -2,9 +2,20 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd start and stop script for Debian-based systems
 | 
			
		||||
#
 | 
			
		||||
# $Id: ngircd.init,v 1.6 2005/07/26 19:37:18 alex Exp $
 | 
			
		||||
# $Id: ngircd.init,v 1.7 2006/12/26 14:43:46 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
### BEGIN INIT INFO
 | 
			
		||||
# Provides:		ircd
 | 
			
		||||
# Required-Start:	$local_fs
 | 
			
		||||
# Required-Stop:	$local_fs
 | 
			
		||||
# Should-Start:		$syslog $network
 | 
			
		||||
# Should-Stop:		$syslog $network
 | 
			
		||||
# Default-Start:	2 3 4 5
 | 
			
		||||
# Default-Stop:		0 1 6
 | 
			
		||||
# Short-Description:	Next Generation IRC Server
 | 
			
		||||
### END INIT INFO
 | 
			
		||||
 | 
			
		||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 | 
			
		||||
DAEMON=/usr/sbin/ngircd
 | 
			
		||||
NAME=ngIRCd
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,20 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
#
 | 
			
		||||
# Debian post-installation script
 | 
			
		||||
# $Id: ngircd.postinst,v 1.1 2003/12/31 17:20:11 alex Exp $
 | 
			
		||||
# $Id: ngircd.postinst,v 1.2 2006/12/26 14:44:40 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
if [ -f /etc/ngircd/ngircd.conf ]; then
 | 
			
		||||
	# make sure that configuration file is not world readable
 | 
			
		||||
	chmod o= /etc/ngircd/ngircd.conf
 | 
			
		||||
fi
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
case "$1" in
 | 
			
		||||
	configure)
 | 
			
		||||
		if [ -f /etc/ngircd/ngircd.conf ]; then
 | 
			
		||||
			# make sure that the configuration file is not
 | 
			
		||||
			# world-readable, it contains passwords!
 | 
			
		||||
			chmod o= /etc/ngircd/ngircd.conf
 | 
			
		||||
		fi
 | 
			
		||||
		;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
#DEBHELPER#
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								contrib/MacOSX/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								contrib/MacOSX/.cvsignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
							
								
								
									
										92
									
								
								contrib/MacOSX/config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								contrib/MacOSX/config.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,92 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2007 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: config.h,v 1.1 2007/11/19 22:11:36 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Static configuration file for Mac OS X Xcode project
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define PACKAGE_NAME "ngircd"
 | 
			
		||||
#define VERSION "??"
 | 
			
		||||
#define SYSCONFDIR "/etc/ngircd"
 | 
			
		||||
 | 
			
		||||
/* -- Build options -- */
 | 
			
		||||
 | 
			
		||||
/* Define if debug-mode should be enabled */
 | 
			
		||||
#define DEBUG 1
 | 
			
		||||
 | 
			
		||||
/* Define if the server should do IDENT requests */
 | 
			
		||||
/*#define IDENTAUTH 1*/
 | 
			
		||||
 | 
			
		||||
/* Define if IRC+ protocol should be used */
 | 
			
		||||
#define IRCPLUS 1
 | 
			
		||||
 | 
			
		||||
/* Define if IRC sniffer should be enabled */
 | 
			
		||||
/*#define SNIFFER 1*/
 | 
			
		||||
 | 
			
		||||
/* Define if syslog should be used for logging */
 | 
			
		||||
#define SYSLOG 1
 | 
			
		||||
 | 
			
		||||
/* Define if TCP wrappers should be used */
 | 
			
		||||
/*#define TCPWRAP 1*/
 | 
			
		||||
 | 
			
		||||
/* Define if support for Zeroconf should be included */
 | 
			
		||||
/*#define ZEROCONF 1*/
 | 
			
		||||
 | 
			
		||||
/* Define if zlib compression should be enabled */
 | 
			
		||||
#define ZLIB 1
 | 
			
		||||
 | 
			
		||||
/* -- Supported features -- */
 | 
			
		||||
 | 
			
		||||
/* Define if SSP C support is enabled. */
 | 
			
		||||
#define ENABLE_SSP_CC 1
 | 
			
		||||
 | 
			
		||||
/* Define to 1 if the C compiler supports function prototypes. */
 | 
			
		||||
#define PROTOTYPES 1
 | 
			
		||||
/* Define like PROTOTYPES; this can be used by system headers. */
 | 
			
		||||
#define __PROTOTYPES 1
 | 
			
		||||
 | 
			
		||||
/* Define to 1 if you have the <sys/types.h> header file. */
 | 
			
		||||
#define HAVE_SYS_TYPES_H 1
 | 
			
		||||
/* Define to 1 if you have the <inttypes.h> header file. */
 | 
			
		||||
#define HAVE_INTTYPES_H 1
 | 
			
		||||
/* Define to 1 if you have the <stddef.h> header file. */
 | 
			
		||||
#define HAVE_STDDEF_H 1
 | 
			
		||||
/* Define to 1 if you have the <stdbool.h> header file. */
 | 
			
		||||
#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 `kqueue' function. */
 | 
			
		||||
#define HAVE_KQUEUE 1
 | 
			
		||||
/* Define to 1 if you have the `inet_ntoa' function. */
 | 
			
		||||
#define HAVE_INET_NTOA 1
 | 
			
		||||
/* Define to 1 if you have the `snprintf' function. */
 | 
			
		||||
#define HAVE_SNPRINTF 1
 | 
			
		||||
/* Define to 1 if you have the `strlcat' function. */
 | 
			
		||||
#define HAVE_STRLCAT 1
 | 
			
		||||
/* Define to 1 if you have the `strlcpy' function. */
 | 
			
		||||
#define HAVE_STRLCPY 1
 | 
			
		||||
/* Define to 1 if you have the `strdup' function. */
 | 
			
		||||
#define HAVE_STRDUP 1
 | 
			
		||||
/* Define to 1 if you have the `vsnprintf' function. */
 | 
			
		||||
#define HAVE_VSNPRINTF 1
 | 
			
		||||
 | 
			
		||||
/* Define if socklen_t exists */
 | 
			
		||||
#define HAVE_socklen_t 1
 | 
			
		||||
 | 
			
		||||
#ifdef ZEROCONF
 | 
			
		||||
/* Define to 1 if you have the <DNSServiceDiscovery/DNSServiceDiscovery.h> header file. */
 | 
			
		||||
#define HAVE_DNSSERVICEDISCOVERY_DNSSERVICEDISCOVERY_H 1
 | 
			
		||||
/* Define to 1 if you have the `DNSServiceRegistrationCreate' function. */
 | 
			
		||||
#define HAVE_DNSSERVICEREGISTRATIONCREATE 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										0
									
								
								contrib/MacOSX/cvs-version.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								contrib/MacOSX/cvs-version.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,5 +1,5 @@
 | 
			
		||||
%define name    ngircd
 | 
			
		||||
%define version CVSHEAD
 | 
			
		||||
%define version 0.11.1
 | 
			
		||||
%define release 1
 | 
			
		||||
%define prefix  %{_prefix}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								doc/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								doc/.cvsignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001-2003 by Alexander Barton,
 | 
			
		||||
                        (c)2001-2006 Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
@@ -47,11 +47,11 @@ Updating the CVS tree:
 | 
			
		||||
You can update a single file or the complete source tree.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
III. Write Access
 | 
			
		||||
~~~~~~~~~~~~~~~~~
 | 
			
		||||
II. Write Access
 | 
			
		||||
~~~~~~~~~~~~~~~~
 | 
			
		||||
If you want to contribute a couple of patches and write access to the CVS
 | 
			
		||||
repository would be handy, please contact Alex Barton, <alex@barton.de>.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: CVS.txt,v 1.8 2006/07/23 12:43:15 alex Exp $
 | 
			
		||||
$Id: CVS.txt,v 1.9 2006/08/03 14:37:29 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								doc/FAQ.txt
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								doc/FAQ.txt
									
									
									
									
									
								
							@@ -62,15 +62,6 @@ A: On Linux/glibc with chroot enabled you need to put some libraries inside
 | 
			
		||||
   is to either disable chroot support or to link against dietlibc instead
 | 
			
		||||
   of glibc. (tnx to Sebastian Siewior)
 | 
			
		||||
 | 
			
		||||
Q: I am running Linux and ngircd dies on startup with the follwing errors:
 | 
			
		||||
   IO subsystem: epoll (hint size 100, initial maxfd 100, masterfd -1).
 | 
			
		||||
   Cannot initialize IO routines: Function not implemented
 | 
			
		||||
   Server isn't listening on a single port!
 | 
			
		||||
   ngircd exiting due to fatal errors!
 | 
			
		||||
A: epoll is only supported on 2.6 Linux kernels. Either use a 2.6 kernel, or
 | 
			
		||||
   re-run configure with the --without-epoll parameter. After configure
 | 
			
		||||
   completed, you should see select() being listed as IO backend:
 | 
			
		||||
   '(I/O backend: "select()"').
 | 
			
		||||
 | 
			
		||||
IV. Bugs!?
 | 
			
		||||
~~~~~~~~~~
 | 
			
		||||
@@ -85,4 +76,4 @@ A: Please file a bug report at <http://ngircd.barton.de/bugzilla/index.cgi>!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: FAQ.txt,v 1.11 2005/12/09 21:14:56 fw Exp $
 | 
			
		||||
$Id: FAQ.txt,v 1.11.4.1 2008/01/02 22:36:48 fw Exp $
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
 | 
			
		||||
# Copyright (c)2001-2007 by 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
 | 
			
		||||
@@ -9,13 +9,13 @@
 | 
			
		||||
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
 | 
			
		||||
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile.am,v 1.21 2005/11/29 20:59:57 alex Exp $
 | 
			
		||||
# $Id: Makefile.am,v 1.22 2007/11/20 21:39:35 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
SUBDIRS = src
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = CVS.txt FAQ.txt Protocol.txt Platforms.txt README-AUX.txt \
 | 
			
		||||
	README-BeOS.txt RFC.txt Zeroconf.txt  sample-ngircd.conf
 | 
			
		||||
	README-BeOS.txt RFC.txt SSL.txt Zeroconf.txt sample-ngircd.conf
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                        (c)2001-2004 Alexander Barton
 | 
			
		||||
                        (c)2001-2006 Alexander Barton
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
@@ -26,24 +26,32 @@ list can be updated. Thanks for your help!
 | 
			
		||||
                                                                    | | | |
 | 
			
		||||
Platform                    Compiler     ngIRCd     Date     Tester C M T R See
 | 
			
		||||
--------------------------- ------------ ---------- -------- ------ - - - - ---
 | 
			
		||||
alpha/unknown/netbsd3.0     gcc 3.3.3    CVSHEAD    06-05-07 fw     Y Y Y Y (3)		
 | 
			
		||||
alpha/unknown/netbsd3.0     gcc 3.3.3    CVSHEAD    06-05-07 fw     Y Y Y Y (3)
 | 
			
		||||
hppa/unknown/openbsd3.5     gcc 2.95.3   CVSHEAD    04-05-25 alex   Y Y Y Y
 | 
			
		||||
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    0.9.x-CVS  05-06-27 alex   Y Y Y Y
 | 
			
		||||
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    CVSHEAD    06-08-04 alex   Y Y Y Y
 | 
			
		||||
i386/unknown/freebsd5.2.1   gcc 3.3.3    0.8.0      04-05-30 alex   Y Y Y Y
 | 
			
		||||
i386/unknown/freebsd6.1     gcc 3.4.4    CVSHEAD    06-05-07 fw     Y Y Y Y (4)
 | 
			
		||||
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/gnu0.3         gcc 3.3.3    0.8.0      04-05-30 alex   Y Y n Y
 | 
			
		||||
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/openbsd3.9     gcc 3.3.5    0.10.0-p1  06-08-30 alex   Y Y Y Y (3)
 | 
			
		||||
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.3    0.8.0      04-05-30 alex   Y Y Y Y (1)
 | 
			
		||||
i386/pc/linux-gnu           gcc 4.1.2    0.10.0-p1  06-08-30 alex   Y Y Y Y (1)
 | 
			
		||||
m68k/apple/aux3.1.1         Orig. A/UX   0.7.x-CVS  03-04-22 alex   Y Y Y Y (2)
 | 
			
		||||
m68k/hp/hp-ux9.10           Orig. HPUX   0.7.x-CVS  03-04-30 goetz  Y Y Y Y
 | 
			
		||||
m88k/dg/dgux5.4R3.10        gcc 2.5.8    CVSHEAD    04-03-15 alex   Y Y ? ?
 | 
			
		||||
powerpc/apple/darwin6.5     gcc 3.1      0.7.x-CVS  03-04-23 alex   Y Y Y Y
 | 
			
		||||
powerpc/apple/darwin7.4.0   gcc 3.3      0.8.0      04-05-30 alex   Y Y Y Y
 | 
			
		||||
powerpc/apple/darwin7.9.0   gcc 3.3      CVSHEAD    06-05-07 fw     Y Y Y Y (3)
 | 
			
		||||
powerpc/apple/darwin8.1.0   gcc 4.0      0.9.x-CVS  05-06-27 alex   Y Y Y Y
 | 
			
		||||
powerpc/unknown/linux-gnu   gcc 3.3.3    0.8.0      04-05-30 alex   Y Y Y Y
 | 
			
		||||
powerpc/unknown/openbsd3.6  gcc 2.95.3   0.10.0     06-10-08 alex   Y Y n Y
 | 
			
		||||
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
 | 
			
		||||
@@ -51,16 +59,19 @@ sparc/unkn./netbsdelf1.6.1  gcc 2.95.3   0.8.0      04-05-30 alex   Y Y Y Y
 | 
			
		||||
 | 
			
		||||
Notes
 | 
			
		||||
~~~~~
 | 
			
		||||
 | 
			
		||||
(1) i686/pc/linux-gnu:
 | 
			
		||||
    ngIRCd has been tested with various Linux distributions, such as SuSE,
 | 
			
		||||
    RedHat, Debian, and Gentoo using Kernels 2.2.x, 2.4.x and 2.6.x with
 | 
			
		||||
    various versions of the GNU C compiler (2.95.3, 3.0, 3.2, and 3.3). The
 | 
			
		||||
    eldest glibc used was glibc-2.0.7. ngIRCd compiled and run on all these
 | 
			
		||||
    systems without problems.
 | 
			
		||||
    various versions of the GNU C compiler (starting with 2.95.x and up to
 | 
			
		||||
    version 4.1.x). The eldest glibc used was glibc-2.0.7. ngIRCd compiled
 | 
			
		||||
    and run on all these systems without problems.
 | 
			
		||||
    Actual Linux kernels (2.6.x) and glic's support the epoll() IO interface.
 | 
			
		||||
 | 
			
		||||
(2) This compiler is an pre-ANSI C compiler, therefore the source code is
 | 
			
		||||
    automatically converted using the included ansi2knr tool while building.
 | 
			
		||||
(3) kqueue io backend			
 | 
			
		||||
(4) 6.1-PRERELEASE
 | 
			
		||||
 | 
			
		||||
(3) Using the kqueue() IO interface.
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: Platforms.txt,v 1.14 2006/05/07 11:07:13 fw Exp $
 | 
			
		||||
$Id: Platforms.txt,v 1.18 2006/10/08 14:09:16 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001-2003 by Alexander Barton,
 | 
			
		||||
                        (c)2001-2007 Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
@@ -79,6 +79,9 @@ The following <serverflags> are defined at the moment:
 | 
			
		||||
     peer understands this flag, it will send "MODE +I" and "MODE +b"
 | 
			
		||||
     commands after the server link has been established.
 | 
			
		||||
 | 
			
		||||
- H: The server supports the "enhanced server handshake", see section II.2
 | 
			
		||||
     for a detailed description.
 | 
			
		||||
 | 
			
		||||
- o: IRC operators are allowed to change channel- and channel-user-modes
 | 
			
		||||
     even if they aren't channel-operator of the affected channel.
 | 
			
		||||
 | 
			
		||||
@@ -90,7 +93,50 @@ The optional parameter <options> is used to propagate server options as
 | 
			
		||||
defined in RFC 2813, section 4.1.1.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
II.2 Exchange channel-modes, topics, and persistent channels
 | 
			
		||||
II.2 Enhanced Server Handshake
 | 
			
		||||
 | 
			
		||||
The "enhanced server handshake" is used when both servers support this IRC+
 | 
			
		||||
extension, which is indicated by the 'H' flag in the <serverflags> sent with
 | 
			
		||||
the PASS command, see section II.1.
 | 
			
		||||
 | 
			
		||||
It basically means, that after exchanging the PASS and SERVER commands the
 | 
			
		||||
server is not registered in the network (as usual), but that IRC numerics
 | 
			
		||||
are exchanged until the numeric 376 (ENDOFMOTD) is received. Afterwards the
 | 
			
		||||
peer is registered in the network as with the regular IRC protocol.
 | 
			
		||||
 | 
			
		||||
A server implementing the enhanced server handshake (and indicating this
 | 
			
		||||
using 'H' in the <serverflags>) MUST ignore all unknown numerics to it
 | 
			
		||||
silently.
 | 
			
		||||
 | 
			
		||||
In addition, such a server should at least send the numeric 005 (ISUPPORT)
 | 
			
		||||
to its peer, containing the following information. Syntax: <key>=<value>,
 | 
			
		||||
one token per IRC parameter. If the server has to send more than 12 token
 | 
			
		||||
it must send separate ISUPPORT numerics (this is a limitation of the IRC
 | 
			
		||||
protocol which allows at max 15 arguments per command).
 | 
			
		||||
 | 
			
		||||
 - NICKLEN: Maximum nickname length. Default: 9.
 | 
			
		||||
 - CASEMAPPING: Case mapping used for nick- and channel name comparing.
 | 
			
		||||
   Default: "ascii", the chars [a-z] are lowercase of [A-Z].
 | 
			
		||||
 - PREFIX: List of channel modes a person can get and the respective prefix
 | 
			
		||||
   a channel or nickname will get in case the person has it. The order of the
 | 
			
		||||
   modes goes from most powerful to least powerful. Default: "(ov)@+"
 | 
			
		||||
 - CHANTYPES: Supported channel prefixes. Default: "#".
 | 
			
		||||
 - CHANMODES: List of channel modes for 4 types, separated by comma (","):
 | 
			
		||||
   Mode that adds or removes a nick or address to a list, mode that changes
 | 
			
		||||
   a setting (both have always has a parameter), mode that changes a setting
 | 
			
		||||
   and only has a parameter when set, and mode that changes a setting and
 | 
			
		||||
   never has a parameter. For example "bI,k,l,imnPst".
 | 
			
		||||
 - CHANLIMIT: Maximum number of channels allowed to join by channel prefix,
 | 
			
		||||
   for example "#:10".
 | 
			
		||||
 | 
			
		||||
Please see <http://www.irc.org/tech_docs/005.html> for details.
 | 
			
		||||
 | 
			
		||||
The information exchanged using ISUPPORT can be used to detect configuration
 | 
			
		||||
incompatibilities (different maximum nick name length, for example) and
 | 
			
		||||
therefore to disconnect the peer prior to registering it in the network.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
II.3 Exchange channel-modes, topics, and persistent channels
 | 
			
		||||
 | 
			
		||||
     Command: CHANINFO
 | 
			
		||||
  Parameters: <channel> +<modes> <key> <limit> [<topic>]
 | 
			
		||||
@@ -115,4 +161,4 @@ channel mode). In this case <limit> should be "0".
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: Protocol.txt,v 1.13 2005/08/27 19:00:06 alex Exp $
 | 
			
		||||
$Id: Protocol.txt,v 1.14 2007/11/21 12:16:35 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                        (c)2001-2005 Alexander Barton
 | 
			
		||||
                        (c)2001-2006 Alexander Barton
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
@@ -16,7 +16,8 @@ with DNS Service Discovery (DNS-SD[3]).
 | 
			
		||||
To use this features you can use one of two APIs:
 | 
			
		||||
 | 
			
		||||
  a) Apple "Bonjour" API as used by Mac OS X,
 | 
			
		||||
  b) the Howl[4] Zeroconf library.
 | 
			
		||||
  b) the Howl[4] Zeroconf library or the Howl compatibility layer
 | 
			
		||||
     of the newer Avahi[5] library.
 | 
			
		||||
 | 
			
		||||
When calling the configure script using the "--with-zeroconf" switch the
 | 
			
		||||
avalable API will be autodetected and the required additional libraries will
 | 
			
		||||
@@ -32,7 +33,8 @@ Links:
 | 
			
		||||
 [2] http://www.multicastdns.org/
 | 
			
		||||
 [3] http://www.dns-sd.org/
 | 
			
		||||
 [4] http://www.porchdogsoft.com/products/howl/
 | 
			
		||||
 [5] http://avahi.org/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: Zeroconf.txt,v 1.1 2005/07/08 16:19:03 alex Exp $
 | 
			
		||||
$Id: Zeroconf.txt,v 1.2 2006/08/03 14:37:29 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
# $Id: sample-ngircd.conf,v 1.37 2006/04/09 12:27:23 alex Exp $
 | 
			
		||||
# $Id: sample-ngircd.conf,v 1.43.2.1 2008/01/07 23:10:28 alex Exp $
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# This is a sample configuration file for the ngIRCd, which must be adepted
 | 
			
		||||
@@ -6,6 +6,10 @@
 | 
			
		||||
#
 | 
			
		||||
# Comments are started with "#" or ";".
 | 
			
		||||
#
 | 
			
		||||
# A lot of configuration options in this file start with a ";". You have
 | 
			
		||||
# to remove the ";" in front of each variable to actually set a value!
 | 
			
		||||
# The disabled variables are shown with example values for completeness.
 | 
			
		||||
#
 | 
			
		||||
# Use "ngircd --configtest" (see manual page ngircd(8)) to validate that the
 | 
			
		||||
# server interprets the configuration file as expected!
 | 
			
		||||
#
 | 
			
		||||
@@ -93,17 +97,28 @@
 | 
			
		||||
	# server? (This is a compatibility hack for ircd-irc2 servers)
 | 
			
		||||
	;OperServerMode = no
 | 
			
		||||
 | 
			
		||||
	# Allow Pre-Defined Channels only (see Section [Channels])
 | 
			
		||||
	;PredefChannelsOnly = no
 | 
			
		||||
 | 
			
		||||
	# Don't do any DNS lookups when a client connects to the server.
 | 
			
		||||
	;NoDNS = no
 | 
			
		||||
 | 
			
		||||
	# Maximum number of simultaneous connection the server is allowed
 | 
			
		||||
	# to accept (<=0: unlimited):
 | 
			
		||||
	;MaxConnections = -1
 | 
			
		||||
	# to accept (0: unlimited):
 | 
			
		||||
	;MaxConnections = 0
 | 
			
		||||
 | 
			
		||||
	# Maximum number of simultaneous connections from a single IP address
 | 
			
		||||
	# the server will accept (<=0: unlimited):
 | 
			
		||||
	# the server will accept (0: unlimited):
 | 
			
		||||
	;MaxConnectionsIP = 5
 | 
			
		||||
 | 
			
		||||
	# Maximum number of channels a user can be member of (<=0: no limit):
 | 
			
		||||
	# Maximum number of channels a user can be member of (0: no limit):
 | 
			
		||||
	;MaxJoins = 10
 | 
			
		||||
 | 
			
		||||
	# Maximum length of an user nick name (Default: 9, as in RFC 2812).
 | 
			
		||||
	# Please note that all servers in an IRC network MUST use the same
 | 
			
		||||
	# maximum nick name length!
 | 
			
		||||
	;MaxNickLength = 9
 | 
			
		||||
 | 
			
		||||
[Operator]
 | 
			
		||||
	# [Operator] sections are used to define IRC Operators. There may be
 | 
			
		||||
	# more than one [Operator] block, one for each local operator.
 | 
			
		||||
@@ -142,6 +157,10 @@
 | 
			
		||||
	# this server should establish the connection).
 | 
			
		||||
	;Host = connect-to-host.the.net
 | 
			
		||||
 | 
			
		||||
	# IP address to use as _source_ address for the connection. if unspecified,
 | 
			
		||||
	# ngircd will let the operating system pick an address.
 | 
			
		||||
	;Bind = 10.0.0.1
 | 
			
		||||
 | 
			
		||||
	# Port of the server to which the ngIRCd should connect. If you
 | 
			
		||||
	# assign no port the ngIRCd waits for incoming connections.
 | 
			
		||||
	;Port = 6667
 | 
			
		||||
@@ -157,6 +176,13 @@
 | 
			
		||||
	# Group of this server (optional)
 | 
			
		||||
	;Group = 123
 | 
			
		||||
 | 
			
		||||
	# Set the "Passive" option to "yes" if you don't want this ngIRCd to
 | 
			
		||||
	# connect to the configured peer (same as leaving the "Port" variable
 | 
			
		||||
	# empty). The advantage of this option is that you can actually configure
 | 
			
		||||
	# a port an use the IRC command CONNECT more easily to manually connect
 | 
			
		||||
	# this specific server later.
 | 
			
		||||
	;Passive = no
 | 
			
		||||
 | 
			
		||||
[Server]
 | 
			
		||||
	# More [Server] sections, if you like ...
 | 
			
		||||
 | 
			
		||||
@@ -175,7 +201,13 @@
 | 
			
		||||
	;Topic = a great topic
 | 
			
		||||
 | 
			
		||||
	# Initial channel modes
 | 
			
		||||
	;Modes = tn
 | 
			
		||||
	;Modes = tnk
 | 
			
		||||
 | 
			
		||||
	# initial channel password (mode k)
 | 
			
		||||
	;Key = Secret
 | 
			
		||||
 | 
			
		||||
	# maximum users per channel (mode l)
 | 
			
		||||
	;MaxUsers = 23
 | 
			
		||||
 | 
			
		||||
[Channel]
 | 
			
		||||
	# More [Channel] sections, if you like ...
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								doc/src/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								doc/src/.cvsignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
html
 | 
			
		||||
@@ -8,14 +8,14 @@
 | 
			
		||||
# (at your option) any later version.
 | 
			
		||||
# Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile.am,v 1.2 2006/04/08 16:35:03 alex Exp $
 | 
			
		||||
# $Id: Makefile.am,v 1.3 2006/12/28 14:04:28 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in
 | 
			
		||||
 | 
			
		||||
distclean-local:
 | 
			
		||||
	rm -f html
 | 
			
		||||
	rm -rf html
 | 
			
		||||
 | 
			
		||||
srcdoc:
 | 
			
		||||
	@doxygen --version >/dev/null 2>&1 \
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								man/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								man/.cvsignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
ngircd.8
 | 
			
		||||
ngircd.conf.5
 | 
			
		||||
@@ -9,12 +9,25 @@
 | 
			
		||||
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
 | 
			
		||||
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile.am,v 1.5 2002/04/04 13:02:41 alex Exp $
 | 
			
		||||
# $Id: Makefile.am,v 1.6 2006/12/25 16:13:26 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
TEMPLATE_MANS = ngircd.conf.5.tmpl ngircd.8.tmpl
 | 
			
		||||
 | 
			
		||||
SUFFIXES = .tmpl .
 | 
			
		||||
 | 
			
		||||
.tmpl:
 | 
			
		||||
	sed \
 | 
			
		||||
	    -e s@:SBINDIR:@${sbindir}@ \
 | 
			
		||||
	    -e s@:BINDIR:@${bindir}@ \
 | 
			
		||||
	    -e s@:ETCDIR:@${sysconfdir}@ \
 | 
			
		||||
	    <$< >$@
 | 
			
		||||
 | 
			
		||||
man_MANS = ngircd.conf.5 ngircd.8
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = $(man_MANS)
 | 
			
		||||
CLEANFILES = $(man_MANS)
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = $(TEMPLATE_MANS)
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
.\"
 | 
			
		||||
.\" $Id: ngircd.8,v 1.11 2005/08/12 13:20:54 alex Exp $
 | 
			
		||||
.\" $Id: ngircd.8.tmpl,v 1.2 2007/11/15 01:03:29 fw Exp $
 | 
			
		||||
.\"
 | 
			
		||||
.TH ngircd 8 "August 2005" ngircd "ngIRCd Manual"
 | 
			
		||||
.SH NAME
 | 
			
		||||
@@ -23,7 +23,8 @@ Linux, Mac OS X, NetBSD, OpenBSD, Solaris, and Windows with Cygwin.
 | 
			
		||||
.PP
 | 
			
		||||
As ngIRCd relies on UNIX standards and uses GNU automake and GNU autoconf
 | 
			
		||||
there are good chances that it also supports other UNIX-based operating
 | 
			
		||||
systems as well.
 | 
			
		||||
systems as well. By default, ngIRCd writes diagnostic and informational messages using
 | 
			
		||||
the syslog mechanism.
 | 
			
		||||
.SH OPTIONS
 | 
			
		||||
The default behaviour of
 | 
			
		||||
.BR ngircd
 | 
			
		||||
@@ -55,11 +56,11 @@ Output version information and exit.
 | 
			
		||||
\fB\-\-help\fR
 | 
			
		||||
Display a brief help text and exit.
 | 
			
		||||
.SH FILES
 | 
			
		||||
.I /usr/local/etc/ngircd.conf
 | 
			
		||||
.I :ETCDIR:/ngircd.conf
 | 
			
		||||
.RS
 | 
			
		||||
The system wide default configuration file.
 | 
			
		||||
.RE
 | 
			
		||||
.I /usr/local/etc/ngircd.motd
 | 
			
		||||
.I :ETCDIR:/ngircd.motd
 | 
			
		||||
.RS
 | 
			
		||||
Default "message of the day" (MOTD).
 | 
			
		||||
.RE
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
.\"
 | 
			
		||||
.\" $Id: ngircd.conf.5,v 1.20 2005/09/02 14:39:00 fw Exp $
 | 
			
		||||
.\" $Id: ngircd.conf.5.tmpl,v 1.7 2007/11/23 16:26:03 fw Exp $
 | 
			
		||||
.\"
 | 
			
		||||
.TH ngircd.conf 5 "August 2005" ngircd "ngIRCd Manual"
 | 
			
		||||
.SH NAME
 | 
			
		||||
ngircd.conf \- configuration file of ngIRCd
 | 
			
		||||
.SH SYNOPSIS
 | 
			
		||||
.B /usr/local/etc/ngircd.conf
 | 
			
		||||
.B :ETCDIR:/ngircd.conf
 | 
			
		||||
.SH DESCRIPTION
 | 
			
		||||
.BR ngircd.conf
 | 
			
		||||
is the configuration file of the
 | 
			
		||||
@@ -146,18 +146,35 @@ If OperCanUseMode is enabled, this may lead the compatibility problems with
 | 
			
		||||
Servers that run the ircd-irc2 Software. This Option "masks" mode requests
 | 
			
		||||
by non-chanops as if they were coming from the server. Default: no.
 | 
			
		||||
.TP
 | 
			
		||||
\fBPredefChannelsOnly\fR
 | 
			
		||||
If enabled, no new channels can be created. Useful if
 | 
			
		||||
you do not want to have channels other than those defined in
 | 
			
		||||
the config file.
 | 
			
		||||
Default: No.
 | 
			
		||||
.TP
 | 
			
		||||
\fBNoDNS\fR
 | 
			
		||||
If enabled, ngircd will not make DNS lookups when clients connect.
 | 
			
		||||
If you configure ngircd to connect to other servers, ngircd may still
 | 
			
		||||
perform a DNS lookup if required.
 | 
			
		||||
Default: No.
 | 
			
		||||
.TP
 | 
			
		||||
\fBMaxConnections\fR
 | 
			
		||||
Maximum number of simultaneous connection the server is allowed to accept
 | 
			
		||||
(<=0: unlimited). Default: -1.
 | 
			
		||||
(0: unlimited). Default: 0.
 | 
			
		||||
.TP
 | 
			
		||||
\fBMaxConnectionsIP\fR
 | 
			
		||||
Maximum number of simultaneous connections from a single IP address that
 | 
			
		||||
the server will accept (<=0: unlimited). This configuration options lowers
 | 
			
		||||
the server will accept (0: unlimited). This configuration options lowers
 | 
			
		||||
the risk of denial of service attacks (DoS). Default: 5.
 | 
			
		||||
.TP
 | 
			
		||||
\fBMaxJoins\fR
 | 
			
		||||
Maximum number of channels a user can be member of (<=0: no limit).
 | 
			
		||||
Maximum number of channels a user can be member of (0: no limit).
 | 
			
		||||
Default: 10.
 | 
			
		||||
.TP
 | 
			
		||||
\fBMaxNickLength\fR
 | 
			
		||||
Maximum length of an user nick name (Default: 9, as in RFC 2812). Please
 | 
			
		||||
note that all servers in an IRC network MUST use the same maximum nick name
 | 
			
		||||
length!
 | 
			
		||||
.SH [OPERATOR]
 | 
			
		||||
.I [Operator]
 | 
			
		||||
sections are used to define IRC Operators. There may be more than one
 | 
			
		||||
@@ -195,6 +212,10 @@ IRC name of the server
 | 
			
		||||
\fBHost\fR
 | 
			
		||||
Internet host name of the peer
 | 
			
		||||
.TP
 | 
			
		||||
\fBBind\fR
 | 
			
		||||
IP address to use as source IP for the outgoing connection. Default ist
 | 
			
		||||
to let the operating system decide.
 | 
			
		||||
.TP
 | 
			
		||||
\fBPort\fR
 | 
			
		||||
Port of the server to which the ngIRCd should connect. If you assign no port
 | 
			
		||||
the ngIRCd waits for incoming connections.
 | 
			
		||||
@@ -209,6 +230,9 @@ Foreign password for this connection. This password has to be configured as
 | 
			
		||||
.TP
 | 
			
		||||
\fBGroup\fR
 | 
			
		||||
Group of this server (optional).
 | 
			
		||||
\fBPassive\fR
 | 
			
		||||
Disable automatic connection even if port value is specified. Default: false.
 | 
			
		||||
You can use the IRC Operator command CONNECT later on to create the link.
 | 
			
		||||
.SH [CHANNEL]
 | 
			
		||||
Pre-defined channels can be configured in
 | 
			
		||||
.I [Channel]
 | 
			
		||||
@@ -230,6 +254,12 @@ Topic for this channel
 | 
			
		||||
.TP
 | 
			
		||||
\fBModes\fR
 | 
			
		||||
Initial channel modes.
 | 
			
		||||
.TP
 | 
			
		||||
\fBKey\fR
 | 
			
		||||
Sets initial channel key (only relevant if mode k is set)
 | 
			
		||||
.TP
 | 
			
		||||
\fBMaxUsers\fR
 | 
			
		||||
Set maximum user limit for this channel (only relevant if mode l is set)
 | 
			
		||||
.SH HINTS
 | 
			
		||||
It's wise to use "ngircd --configtest" to validate the configuration file
 | 
			
		||||
after changing it. See
 | 
			
		||||
							
								
								
									
										5
									
								
								src/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/.cvsignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
config.h
 | 
			
		||||
config.h.in
 | 
			
		||||
stamp-h1
 | 
			
		||||
							
								
								
									
										8
									
								
								src/ngircd/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/ngircd/.cvsignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
.deps
 | 
			
		||||
check-help
 | 
			
		||||
check-version
 | 
			
		||||
cvs-version.h
 | 
			
		||||
cvs-version.new
 | 
			
		||||
ngircd
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
# (at your option) any later version.
 | 
			
		||||
# Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile.am,v 1.49 2006/03/11 01:48:50 alex Exp $
 | 
			
		||||
# $Id: Makefile.am,v 1.50 2007/11/21 12:16:36 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
AUTOMAKE_OPTIONS = ../portab/ansi2knr
 | 
			
		||||
@@ -23,7 +23,7 @@ sbin_PROGRAMS = ngircd
 | 
			
		||||
ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.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 parse.c rendezvous.c resolve.c
 | 
			
		||||
	match.c numeric.c parse.c rendezvous.c resolve.c
 | 
			
		||||
 | 
			
		||||
ngircd_LDFLAGS = -L../portab -L../tool
 | 
			
		||||
 | 
			
		||||
@@ -32,7 +32,7 @@ ngircd_LDADD = -lngportab -lngtool
 | 
			
		||||
noinst_HEADERS = ngircd.h array.h channel.h client.h conf.h conn.h conn-func.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 parse.h rendezvous.h resolve.h \
 | 
			
		||||
	match.h numeric.h parse.h rendezvous.h resolve.h \
 | 
			
		||||
	defines.h messages.h
 | 
			
		||||
 | 
			
		||||
clean-local:
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 | 
			
		||||
#include "array.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: array.c,v 1.11 2006/07/01 22:11:48 fw Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: array.c,v 1.15 2007/11/18 15:05:35 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
@@ -28,9 +28,9 @@ static char UNUSED id[] = "$Id: array.c,v 1.11 2006/07/01 22:11:48 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#define array_UNUSABLE(x)	( !(x)->mem || (0 == (x)->allocated) )
 | 
			
		||||
 | 
			
		||||
#define ALIGN_32U(x)            (((x)+31U  ) & ~(31U))
 | 
			
		||||
#define ALIGN_1024U(x)          (((x)+1023U) & ~(1023U))
 | 
			
		||||
#define ALIGN_4096U(x)          (((x)+4095U) & ~(4095U))
 | 
			
		||||
#define ALIGN_32U(x)            (((x)+(unsigned)31  ) & ~((unsigned)31))
 | 
			
		||||
#define ALIGN_1024U(x)          (((x)+(unsigned)1023) & ~((unsigned)1023))
 | 
			
		||||
#define ALIGN_4096U(x)          (((x)+(unsigned)4095) & ~((unsigned)4095))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
@@ -66,10 +66,7 @@ array_alloc(array * a, size_t size, size_t pos)
 | 
			
		||||
 | 
			
		||||
	assert(size > 0);
 | 
			
		||||
 | 
			
		||||
	if (pos_plus1 < pos)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	if (!safemult_sizet(size, pos_plus1, &alloc))
 | 
			
		||||
	if (pos_plus1 == 0 || !safemult_sizet(size, pos_plus1, &alloc))
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	if (a->allocated < alloc) {
 | 
			
		||||
@@ -250,20 +247,22 @@ void *
 | 
			
		||||
array_get(array * a, size_t membersize, size_t pos)
 | 
			
		||||
{
 | 
			
		||||
	size_t totalsize;
 | 
			
		||||
	size_t posplus1 = pos + 1;
 | 
			
		||||
 | 
			
		||||
	assert(membersize > 0);
 | 
			
		||||
	assert(a != NULL);
 | 
			
		||||
 | 
			
		||||
	if (array_UNUSABLE(a))
 | 
			
		||||
	if (!posplus1 || array_UNUSABLE(a))
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	if (!safemult_sizet(pos, membersize, &totalsize))
 | 
			
		||||
	if (!safemult_sizet(posplus1, membersize, &totalsize))
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	if (a->allocated < totalsize)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	return a->mem + pos * membersize;
 | 
			
		||||
	totalsize = pos * membersize;
 | 
			
		||||
	return a->mem + totalsize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -271,7 +270,7 @@ void
 | 
			
		||||
array_free(array * a)
 | 
			
		||||
{
 | 
			
		||||
	assert(a != NULL);
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
#ifdef DEBUG_ARRAY
 | 
			
		||||
	Log(LOG_DEBUG,
 | 
			
		||||
	    "array_free(): %u bytes free'd (%u bytes still used at time of free()).",
 | 
			
		||||
	    a->allocated, a->used);
 | 
			
		||||
@@ -283,16 +282,6 @@ array_free(array * a)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
array_free_wipe(array * a)
 | 
			
		||||
{
 | 
			
		||||
	if (!array_UNUSABLE(a))
 | 
			
		||||
		memset(a->mem, 0, a->allocated);
 | 
			
		||||
 | 
			
		||||
	array_free(a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void *
 | 
			
		||||
array_start(const array * const a)
 | 
			
		||||
{
 | 
			
		||||
@@ -331,9 +320,6 @@ array_moveleft(array * a, size_t membersize, size_t pos)
 | 
			
		||||
	assert(a != NULL);
 | 
			
		||||
	assert(membersize > 0);
 | 
			
		||||
 | 
			
		||||
	if (!pos)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (!safemult_sizet(membersize, pos, &bytepos)) {
 | 
			
		||||
		a->used = 0;
 | 
			
		||||
		return;
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: channel.c,v 1.56 2006/07/24 22:54:09 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: channel.c,v 1.63 2007/06/11 20:06:46 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -70,6 +70,22 @@ Channel_Init( void )
 | 
			
		||||
} /* Channel_Init */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL struct list_head *
 | 
			
		||||
Channel_GetListBans(CHANNEL *c)
 | 
			
		||||
{
 | 
			
		||||
	assert(c != NULL);
 | 
			
		||||
	return &c->list_bans;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL struct list_head *
 | 
			
		||||
Channel_GetListInvites(CHANNEL *c)
 | 
			
		||||
{
 | 
			
		||||
	assert(c != NULL);
 | 
			
		||||
	return &c->list_invites;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Channel_InitPredefined( void )
 | 
			
		||||
{
 | 
			
		||||
@@ -114,7 +130,10 @@ Channel_InitPredefined( void )
 | 
			
		||||
			c = Conf_Channel[i].modes;
 | 
			
		||||
			while (*c)
 | 
			
		||||
				Channel_ModeAdd(chan, *c++);
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
			Channel_SetKey(chan, Conf_Channel[i].key);
 | 
			
		||||
			Channel_SetMaxUsers(chan, Conf_Channel[i].maxusers);
 | 
			
		||||
 | 
			
		||||
			Log(LOG_INFO, "Created pre-defined channel \"%s\".",
 | 
			
		||||
							Conf_Channel[i].name );
 | 
			
		||||
		}
 | 
			
		||||
@@ -129,7 +148,7 @@ Channel_Exit( void )
 | 
			
		||||
{
 | 
			
		||||
	CHANNEL *c, *c_next;
 | 
			
		||||
	CL2CHAN *cl2chan, *cl2chan_next;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/* Channel-Strukturen freigeben */
 | 
			
		||||
	c = My_Channels;
 | 
			
		||||
	while( c )
 | 
			
		||||
@@ -173,7 +192,7 @@ Channel_Join( CLIENT *Client, char *Name )
 | 
			
		||||
	{
 | 
			
		||||
		/* Gibt es noch nicht? Dann neu anlegen: */
 | 
			
		||||
		chan = Channel_Create( Name );
 | 
			
		||||
		if( ! chan ) return false;
 | 
			
		||||
		if (!chan) return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* User dem Channel hinzufuegen */
 | 
			
		||||
@@ -214,7 +233,6 @@ Channel_Kick( CLIENT *Client, CLIENT *Origin, char *Name, char *Reason )
 | 
			
		||||
	assert( Name != NULL );
 | 
			
		||||
	assert( Reason != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Channel suchen */
 | 
			
		||||
	chan = Channel_Search( Name );
 | 
			
		||||
	if( ! chan )
 | 
			
		||||
	{
 | 
			
		||||
@@ -266,11 +284,11 @@ Channel_Quit( CLIENT *Client, char *Reason )
 | 
			
		||||
} /* Channel_Quit */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL long
 | 
			
		||||
GLOBAL unsigned long
 | 
			
		||||
Channel_Count( void )
 | 
			
		||||
{
 | 
			
		||||
	CHANNEL *c;
 | 
			
		||||
	long count = 0;
 | 
			
		||||
	unsigned long count = 0;
 | 
			
		||||
	
 | 
			
		||||
	c = My_Channels;
 | 
			
		||||
	while( c )
 | 
			
		||||
@@ -282,11 +300,11 @@ Channel_Count( void )
 | 
			
		||||
} /* Channel_Count */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL long
 | 
			
		||||
GLOBAL unsigned long
 | 
			
		||||
Channel_MemberCount( CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	long count = 0;
 | 
			
		||||
	unsigned long count = 0;
 | 
			
		||||
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
@@ -321,27 +339,9 @@ Channel_CountForUser( CLIENT *Client )
 | 
			
		||||
} /* Channel_CountForUser */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL int
 | 
			
		||||
Channel_PCount( void )
 | 
			
		||||
{
 | 
			
		||||
	/* Count the number of persistent (mode 'P') channels */
 | 
			
		||||
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	int count = 0;
 | 
			
		||||
 | 
			
		||||
	chan = My_Channels;
 | 
			
		||||
	while( chan )
 | 
			
		||||
	{
 | 
			
		||||
		if( strchr( chan->modes, 'P' )) count++;
 | 
			
		||||
		chan = chan->next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return count;
 | 
			
		||||
} /* Channel_PCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL char *
 | 
			
		||||
Channel_Name( CHANNEL *Chan )
 | 
			
		||||
GLOBAL const char *
 | 
			
		||||
Channel_Name( const CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	return Chan->name;
 | 
			
		||||
@@ -364,7 +364,7 @@ Channel_Key( CHANNEL *Chan )
 | 
			
		||||
} /* Channel_Key */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL long
 | 
			
		||||
GLOBAL unsigned long
 | 
			
		||||
Channel_MaxUsers( CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
@@ -463,25 +463,13 @@ Channel_GetChannel( CL2CHAN *Cl2Chan )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Channel_IsValidName( char *Name )
 | 
			
		||||
Channel_IsValidName( const char *Name )
 | 
			
		||||
{
 | 
			
		||||
	/* Pruefen, ob Name als Channelname gueltig */
 | 
			
		||||
 | 
			
		||||
	char *ptr, badchars[10];
 | 
			
		||||
	
 | 
			
		||||
	assert( Name != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Name[0] != '#' ) || ( strlen( Name ) >= CHANNEL_NAME_LEN )) return false;
 | 
			
		||||
 | 
			
		||||
	ptr = Name;
 | 
			
		||||
	strcpy( badchars, " ,:\007" );
 | 
			
		||||
	while( *ptr )
 | 
			
		||||
	{
 | 
			
		||||
		if( strchr( badchars, *ptr )) return false;
 | 
			
		||||
		ptr++;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return true;
 | 
			
		||||
	return Name[strcspn(Name, " ,:\007")] == 0;
 | 
			
		||||
} /* Channel_IsValidName */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -548,7 +536,7 @@ Channel_UserModeAdd( CHANNEL *Chan, CLIENT *Client, char Mode )
 | 
			
		||||
 | 
			
		||||
	cl2chan = Get_Cl2Chan( Chan, Client );
 | 
			
		||||
	assert( cl2chan != NULL );
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	x[0] = Mode; x[1] = '\0';
 | 
			
		||||
	if( ! strchr( cl2chan->modes, x[0] ))
 | 
			
		||||
	{
 | 
			
		||||
@@ -594,7 +582,7 @@ GLOBAL char *
 | 
			
		||||
Channel_UserModes( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	/* return Users' Channel-Modes */
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
@@ -614,9 +602,7 @@ Channel_IsMemberOf( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Get_Cl2Chan( Chan, Client )) return true;
 | 
			
		||||
	else return false;
 | 
			
		||||
	return Get_Cl2Chan(Chan, Client) != NULL;
 | 
			
		||||
} /* Channel_IsMemberOf */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -661,12 +647,9 @@ Channel_SetTopic(CHANNEL *Chan, CLIENT *Client, char *Topic)
 | 
			
		||||
	if (len < array_bytes(&Chan->topic))
 | 
			
		||||
		array_free(&Chan->topic);
 | 
			
		||||
 | 
			
		||||
	if (!array_copyb(&Chan->topic, Topic, len))
 | 
			
		||||
	if (len >= COMMAND_LEN || !array_copyb(&Chan->topic, Topic, len+1))
 | 
			
		||||
		Log(LOG_WARNING, "could not set new Topic \"%s\" on %s: %s",
 | 
			
		||||
					Topic, Chan->name, strerror(errno));
 | 
			
		||||
 | 
			
		||||
	array_cat0(&Chan->topic);
 | 
			
		||||
 | 
			
		||||
#ifndef STRICT_RFC
 | 
			
		||||
	Chan->topic_time = time(NULL);
 | 
			
		||||
	if (Client != NULL && Client_Type(Client) != CLIENT_SERVER)
 | 
			
		||||
@@ -698,17 +681,17 @@ Channel_SetKey( CHANNEL *Chan, char *Key )
 | 
			
		||||
	assert( Key != NULL );
 | 
			
		||||
 | 
			
		||||
	strlcpy( Chan->key, Key, sizeof( Chan->key ));
 | 
			
		||||
	Log( LOG_DEBUG, "Channel %s: Key is now \"%s\".", Chan->name, Chan->key );
 | 
			
		||||
	LogDebug("Channel %s: Key is now \"%s\".", Chan->name, Chan->key );
 | 
			
		||||
} /* Channel_SetKey */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Channel_SetMaxUsers( CHANNEL *Chan, long Count )
 | 
			
		||||
Channel_SetMaxUsers(CHANNEL *Chan, unsigned long Count)
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	Chan->maxusers = Count;
 | 
			
		||||
	Log( LOG_DEBUG, "Channel %s: Member limit is now %ld.", Chan->name, Chan->maxusers );
 | 
			
		||||
	LogDebug("Channel %s: Member limit is now %lu.", Chan->name, Chan->maxusers );
 | 
			
		||||
} /* Channel_SetMaxUsers */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -730,9 +713,9 @@ Channel_Write( CHANNEL *Chan, CLIENT *From, CLIENT *Client, char *Text )
 | 
			
		||||
	ok = true;
 | 
			
		||||
	if( strchr( Channel_Modes( Chan ), 'n' ) && ( ! is_member )) ok = false;
 | 
			
		||||
	if( strchr( Channel_Modes( Chan ), 'm' ) && ( ! is_op ) && ( ! has_voice )) ok = false;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/* Is the client banned? */
 | 
			
		||||
	if( Lists_CheckBanned( From, Chan ))
 | 
			
		||||
	if( Lists_Check(&Chan->list_bans, From))
 | 
			
		||||
	{
 | 
			
		||||
		/* Client is banned, but is he channel operator or has voice? */
 | 
			
		||||
		if(( ! has_voice ) && ( ! is_op )) ok = false;
 | 
			
		||||
@@ -753,7 +736,7 @@ Channel_Create( char *Name )
 | 
			
		||||
	CHANNEL *c;
 | 
			
		||||
 | 
			
		||||
	assert( Name != NULL );
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	c = (CHANNEL *)malloc( sizeof( CHANNEL ));
 | 
			
		||||
	if( ! c )
 | 
			
		||||
	{
 | 
			
		||||
@@ -765,9 +748,7 @@ Channel_Create( char *Name )
 | 
			
		||||
	c->hash = Hash( c->name );
 | 
			
		||||
	c->next = My_Channels;
 | 
			
		||||
	My_Channels = c;
 | 
			
		||||
#ifdef DEBUG	
 | 
			
		||||
	Log( LOG_DEBUG, "Created new channel structure for \"%s\".", Name );
 | 
			
		||||
#endif
 | 
			
		||||
	LogDebug("Created new channel structure for \"%s\".", Name);
 | 
			
		||||
	return c;
 | 
			
		||||
} /* Channel_Create */
 | 
			
		||||
 | 
			
		||||
@@ -851,25 +832,42 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, char *Re
 | 
			
		||||
	switch( Type )
 | 
			
		||||
	{
 | 
			
		||||
		case REMOVE_QUIT:
 | 
			
		||||
			/* QUIT: andere Server wurden bereits informiert, vgl. Client_Destroy();
 | 
			
		||||
			 * hier also "nur" noch alle User in betroffenen Channeln infomieren */
 | 
			
		||||
			/* QUIT: other servers have already been notified, see Client_Destroy();
 | 
			
		||||
			 * so only inform other clients in same channel. */
 | 
			
		||||
			assert( InformServer == false );
 | 
			
		||||
			Log( LOG_DEBUG, "User \"%s\" left channel \"%s\" (%s).", Client_Mask( Client ), c->name, Reason );
 | 
			
		||||
			LogDebug("User \"%s\" left channel \"%s\" (%s).",
 | 
			
		||||
					Client_Mask( Client ), c->name, Reason );
 | 
			
		||||
			break;
 | 
			
		||||
		case REMOVE_KICK:
 | 
			
		||||
			/* User wurde geKICKed: ggf. andere Server sowie alle betroffenen User
 | 
			
		||||
			 * im entsprechenden Channel informieren */
 | 
			
		||||
			if( InformServer ) IRC_WriteStrServersPrefix( Client_NextHop( Origin ), Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason );
 | 
			
		||||
			IRC_WriteStrChannelPrefix( Client, c, Origin, false, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason );
 | 
			
		||||
			if(( Client_Conn( Client ) > NONE ) && ( Client_Type( Client ) == CLIENT_USER )) IRC_WriteStrClientPrefix( Client, Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason );
 | 
			
		||||
			Log( LOG_DEBUG, "User \"%s\" has been kicked of \"%s\" by \"%s\": %s.", Client_Mask( Client ), c->name, Client_ID( Origin ), Reason );
 | 
			
		||||
			/* User was KICKed: inform other servers and all users in channel */
 | 
			
		||||
			if( InformServer )
 | 
			
		||||
				IRC_WriteStrServersPrefix( Client_NextHop( Origin ),
 | 
			
		||||
					Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason);
 | 
			
		||||
			IRC_WriteStrChannelPrefix(Client, c, Origin, false, "KICK %s %s :%s",
 | 
			
		||||
							c->name, Client_ID( Client ), Reason );
 | 
			
		||||
			if ((Client_Conn(Client) > NONE) &&
 | 
			
		||||
					(Client_Type(Client) == CLIENT_USER))
 | 
			
		||||
			{
 | 
			
		||||
				IRC_WriteStrClientPrefix(Client, Origin, "KICK %s %s :%s",
 | 
			
		||||
								c->name, Client_ID( Client ), Reason);
 | 
			
		||||
			}
 | 
			
		||||
			LogDebug("User \"%s\" has been kicked of \"%s\" by \"%s\": %s.",
 | 
			
		||||
				Client_Mask( Client ), c->name, Client_ID(Origin), Reason);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			/* PART */
 | 
			
		||||
			if( InformServer ) IRC_WriteStrServersPrefix( Origin, Client, "PART %s :%s", c->name, Reason );
 | 
			
		||||
			IRC_WriteStrChannelPrefix( Origin, c, Client, false, "PART %s :%s", c->name, Reason );
 | 
			
		||||
			if(( Client_Conn( Origin ) > NONE ) && ( Client_Type( Origin ) == CLIENT_USER )) IRC_WriteStrClientPrefix( Origin, Client, "PART %s :%s", c->name, Reason );
 | 
			
		||||
			Log( LOG_DEBUG, "User \"%s\" left channel \"%s\" (%s).", Client_Mask( Client ), c->name, Reason );
 | 
			
		||||
		default: /* PART */
 | 
			
		||||
			if (InformServer)
 | 
			
		||||
				IRC_WriteStrServersPrefix(Origin, Client, "PART %s :%s", c->name, Reason);
 | 
			
		||||
 | 
			
		||||
			IRC_WriteStrChannelPrefix(Origin, c, Client, false, "PART %s :%s",
 | 
			
		||||
									c->name, Reason);
 | 
			
		||||
 | 
			
		||||
			if ((Client_Conn(Origin) > NONE) &&
 | 
			
		||||
					(Client_Type(Origin) == CLIENT_USER))
 | 
			
		||||
			{
 | 
			
		||||
				IRC_WriteStrClientPrefix( Origin, Client, "PART %s :%s", c->name, Reason);
 | 
			
		||||
				LogDebug("User \"%s\" left channel \"%s\" (%s).",
 | 
			
		||||
					Client_Mask(Client), c->name, Reason);
 | 
			
		||||
			}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Wenn Channel nun leer und nicht pre-defined: loeschen */
 | 
			
		||||
@@ -882,6 +880,68 @@ Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, char *Re
 | 
			
		||||
} /* Remove_Client */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Channel_AddBan(CHANNEL *c, const char *mask )
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *h = Channel_GetListBans(c);
 | 
			
		||||
	return Lists_Add(h, mask, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Channel_AddInvite(CHANNEL *c, const char *mask, bool onlyonce)
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *h = Channel_GetListInvites(c);
 | 
			
		||||
	return Lists_Add(h, mask, onlyonce);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
ShowInvitesBans(struct list_head *head, CLIENT *Client, CHANNEL *Channel, bool invite)
 | 
			
		||||
{
 | 
			
		||||
	struct list_elem *e;
 | 
			
		||||
	char *msg = invite ? RPL_INVITELIST_MSG : RPL_BANLIST_MSG;
 | 
			
		||||
	char *msg_end;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Channel != NULL );
 | 
			
		||||
 | 
			
		||||
	e = Lists_GetFirst(head);
 | 
			
		||||
	while (e) {
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, msg, Client_ID( Client ),
 | 
			
		||||
				Channel_Name( Channel ), Lists_GetMask(e) )) return DISCONNECTED;
 | 
			
		||||
		e = Lists_GetNext(e);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	msg_end = invite ? RPL_ENDOFINVITELIST_MSG : RPL_ENDOFBANLIST_MSG;
 | 
			
		||||
	return IRC_WriteStrClient( Client, msg_end, Client_ID( Client ), Channel_Name( Channel ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Channel_ShowBans( CLIENT *Client, CHANNEL *Channel )
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *h;
 | 
			
		||||
 | 
			
		||||
	assert( Channel != NULL );
 | 
			
		||||
 | 
			
		||||
	h = Channel_GetListBans(Channel);
 | 
			
		||||
	return ShowInvitesBans(h, Client, Channel, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Channel_ShowInvites( CLIENT *Client, CHANNEL *Channel )
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *h;
 | 
			
		||||
 | 
			
		||||
	assert( Channel != NULL );
 | 
			
		||||
 | 
			
		||||
	h = Channel_GetListInvites(Channel);
 | 
			
		||||
	return ShowInvitesBans(h, Client, Channel, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static CL2CHAN *
 | 
			
		||||
Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
@@ -911,7 +971,7 @@ static bool
 | 
			
		||||
Delete_Channel( CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	/* Channel-Struktur loeschen */
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	CHANNEL *chan, *last_chan;
 | 
			
		||||
 | 
			
		||||
	last_chan = NULL;
 | 
			
		||||
@@ -927,13 +987,14 @@ Delete_Channel( CHANNEL *Chan )
 | 
			
		||||
	Log( LOG_DEBUG, "Freed channel structure for \"%s\".", Chan->name );
 | 
			
		||||
 | 
			
		||||
	/* Invite- und Ban-Lists aufraeumen */
 | 
			
		||||
	Lists_DeleteChannel( chan );
 | 
			
		||||
	Lists_Free( &chan->list_bans );
 | 
			
		||||
	Lists_Free( &chan->list_invites );
 | 
			
		||||
 | 
			
		||||
	/* Neu verketten und freigeben */
 | 
			
		||||
	if( last_chan ) last_chan->next = chan->next;
 | 
			
		||||
	else My_Channels = chan->next;
 | 
			
		||||
	free( chan );
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
} /* Delete_Channel */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: channel.h,v 1.29 2005/09/02 12:50:25 alex Exp $
 | 
			
		||||
 * $Id: channel.h,v 1.33 2006/12/07 22:23:39 fw Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Channel management (header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -20,6 +20,7 @@
 | 
			
		||||
 | 
			
		||||
#if defined(__channel_c__) | defined(S_SPLINT_S)
 | 
			
		||||
 | 
			
		||||
#include "lists.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "array.h"
 | 
			
		||||
 | 
			
		||||
@@ -35,7 +36,9 @@ typedef struct _CHANNEL
 | 
			
		||||
	char topic_who[CLIENT_NICK_LEN];/* Nickname of user that set topic */
 | 
			
		||||
#endif
 | 
			
		||||
	char key[CLIENT_PASS_LEN];	/* Channel key ("password", mode "k" ) */
 | 
			
		||||
	long maxusers;			/* Maximum number of members (mode "l") */
 | 
			
		||||
	unsigned long maxusers;		/* Maximum number of members (mode "l") */
 | 
			
		||||
	struct list_head list_bans;	/* list head of banned users */
 | 
			
		||||
	struct list_head list_invites;	/* list head of invited users */
 | 
			
		||||
} CHANNEL;
 | 
			
		||||
 | 
			
		||||
typedef struct _CLIENT2CHAN
 | 
			
		||||
@@ -53,6 +56,8 @@ typedef POINTER CL2CHAN;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
GLOBAL struct list_head *Channel_GetListBans PARAMS((CHANNEL *c));
 | 
			
		||||
GLOBAL struct list_head *Channel_GetListInvites PARAMS((CHANNEL *c));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Channel_Init PARAMS(( void ));
 | 
			
		||||
GLOBAL void Channel_InitPredefined PARAMS((  void ));
 | 
			
		||||
@@ -65,21 +70,20 @@ GLOBAL void Channel_Quit PARAMS(( CLIENT *Client, char *Reason ));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Channel_Kick PARAMS((  CLIENT *Client, CLIENT *Origin, char *Name, char *Reason ));
 | 
			
		||||
 | 
			
		||||
GLOBAL long Channel_Count PARAMS(( void ));
 | 
			
		||||
GLOBAL long Channel_MemberCount PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL unsigned long Channel_Count PARAMS(( void ));
 | 
			
		||||
GLOBAL unsigned long Channel_MemberCount PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL int Channel_CountForUser PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL int Channel_PCount PARAMS(( void ));
 | 
			
		||||
 | 
			
		||||
GLOBAL char *Channel_Name PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL const char *Channel_Name PARAMS(( const CHANNEL *Chan ));
 | 
			
		||||
GLOBAL char *Channel_Modes PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL char *Channel_Topic PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL char *Channel_Key PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL long Channel_MaxUsers PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL unsigned long Channel_MaxUsers PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Channel_SetTopic PARAMS(( CHANNEL *Chan, CLIENT *Client, char *Topic ));
 | 
			
		||||
GLOBAL void Channel_SetModes PARAMS(( CHANNEL *Chan, char *Modes ));
 | 
			
		||||
GLOBAL void Channel_SetKey PARAMS(( CHANNEL *Chan, char *Key ));
 | 
			
		||||
GLOBAL void Channel_SetMaxUsers PARAMS(( CHANNEL *Chan, long Count ));
 | 
			
		||||
GLOBAL void Channel_SetMaxUsers PARAMS(( CHANNEL *Chan, unsigned long Count ));
 | 
			
		||||
 | 
			
		||||
GLOBAL CHANNEL *Channel_Search PARAMS(( char *Name ));
 | 
			
		||||
 | 
			
		||||
@@ -94,7 +98,7 @@ GLOBAL CL2CHAN *Channel_NextChannelOf PARAMS(( CLIENT *Client, CL2CHAN *Cl2Chan
 | 
			
		||||
GLOBAL CLIENT *Channel_GetClient PARAMS(( CL2CHAN *Cl2Chan ));
 | 
			
		||||
GLOBAL CHANNEL *Channel_GetChannel PARAMS(( CL2CHAN *Cl2Chan ));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Channel_IsValidName PARAMS(( char *Name ));
 | 
			
		||||
GLOBAL bool Channel_IsValidName PARAMS(( const char *Name ));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Channel_ModeAdd PARAMS(( CHANNEL *Chan, char Mode ));
 | 
			
		||||
GLOBAL bool Channel_ModeDel PARAMS(( CHANNEL *Chan, char Mode ));
 | 
			
		||||
@@ -114,8 +118,10 @@ GLOBAL unsigned int Channel_TopicTime PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL char *Channel_TopicWho PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Channel_AddInvite PARAMS((CHANNEL *c, const char *Mask, bool OnlyOnce ));
 | 
			
		||||
GLOBAL bool Channel_AddBan PARAMS((CHANNEL *c, const char *Mask ));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Channel_ShowBans PARAMS((CLIENT *client, CHANNEL *c));
 | 
			
		||||
GLOBAL bool Channel_ShowInvites PARAMS((CLIENT *client, CHANNEL *c));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: client.c,v 1.91 2006/04/23 10:37:27 fw Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: client.c,v 1.97 2007/11/21 12:16:36 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -57,8 +57,8 @@ static WHOWAS My_Whowas[MAX_WHOWAS];
 | 
			
		||||
static int Last_Whowas = -1;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static long Count PARAMS(( CLIENT_TYPE Type ));
 | 
			
		||||
static long MyCount PARAMS(( CLIENT_TYPE Type ));
 | 
			
		||||
static unsigned long Count PARAMS(( CLIENT_TYPE Type ));
 | 
			
		||||
static unsigned long MyCount PARAMS(( CLIENT_TYPE Type ));
 | 
			
		||||
 | 
			
		||||
static CLIENT *New_Client_Struct PARAMS(( void ));
 | 
			
		||||
static void Generate_MyToken PARAMS(( CLIENT *Client ));
 | 
			
		||||
@@ -68,10 +68,6 @@ static CLIENT *Init_New_Client PARAMS((CONN_ID Idx, CLIENT *Introducer,
 | 
			
		||||
 CLIENT *TopServer, int Type, char *ID, char *User, char *Hostname,
 | 
			
		||||
 char *Info, int Hops, int Token, char *Modes, bool Idented));
 | 
			
		||||
 | 
			
		||||
#ifndef Client_DestroyNow
 | 
			
		||||
GLOBAL void Client_DestroyNow PARAMS((CLIENT *Client ));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
long Max_Users = 0, My_Max_Users = 0;
 | 
			
		||||
 | 
			
		||||
@@ -98,9 +94,10 @@ Client_Init( void )
 | 
			
		||||
	This_Server->hops = 0;
 | 
			
		||||
 | 
			
		||||
	gethostname( This_Server->host, CLIENT_HOST_LEN );
 | 
			
		||||
	h = gethostbyname( This_Server->host );
 | 
			
		||||
	if( h ) strlcpy( This_Server->host, h->h_name, sizeof( This_Server->host ));
 | 
			
		||||
 | 
			
		||||
	if (!Conf_NoDNS) {
 | 
			
		||||
		h = gethostbyname( This_Server->host );
 | 
			
		||||
		if (h) strlcpy(This_Server->host, h->h_name, sizeof(This_Server->host));
 | 
			
		||||
	}
 | 
			
		||||
	Client_SetID( This_Server, Conf_ServerName );
 | 
			
		||||
	Client_SetInfo( This_Server, Conf_ServerInfo );
 | 
			
		||||
 | 
			
		||||
@@ -211,8 +208,8 @@ Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer,
 | 
			
		||||
	if( Modes ) Client_SetModes( client, Modes );
 | 
			
		||||
	if( Type == CLIENT_SERVER ) Generate_MyToken( client );
 | 
			
		||||
 | 
			
		||||
	/* ist der User away? */
 | 
			
		||||
	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 ));
 | 
			
		||||
 | 
			
		||||
	/* Verketten */
 | 
			
		||||
	client->next = (POINTER *)My_Clients;
 | 
			
		||||
@@ -336,43 +333,14 @@ Client_Destroy( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit )
 | 
			
		||||
} /* Client_Destroy */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Client_DestroyNow( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	/* Destroy client structure immediately. This function is only
 | 
			
		||||
	 * intended for the connection layer to remove client structures
 | 
			
		||||
	 * of connections that can't be established! */
 | 
			
		||||
 | 
			
		||||
	CLIENT *last, *c;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
	last = NULL;
 | 
			
		||||
	c = My_Clients;
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		if( c == Client )
 | 
			
		||||
		{
 | 
			
		||||
			/* Wir haben den Client gefunden: entfernen */
 | 
			
		||||
			if( last ) last->next = c->next;
 | 
			
		||||
			else My_Clients = (CLIENT *)c->next;
 | 
			
		||||
			free( c );
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		last = c;
 | 
			
		||||
		c = (CLIENT *)c->next;
 | 
			
		||||
	}
 | 
			
		||||
} /* Client_DestroyNow */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Client_SetHostname( CLIENT *Client, char *Hostname )
 | 
			
		||||
{
 | 
			
		||||
	/* Hostname eines Clients setzen */
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Hostname != NULL );
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	strlcpy( Client->host, Hostname, sizeof( Client->host ));
 | 
			
		||||
} /* Client_SetHostname */
 | 
			
		||||
 | 
			
		||||
@@ -399,7 +367,7 @@ Client_SetUser( CLIENT *Client, char *User, bool Idented )
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( User != NULL );
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	if( Idented ) strlcpy( Client->user, User, sizeof( Client->user ));
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
@@ -416,7 +384,7 @@ Client_SetInfo( CLIENT *Client, char *Info )
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Info != NULL );
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	strlcpy( Client->info, Info, sizeof( Client->info ));
 | 
			
		||||
} /* Client_SetInfo */
 | 
			
		||||
 | 
			
		||||
@@ -452,7 +420,7 @@ Client_SetPassword( CLIENT *Client, char *Pwd )
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Pwd != NULL );
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	strlcpy( Client->pwd, Pwd, sizeof( Client->pwd ));
 | 
			
		||||
} /* Client_SetPassword */
 | 
			
		||||
 | 
			
		||||
@@ -522,7 +490,7 @@ Client_ModeAdd( CLIENT *Client, char Mode )
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	char x[2];
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
	x[0] = Mode; x[1] = '\0';
 | 
			
		||||
@@ -641,7 +609,8 @@ Client_ID( CLIENT *Client )
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	if( Client->type == CLIENT_USER ) assert( strlen( Client->id ) < CLIENT_NICK_LEN );
 | 
			
		||||
	if(Client->type == CLIENT_USER)
 | 
			
		||||
		assert(strlen(Client->id) < Conf_MaxNickLength);
 | 
			
		||||
#endif
 | 
			
		||||
						   
 | 
			
		||||
	if( Client->id[0] ) return Client->id;
 | 
			
		||||
@@ -661,8 +630,7 @@ GLOBAL char *
 | 
			
		||||
Client_User( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	if( Client->user[0] ) return Client->user;
 | 
			
		||||
	else return "~";
 | 
			
		||||
	return Client->user[0] ? Client->user : "~";
 | 
			
		||||
} /* Client_User */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -734,11 +702,13 @@ GLOBAL CLIENT *
 | 
			
		||||
Client_NextHop( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
	c = Client;
 | 
			
		||||
	while( c->introducer && ( c->introducer != c ) && ( c->introducer != This_Server )) c = c->introducer;
 | 
			
		||||
	while( c->introducer && ( c->introducer != c ) && ( c->introducer != This_Server ))
 | 
			
		||||
		c = c->introducer;
 | 
			
		||||
 | 
			
		||||
	return c;
 | 
			
		||||
} /* Client_NextHop */
 | 
			
		||||
 | 
			
		||||
@@ -750,7 +720,7 @@ Client_Mask( CLIENT *Client )
 | 
			
		||||
	 * Prefixe benoetigt wird. */
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	if( Client->type == CLIENT_SERVER ) return Client->id;
 | 
			
		||||
 | 
			
		||||
	snprintf( GetID_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user, Client->host );
 | 
			
		||||
@@ -795,12 +765,9 @@ Client_Away( CLIENT *Client )
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Client_CheckNick( CLIENT *Client, char *Nick )
 | 
			
		||||
{
 | 
			
		||||
	/* Nick ueberpruefen */
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Nick != NULL );
 | 
			
		||||
	
 | 
			
		||||
	/* Nick ungueltig? */
 | 
			
		||||
 | 
			
		||||
	if( ! Client_IsValidNick( Nick ))
 | 
			
		||||
	{
 | 
			
		||||
		IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), Nick );
 | 
			
		||||
@@ -913,13 +880,12 @@ Client_MyServiceCount( void )
 | 
			
		||||
} /* Client_MyServiceCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL long
 | 
			
		||||
GLOBAL unsigned long
 | 
			
		||||
Client_MyServerCount( void )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	long cnt;
 | 
			
		||||
	unsigned long cnt = 0;
 | 
			
		||||
 | 
			
		||||
	cnt = 0;
 | 
			
		||||
	c = My_Clients;
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
@@ -930,13 +896,12 @@ Client_MyServerCount( void )
 | 
			
		||||
} /* Client_MyServerCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL long
 | 
			
		||||
GLOBAL unsigned long
 | 
			
		||||
Client_OperCount( void )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	long cnt;
 | 
			
		||||
	unsigned long cnt = 0;
 | 
			
		||||
 | 
			
		||||
	cnt = 0;
 | 
			
		||||
	c = My_Clients;
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
@@ -947,19 +912,19 @@ Client_OperCount( void )
 | 
			
		||||
} /* Client_OperCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL long
 | 
			
		||||
GLOBAL unsigned long
 | 
			
		||||
Client_UnknownCount( void )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	long cnt;
 | 
			
		||||
	unsigned long cnt = 0;
 | 
			
		||||
 | 
			
		||||
	cnt = 0;
 | 
			
		||||
	c = My_Clients;
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		if( c && ( c->type != CLIENT_USER ) && ( c->type != CLIENT_SERVICE ) && ( c->type != CLIENT_SERVER )) cnt++;
 | 
			
		||||
		c = (CLIENT *)c->next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return cnt;
 | 
			
		||||
} /* Client_UnknownCount */
 | 
			
		||||
 | 
			
		||||
@@ -979,28 +944,25 @@ Client_MyMaxUserCount( void )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Client_IsValidNick( char *Nick )
 | 
			
		||||
Client_IsValidNick( const char *Nick )
 | 
			
		||||
{
 | 
			
		||||
	/* Ist der Nick gueltig? */
 | 
			
		||||
	const char *ptr;
 | 
			
		||||
	static const char goodchars[] = ";0123456789-";
 | 
			
		||||
 | 
			
		||||
	char *ptr, goodchars[20];
 | 
			
		||||
	
 | 
			
		||||
	assert( Nick != NULL );
 | 
			
		||||
 | 
			
		||||
	strcpy( goodchars, ";0123456789-" );
 | 
			
		||||
 | 
			
		||||
	if( Nick[0] == '#' ) return false;
 | 
			
		||||
	if( strchr( goodchars, Nick[0] )) return false;
 | 
			
		||||
	if( strlen( Nick ) >= CLIENT_NICK_LEN ) return false;
 | 
			
		||||
	if( strlen( Nick ) >= Conf_MaxNickLength) return false;
 | 
			
		||||
 | 
			
		||||
	ptr = Nick;
 | 
			
		||||
	while( *ptr )
 | 
			
		||||
	{
 | 
			
		||||
		if(( *ptr < 'A' ) && ( ! strchr( goodchars, *ptr ))) return false;
 | 
			
		||||
		if(( *ptr > '}' ) && ( ! strchr( goodchars, *ptr ))) return false;
 | 
			
		||||
		if (( *ptr < 'A' ) && ( ! strchr( goodchars, *ptr ))) return false;
 | 
			
		||||
		if ( *ptr > '}' ) return false;
 | 
			
		||||
		ptr++;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
} /* Client_IsValidNick */
 | 
			
		||||
 | 
			
		||||
@@ -1037,13 +999,12 @@ Client_StartTime(CLIENT *Client)
 | 
			
		||||
} /* Client_Uptime */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static long
 | 
			
		||||
static unsigned long
 | 
			
		||||
Count( CLIENT_TYPE Type )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	long cnt;
 | 
			
		||||
	unsigned long cnt = 0;
 | 
			
		||||
 | 
			
		||||
	cnt = 0;
 | 
			
		||||
	c = My_Clients;
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
@@ -1054,13 +1015,12 @@ Count( CLIENT_TYPE Type )
 | 
			
		||||
} /* Count */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static long
 | 
			
		||||
static unsigned long
 | 
			
		||||
MyCount( CLIENT_TYPE Type )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	long cnt;
 | 
			
		||||
	unsigned long cnt = 0;
 | 
			
		||||
 | 
			
		||||
	cnt = 0;
 | 
			
		||||
	c = My_Clients;
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
@@ -1075,9 +1035,9 @@ static CLIENT *
 | 
			
		||||
New_Client_Struct( void )
 | 
			
		||||
{
 | 
			
		||||
	/* Neue CLIENT-Struktur pre-initialisieren */
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	c = (CLIENT *)malloc( sizeof( CLIENT ));
 | 
			
		||||
	if( ! c )
 | 
			
		||||
	{
 | 
			
		||||
@@ -1130,7 +1090,7 @@ Adjust_Counters( CLIENT *Client )
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Client->type != CLIENT_USER ) return;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	if( Client->conn_id != NONE )
 | 
			
		||||
	{
 | 
			
		||||
		/* Local connection */
 | 
			
		||||
@@ -1153,7 +1113,7 @@ Client_RegisterWhowas( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	int slot;
 | 
			
		||||
	time_t now;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
	now = time(NULL);
 | 
			
		||||
@@ -1167,7 +1127,7 @@ Client_RegisterWhowas( CLIENT *Client )
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	Log( LOG_DEBUG, "Saving WHOWAS information to slot %d ...", slot );
 | 
			
		||||
#endif
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	My_Whowas[slot].time = now;
 | 
			
		||||
	strlcpy( My_Whowas[slot].id, Client_ID( Client ),
 | 
			
		||||
		 sizeof( My_Whowas[slot].id ));
 | 
			
		||||
@@ -1179,7 +1139,7 @@ Client_RegisterWhowas( CLIENT *Client )
 | 
			
		||||
		 sizeof( My_Whowas[slot].info ));
 | 
			
		||||
	strlcpy( My_Whowas[slot].server, Client_ID( Client_Introducer( Client )),
 | 
			
		||||
		 sizeof( My_Whowas[slot].server ));
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	Last_Whowas = slot;
 | 
			
		||||
} /* Client_RegisterWhowas */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: client.h,v 1.42 2006/04/23 10:37:27 fw Exp $
 | 
			
		||||
 * $Id: client.h,v 1.46 2007/01/23 16:07:19 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Client management (header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -23,10 +23,9 @@
 | 
			
		||||
#define CLIENT_GOTNICK 4		/* client did send NICK */
 | 
			
		||||
#define CLIENT_GOTUSER 8		/* client did send USER */
 | 
			
		||||
#define CLIENT_USER 16			/* client is an IRC user */
 | 
			
		||||
#define CLIENT_UNKNOWNSERVER 32		/* unregistered server connection */
 | 
			
		||||
#define CLIENT_GOTPASSSERVER 64		/* client did send PASS in "server style" */
 | 
			
		||||
#define CLIENT_SERVER 128		/* client is a server */
 | 
			
		||||
#define CLIENT_SERVICE 256		/* client is a service */
 | 
			
		||||
#define CLIENT_SERVER 32		/* client is a server */
 | 
			
		||||
#define CLIENT_SERVICE 64		/* client is a service */
 | 
			
		||||
#define CLIENT_UNKNOWNSERVER 128	/* unregistered server connection */
 | 
			
		||||
 | 
			
		||||
#define CLIENT_TYPE int
 | 
			
		||||
 | 
			
		||||
@@ -81,9 +80,6 @@ GLOBAL CLIENT *Client_NewRemoteServer PARAMS(( CLIENT *Introducer, char *Hostnam
 | 
			
		||||
GLOBAL CLIENT *Client_NewRemoteUser PARAMS(( CLIENT *Introducer, char *Nick, int Hops, char *User, char *Hostname, int Token, char *Modes, char *Info, bool Idented ));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Client_Destroy PARAMS(( CLIENT *Client, char *LogMsg, char *FwdMsg, bool SendQuit ));
 | 
			
		||||
#ifdef CONN_MODULE
 | 
			
		||||
GLOBAL void Client_DestroyNow PARAMS(( CLIENT *Client ));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_ThisServer PARAMS(( void ));
 | 
			
		||||
 | 
			
		||||
@@ -138,15 +134,15 @@ GLOBAL bool Client_CheckID PARAMS(( CLIENT *Client, char *ID ));
 | 
			
		||||
GLOBAL long Client_UserCount PARAMS(( void ));
 | 
			
		||||
GLOBAL long Client_ServiceCount PARAMS(( void ));
 | 
			
		||||
GLOBAL long Client_ServerCount PARAMS(( void ));
 | 
			
		||||
GLOBAL long Client_OperCount PARAMS(( void ));
 | 
			
		||||
GLOBAL long Client_UnknownCount PARAMS(( void ));
 | 
			
		||||
GLOBAL unsigned long Client_OperCount PARAMS(( void ));
 | 
			
		||||
GLOBAL unsigned long Client_UnknownCount PARAMS(( void ));
 | 
			
		||||
GLOBAL long Client_MyUserCount PARAMS(( void ));
 | 
			
		||||
GLOBAL long Client_MyServiceCount PARAMS(( void ));
 | 
			
		||||
GLOBAL long Client_MyServerCount PARAMS(( void ));
 | 
			
		||||
GLOBAL unsigned long Client_MyServerCount PARAMS(( void ));
 | 
			
		||||
GLOBAL long Client_MaxUserCount PARAMS((  void ));
 | 
			
		||||
GLOBAL long Client_MyMaxUserCount PARAMS((  void ));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Client_IsValidNick PARAMS(( char *Nick ));
 | 
			
		||||
GLOBAL bool Client_IsValidNick PARAMS(( const char *Nick ));
 | 
			
		||||
 | 
			
		||||
GLOBAL WHOWAS *Client_GetWhowas PARAMS(( void ));
 | 
			
		||||
GLOBAL int Client_GetLastWhowasIndex PARAMS(( void ));
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: conf.c,v 1.92 2006/07/23 16:42:45 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: conf.c,v 1.103 2007/11/23 16:26:04 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -146,6 +146,9 @@ Conf_Rehash( void )
 | 
			
		||||
	Set_Defaults( false );
 | 
			
		||||
	Read_Config( );
 | 
			
		||||
	Validate_Config(false, true);
 | 
			
		||||
 | 
			
		||||
	/* Update CLIENT structure of local server */
 | 
			
		||||
	Client_SetInfo(Client_ThisServer(), Conf_ServerInfo);
 | 
			
		||||
} /* Config_Rehash */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -199,15 +202,18 @@ Conf_Test( void )
 | 
			
		||||
	printf( "  PingTimeout = %d\n", Conf_PingTimeout );
 | 
			
		||||
	printf( "  PongTimeout = %d\n", Conf_PongTimeout );
 | 
			
		||||
	printf( "  ConnectRetry = %d\n", Conf_ConnectRetry );
 | 
			
		||||
	printf( "  OperCanUseMode = %s\n", Conf_OperCanMode == true? "yes" : "no" );
 | 
			
		||||
	printf( "  OperCanUseMode = %s\n", Conf_OperCanMode == true ? "yes" : "no" );
 | 
			
		||||
	printf( "  OperServerMode = %s\n", Conf_OperServerMode == true? "yes" : "no" );
 | 
			
		||||
	printf( "  MaxConnections = %ld\n", Conf_MaxConnections>0 ? Conf_MaxConnections : -1);
 | 
			
		||||
	printf( "  MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP>0 ? Conf_MaxConnectionsIP : -1);
 | 
			
		||||
	printf( "  MaxJoins = %d\n\n", Conf_MaxJoins>0 ? Conf_MaxJoins : -1);
 | 
			
		||||
	printf( "  PredefChannelsOnly = %s\n", Conf_PredefChannelsOnly == true ? "yes" : "no" );
 | 
			
		||||
	printf( "  NoDNS = %s\n", Conf_NoDNS ? "yes" : "no");
 | 
			
		||||
	printf( "  MaxConnections = %ld\n", Conf_MaxConnections);
 | 
			
		||||
	printf( "  MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP);
 | 
			
		||||
	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 );
 | 
			
		||||
@@ -218,7 +224,7 @@ Conf_Test( void )
 | 
			
		||||
 | 
			
		||||
	for( i = 0; i < MAX_SERVERS; i++ ) {
 | 
			
		||||
		if( ! Conf_Server[i].name[0] ) continue;
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		/* Valid "Server" section */
 | 
			
		||||
		puts( "[SERVER]" );
 | 
			
		||||
		printf( "  Name = %s\n", Conf_Server[i].name );
 | 
			
		||||
@@ -226,21 +232,24 @@ Conf_Test( void )
 | 
			
		||||
		printf( "  Port = %u\n", (unsigned int)Conf_Server[i].port );
 | 
			
		||||
		printf( "  MyPassword = %s\n", Conf_Server[i].pwd_in );
 | 
			
		||||
		printf( "  PeerPassword = %s\n", Conf_Server[i].pwd_out );
 | 
			
		||||
		printf( "  Group = %d\n\n", Conf_Server[i].group );
 | 
			
		||||
		printf( "  Group = %d\n", Conf_Server[i].group );
 | 
			
		||||
		printf( "  Passive = %s\n\n", Conf_Server[i].flags & CONF_SFLAG_DISABLED ? "yes" : "no");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for( i = 0; i < Conf_Channel_Count; i++ ) {
 | 
			
		||||
		if( ! Conf_Channel[i].name[0] ) continue;
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		/* Valid "Channel" section */
 | 
			
		||||
		puts( "[CHANNEL]" );
 | 
			
		||||
		printf( "  Name = %s\n", Conf_Channel[i].name );
 | 
			
		||||
		printf( "  Modes = %s\n", Conf_Channel[i].modes );
 | 
			
		||||
		printf( "  Key = %s\n", Conf_Channel[i].key );
 | 
			
		||||
		printf( "  MaxUsers = %lu\n", Conf_Channel[i].maxusers );
 | 
			
		||||
 | 
			
		||||
		topic = (char*)array_start(&Conf_Channel[i].topic);
 | 
			
		||||
		printf( "  Topic = %s\n\n", topic ? topic : "");
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
} /* Conf_Test */
 | 
			
		||||
 | 
			
		||||
@@ -268,14 +277,14 @@ Conf_UnsetServer( CONN_ID Idx )
 | 
			
		||||
			Init_Server_Struct( &Conf_Server[i] );
 | 
			
		||||
		} else {
 | 
			
		||||
			/* Set time for next connect attempt */
 | 
			
		||||
 			t = time(NULL);
 | 
			
		||||
 			if (Conf_Server[i].lasttry < t - Conf_ConnectRetry) {
 | 
			
		||||
 				/* The connection has been "long", so we don't
 | 
			
		||||
 				 * require the next attempt to be delayed. */
 | 
			
		||||
 				Conf_Server[i].lasttry =
 | 
			
		||||
 					t - Conf_ConnectRetry + RECONNECT_DELAY;
 | 
			
		||||
 			} else
 | 
			
		||||
 				Conf_Server[i].lasttry = t;
 | 
			
		||||
			t = time(NULL);
 | 
			
		||||
			if (Conf_Server[i].lasttry < t - Conf_ConnectRetry) {
 | 
			
		||||
				/* The connection has been "long", so we don't
 | 
			
		||||
				 * require the next attempt to be delayed. */
 | 
			
		||||
				Conf_Server[i].lasttry =
 | 
			
		||||
					t - Conf_ConnectRetry + RECONNECT_DELAY;
 | 
			
		||||
			} else
 | 
			
		||||
				Conf_Server[i].lasttry = t;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
} /* Conf_UnsetServer */
 | 
			
		||||
@@ -297,9 +306,9 @@ GLOBAL int
 | 
			
		||||
Conf_GetServer( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Get index of server in configuration structure */
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	int i = 0;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
 | 
			
		||||
	for( i = 0; i < MAX_SERVERS; i++ ) {
 | 
			
		||||
@@ -330,6 +339,24 @@ Conf_EnableServer( char *Name, UINT16 Port )
 | 
			
		||||
} /* Conf_EnableServer */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Conf_EnablePassiveServer(const char *Name)
 | 
			
		||||
{
 | 
			
		||||
	/* Enable specified server */
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	assert( Name != NULL );
 | 
			
		||||
	for (i = 0; i < MAX_SERVERS; i++) {
 | 
			
		||||
		if ((strcasecmp( Conf_Server[i].name, Name ) == 0) && (Conf_Server[i].port > 0)) {
 | 
			
		||||
			/* BINGO! Enable server */
 | 
			
		||||
			Conf_Server[i].flags &= ~CONF_SFLAG_DISABLED;
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
} /* Conf_EnablePassiveServer */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Conf_DisableServer( char *Name )
 | 
			
		||||
{
 | 
			
		||||
@@ -377,7 +404,7 @@ Conf_AddServer( char *Name, UINT16 Port, char *Host, char *MyPwd, char *PeerPwd
 | 
			
		||||
	strlcpy( Conf_Server[i].pwd_in, PeerPwd, sizeof( Conf_Server[i].pwd_in ));
 | 
			
		||||
	Conf_Server[i].port = Port;
 | 
			
		||||
	Conf_Server[i].flags = CONF_SFLAG_ONCE;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
} /* Conf_AddServer */
 | 
			
		||||
 | 
			
		||||
@@ -409,7 +436,7 @@ Set_Defaults( bool InitServers )
 | 
			
		||||
	strcpy( Conf_ListenAddress, "" );
 | 
			
		||||
 | 
			
		||||
	Conf_UID = Conf_GID = 0;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	Conf_PingTimeout = 120;
 | 
			
		||||
	Conf_PongTimeout = 20;
 | 
			
		||||
 | 
			
		||||
@@ -419,11 +446,14 @@ Set_Defaults( bool InitServers )
 | 
			
		||||
	Conf_Channel_Count = 0;
 | 
			
		||||
 | 
			
		||||
	Conf_OperCanMode = false;
 | 
			
		||||
	Conf_NoDNS = false;
 | 
			
		||||
	Conf_PredefChannelsOnly = false;
 | 
			
		||||
	Conf_OperServerMode = false;
 | 
			
		||||
	
 | 
			
		||||
	Conf_MaxConnections = -1;
 | 
			
		||||
 | 
			
		||||
	Conf_MaxConnections = 0;
 | 
			
		||||
	Conf_MaxConnectionsIP = 5;
 | 
			
		||||
	Conf_MaxJoins = 10;
 | 
			
		||||
	Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
 | 
			
		||||
 | 
			
		||||
	/* Initialize server configuration structures */
 | 
			
		||||
	if( InitServers ) for( i = 0; i < MAX_SERVERS; Init_Server_Struct( &Conf_Server[i++] ));
 | 
			
		||||
@@ -550,6 +580,8 @@ Read_Config( void )
 | 
			
		||||
					/* Initialize new channel structure */
 | 
			
		||||
					strcpy( Conf_Channel[Conf_Channel_Count].name, "" );
 | 
			
		||||
					strcpy( Conf_Channel[Conf_Channel_Count].modes, "" );
 | 
			
		||||
					strcpy( Conf_Channel[Conf_Channel_Count].key, "" );
 | 
			
		||||
					Conf_Channel[Conf_Channel_Count].maxusers = 0;
 | 
			
		||||
					array_free(&Conf_Channel[Conf_Channel_Count].topic);
 | 
			
		||||
					Conf_Channel_Count++;
 | 
			
		||||
				}
 | 
			
		||||
@@ -608,6 +640,27 @@ Check_ArgIsTrue( const char *Arg )
 | 
			
		||||
} /* Check_ArgIsTrue */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static unsigned int Handle_MaxNickLength(int Line, const char *Arg)
 | 
			
		||||
{
 | 
			
		||||
	unsigned new;
 | 
			
		||||
 | 
			
		||||
	new = (unsigned) atoi(Arg) + 1;
 | 
			
		||||
	if (new > CLIENT_NICK_LEN) {
 | 
			
		||||
		Config_Error(LOG_WARNING,
 | 
			
		||||
			     "%s, line %d: Value of \"MaxNickLength\" exceeds %u!",
 | 
			
		||||
			     NGIRCd_ConfFile, Line, CLIENT_NICK_LEN - 1);
 | 
			
		||||
		return CLIENT_NICK_LEN;
 | 
			
		||||
	}
 | 
			
		||||
	if (new < 2) {
 | 
			
		||||
		Config_Error(LOG_WARNING,
 | 
			
		||||
			     "%s, line %d: Value of \"MaxNickLength\" must be at least 1!",
 | 
			
		||||
			     NGIRCd_ConfFile, Line);
 | 
			
		||||
		return 2;
 | 
			
		||||
	}
 | 
			
		||||
	return new;
 | 
			
		||||
} /* Handle_MaxNickLength */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
Handle_GLOBAL( int Line, char *Var, char *Arg )
 | 
			
		||||
{
 | 
			
		||||
@@ -750,6 +803,16 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 | 
			
		||||
		}
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if( strcasecmp( Var, "PredefChannelsOnly" ) == 0 ) {
 | 
			
		||||
		/* Should we only allow pre-defined-channels? (i.e. users cannot create their own channels) */
 | 
			
		||||
		Conf_PredefChannelsOnly = Check_ArgIsTrue( Arg );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if( strcasecmp( Var, "NoDNS" ) == 0 ) {
 | 
			
		||||
		/* don't do reverse dns lookups when clients connect? */
 | 
			
		||||
		Conf_NoDNS = Check_ArgIsTrue( Arg );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if( strcasecmp( Var, "OperCanUseMode" ) == 0 ) {
 | 
			
		||||
		/* Are IRC operators allowed to use MODE in channels they aren't Op in? */
 | 
			
		||||
		Conf_OperCanMode = Check_ArgIsTrue( Arg );
 | 
			
		||||
@@ -761,7 +824,7 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if( strcasecmp( Var, "MaxConnections" ) == 0 ) {
 | 
			
		||||
		/* Maximum number of connections. Values <= 0 are equal to "no limit". */
 | 
			
		||||
		/* Maximum number of connections. 0 -> "no limit". */
 | 
			
		||||
#ifdef HAVE_ISDIGIT
 | 
			
		||||
		if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var);
 | 
			
		||||
		else
 | 
			
		||||
@@ -770,7 +833,7 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if( strcasecmp( Var, "MaxConnectionsIP" ) == 0 ) {
 | 
			
		||||
		/* Maximum number of simultaneous connections from one IP. Values <= 0 -> "no limit" */
 | 
			
		||||
		/* Maximum number of simultaneous connections from one IP. 0 -> "no limit" */
 | 
			
		||||
#ifdef HAVE_ISDIGIT
 | 
			
		||||
		if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var );
 | 
			
		||||
		else
 | 
			
		||||
@@ -779,7 +842,7 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if( strcasecmp( Var, "MaxJoins" ) == 0 ) {
 | 
			
		||||
		/* Maximum number of channels a user can join. Values <= 0 are equal to "no limit". */
 | 
			
		||||
		/* Maximum number of channels a user can join. 0 -> "no limit". */
 | 
			
		||||
#ifdef HAVE_ISDIGIT
 | 
			
		||||
		if( ! isdigit( (int)*Arg )) Config_Error_NaN( Line, Var );
 | 
			
		||||
		else
 | 
			
		||||
@@ -787,6 +850,13 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 | 
			
		||||
		Conf_MaxJoins = atoi( Arg );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if( strcasecmp( Var, "MaxNickLength" ) == 0 ) {
 | 
			
		||||
		/* Maximum length of a nick name; must be same on all servers
 | 
			
		||||
		 * within the IRC network! */
 | 
			
		||||
		Conf_MaxNickLength = Handle_MaxNickLength(Line, Arg);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( strcasecmp( Var, "Listen" ) == 0 ) {
 | 
			
		||||
		/* IP-Address to bind sockets */
 | 
			
		||||
		len = strlcpy( Conf_ListenAddress, Arg, sizeof( Conf_ListenAddress ));
 | 
			
		||||
@@ -867,6 +937,14 @@ Handle_SERVER( int Line, char *Var, char *Arg )
 | 
			
		||||
			Config_Error_TooLong( Line, Var );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (strcasecmp(Var, "Bind") == 0) {
 | 
			
		||||
		if (ngt_IPStrToBin(Arg, &New_Server.bind_addr))
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		Config_Error(LOG_ERR, "%s, line %d (section \"Server\"): Can't parse IP address \"%s\"",
 | 
			
		||||
				NGIRCd_ConfFile, Line, Arg);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if( strcasecmp( Var, "MyPassword" ) == 0 ) {
 | 
			
		||||
		/* Password of this server which is sent to the peer */
 | 
			
		||||
		if (*Arg == ':') {
 | 
			
		||||
@@ -906,12 +984,32 @@ Handle_SERVER( int Line, char *Var, char *Arg )
 | 
			
		||||
		New_Server.group = atoi( Arg );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if( strcasecmp( Var, "Passive" ) == 0 ) {
 | 
			
		||||
		if (Check_ArgIsTrue(Arg))
 | 
			
		||||
			New_Server.flags |= CONF_SFLAG_DISABLED;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Unknown variable \"%s\"!",
 | 
			
		||||
								NGIRCd_ConfFile, Line, Var );
 | 
			
		||||
} /* Handle_SERVER */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
Handle_Channelname(size_t chancount, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	size_t size = sizeof( Conf_Channel[chancount].name );
 | 
			
		||||
	char *dest = Conf_Channel[chancount].name;
 | 
			
		||||
 | 
			
		||||
	if (*name && *name != '#') {
 | 
			
		||||
		*dest = '#';
 | 
			
		||||
		--size;
 | 
			
		||||
		++dest;
 | 
			
		||||
	}
 | 
			
		||||
	return size > strlcpy(dest, name, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
Handle_CHANNEL( int Line, char *Var, char *Arg )
 | 
			
		||||
{
 | 
			
		||||
@@ -925,9 +1023,7 @@ Handle_CHANNEL( int Line, char *Var, char *Arg )
 | 
			
		||||
		chancount = Conf_Channel_Count - 1;
 | 
			
		||||
 | 
			
		||||
	if( strcasecmp( Var, "Name" ) == 0 ) {
 | 
			
		||||
		/* Name of the channel */
 | 
			
		||||
		len = strlcpy( Conf_Channel[chancount].name, Arg, sizeof( Conf_Channel[chancount].name ));
 | 
			
		||||
		if (len >= sizeof( Conf_Channel[chancount].name ))
 | 
			
		||||
		if (!Handle_Channelname(chancount, Arg))
 | 
			
		||||
			Config_Error_TooLong( Line, Var );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
@@ -945,6 +1041,22 @@ Handle_CHANNEL( int Line, char *Var, char *Arg )
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( strcasecmp( Var, "Key" ) == 0 ) {
 | 
			
		||||
		/* Initial Channel Key (mode k) */
 | 
			
		||||
		len = strlcpy(Conf_Channel[chancount].key, Arg, sizeof(Conf_Channel[chancount].key));
 | 
			
		||||
		if (len >= sizeof( Conf_Channel[chancount].key ))
 | 
			
		||||
			Config_Error_TooLong(Line, Var);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( strcasecmp( Var, "MaxUsers" ) == 0 ) {
 | 
			
		||||
		/* maximum user limit, mode l */
 | 
			
		||||
		Conf_Channel[chancount].maxusers = (unsigned long) atol(Arg);
 | 
			
		||||
		if (Conf_Channel[chancount].maxusers == 0)
 | 
			
		||||
			Config_Error_NaN(Line, Var);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Config_Error( LOG_ERR, "%s, line %d (section \"Channel\"): Unknown variable \"%s\"!",
 | 
			
		||||
								NGIRCd_ConfFile, Line, Var );
 | 
			
		||||
} /* Handle_CHANNEL */
 | 
			
		||||
@@ -965,7 +1077,7 @@ Validate_Config(bool Configtest, bool Rehash)
 | 
			
		||||
	do {
 | 
			
		||||
		if (*ptr >= 'a' && *ptr <= 'z') continue;
 | 
			
		||||
		if (*ptr >= 'A' && *ptr <= 'Z') continue;
 | 
			
		||||
		if (*ptr >= '1' && *ptr <= '0') continue;
 | 
			
		||||
		if (*ptr >= '0' && *ptr <= '9') continue;
 | 
			
		||||
		if (ptr > Conf_ServerName) {
 | 
			
		||||
			if (*ptr == '.' || *ptr == '-')
 | 
			
		||||
				continue;
 | 
			
		||||
@@ -1101,6 +1213,7 @@ Init_Server_Struct( CONF_SERVER *Server )
 | 
			
		||||
 | 
			
		||||
	Resolve_Init(&Server->res_stat);
 | 
			
		||||
	Server->conn_id = NONE;
 | 
			
		||||
	Server->bind_addr.s_addr = htonl(INADDR_ANY);
 | 
			
		||||
} /* Init_Server_Struct */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: conf.h,v 1.40 2006/05/10 21:24:01 alex Exp $
 | 
			
		||||
 * $Id: conf.h,v 1.47 2007/11/23 16:28:37 fw Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Configuration management (header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -33,7 +33,6 @@ typedef struct _Conf_Oper
 | 
			
		||||
typedef struct _Conf_Server
 | 
			
		||||
{
 | 
			
		||||
	char host[HOST_LEN];		/* Hostname */
 | 
			
		||||
	char ip[16];			/* IP address (Resolver) */
 | 
			
		||||
	char name[CLIENT_ID_LEN];	/* IRC-Client-ID */
 | 
			
		||||
	char pwd_in[CLIENT_PASS_LEN];	/* Password which must be received */
 | 
			
		||||
	char pwd_out[CLIENT_PASS_LEN];	/* Password to send to peer */
 | 
			
		||||
@@ -43,12 +42,15 @@ typedef struct _Conf_Server
 | 
			
		||||
	RES_STAT res_stat;		/* Status of the resolver */
 | 
			
		||||
	int flags;			/* Flags */
 | 
			
		||||
	CONN_ID conn_id;		/* ID of server connection or NONE */
 | 
			
		||||
	struct in_addr bind_addr;	/* source address to use for outgoing connections */
 | 
			
		||||
} CONF_SERVER;
 | 
			
		||||
 | 
			
		||||
typedef struct _Conf_Channel
 | 
			
		||||
{
 | 
			
		||||
	char name[CHANNEL_NAME_LEN];	/* Name of the channel */
 | 
			
		||||
	char modes[CHANNEL_MODE_LEN];	/* Initial channel modes */
 | 
			
		||||
	char key[CLIENT_PASS_LEN];      /* Channel key ("password", mode "k" ) */
 | 
			
		||||
	unsigned long maxusers;		/* maximum usercount for this channel, mode "l" */
 | 
			
		||||
	array topic;			/* Initial topic */
 | 
			
		||||
} CONF_CHANNEL;
 | 
			
		||||
 | 
			
		||||
@@ -110,10 +112,15 @@ GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS];
 | 
			
		||||
/* Pre-defined channels */
 | 
			
		||||
GLOBAL CONF_CHANNEL Conf_Channel[MAX_DEFCHANNELS];
 | 
			
		||||
GLOBAL unsigned int Conf_Channel_Count;
 | 
			
		||||
/* Pre-defined channels only */
 | 
			
		||||
GLOBAL bool Conf_PredefChannelsOnly;
 | 
			
		||||
 | 
			
		||||
/* Are IRC operators allowed to always use MODE? */
 | 
			
		||||
GLOBAL bool Conf_OperCanMode;
 | 
			
		||||
 | 
			
		||||
/* Disable all DNS functions? */
 | 
			
		||||
GLOBAL bool Conf_NoDNS;
 | 
			
		||||
 | 
			
		||||
/* If an IRC op gives chanop privileges without being a chanop,
 | 
			
		||||
 * ircd2 will ignore the command. This enables a workaround:
 | 
			
		||||
 * It masks the command as coming from the server */
 | 
			
		||||
@@ -128,6 +135,8 @@ GLOBAL int Conf_MaxJoins;
 | 
			
		||||
/* Maximum number of connections per IP address */
 | 
			
		||||
GLOBAL int Conf_MaxConnectionsIP;
 | 
			
		||||
 | 
			
		||||
/* Maximum length of a nick name */
 | 
			
		||||
GLOBAL unsigned int Conf_MaxNickLength;
 | 
			
		||||
 | 
			
		||||
GLOBAL void Conf_Init PARAMS((void));
 | 
			
		||||
GLOBAL void Conf_Rehash PARAMS((void));
 | 
			
		||||
@@ -138,6 +147,7 @@ GLOBAL void Conf_SetServer PARAMS(( int ConfServer, CONN_ID Idx ));
 | 
			
		||||
GLOBAL int Conf_GetServer PARAMS(( CONN_ID Idx ));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Conf_EnableServer PARAMS(( char *Name, UINT16 Port ));
 | 
			
		||||
GLOBAL bool Conf_EnablePassiveServer PARAMS((const char *Name));
 | 
			
		||||
GLOBAL bool Conf_DisableServer PARAMS(( char *Name ));
 | 
			
		||||
GLOBAL bool Conf_AddServer PARAMS(( char *Name, UINT16 Port, char *Host, char *MyPwd, char *PeerPwd ));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: conn-func.c,v 1.10 2006/05/10 21:24:01 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: conn-func.c,v 1.11 2007/10/04 15:03:56 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -39,6 +39,16 @@ Conn_UpdateIdle( CONN_ID Idx )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Get signon time of a connection.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL time_t
 | 
			
		||||
Conn_GetSignon(CONN_ID Idx)
 | 
			
		||||
{
 | 
			
		||||
	assert(Idx > NONE);
 | 
			
		||||
	return My_Connections[Idx].signon;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLOBAL time_t
 | 
			
		||||
Conn_GetIdle( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: conn-func.h,v 1.5 2006/05/10 21:24:01 alex Exp $
 | 
			
		||||
 * $Id: conn-func.h,v 1.7 2007/10/04 15:03:56 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Connection management: Global functions (header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -27,6 +27,7 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void Conn_UpdateIdle PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL time_t Conn_GetSignon PARAMS((CONN_ID Idx));
 | 
			
		||||
GLOBAL time_t Conn_GetIdle PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL time_t Conn_LastPing PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL time_t Conn_StartTime PARAMS(( CONN_ID Idx ));
 | 
			
		||||
@@ -52,9 +53,9 @@ GLOBAL UINT16 Conn_Options PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL void Conn_ResetWCounter PARAMS(( void ));
 | 
			
		||||
GLOBAL long Conn_WCounter PARAMS(( void ));
 | 
			
		||||
 | 
			
		||||
#define Conn_OPTION_ADD( x, opt )   ( (x)->options |= opt ) 
 | 
			
		||||
#define Conn_OPTION_DEL( x, opt )   ( (x)->options &= ~opt )
 | 
			
		||||
#define Conn_OPTION_ISSET( x, opt ) ( (x)->options & opt )
 | 
			
		||||
#define Conn_OPTION_ADD( x, opt )   ( (x)->options |= (opt) )
 | 
			
		||||
#define Conn_OPTION_DEL( x, opt )   ( (x)->options &= ~(opt) )
 | 
			
		||||
#define Conn_OPTION_ISSET( x, opt ) ( ((x)->options & (opt)) != 0)
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2006 Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2007 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,7 @@
 | 
			
		||||
/* enable more zlib related debug messages: */
 | 
			
		||||
/* #define DEBUG_ZLIB */
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: conn-zip.c,v 1.11 2006/07/23 15:19:20 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: conn-zip.c,v 1.16 2007/05/17 23:34:24 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -82,47 +82,63 @@ Zip_InitConn( CONN_ID Idx )
 | 
			
		||||
} /* Zip_InitConn */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Copy data to the compression buffer of a connection. We do collect
 | 
			
		||||
 * some data there until it's full so that we can achieve better
 | 
			
		||||
 * compression ratios.
 | 
			
		||||
 * If the (pre-)compression buffer is full, we try to flush it ("actually
 | 
			
		||||
 * compress some data") and to add the new (uncompressed) data afterwards.
 | 
			
		||||
 * @param Idx Connection handle.
 | 
			
		||||
 * @param Data Pointer to the data.
 | 
			
		||||
 * @param Len Length of the data to add.
 | 
			
		||||
 * @return true on success, false otherwise. */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Zip_Buffer( CONN_ID Idx, char *Data, size_t Len )
 | 
			
		||||
{
 | 
			
		||||
	/* Daten zum Komprimieren im "Kompressions-Puffer" sammeln.
 | 
			
		||||
	* Es wird true bei Erfolg, sonst false geliefert. */
 | 
			
		||||
	size_t buflen;
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	assert( Data != NULL );
 | 
			
		||||
	assert( Len > 0 );
 | 
			
		||||
	assert( Len <= ZWRITEBUFFER_LEN );
 | 
			
		||||
 | 
			
		||||
	if (Len > ZWRITEBUFFER_LEN)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	if ( array_bytes( &My_Connections[Idx].zip.wbuf ) >= ZWRITEBUFFER_LEN ) {
 | 
			
		||||
	buflen = array_bytes(&My_Connections[Idx].zip.wbuf);
 | 
			
		||||
	if (buflen + Len >= WRITEBUFFER_SLINK_LEN) {
 | 
			
		||||
		/* compression buffer is full, flush */
 | 
			
		||||
		if( ! Zip_Flush( Idx )) return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* check again; if zip buf is still too large do not append data:
 | 
			
		||||
	 * otherwise the zip wbuf would grow too large */
 | 
			
		||||
	buflen = array_bytes(&My_Connections[Idx].zip.wbuf);
 | 
			
		||||
	if (buflen + Len >= WRITEBUFFER_SLINK_LEN)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	return array_catb(&My_Connections[Idx].zip.wbuf, Data, Len);
 | 
			
		||||
} /* Zip_Buffer */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Compress data in ZIP buffer and move result to the write buffer of
 | 
			
		||||
 * the connection.
 | 
			
		||||
 * @param Idx Connection handle.
 | 
			
		||||
 * @retrun true on success, false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Zip_Flush( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Daten komprimieren und in Schreibpuffer kopieren.
 | 
			
		||||
	* Es wird true bei Erfolg, sonst false geliefert. */
 | 
			
		||||
 | 
			
		||||
	int result;
 | 
			
		||||
	unsigned char zipbuf[WRITEBUFFER_LEN];
 | 
			
		||||
	unsigned char zipbuf[WRITEBUFFER_SLINK_LEN];
 | 
			
		||||
	int zipbuf_used = 0;
 | 
			
		||||
	z_stream *out;
 | 
			
		||||
 | 
			
		||||
	out = &My_Connections[Idx].zip.out;
 | 
			
		||||
 | 
			
		||||
	out->next_in = array_start(&My_Connections[Idx].zip.wbuf);
 | 
			
		||||
	if (!out->next_in)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	out->avail_in = (uInt)array_bytes(&My_Connections[Idx].zip.wbuf);
 | 
			
		||||
	if (!out->avail_in)
 | 
			
		||||
		return true;	/* nothing to do. */
 | 
			
		||||
 | 
			
		||||
	out->next_in = array_start(&My_Connections[Idx].zip.wbuf);
 | 
			
		||||
	assert(out->next_in != NULL);
 | 
			
		||||
 | 
			
		||||
	out->next_out = zipbuf;
 | 
			
		||||
	out->avail_out = (uInt)sizeof zipbuf;
 | 
			
		||||
@@ -139,14 +155,26 @@ Zip_Flush( CONN_ID Idx )
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	assert(out->avail_out <= WRITEBUFFER_LEN);
 | 
			
		||||
	zipbuf_used = WRITEBUFFER_LEN - out->avail_out;
 | 
			
		||||
	if (out->avail_out <= 0) {
 | 
			
		||||
		/* Not all data was compressed, because data became
 | 
			
		||||
		 * bigger while compressing it. */
 | 
			
		||||
		Log (LOG_ALERT, "Compression error: buffer overvlow!?");
 | 
			
		||||
		Conn_Close(Idx, "Compression error!", NULL, false);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	assert(out->avail_out <= WRITEBUFFER_SLINK_LEN);
 | 
			
		||||
 | 
			
		||||
	zipbuf_used = WRITEBUFFER_SLINK_LEN - out->avail_out;
 | 
			
		||||
#ifdef DEBUG_ZIP
 | 
			
		||||
	Log(LOG_DEBUG, "zipbuf_used: %d", zipbuf_used);
 | 
			
		||||
#endif
 | 
			
		||||
	if (!array_catb(&My_Connections[Idx].wbuf,
 | 
			
		||||
			(char *)zipbuf, (size_t) zipbuf_used))
 | 
			
		||||
			(char *)zipbuf, (size_t) zipbuf_used)) {
 | 
			
		||||
		Log (LOG_ALERT, "Compression error: can't copy data!?");
 | 
			
		||||
		Conn_Close(Idx, "Compression error!", NULL, false);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	My_Connections[Idx].bytes_out += zipbuf_used;
 | 
			
		||||
	My_Connections[Idx].zip.bytes_out += array_bytes(&My_Connections[Idx].zip.wbuf); 
 | 
			
		||||
@@ -178,10 +206,9 @@ Unzip_Buffer( CONN_ID Idx )
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	in = &My_Connections[Idx].zip.in;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	in->next_in = array_start(&My_Connections[Idx].zip.rbuf);
 | 
			
		||||
	if (!in->next_in)
 | 
			
		||||
		return false;
 | 
			
		||||
	assert(in->next_in != NULL);
 | 
			
		||||
 | 
			
		||||
	in->avail_in = z_rdatalen;
 | 
			
		||||
	in->next_out = unzipbuf;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2005 Alexander Barton <alex@barton.de>
 | 
			
		||||
 * Copyright (c)2001-2007 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
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: conn.c,v 1.198 2006/07/23 23:05:20 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: conn.c,v 1.220 2007/12/13 01:30:16 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -41,12 +41,6 @@ static char UNUSED id[] = "$Id: conn.c,v 1.198 2006/07/23 23:05:20 alex Exp $";
 | 
			
		||||
# include <netinet/ip.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_ARPA_INET_H
 | 
			
		||||
# include <arpa/inet.h>
 | 
			
		||||
#else
 | 
			
		||||
# define PF_INET AF_INET
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_STDINT_H
 | 
			
		||||
# include <stdint.h>			/* e.g. for Mac OS X */
 | 
			
		||||
#endif
 | 
			
		||||
@@ -83,6 +77,7 @@ static char UNUSED id[] = "$Id: conn.c,v 1.198 2006/07/23 23:05:20 alex Exp $";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool Handle_Write PARAMS(( CONN_ID Idx ));
 | 
			
		||||
static bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
 | 
			
		||||
static int New_Connection PARAMS(( int Sock ));
 | 
			
		||||
static CONN_ID Socket2Index PARAMS(( int Sock ));
 | 
			
		||||
static void Read_Request PARAMS(( CONN_ID Idx ));
 | 
			
		||||
@@ -91,7 +86,7 @@ static void Check_Connections PARAMS(( void ));
 | 
			
		||||
static void Check_Servers PARAMS(( void ));
 | 
			
		||||
static void Init_Conn_Struct PARAMS(( CONN_ID Idx ));
 | 
			
		||||
static bool Init_Socket PARAMS(( int Sock ));
 | 
			
		||||
static void New_Server PARAMS(( int Server ));
 | 
			
		||||
static void New_Server PARAMS(( int Server, struct in_addr *dest));
 | 
			
		||||
static void Simple_Message PARAMS(( int Sock, const char *Msg ));
 | 
			
		||||
static int Count_Connections PARAMS(( struct sockaddr_in addr ));
 | 
			
		||||
static int NewListener PARAMS(( const UINT16 Port ));
 | 
			
		||||
@@ -123,7 +118,6 @@ cb_connserver(int sock, UNUSED short what)
 | 
			
		||||
{
 | 
			
		||||
	int res, err;
 | 
			
		||||
	socklen_t sock_len;
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	CONN_ID idx = Socket2Index( sock );
 | 
			
		||||
	if (idx <= NONE) {
 | 
			
		||||
		LogDebug("cb_connserver wants to write on unknown socket?!");
 | 
			
		||||
@@ -150,14 +144,7 @@ cb_connserver(int sock, UNUSED short what)
 | 
			
		||||
 			    Conf_Server[Conf_GetServer(idx)].port,
 | 
			
		||||
 			    idx, strerror(err));
 | 
			
		||||
 | 
			
		||||
		/* Clean up the CLIENT structure (to avoid silly log
 | 
			
		||||
 		 * messages) and call Conn_Close() to do the rest. */
 | 
			
		||||
 		c = Conn_GetClient(idx);
 | 
			
		||||
 		if (c)
 | 
			
		||||
			Client_DestroyNow(c);
 | 
			
		||||
 
 | 
			
		||||
 		Conn_Close(idx, "Can't connect!", NULL, false);
 | 
			
		||||
 
 | 
			
		||||
		Conn_Close(idx, "Can't connect!", NULL, false);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -267,10 +254,10 @@ Conn_Exit( void )
 | 
			
		||||
} /* Conn_Exit */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
static unsigned int
 | 
			
		||||
ports_initlisteners(array *a, void (*func)(int,short))
 | 
			
		||||
{
 | 
			
		||||
	int created = 0;
 | 
			
		||||
	unsigned int created = 0;
 | 
			
		||||
	size_t len;
 | 
			
		||||
	int fd;
 | 
			
		||||
	UINT16 *port;
 | 
			
		||||
@@ -298,12 +285,12 @@ ports_initlisteners(array *a, void (*func)(int,short))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL int
 | 
			
		||||
GLOBAL unsigned int
 | 
			
		||||
Conn_InitListeners( void )
 | 
			
		||||
{
 | 
			
		||||
	/* Initialize ports on which the server should accept connections */
 | 
			
		||||
 | 
			
		||||
	int created;
 | 
			
		||||
	unsigned int created;
 | 
			
		||||
 | 
			
		||||
	if (!io_library_init(CONNECTION_POOL)) {
 | 
			
		||||
		Log(LOG_EMERG, "Cannot initialize IO routines: %s", strerror(errno));
 | 
			
		||||
@@ -340,6 +327,42 @@ Conn_ExitListeners( void )
 | 
			
		||||
} /* Conn_ExitListeners */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
InitSinaddr(struct sockaddr_in *addr, UINT16 Port)
 | 
			
		||||
{
 | 
			
		||||
	struct in_addr inaddr;
 | 
			
		||||
 | 
			
		||||
	memset(addr, 0, sizeof(*addr));
 | 
			
		||||
	memset( &inaddr, 0, sizeof(inaddr));
 | 
			
		||||
 | 
			
		||||
	addr->sin_family = AF_INET;
 | 
			
		||||
	addr->sin_port = htons(Port);
 | 
			
		||||
	inaddr.s_addr = htonl(INADDR_ANY);
 | 
			
		||||
	addr->sin_addr = inaddr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
InitSinaddrListenAddr(struct sockaddr_in *addr, UINT16 Port)
 | 
			
		||||
{
 | 
			
		||||
	struct in_addr inaddr;
 | 
			
		||||
 | 
			
		||||
	InitSinaddr(addr, Port);
 | 
			
		||||
 | 
			
		||||
	if (!Conf_ListenAddress[0])
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	if (!ngt_IPStrToBin(Conf_ListenAddress, &inaddr)) {
 | 
			
		||||
		Log( LOG_CRIT, "Can't bind to %s:%u: can't convert ip address \"%s\"",
 | 
			
		||||
				Conf_ListenAddress, Port, Conf_ListenAddress);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	addr->sin_addr = inaddr;
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* return new listening port file descriptor or -1 on failure */
 | 
			
		||||
static int
 | 
			
		||||
NewListener( const UINT16 Port )
 | 
			
		||||
@@ -347,33 +370,15 @@ NewListener( const UINT16 Port )
 | 
			
		||||
	/* Create new listening socket on specified port */
 | 
			
		||||
 | 
			
		||||
	struct sockaddr_in addr;
 | 
			
		||||
	struct in_addr inaddr;
 | 
			
		||||
	int sock;
 | 
			
		||||
#ifdef ZEROCONF
 | 
			
		||||
	char name[CLIENT_ID_LEN], *info;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Server-"Listen"-Socket initialisieren */
 | 
			
		||||
	memset( &addr, 0, sizeof( addr ));
 | 
			
		||||
	memset( &inaddr, 0, sizeof( inaddr ));
 | 
			
		||||
	addr.sin_family = (sa_family_t)AF_INET;
 | 
			
		||||
	InitSinaddrListenAddr(&addr, Port);
 | 
			
		||||
 | 
			
		||||
	addr.sin_family = AF_INET;
 | 
			
		||||
	addr.sin_port = htons( Port );
 | 
			
		||||
	if( Conf_ListenAddress[0] )
 | 
			
		||||
	{
 | 
			
		||||
#ifdef HAVE_INET_ATON
 | 
			
		||||
		if( inet_aton( Conf_ListenAddress, &inaddr ) == 0 )
 | 
			
		||||
#else
 | 
			
		||||
		inaddr.s_addr = inet_addr( Conf_ListenAddress );
 | 
			
		||||
		if( inaddr.s_addr == (unsigned)-1 )
 | 
			
		||||
#endif
 | 
			
		||||
		{
 | 
			
		||||
			Log( LOG_CRIT, "Can't listen on %s:%u: can't convert ip address %s!",
 | 
			
		||||
					Conf_ListenAddress, Port, Conf_ListenAddress );
 | 
			
		||||
			return -1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else inaddr.s_addr = htonl( INADDR_ANY );
 | 
			
		||||
	addr.sin_addr = inaddr;
 | 
			
		||||
 | 
			
		||||
	sock = socket( PF_INET, SOCK_STREAM, 0);
 | 
			
		||||
	if( sock < 0 ) {
 | 
			
		||||
@@ -384,7 +389,7 @@ NewListener( const UINT16 Port )
 | 
			
		||||
	if( ! Init_Socket( sock )) return -1;
 | 
			
		||||
 | 
			
		||||
	if (bind(sock, (struct sockaddr *)&addr, (socklen_t)sizeof(addr)) != 0) {
 | 
			
		||||
		Log( LOG_CRIT, "Can't bind socket: %s!", strerror( errno ));
 | 
			
		||||
		Log( LOG_CRIT, "Can't bind socket (port %d) : %s!", Port, strerror( errno ));
 | 
			
		||||
		close( sock );
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
@@ -615,51 +620,74 @@ va_dcl
 | 
			
		||||
} /* Conn_WriteStr */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
/**
 | 
			
		||||
 * Append Data to the outbound write buffer of a connection.
 | 
			
		||||
 * @param Idx Index of the connection.
 | 
			
		||||
 * @param Data pointer to the data.
 | 
			
		||||
 * @param Len length of Data.
 | 
			
		||||
 * @return true on success, false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
static bool
 | 
			
		||||
Conn_Write( CONN_ID Idx, char *Data, size_t Len )
 | 
			
		||||
{
 | 
			
		||||
	/* Daten in Socket schreiben. Bei "fatalen" Fehlern wird
 | 
			
		||||
	 * der Client disconnectiert und false geliefert. */
 | 
			
		||||
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	size_t writebuf_limit = WRITEBUFFER_LEN;
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	assert( Data != NULL );
 | 
			
		||||
	assert( Len > 0 );
 | 
			
		||||
 | 
			
		||||
	/* Ist der entsprechende Socket ueberhaupt noch offen? In einem
 | 
			
		||||
	 * "Handler-Durchlauf" kann es passieren, dass dem nicht mehr so
 | 
			
		||||
	 * ist, wenn einer von mehreren Conn_Write()'s fehlgeschlagen ist.
 | 
			
		||||
	 * In diesem Fall wird hier einfach ein Fehler geliefert. */
 | 
			
		||||
	c = Conn_GetClient(Idx);
 | 
			
		||||
	assert( c != NULL);
 | 
			
		||||
 | 
			
		||||
	/* Servers do get special write buffer limits, so they can generate
 | 
			
		||||
	 * all the messages that are required while peering. */
 | 
			
		||||
	if (Client_Type(c) == CLIENT_SERVER)
 | 
			
		||||
		writebuf_limit = WRITEBUFFER_SLINK_LEN;
 | 
			
		||||
 | 
			
		||||
	/* Is the socket still open? A previous call to Conn_Write()
 | 
			
		||||
	 * may have closed the connection due to a fatal error.
 | 
			
		||||
	 * In this case it is sufficient to return an error, as well. */
 | 
			
		||||
	if( My_Connections[Idx].sock <= NONE ) {
 | 
			
		||||
		LogDebug("Skipped write on closed socket (connection %d).", Idx );
 | 
			
		||||
		LogDebug("Skipped write on closed socket (connection %d).", Idx);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Pruefen, ob im Schreibpuffer genuegend Platz ist. Ziel ist es,
 | 
			
		||||
	 * moeglichts viel im Puffer zu haben und _nicht_ gleich alles auf den
 | 
			
		||||
	 * Socket zu schreiben (u.a. wg. Komprimierung). */
 | 
			
		||||
	if( array_bytes(&My_Connections[Idx].wbuf) >= WRITEBUFFER_LEN) {
 | 
			
		||||
		/* Der Puffer ist dummerweise voll. Jetzt versuchen, den Puffer
 | 
			
		||||
		 * zu schreiben, wenn das nicht klappt, haben wir ein Problem ... */
 | 
			
		||||
		if( ! Handle_Write( Idx )) return false;
 | 
			
		||||
 | 
			
		||||
		/* check again: if our writebuf is twice als large as the initial limit: Kill connection */
 | 
			
		||||
		if( array_bytes(&My_Connections[Idx].wbuf) >= (WRITEBUFFER_LEN*2)) {
 | 
			
		||||
			Log( LOG_NOTICE, "Write buffer overflow (connection %d)!", Idx );
 | 
			
		||||
			Conn_Close( Idx, "Write buffer overflow!", NULL, false );
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
	if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) {
 | 
			
		||||
		/* Daten komprimieren und in Puffer kopieren */
 | 
			
		||||
		if( ! Zip_Buffer( Idx, Data, Len )) return false;
 | 
			
		||||
		/* Compressed link:
 | 
			
		||||
		 * Zip_Buffer() does all the dirty work for us: it flushes
 | 
			
		||||
		 * the (pre-)compression buffers if required and handles
 | 
			
		||||
		 * all error conditions. */
 | 
			
		||||
		if (!Zip_Buffer(Idx, Data, Len))
 | 
			
		||||
			return false;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
#endif
 | 
			
		||||
	{
 | 
			
		||||
		/* Daten in Puffer kopieren */
 | 
			
		||||
		if (!array_catb( &My_Connections[Idx].wbuf, Data, Len ))
 | 
			
		||||
		/* Uncompressed link:
 | 
			
		||||
		 * Check if outbound buffer has enough space for the data. */
 | 
			
		||||
		if (array_bytes(&My_Connections[Idx].wbuf) + Len >=
 | 
			
		||||
		    writebuf_limit) {
 | 
			
		||||
			/* Buffer is full, flush it. Handle_Write deals with
 | 
			
		||||
			 * low-level errors, if any. */
 | 
			
		||||
			if (!Handle_Write(Idx))
 | 
			
		||||
				return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* When the write buffer is still too big after flushing it,
 | 
			
		||||
		 * the connection will be killed. */
 | 
			
		||||
		if (array_bytes(&My_Connections[Idx].wbuf) + Len >=
 | 
			
		||||
		    writebuf_limit) {
 | 
			
		||||
			Log(LOG_NOTICE,
 | 
			
		||||
			    "Write buffer overflow (connection %d, size %lu byte)!",
 | 
			
		||||
			    Idx,
 | 
			
		||||
			    (unsigned long)array_bytes(&My_Connections[Idx].wbuf));
 | 
			
		||||
			Conn_Close(Idx, "Write buffer overflow!", NULL, false);
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Copy data to write buffer */
 | 
			
		||||
		if (!array_catb(&My_Connections[Idx].wbuf, Data, Len))
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		My_Connections[Idx].bytes_out += Len;
 | 
			
		||||
@@ -700,7 +728,7 @@ Conn_Close( CONN_ID Idx, char *LogMsg, char *FwdMsg, bool InformClient )
 | 
			
		||||
 | 
			
		||||
	/* Mark link as "closing" */
 | 
			
		||||
	Conn_OPTION_ADD( &My_Connections[Idx], CONN_ISCLOSING );
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	if (LogMsg)
 | 
			
		||||
		txt = LogMsg;
 | 
			
		||||
	else
 | 
			
		||||
@@ -728,7 +756,6 @@ Conn_Close( CONN_ID Idx, char *LogMsg, char *FwdMsg, bool InformClient )
 | 
			
		||||
			 (double)My_Connections[Idx].bytes_out / 1024);
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		/* Send ERROR to client (see RFC!) */
 | 
			
		||||
		if (FwdMsg)
 | 
			
		||||
			Conn_WriteStr(Idx, "ERROR :%s", FwdMsg);
 | 
			
		||||
@@ -872,24 +899,23 @@ Handle_Write( CONN_ID Idx )
 | 
			
		||||
	wdatalen = array_bytes(&My_Connections[Idx].wbuf );
 | 
			
		||||
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
	if (wdatalen == 0 && !array_bytes(&My_Connections[Idx].zip.wbuf)) {
 | 
			
		||||
		io_event_del(My_Connections[Idx].sock, IO_WANTWRITE );
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* write buffer empty, but not compression buffer?
 | 
			
		||||
         * -> flush compression buffer! */
 | 
			
		||||
	if (wdatalen == 0)
 | 
			
		||||
		Zip_Flush(Idx);
 | 
			
		||||
#else
 | 
			
		||||
	if (wdatalen == 0) {
 | 
			
		||||
		io_event_del(My_Connections[Idx].sock, IO_WANTWRITE );
 | 
			
		||||
		return true;
 | 
			
		||||
		/* Write buffer is empty, so we try to flush the compression
 | 
			
		||||
		 * buffer and get some data to work with from there :-) */
 | 
			
		||||
		if (!Zip_Flush(Idx))
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		/* Now the write buffer most probably has changed: */
 | 
			
		||||
		wdatalen = array_bytes(&My_Connections[Idx].wbuf);
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Zip_Flush() may have changed the write buffer ... */
 | 
			
		||||
	wdatalen = array_bytes(&My_Connections[Idx].wbuf);
 | 
			
		||||
	if (wdatalen == 0) {
 | 
			
		||||
		/* Still no data, fine. */
 | 
			
		||||
		io_event_del(My_Connections[Idx].sock, IO_WANTWRITE );
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	LogDebug
 | 
			
		||||
	    ("Handle_Write() called for connection %d, %ld bytes pending ...",
 | 
			
		||||
	     Idx, wdatalen);
 | 
			
		||||
@@ -995,11 +1021,19 @@ New_Connection( int Sock )
 | 
			
		||||
			Init_Conn_Struct(Pool_Size++);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* register callback */
 | 
			
		||||
	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, inet_ntoa( new_addr.sin_addr ), CLIENT_UNKNOWN, false );
 | 
			
		||||
	if( ! c ) {
 | 
			
		||||
		Log( LOG_ALERT, "Can't accept connection: can't create client structure!" );
 | 
			
		||||
		Simple_Message( new_sock, "ERROR :Internal error" );
 | 
			
		||||
		close( new_sock );
 | 
			
		||||
		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;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1008,13 +1042,6 @@ New_Connection( int Sock )
 | 
			
		||||
	My_Connections[new_sock].addr = new_addr;
 | 
			
		||||
	My_Connections[new_sock].client = c;
 | 
			
		||||
 | 
			
		||||
	/* register callback */
 | 
			
		||||
	if (!io_event_create( new_sock, IO_WANTREAD, cb_clientserver)) {
 | 
			
		||||
		Simple_Message( new_sock, "ERROR :Internal error" );
 | 
			
		||||
		Conn_Close( new_sock, "io_event_create() failed", NULL, false );
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log( LOG_INFO, "Accepted connection %d from %s:%d on socket %d.", new_sock,
 | 
			
		||||
			inet_ntoa( new_addr.sin_addr ), ntohs( new_addr.sin_port), Sock );
 | 
			
		||||
 | 
			
		||||
@@ -1024,11 +1051,11 @@ New_Connection( int Sock )
 | 
			
		||||
 | 
			
		||||
	Client_SetHostname( c, My_Connections[new_sock].host );
 | 
			
		||||
 | 
			
		||||
	Resolve_Addr(&My_Connections[new_sock].res_stat, &new_addr,
 | 
			
		||||
		My_Connections[new_sock].sock, cb_Read_Resolver_Result);
 | 
			
		||||
	if (!Conf_NoDNS)
 | 
			
		||||
		Resolve_Addr(&My_Connections[new_sock].res_stat, &new_addr,
 | 
			
		||||
			My_Connections[new_sock].sock, cb_Read_Resolver_Result);
 | 
			
		||||
 | 
			
		||||
	/* Penalty-Zeit setzen */
 | 
			
		||||
	Conn_SetPenalty( new_sock, 4 );
 | 
			
		||||
	Conn_SetPenalty(new_sock, 4);
 | 
			
		||||
	return new_sock;
 | 
			
		||||
} /* New_Connection */
 | 
			
		||||
 | 
			
		||||
@@ -1050,47 +1077,52 @@ Socket2Index( int Sock )
 | 
			
		||||
} /* Socket2Index */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Read data from the network to the read buffer. If an error occures,
 | 
			
		||||
 * the socket of this connection will be shut down.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
Read_Request( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Daten von Socket einlesen und entsprechend behandeln.
 | 
			
		||||
	 * Tritt ein Fehler auf, so wird der Socket geschlossen. */
 | 
			
		||||
 | 
			
		||||
	ssize_t len;
 | 
			
		||||
	char readbuf[1024];
 | 
			
		||||
	char readbuf[READBUFFER_LEN];
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	assert( My_Connections[Idx].sock > NONE );
 | 
			
		||||
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
	if (( array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN ) ||
 | 
			
		||||
		( array_bytes(&My_Connections[Idx].zip.rbuf) >= ZREADBUFFER_LEN ))
 | 
			
		||||
	if ((array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN) ||
 | 
			
		||||
		(array_bytes(&My_Connections[Idx].zip.rbuf) >= READBUFFER_LEN))
 | 
			
		||||
#else
 | 
			
		||||
	if ( array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN )
 | 
			
		||||
	if (array_bytes(&My_Connections[Idx].rbuf) >= READBUFFER_LEN)
 | 
			
		||||
#endif
 | 
			
		||||
	{
 | 
			
		||||
		/* Der Lesepuffer ist voll */
 | 
			
		||||
		Log( LOG_ERR, "Receive buffer overflow (connection %d): %d bytes!", Idx,
 | 
			
		||||
						array_bytes(&My_Connections[Idx].rbuf));
 | 
			
		||||
		/* Read buffer is full */
 | 
			
		||||
		Log(LOG_ERR,
 | 
			
		||||
		    "Receive buffer overflow (connection %d): %d bytes!",
 | 
			
		||||
		    Idx, array_bytes(&My_Connections[Idx].rbuf));
 | 
			
		||||
		Conn_Close( Idx, "Receive buffer overflow!", NULL, false );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	len = read( My_Connections[Idx].sock, readbuf, sizeof readbuf -1 );
 | 
			
		||||
	if( len == 0 ) {
 | 
			
		||||
		Log( LOG_INFO, "%s:%d (%s) is closing the connection ...",
 | 
			
		||||
			My_Connections[Idx].host, ntohs( My_Connections[Idx].addr.sin_port),
 | 
			
		||||
					inet_ntoa( My_Connections[Idx].addr.sin_addr ));
 | 
			
		||||
		Conn_Close( Idx, "Socket closed!", "Client closed connection", false );
 | 
			
		||||
	len = read(My_Connections[Idx].sock, readbuf, sizeof(readbuf));
 | 
			
		||||
	if (len == 0) {
 | 
			
		||||
		Log(LOG_INFO, "%s:%d (%s) is closing the connection ...",
 | 
			
		||||
		    My_Connections[Idx].host,
 | 
			
		||||
		    ntohs(My_Connections[Idx].addr.sin_port),
 | 
			
		||||
		    inet_ntoa( My_Connections[Idx].addr.sin_addr));
 | 
			
		||||
		Conn_Close(Idx,
 | 
			
		||||
			   "Socket closed!", "Client closed connection",
 | 
			
		||||
			   false);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( len < 0 ) {
 | 
			
		||||
	if (len < 0) {
 | 
			
		||||
		if( errno == EAGAIN ) return;
 | 
			
		||||
		Log( LOG_ERR, "Read error on connection %d (socket %d): %s!", Idx,
 | 
			
		||||
					My_Connections[Idx].sock, strerror( errno ));
 | 
			
		||||
		Conn_Close( Idx, "Read error!", "Client closed connection", false );
 | 
			
		||||
		Log(LOG_ERR, "Read error on connection %d (socket %d): %s!",
 | 
			
		||||
		    Idx, My_Connections[Idx].sock, strerror(errno));
 | 
			
		||||
		Conn_Close(Idx, "Read error!", "Client closed connection",
 | 
			
		||||
			   false);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
@@ -1107,8 +1139,7 @@ Read_Request( CONN_ID Idx )
 | 
			
		||||
	} else
 | 
			
		||||
#endif
 | 
			
		||||
	{
 | 
			
		||||
		readbuf[len] = 0;
 | 
			
		||||
		if (!array_cats( &My_Connections[Idx].rbuf, readbuf )) {
 | 
			
		||||
		if (!array_catb( &My_Connections[Idx].rbuf, readbuf, len)) {
 | 
			
		||||
			Log( LOG_ERR, "Could not append recieved data to input buffer (connn %d): %d bytes!", Idx, len );
 | 
			
		||||
			Conn_Close( Idx, "Receive buffer overflow!", NULL, false );
 | 
			
		||||
		}
 | 
			
		||||
@@ -1227,11 +1258,6 @@ Handle_Buffer( CONN_ID Idx )
 | 
			
		||||
			/* The last Command activated Socket-Compression.
 | 
			
		||||
			 * Data that was read after that needs to be copied to Unzip-buf
 | 
			
		||||
			 * for decompression */
 | 
			
		||||
			if( array_bytes(&My_Connections[Idx].rbuf)> ZREADBUFFER_LEN ) {
 | 
			
		||||
				Log( LOG_ALERT, "Connection %d: No space left in unzip buf (need %u bytes)!",
 | 
			
		||||
								Idx, array_bytes(&My_Connections[Idx].rbuf ));
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
			if (!array_copy( &My_Connections[Idx].zip.rbuf, &My_Connections[Idx].rbuf ))
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
@@ -1319,7 +1345,7 @@ Check_Servers( void )
 | 
			
		||||
		if( Conf_Server[i].group > NONE ) {
 | 
			
		||||
			for (n = 0; n < MAX_SERVERS; n++) {
 | 
			
		||||
				if (n == i) continue;
 | 
			
		||||
				if ((Conf_Server[n].conn_id > NONE) &&
 | 
			
		||||
				if ((Conf_Server[n].conn_id != NONE) &&
 | 
			
		||||
					(Conf_Server[n].group == Conf_Server[i].group))
 | 
			
		||||
						break;
 | 
			
		||||
			}
 | 
			
		||||
@@ -1333,6 +1359,7 @@ Check_Servers( void )
 | 
			
		||||
 | 
			
		||||
		/* 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);
 | 
			
		||||
	}
 | 
			
		||||
@@ -1340,36 +1367,19 @@ Check_Servers( void )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
New_Server( int Server )
 | 
			
		||||
New_Server( int Server , struct in_addr *dest)
 | 
			
		||||
{
 | 
			
		||||
	/* Establish new server link */
 | 
			
		||||
 | 
			
		||||
	struct sockaddr_in local_addr;
 | 
			
		||||
	struct sockaddr_in new_addr;
 | 
			
		||||
	struct in_addr inaddr;
 | 
			
		||||
	int res, new_sock;
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
 | 
			
		||||
	assert( Server > NONE );
 | 
			
		||||
 | 
			
		||||
	Log( LOG_INFO, "Establishing connection to \"%s\", %s, port %d ... ", Conf_Server[Server].host,
 | 
			
		||||
							Conf_Server[Server].ip, Conf_Server[Server].port );
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_INET_ATON
 | 
			
		||||
	if( inet_aton( Conf_Server[Server].ip, &inaddr ) == 0 )
 | 
			
		||||
#else
 | 
			
		||||
	memset( &inaddr, 0, sizeof( inaddr ));
 | 
			
		||||
	inaddr.s_addr = inet_addr( Conf_Server[Server].ip );
 | 
			
		||||
	if( inaddr.s_addr == (unsigned)-1 )
 | 
			
		||||
#endif
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_ERR, "Can't connect to \"%s\": can't convert ip address %s!",
 | 
			
		||||
				Conf_Server[Server].host, Conf_Server[Server].ip );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	memset( &new_addr, 0, sizeof( new_addr ));
 | 
			
		||||
	new_addr.sin_family = (sa_family_t)AF_INET;
 | 
			
		||||
	new_addr.sin_addr = inaddr;
 | 
			
		||||
	memset(&new_addr, 0, sizeof( new_addr ));
 | 
			
		||||
	new_addr.sin_family = AF_INET;
 | 
			
		||||
	new_addr.sin_addr = *dest;
 | 
			
		||||
	new_addr.sin_port = htons( Conf_Server[Server].port );
 | 
			
		||||
 | 
			
		||||
	new_sock = socket( PF_INET, SOCK_STREAM, 0 );
 | 
			
		||||
@@ -1380,6 +1390,12 @@ New_Server( int Server )
 | 
			
		||||
 | 
			
		||||
	if( ! Init_Socket( new_sock )) return;
 | 
			
		||||
 | 
			
		||||
	/* if we fail to bind, just continue and let connect() pick a source address */
 | 
			
		||||
	InitSinaddr(&local_addr, 0);
 | 
			
		||||
	local_addr.sin_addr = Conf_Server[Server].bind_addr;
 | 
			
		||||
	if (bind(new_sock, (struct sockaddr *)&local_addr, (socklen_t)sizeof(local_addr)))
 | 
			
		||||
		Log(LOG_WARNING, "Can't bind socket to %s: %s!", inet_ntoa(Conf_Server[Server].bind_addr), strerror( errno ));
 | 
			
		||||
 | 
			
		||||
	res = connect(new_sock, (struct sockaddr *)&new_addr,
 | 
			
		||||
			(socklen_t)sizeof(new_addr));
 | 
			
		||||
	if(( res != 0 ) && ( errno != EINPROGRESS )) {
 | 
			
		||||
@@ -1387,7 +1403,7 @@ New_Server( int Server )
 | 
			
		||||
		close( new_sock );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	if (!array_alloc(&My_ConnArray, sizeof(CONNECTION), (size_t)new_sock)) {
 | 
			
		||||
		Log(LOG_ALERT,
 | 
			
		||||
		    "Cannot allocate memory for server connection (socket %d)",
 | 
			
		||||
@@ -1434,14 +1450,17 @@ New_Server( int Server )
 | 
			
		||||
} /* New_Server */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialize connection structure.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
Init_Conn_Struct( CONN_ID Idx )
 | 
			
		||||
Init_Conn_Struct(CONN_ID Idx)
 | 
			
		||||
{
 | 
			
		||||
	time_t now = time( NULL );
 | 
			
		||||
	/* Connection-Struktur initialisieren */
 | 
			
		||||
	time_t now = time(NULL);
 | 
			
		||||
 | 
			
		||||
	memset( &My_Connections[Idx], 0, sizeof ( CONNECTION ));
 | 
			
		||||
	memset(&My_Connections[Idx], 0, sizeof(CONNECTION));
 | 
			
		||||
	My_Connections[Idx].sock = -1;
 | 
			
		||||
	My_Connections[Idx].signon = now;
 | 
			
		||||
	My_Connections[Idx].lastdata = now;
 | 
			
		||||
	My_Connections[Idx].lastprivmsg = now;
 | 
			
		||||
	Resolve_Init(&My_Connections[Idx].res_stat);
 | 
			
		||||
@@ -1491,6 +1510,7 @@ cb_Connect_to_Server(int fd, UNUSED short events)
 | 
			
		||||
	/* Read result of resolver sub-process from pipe and start connection */
 | 
			
		||||
	int i;
 | 
			
		||||
	size_t len;
 | 
			
		||||
	struct in_addr dest_addr;
 | 
			
		||||
	char readbuf[HOST_LEN + 1];
 | 
			
		||||
 | 
			
		||||
	LogDebug("Resolver: Got forward lookup callback on fd %d, events %d", fd, events);
 | 
			
		||||
@@ -1499,7 +1519,7 @@ cb_Connect_to_Server(int fd, UNUSED short events)
 | 
			
		||||
		  if (Resolve_Getfd(&Conf_Server[i].res_stat) == fd )
 | 
			
		||||
			  break;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	if( i >= MAX_SERVERS) {
 | 
			
		||||
		/* Ops, no matching server found?! */
 | 
			
		||||
		io_close( fd );
 | 
			
		||||
@@ -1508,16 +1528,23 @@ cb_Connect_to_Server(int fd, UNUSED short events)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Read result from pipe */
 | 
			
		||||
	len = Resolve_Read(&Conf_Server[i].res_stat, readbuf, sizeof readbuf -1);
 | 
			
		||||
	len = Resolve_Read(&Conf_Server[i].res_stat, readbuf, sizeof(readbuf)-1);
 | 
			
		||||
	if (len == 0)
 | 
			
		||||
		return;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	readbuf[len] = '\0';
 | 
			
		||||
	LogDebug("Got result from resolver: \"%s\" (%u bytes read).", readbuf, len);
 | 
			
		||||
	strlcpy( Conf_Server[i].ip, readbuf, sizeof( Conf_Server[i].ip ));
 | 
			
		||||
 | 
			
		||||
	if (!ngt_IPStrToBin(readbuf, &dest_addr)) {
 | 
			
		||||
		Log(LOG_ERR, "Can't connect to \"%s\": can't convert ip address %s!",
 | 
			
		||||
						Conf_Server[i].host, readbuf);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log( LOG_INFO, "Establishing connection to \"%s\", %s, port %d ... ",
 | 
			
		||||
			Conf_Server[i].host, readbuf, Conf_Server[i].port );
 | 
			
		||||
	/* connect() */
 | 
			
		||||
	New_Server(i);
 | 
			
		||||
	New_Server(i, &dest_addr);
 | 
			
		||||
} /* cb_Read_Forward_Lookup */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1584,10 +1611,10 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
		++identptr;
 | 
			
		||||
		if (*identptr) {
 | 
			
		||||
			Log( LOG_INFO, "IDENT lookup for connection %ld: \"%s\".", i, identptr);
 | 
			
		||||
			Client_SetUser( c, identptr, true );
 | 
			
		||||
			Log(LOG_INFO, "IDENT lookup for connection %d: \"%s\".", i, identptr);
 | 
			
		||||
			Client_SetUser(c, identptr, true);
 | 
			
		||||
		} else {
 | 
			
		||||
			Log( LOG_INFO, "IDENT lookup for connection %ld: no result.", i );
 | 
			
		||||
			Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
@@ -1639,9 +1666,9 @@ Conn_GetClient( CONN_ID Idx )
 | 
			
		||||
	assert( Idx >= 0 );
 | 
			
		||||
 | 
			
		||||
	c = array_get(&My_ConnArray, sizeof (CONNECTION), (size_t)Idx);
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	assert(c != NULL);
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	return c ? c->client : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: conn.h,v 1.42 2006/05/10 21:24:01 alex Exp $
 | 
			
		||||
 * $Id: conn.h,v 1.45 2007/10/04 15:03:56 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Connection management (header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -59,6 +59,7 @@ typedef struct _Connection
 | 
			
		||||
	char host[HOST_LEN];		/* Hostname */
 | 
			
		||||
	array rbuf;			/* Read buffer */
 | 
			
		||||
	array wbuf;			/* Write buffer */
 | 
			
		||||
	time_t signon;			/* Signon ("connect") time */
 | 
			
		||||
	time_t lastdata;		/* Last activity */
 | 
			
		||||
	time_t lastping;		/* Last PING */
 | 
			
		||||
	time_t lastprivmsg;		/* Last PRIVMSG */
 | 
			
		||||
@@ -83,12 +84,11 @@ GLOBAL long WCounter;
 | 
			
		||||
GLOBAL void Conn_Init PARAMS((void ));
 | 
			
		||||
GLOBAL void Conn_Exit PARAMS(( void ));
 | 
			
		||||
 | 
			
		||||
GLOBAL int Conn_InitListeners PARAMS(( void ));
 | 
			
		||||
GLOBAL unsigned int Conn_InitListeners PARAMS(( void ));
 | 
			
		||||
GLOBAL void Conn_ExitListeners PARAMS(( void ));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Conn_Handler PARAMS(( void ));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Conn_Write PARAMS(( CONN_ID Idx, char *Data, size_t Len ));
 | 
			
		||||
GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, char *Format, ... ));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, char *LogMsg, char *FwdMsg, bool InformClient ));
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2005 Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2007 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,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: defines.h,v 1.58 2006/06/15 20:28:15 alex Exp $
 | 
			
		||||
 * $Id: defines.h,v 1.62 2007/11/21 12:16:36 alex Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -47,14 +47,15 @@
 | 
			
		||||
 | 
			
		||||
#define CLIENT_ID_LEN 64		/* Max. length of an IRC ID; see RFC
 | 
			
		||||
					   RFC 2812 section 1.1 and 1.2.1 */
 | 
			
		||||
#define CLIENT_NICK_LEN 10		/* Max. nick length, see. RFC 2812
 | 
			
		||||
					   section 1.2.1 */
 | 
			
		||||
#define CLIENT_NICK_LEN_DEFAULT 10	/* Default nick length, see. RFC 2812
 | 
			
		||||
					 * section 1.2.1 */
 | 
			
		||||
#define CLIENT_NICK_LEN 32		/* Maximum nick name length */
 | 
			
		||||
#define CLIENT_PASS_LEN 21		/* Max. password length */
 | 
			
		||||
#define CLIENT_USER_LEN 10		/* Max. length of user name ("login")
 | 
			
		||||
					   see RFC 2812, section 1.2.1 */
 | 
			
		||||
#define CLIENT_NAME_LEN 32		/* Max. length of "real names" */
 | 
			
		||||
#define CLIENT_HOST_LEN 64		/* Max. host name length */
 | 
			
		||||
#define CLIENT_MODE_LEN 8		/* Max. lenth of all client modes */
 | 
			
		||||
#define CLIENT_MODE_LEN 9		/* Max. lenth of all client modes */
 | 
			
		||||
#define CLIENT_INFO_LEN 64		/* Max. length of server info texts */
 | 
			
		||||
#define CLIENT_AWAY_LEN 128		/* Max. length of away messages */
 | 
			
		||||
#define CLIENT_FLAGS_LEN 100		/* Max. length of client flags */
 | 
			
		||||
@@ -70,13 +71,8 @@
 | 
			
		||||
					   connection in bytes. */
 | 
			
		||||
#define WRITEBUFFER_LEN 4096		/* Size of the write buffer of a
 | 
			
		||||
					   connection in bytes. */
 | 
			
		||||
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
#define ZREADBUFFER_LEN 1024		/* Size of the compressed read buffer
 | 
			
		||||
					   of a connection in bytes. */
 | 
			
		||||
#define ZWRITEBUFFER_LEN 4096		/* Size of the compressed write buffer
 | 
			
		||||
					   of a connection in bytes. */
 | 
			
		||||
#endif
 | 
			
		||||
#define WRITEBUFFER_SLINK_LEN 51200	/* Size of the write buffer of a
 | 
			
		||||
					   server link connection in bytes. */
 | 
			
		||||
 | 
			
		||||
#define PROTOVER "0210"			/* Implemented IRC protocol version,
 | 
			
		||||
					   see RFC 2813 section 4.1.1. */
 | 
			
		||||
@@ -86,7 +82,7 @@
 | 
			
		||||
					   protocol, see doc/Protocol.txt */
 | 
			
		||||
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
# define IRCPLUSFLAGS "CL"		/* Standard IRC+ flags */
 | 
			
		||||
# define IRCPLUSFLAGS "CHL"		/* Standard IRC+ flags */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define STARTUP_DELAY 1			/* Delay outgoing connections n seconds
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: hash.c,v 1.12 2005/07/31 20:13:08 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: hash.c,v 1.13 2006/10/06 21:23:47 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -31,7 +31,7 @@ static UINT32 jenkins_hash PARAMS(( register UINT8 *k, register UINT32 length, r
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL UINT32
 | 
			
		||||
Hash( char *String )
 | 
			
		||||
Hash( const char *String )
 | 
			
		||||
{
 | 
			
		||||
	/* Hash-Wert ueber String berechnen */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: hash.h,v 1.5 2005/03/19 18:43:48 fw Exp $
 | 
			
		||||
 * $Id: hash.h,v 1.6 2006/10/06 21:23:47 fw Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Hash calculation (header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -17,8 +17,7 @@
 | 
			
		||||
#ifndef __hash_h__
 | 
			
		||||
#define __hash_h__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL UINT32 Hash PARAMS((char *String ));
 | 
			
		||||
GLOBAL UINT32 Hash PARAMS((const char *String ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										550
									
								
								src/ngircd/io.c
									
									
									
									
									
								
							
							
						
						
									
										550
									
								
								src/ngircd/io.c
									
									
									
									
									
								
							@@ -12,7 +12,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: io.c,v 1.16 2006/07/23 23:11:44 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: io.c,v 1.28.2.1 2008/04/03 14:16:35 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
@@ -30,29 +30,48 @@ static char UNUSED id[] = "$Id: io.c,v 1.16 2006/07/23 23:11:44 alex Exp $";
 | 
			
		||||
/* #define DEBUG_IO */
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
 void (*callback)(int, short);
 | 
			
		||||
#else
 | 
			
		||||
 void (*callback)();
 | 
			
		||||
#endif
 | 
			
		||||
 short what;
 | 
			
		||||
} io_event;
 | 
			
		||||
 | 
			
		||||
#define INIT_IOEVENT    { NULL, -1, 0, NULL }
 | 
			
		||||
#define IO_ERROR        4
 | 
			
		||||
#define INIT_IOEVENT		{ NULL, -1, 0, NULL }
 | 
			
		||||
#define IO_ERROR		4
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_EPOLL_CREATE
 | 
			
		||||
#define IO_USE_EPOLL    1
 | 
			
		||||
#  define IO_USE_EPOLL		1
 | 
			
		||||
#  ifdef HAVE_SELECT
 | 
			
		||||
#    define IO_USE_SELECT	1
 | 
			
		||||
#  endif
 | 
			
		||||
#else
 | 
			
		||||
# ifdef HAVE_KQUEUE
 | 
			
		||||
#define IO_USE_KQUEUE   1
 | 
			
		||||
# else
 | 
			
		||||
#define IO_USE_SELECT   1
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
#  ifdef HAVE_KQUEUE
 | 
			
		||||
#    define IO_USE_KQUEUE	1
 | 
			
		||||
#  else
 | 
			
		||||
#    ifdef HAVE_SYS_DEVPOLL_H
 | 
			
		||||
#      define IO_USE_DEVPOLL	1
 | 
			
		||||
#    else
 | 
			
		||||
#      ifdef HAVE_POLL
 | 
			
		||||
#        define IO_USE_POLL	1
 | 
			
		||||
#      else
 | 
			
		||||
#        ifdef HAVE_SELECT
 | 
			
		||||
#          define IO_USE_SELECT	1
 | 
			
		||||
#        else
 | 
			
		||||
#          error "no IO API available!?"
 | 
			
		||||
#        endif /* HAVE_SELECT */
 | 
			
		||||
#      endif /* HAVE_POLL */
 | 
			
		||||
#    endif /* HAVE_SYS_DEVPOLL_H */
 | 
			
		||||
#  endif /* HAVE_KQUEUE */
 | 
			
		||||
#endif /* HAVE_EPOLL_CREATE */
 | 
			
		||||
 | 
			
		||||
static bool library_initialized;
 | 
			
		||||
static bool library_initialized = false;
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_EPOLL
 | 
			
		||||
#include <sys/epoll.h>
 | 
			
		||||
 | 
			
		||||
static int io_masterfd;
 | 
			
		||||
static int io_masterfd = -1;
 | 
			
		||||
static bool io_event_change_epoll(int fd, short what, const int action);
 | 
			
		||||
static int io_dispatch_epoll(struct timeval *tv);
 | 
			
		||||
#endif
 | 
			
		||||
@@ -67,6 +86,22 @@ static int io_dispatch_kqueue(struct timeval *tv);
 | 
			
		||||
static bool io_event_change_kqueue(int, short, const int action);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_POLL
 | 
			
		||||
#include <poll.h>
 | 
			
		||||
 | 
			
		||||
static array pollfds;
 | 
			
		||||
static int poll_maxfd;
 | 
			
		||||
 | 
			
		||||
static bool io_event_change_poll PARAMS((int fd, short what));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_DEVPOLL
 | 
			
		||||
#include <sys/devpoll.h>
 | 
			
		||||
static int io_masterfd;
 | 
			
		||||
 | 
			
		||||
static bool io_event_change_devpoll(int fd, short what);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_SELECT
 | 
			
		||||
#include "defines.h"	/* for conn.h */
 | 
			
		||||
#include "conn.h"	/* for CONN_IDX (needed by resolve.h) */
 | 
			
		||||
@@ -77,7 +112,11 @@ static fd_set readers;
 | 
			
		||||
static fd_set writers;
 | 
			
		||||
static int select_maxfd;		/* the select() interface sucks badly */
 | 
			
		||||
static int io_dispatch_select(struct timeval *tv);
 | 
			
		||||
 | 
			
		||||
#ifndef IO_USE_EPOLL
 | 
			
		||||
#define io_masterfd -1
 | 
			
		||||
#endif
 | 
			
		||||
#endif /* IO_USE_SELECT */
 | 
			
		||||
 | 
			
		||||
static array io_events;
 | 
			
		||||
 | 
			
		||||
@@ -98,40 +137,45 @@ io_event_get(int fd)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
io_library_init(unsigned int eventsize)
 | 
			
		||||
#ifdef IO_USE_DEVPOLL
 | 
			
		||||
static void
 | 
			
		||||
io_library_init_devpoll(unsigned int eventsize)
 | 
			
		||||
{
 | 
			
		||||
#if defined(IO_USE_EPOLL) || defined(IO_USE_KQUEUE)
 | 
			
		||||
	bool ret;
 | 
			
		||||
	io_masterfd = open("/dev/poll", O_RDWR);
 | 
			
		||||
	if (io_masterfd >= 0)
 | 
			
		||||
		library_initialized = true;
 | 
			
		||||
	Log(LOG_INFO, "IO subsystem: /dev/poll (initial maxfd %u, masterfd %d).",
 | 
			
		||||
		eventsize, io_masterfd);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_EPOLL
 | 
			
		||||
	int ecreate_hint = (int)eventsize;
 | 
			
		||||
	if (ecreate_hint <= 0)
 | 
			
		||||
		ecreate_hint = 128;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_POLL
 | 
			
		||||
static void
 | 
			
		||||
io_library_init_poll(unsigned int eventsize)
 | 
			
		||||
{
 | 
			
		||||
	struct pollfd *p;
 | 
			
		||||
	array_init(&pollfds);
 | 
			
		||||
	poll_maxfd = 0;
 | 
			
		||||
	Log(LOG_INFO, "IO subsystem: poll (initial maxfd %u).",
 | 
			
		||||
	    eventsize);
 | 
			
		||||
	p = array_alloc(&pollfds, sizeof(struct pollfd), eventsize);
 | 
			
		||||
	if (p) {
 | 
			
		||||
		unsigned i;
 | 
			
		||||
		p = array_start(&pollfds);
 | 
			
		||||
		for (i = 0; i < eventsize; i++)
 | 
			
		||||
			p[i].fd = -1;
 | 
			
		||||
 | 
			
		||||
		library_initialized = true;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
	if (library_initialized)
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_SELECT
 | 
			
		||||
#ifdef FD_SETSIZE
 | 
			
		||||
	if (eventsize >= FD_SETSIZE)
 | 
			
		||||
		eventsize = FD_SETSIZE - 1;
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
	if ((eventsize > 0) && !array_alloc(&io_events, sizeof(io_event), (size_t)eventsize))
 | 
			
		||||
		eventsize = 0;
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_EPOLL
 | 
			
		||||
	io_masterfd = epoll_create(ecreate_hint);
 | 
			
		||||
	Log(LOG_INFO,
 | 
			
		||||
	    "IO subsystem: epoll (hint size %d, initial maxfd %u, masterfd %d).",
 | 
			
		||||
	    ecreate_hint, eventsize, io_masterfd);
 | 
			
		||||
	ret = io_masterfd >= 0;
 | 
			
		||||
	if (ret) library_initialized = true;
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_SELECT
 | 
			
		||||
static void
 | 
			
		||||
io_library_init_select(unsigned int eventsize)
 | 
			
		||||
{
 | 
			
		||||
	Log(LOG_INFO, "IO subsystem: select (initial maxfd %u).",
 | 
			
		||||
	    eventsize);
 | 
			
		||||
	FD_ZERO(&readers);
 | 
			
		||||
@@ -144,24 +188,82 @@ io_library_init(unsigned int eventsize)
 | 
			
		||||
 | 
			
		||||
		Conf_MaxConnections = FD_SETSIZE - 1;
 | 
			
		||||
	}
 | 
			
		||||
#else
 | 
			
		||||
	Log(LOG_WARNING,
 | 
			
		||||
	    "FD_SETSIZE undefined, don't know how many descriptors select() can handle on your platform ...");
 | 
			
		||||
#endif /* FD_SETSIZE */
 | 
			
		||||
	library_initialized = true;
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
#endif /* SELECT */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_EPOLL
 | 
			
		||||
static void
 | 
			
		||||
io_library_init_epoll(unsigned int eventsize)
 | 
			
		||||
{
 | 
			
		||||
	int ecreate_hint = (int)eventsize;
 | 
			
		||||
	if (ecreate_hint <= 0)
 | 
			
		||||
		ecreate_hint = 128;
 | 
			
		||||
	io_masterfd = epoll_create(ecreate_hint);
 | 
			
		||||
	if (io_masterfd >= 0) {
 | 
			
		||||
		library_initialized = true;
 | 
			
		||||
		Log(LOG_INFO,
 | 
			
		||||
		    "IO subsystem: epoll (hint size %d, initial maxfd %u, masterfd %d).",
 | 
			
		||||
		    ecreate_hint, eventsize, io_masterfd);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_KQUEUE
 | 
			
		||||
static void
 | 
			
		||||
io_library_init_kqueue(unsigned int eventsize)
 | 
			
		||||
{
 | 
			
		||||
	io_masterfd = kqueue();
 | 
			
		||||
 | 
			
		||||
	Log(LOG_INFO,
 | 
			
		||||
	    "IO subsystem: kqueue (initial maxfd %u, masterfd %d)",
 | 
			
		||||
	    eventsize, io_masterfd);
 | 
			
		||||
	ret = io_masterfd >= 0;
 | 
			
		||||
	if (ret) library_initialized = true;
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
	if (io_masterfd >= 0)
 | 
			
		||||
		library_initialized = true;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
io_library_init(unsigned int eventsize)
 | 
			
		||||
{
 | 
			
		||||
	if (library_initialized)
 | 
			
		||||
		return true;
 | 
			
		||||
#ifdef IO_USE_SELECT
 | 
			
		||||
#ifndef FD_SETSIZE
 | 
			
		||||
	Log(LOG_WARNING,
 | 
			
		||||
	    "FD_SETSIZE undefined, don't know how many descriptors select() can handle on your platform ...");
 | 
			
		||||
#else
 | 
			
		||||
	if (eventsize >= FD_SETSIZE)
 | 
			
		||||
		eventsize = FD_SETSIZE - 1;
 | 
			
		||||
#endif /* FD_SETSIZE */
 | 
			
		||||
#endif /* IO_USE_SELECT */
 | 
			
		||||
	if ((eventsize > 0) && !array_alloc(&io_events, sizeof(io_event), (size_t)eventsize))
 | 
			
		||||
		eventsize = 0;
 | 
			
		||||
#ifdef IO_USE_EPOLL
 | 
			
		||||
	io_library_init_epoll(eventsize);
 | 
			
		||||
#ifdef IO_USE_SELECT
 | 
			
		||||
	if (io_masterfd < 0)
 | 
			
		||||
		Log(LOG_INFO, "Can't initialize epoll() IO interface, falling back to select() ...");
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_KQUEUE
 | 
			
		||||
	io_library_init_kqueue(eventsize);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_DEVPOLL
 | 
			
		||||
	io_library_init_devpoll(eventsize);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_POLL
 | 
			
		||||
	io_library_init_poll(eventsize);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_SELECT
 | 
			
		||||
	if (! library_initialized)
 | 
			
		||||
		io_library_init_select(eventsize);
 | 
			
		||||
#endif
 | 
			
		||||
	return library_initialized;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -171,11 +273,15 @@ io_library_shutdown(void)
 | 
			
		||||
#ifdef IO_USE_SELECT
 | 
			
		||||
	FD_ZERO(&readers);
 | 
			
		||||
	FD_ZERO(&writers);
 | 
			
		||||
#else
 | 
			
		||||
	close(io_masterfd);	/* kqueue, epoll */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_EPOLL
 | 
			
		||||
	if (io_masterfd >= 0)
 | 
			
		||||
		close(io_masterfd);
 | 
			
		||||
	io_masterfd = -1;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_KQUEUE
 | 
			
		||||
	close(io_masterfd);
 | 
			
		||||
	io_masterfd = -1;
 | 
			
		||||
	array_free(&io_evcache);
 | 
			
		||||
#endif
 | 
			
		||||
	library_initialized = false;
 | 
			
		||||
@@ -201,18 +307,14 @@ io_event_create(int fd, short what, void (*cbfunc) (int, short))
 | 
			
		||||
	io_event *i;
 | 
			
		||||
 | 
			
		||||
	assert(fd >= 0);
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_SELECT
 | 
			
		||||
#ifdef FD_SETSIZE
 | 
			
		||||
	if (fd >= FD_SETSIZE) {
 | 
			
		||||
#if defined(IO_USE_SELECT) && defined(FD_SETSIZE)
 | 
			
		||||
	if (io_masterfd < 0 && fd >= FD_SETSIZE) {
 | 
			
		||||
		Log(LOG_ERR,
 | 
			
		||||
		    "fd %d exceeds FD_SETSIZE (%u) (select can't handle more file descriptors)",
 | 
			
		||||
		    fd, FD_SETSIZE);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
#endif				/* FD_SETSIZE */
 | 
			
		||||
#endif				/* IO_USE_SELECT */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
	i = (io_event *) array_alloc(&io_events, sizeof(io_event), (size_t) fd);
 | 
			
		||||
	if (!i) {
 | 
			
		||||
		Log(LOG_WARNING,
 | 
			
		||||
@@ -223,6 +325,12 @@ io_event_create(int fd, short what, void (*cbfunc) (int, short))
 | 
			
		||||
 | 
			
		||||
	i->callback = cbfunc;
 | 
			
		||||
	i->what = 0;
 | 
			
		||||
#ifdef IO_USE_DEVPOLL
 | 
			
		||||
	ret = io_event_change_devpoll(fd, what);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_POLL
 | 
			
		||||
	ret = io_event_change_poll(fd, what);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_EPOLL
 | 
			
		||||
	ret = io_event_change_epoll(fd, what, EPOLL_CTL_ADD);
 | 
			
		||||
#endif
 | 
			
		||||
@@ -230,13 +338,57 @@ io_event_create(int fd, short what, void (*cbfunc) (int, short))
 | 
			
		||||
	ret = io_event_change_kqueue(fd, what, EV_ADD|EV_ENABLE);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_SELECT
 | 
			
		||||
	ret = io_event_add(fd, what);
 | 
			
		||||
	if (io_masterfd < 0)
 | 
			
		||||
		ret = io_event_add(fd, what);
 | 
			
		||||
#endif
 | 
			
		||||
	if (ret) i->what = what;
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_DEVPOLL
 | 
			
		||||
static bool
 | 
			
		||||
io_event_change_devpoll(int fd, short what)
 | 
			
		||||
{
 | 
			
		||||
	struct pollfd p;
 | 
			
		||||
 | 
			
		||||
	p.events = 0;
 | 
			
		||||
 | 
			
		||||
	if (what & IO_WANTREAD)
 | 
			
		||||
		p.events = POLLIN | POLLPRI;
 | 
			
		||||
	if (what & IO_WANTWRITE)
 | 
			
		||||
		p.events |= POLLOUT;
 | 
			
		||||
 | 
			
		||||
	p.fd = fd;
 | 
			
		||||
	return write(io_masterfd, &p, sizeof p) == (ssize_t)sizeof p;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_POLL
 | 
			
		||||
static bool
 | 
			
		||||
io_event_change_poll(int fd, short what)
 | 
			
		||||
{
 | 
			
		||||
	struct pollfd *p;
 | 
			
		||||
	short events = 0;
 | 
			
		||||
 | 
			
		||||
	if (what & IO_WANTREAD)
 | 
			
		||||
		events = POLLIN | POLLPRI;
 | 
			
		||||
	if (what & IO_WANTWRITE)
 | 
			
		||||
		events |= POLLOUT;
 | 
			
		||||
 | 
			
		||||
	p = array_alloc(&pollfds, sizeof *p, fd);
 | 
			
		||||
	if (p) {
 | 
			
		||||
		p->events = events;
 | 
			
		||||
		p->fd = fd;
 | 
			
		||||
		if (fd > poll_maxfd)
 | 
			
		||||
			poll_maxfd = fd;
 | 
			
		||||
	}
 | 
			
		||||
	return p != NULL;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_EPOLL
 | 
			
		||||
static bool
 | 
			
		||||
io_event_change_epoll(int fd, short what, const int action)
 | 
			
		||||
@@ -260,7 +412,7 @@ io_event_kqueue_commit_cache(void)
 | 
			
		||||
	struct kevent *events;
 | 
			
		||||
	bool ret;
 | 
			
		||||
	int len = (int) array_length(&io_evcache, sizeof (struct kevent));
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
	if (!len) /* nothing to do */
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
@@ -293,7 +445,7 @@ io_event_change_kqueue(int fd, short what, const int action)
 | 
			
		||||
		ret = array_catb(&io_evcache, (char*) &kev, sizeof (kev));
 | 
			
		||||
		if (!ret)
 | 
			
		||||
			ret = kevent(io_masterfd, &kev,1, NULL, 0, NULL) == 0;
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ret && (what & IO_WANTWRITE)) {
 | 
			
		||||
		EV_SET(&kev, fd, EVFILT_WRITE, action, 0, 0, 0);
 | 
			
		||||
@@ -315,19 +467,27 @@ io_event_add(int fd, short what)
 | 
			
		||||
	io_event *i = io_event_get(fd);
 | 
			
		||||
 | 
			
		||||
	if (!i) return false;
 | 
			
		||||
	if (i->what == what) return true;
 | 
			
		||||
 | 
			
		||||
	if ((i->what & what) == what) /* event type is already registered */
 | 
			
		||||
		return true;
 | 
			
		||||
#ifdef DEBUG_IO
 | 
			
		||||
	Log(LOG_DEBUG, "io_event_add(): fd %d (arg: %d), what %d.", i->fd, fd, what);
 | 
			
		||||
	Log(LOG_DEBUG, "io_event_add(): fd %d, what %d.", fd, what);
 | 
			
		||||
#endif
 | 
			
		||||
	i->what |= what;
 | 
			
		||||
#ifdef IO_USE_EPOLL
 | 
			
		||||
	return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD);
 | 
			
		||||
	if (io_masterfd >= 0)
 | 
			
		||||
		return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_KQUEUE
 | 
			
		||||
	return io_event_change_kqueue(fd, what, EV_ADD | EV_ENABLE);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_DEVPOLL
 | 
			
		||||
	return io_event_change_devpoll(fd, i->what);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_POLL
 | 
			
		||||
	return io_event_change_poll(fd, i->what);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_SELECT
 | 
			
		||||
	if (fd > select_maxfd)
 | 
			
		||||
		select_maxfd = fd;
 | 
			
		||||
@@ -358,22 +518,85 @@ io_setnonblock(int fd)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_DEVPOLL
 | 
			
		||||
static void
 | 
			
		||||
io_close_devpoll(int fd)
 | 
			
		||||
{
 | 
			
		||||
	struct pollfd p;
 | 
			
		||||
	p.events = POLLREMOVE;
 | 
			
		||||
	p.fd = fd;
 | 
			
		||||
	write(io_masterfd, &p, sizeof p);
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
static inline void
 | 
			
		||||
io_close_devpoll(int UNUSED x)
 | 
			
		||||
{ 
 | 
			
		||||
	/* NOTHING */
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_POLL
 | 
			
		||||
static void
 | 
			
		||||
io_close_poll(int fd)
 | 
			
		||||
{
 | 
			
		||||
	struct pollfd *p;
 | 
			
		||||
	p = array_get(&pollfds, sizeof *p, fd);
 | 
			
		||||
	if (!p) return;
 | 
			
		||||
 | 
			
		||||
	p->fd = -1;
 | 
			
		||||
	if (fd == poll_maxfd) {
 | 
			
		||||
		while (poll_maxfd > 0) {
 | 
			
		||||
			--poll_maxfd;
 | 
			
		||||
			p = array_get(&pollfds, sizeof *p, poll_maxfd);
 | 
			
		||||
			if (p && p->fd >= 0)
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
static inline void io_close_poll(int UNUSED x) { /* NOTHING */ }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_SELECT
 | 
			
		||||
static void
 | 
			
		||||
io_close_select(int fd)
 | 
			
		||||
{
 | 
			
		||||
	io_event *i;
 | 
			
		||||
 | 
			
		||||
	if (io_masterfd >= 0)	/* Are we using epoll()? */
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	FD_CLR(fd, &writers);
 | 
			
		||||
	FD_CLR(fd, &readers);
 | 
			
		||||
 | 
			
		||||
	i = io_event_get(fd);
 | 
			
		||||
	if (!i) return;
 | 
			
		||||
 | 
			
		||||
	if (fd == select_maxfd) {
 | 
			
		||||
		while (select_maxfd>0) {
 | 
			
		||||
			--select_maxfd; /* find largest fd */
 | 
			
		||||
			i = io_event_get(select_maxfd);
 | 
			
		||||
			if (i && i->callback) break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
static inline void
 | 
			
		||||
io_close_select(int UNUSED x)
 | 
			
		||||
{ 
 | 
			
		||||
	/* NOTHING */
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
io_close(int fd)
 | 
			
		||||
{
 | 
			
		||||
	io_event *i;
 | 
			
		||||
#ifdef IO_USE_SELECT
 | 
			
		||||
	FD_CLR(fd, &writers);
 | 
			
		||||
	FD_CLR(fd, &readers);
 | 
			
		||||
 | 
			
		||||
	if (fd == select_maxfd) {
 | 
			
		||||
		while (select_maxfd>0) {
 | 
			
		||||
			--select_maxfd; /* find largest fd */  
 | 
			
		||||
			i = io_event_get(select_maxfd);
 | 
			
		||||
			if (i && i->callback) break;
 | 
			
		||||
		}	
 | 
			
		||||
	}	
 | 
			
		||||
#endif
 | 
			
		||||
	i = io_event_get(fd);
 | 
			
		||||
#ifdef IO_USE_KQUEUE
 | 
			
		||||
	if (array_length(&io_evcache, sizeof (struct kevent)))	/* pending data in cache? */
 | 
			
		||||
@@ -385,8 +608,13 @@ io_close(int fd)
 | 
			
		||||
	if (i) {
 | 
			
		||||
		io_event_change_kqueue(fd, i->what, EV_DELETE);
 | 
			
		||||
		io_event_kqueue_commit_cache();
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	io_close_devpoll(fd);
 | 
			
		||||
	io_close_poll(fd);
 | 
			
		||||
	io_close_select(fd);
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_EPOLL
 | 
			
		||||
	io_event_change_epoll(fd, 0, EPOLL_CTL_DEL);
 | 
			
		||||
#endif
 | 
			
		||||
@@ -407,10 +635,20 @@ io_event_del(int fd, short what)
 | 
			
		||||
#endif
 | 
			
		||||
	if (!i) return false;
 | 
			
		||||
 | 
			
		||||
	if (!(i->what & what)) /* event is already disabled */
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	i->what &= ~what;
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_DEVPOLL
 | 
			
		||||
	return io_event_change_devpoll(fd, i->what);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_POLL
 | 
			
		||||
	return io_event_change_poll(fd, i->what);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_EPOLL
 | 
			
		||||
	return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD);
 | 
			
		||||
	if (io_masterfd >= 0)
 | 
			
		||||
		return io_event_change_epoll(fd, i->what, EPOLL_CTL_MOD);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_KQUEUE
 | 
			
		||||
@@ -465,6 +703,92 @@ io_dispatch_select(struct timeval *tv)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_DEVPOLL
 | 
			
		||||
static int
 | 
			
		||||
io_dispatch_devpoll(struct timeval *tv)
 | 
			
		||||
{
 | 
			
		||||
	struct dvpoll dvp;
 | 
			
		||||
	time_t sec = tv->tv_sec * 1000;
 | 
			
		||||
	int i, total, ret, timeout = tv->tv_usec + sec;
 | 
			
		||||
	short what;
 | 
			
		||||
	struct pollfd p[100];
 | 
			
		||||
 | 
			
		||||
	if (timeout < 0)
 | 
			
		||||
		timeout = 1000;
 | 
			
		||||
 | 
			
		||||
	total = 0;
 | 
			
		||||
	do {
 | 
			
		||||
		dvp.dp_timeout = timeout;
 | 
			
		||||
		dvp.dp_nfds = 100;
 | 
			
		||||
		dvp.dp_fds = p;
 | 
			
		||||
		ret = ioctl(io_masterfd, DP_POLL, &dvp);
 | 
			
		||||
		total += ret;
 | 
			
		||||
		if (ret <= 0)
 | 
			
		||||
			return total;
 | 
			
		||||
		for (i=0; i < ret ; i++) {
 | 
			
		||||
			what = 0;
 | 
			
		||||
			if (p[i].revents & (POLLIN|POLLPRI))
 | 
			
		||||
				what = IO_WANTREAD;
 | 
			
		||||
 | 
			
		||||
			if (p[i].revents & POLLOUT)
 | 
			
		||||
				what |= IO_WANTWRITE;
 | 
			
		||||
 | 
			
		||||
			if (p[i].revents && !what) {
 | 
			
		||||
				/* other flag is set, probably POLLERR */
 | 
			
		||||
				what = IO_ERROR;
 | 
			
		||||
			}
 | 
			
		||||
			io_docallback(p[i].fd, what);
 | 
			
		||||
		}
 | 
			
		||||
	} while (ret == 100);
 | 
			
		||||
 | 
			
		||||
	return total;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_POLL
 | 
			
		||||
static int
 | 
			
		||||
io_dispatch_poll(struct timeval *tv)
 | 
			
		||||
{
 | 
			
		||||
	time_t sec = tv->tv_sec * 1000;
 | 
			
		||||
	int i, ret, timeout = tv->tv_usec + sec;
 | 
			
		||||
	int fds_ready;
 | 
			
		||||
	short what;
 | 
			
		||||
	struct pollfd *p = array_start(&pollfds);
 | 
			
		||||
 | 
			
		||||
	if (timeout < 0)
 | 
			
		||||
		timeout = 1000;
 | 
			
		||||
 | 
			
		||||
	ret = poll(p, poll_maxfd + 1, timeout);
 | 
			
		||||
	if (ret <= 0)
 | 
			
		||||
		return ret;
 | 
			
		||||
 | 
			
		||||
	fds_ready = ret;
 | 
			
		||||
	for (i=0; i <= poll_maxfd; i++) {
 | 
			
		||||
		what = 0;
 | 
			
		||||
		if (p[i].revents & (POLLIN|POLLPRI))
 | 
			
		||||
			what = IO_WANTREAD;
 | 
			
		||||
 | 
			
		||||
		if (p[i].revents & POLLOUT)
 | 
			
		||||
			what |= IO_WANTWRITE;
 | 
			
		||||
 | 
			
		||||
		if (p[i].revents && !what) {
 | 
			
		||||
			/* other flag is set, probably POLLERR */
 | 
			
		||||
			what = IO_ERROR;
 | 
			
		||||
		}
 | 
			
		||||
		if (what) {
 | 
			
		||||
			fds_ready--;
 | 
			
		||||
			io_docallback(i, what);
 | 
			
		||||
		}
 | 
			
		||||
		if (fds_ready <= 0)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_EPOLL
 | 
			
		||||
static int
 | 
			
		||||
io_dispatch_epoll(struct timeval *tv)
 | 
			
		||||
@@ -516,20 +840,14 @@ io_dispatch_kqueue(struct timeval *tv)
 | 
			
		||||
	int newevents_len;
 | 
			
		||||
	ts.tv_sec = tv->tv_sec;
 | 
			
		||||
	ts.tv_nsec = tv->tv_usec * 1000;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		newevents_len = (int) array_length(&io_evcache, sizeof (struct kevent));
 | 
			
		||||
		newevents = (newevents_len > 0) ? array_start(&io_evcache) : NULL;
 | 
			
		||||
		assert(newevents_len >= 0);
 | 
			
		||||
		if (newevents_len < 0)
 | 
			
		||||
			newevents_len = 0;
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
		if (newevents_len)
 | 
			
		||||
			assert(newevents != NULL);
 | 
			
		||||
#endif
 | 
			
		||||
		ret = kevent(io_masterfd, newevents, newevents_len, kev,
 | 
			
		||||
			     100, &ts);
 | 
			
		||||
		if ((newevents_len>0) && ret != -1)
 | 
			
		||||
 | 
			
		||||
		ret = kevent(io_masterfd, newevents, newevents_len, kev, 100, &ts);
 | 
			
		||||
		if (newevents && ret != -1)
 | 
			
		||||
			array_trunc(&io_evcache);
 | 
			
		||||
 | 
			
		||||
		total += ret;
 | 
			
		||||
@@ -537,30 +855,31 @@ io_dispatch_kqueue(struct timeval *tv)
 | 
			
		||||
			return total;
 | 
			
		||||
 | 
			
		||||
		for (i = 0; i < ret; i++) {
 | 
			
		||||
			if (kev[i].flags & EV_EOF) {
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
				LogDebug("kev.flag has EV_EOF set, setting IO_ERROR",
 | 
			
		||||
					kev[i].filter, kev[i].ident);
 | 
			
		||||
#endif				
 | 
			
		||||
#ifdef DEBUG_IO
 | 
			
		||||
			LogDebug("fd %d, kev.flags: %x", (int)kev[i].ident, kev[i].flags);
 | 
			
		||||
#endif
 | 
			
		||||
			if (kev[i].flags & (EV_EOF|EV_ERROR)) {
 | 
			
		||||
				if (kev[i].flags & EV_ERROR)
 | 
			
		||||
					Log(LOG_ERR, "kevent fd %d: EV_ERROR (%s)",
 | 
			
		||||
						(int)kev[i].ident, strerror((int)kev[i].data));
 | 
			
		||||
				io_docallback((int)kev[i].ident, IO_ERROR);
 | 
			
		||||
				continue;
 | 
			
		||||
			}	
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			switch (kev[i].filter) {
 | 
			
		||||
				case EVFILT_READ:
 | 
			
		||||
					io_docallback((int)kev[i].ident, IO_WANTREAD);
 | 
			
		||||
					break;
 | 
			
		||||
				case EVFILT_WRITE:
 | 
			
		||||
					io_docallback((int)kev[i].ident, IO_WANTWRITE);
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
					LogDebug("Unknown kev.filter number %d for fd %d",
 | 
			
		||||
						kev[i].filter, kev[i].ident); /* Fall through */
 | 
			
		||||
#endif
 | 
			
		||||
				case EV_ERROR:
 | 
			
		||||
					io_docallback((int)kev[i].ident, IO_ERROR);
 | 
			
		||||
					break;
 | 
			
		||||
			case EVFILT_READ:
 | 
			
		||||
				io_docallback((int)kev[i].ident, IO_WANTREAD);
 | 
			
		||||
				break;
 | 
			
		||||
			case EVFILT_WRITE:
 | 
			
		||||
				io_docallback((int)kev[i].ident, IO_WANTWRITE);
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				LogDebug("Unknown kev.filter number %d for fd %d",
 | 
			
		||||
					kev[i].filter, kev[i].ident);
 | 
			
		||||
				/* Fall through */
 | 
			
		||||
			case EV_ERROR:
 | 
			
		||||
				io_docallback((int)kev[i].ident, IO_ERROR);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		ts.tv_sec = 0;
 | 
			
		||||
@@ -575,14 +894,21 @@ io_dispatch_kqueue(struct timeval *tv)
 | 
			
		||||
int
 | 
			
		||||
io_dispatch(struct timeval *tv)
 | 
			
		||||
{
 | 
			
		||||
#ifdef IO_USE_EPOLL
 | 
			
		||||
	if (io_masterfd >= 0)
 | 
			
		||||
		return io_dispatch_epoll(tv);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_SELECT
 | 
			
		||||
	return io_dispatch_select(tv);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_KQUEUE
 | 
			
		||||
	return io_dispatch_kqueue(tv);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_EPOLL
 | 
			
		||||
	return io_dispatch_epoll(tv);
 | 
			
		||||
#ifdef IO_USE_DEVPOLL
 | 
			
		||||
	return io_dispatch_devpoll(tv);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IO_USE_POLL
 | 
			
		||||
	return io_dispatch_poll(tv);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -597,9 +923,9 @@ io_docallback(int fd, short what)
 | 
			
		||||
#endif
 | 
			
		||||
	i = io_event_get(fd);
 | 
			
		||||
 | 
			
		||||
	if (i->callback) {	/* callback might be NULL if a previous callback function 
 | 
			
		||||
	if (i->callback) {	/* callback might be NULL if a previous callback function
 | 
			
		||||
				   called io_close on this fd */
 | 
			
		||||
		i->callback(fd, (what & IO_ERROR) ? i->what : what);
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
	/* if error indicator is set, we return the event(s) that were registered */
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,10 +7,10 @@
 | 
			
		||||
 *
 | 
			
		||||
 * I/O abstraction interface header
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: io.h,v 1.3 2005/07/14 09:15:58 alex Exp $
 | 
			
		||||
 * $Id: io.h,v 1.4 2006/12/25 22:53:52 alex Exp $
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef io_H_inclucded
 | 
			
		||||
#ifndef io_H_included
 | 
			
		||||
#define io_H_included
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-channel.c,v 1.35 2006/03/16 20:14:16 fw Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-channel.c,v 1.40.2.2 2008/02/26 12:07:41 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -52,7 +52,9 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Bad number of arguments? */
 | 
			
		||||
	if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
	if (Req->argc < 1 || Req->argc > 2)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
	/* Who is the sender? */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
 | 
			
		||||
@@ -77,22 +79,27 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	{
 | 
			
		||||
		chan = NULL; flags = NULL;
 | 
			
		||||
 | 
			
		||||
		/* wird der Channel neu angelegt? */
 | 
			
		||||
		if( Channel_Search( channame )) is_new_chan = false;
 | 
			
		||||
		else is_new_chan = true;
 | 
			
		||||
 | 
			
		||||
		/* Hat ein Server Channel-User-Modes uebergeben? */
 | 
			
		||||
		if( Client_Type( Client ) == CLIENT_SERVER )
 | 
			
		||||
		{
 | 
			
		||||
			/* Channel-Flags extrahieren */
 | 
			
		||||
		if (Client_Type(Client) == CLIENT_SERVER) {
 | 
			
		||||
			flags = strchr( channame, 0x7 );
 | 
			
		||||
			if( flags )
 | 
			
		||||
			{
 | 
			
		||||
			if( flags ) {
 | 
			
		||||
				*flags = '\0';
 | 
			
		||||
				flags++;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* wird der Channel neu angelegt? */
 | 
			
		||||
		if( Channel_Search( channame )) {
 | 
			
		||||
			is_new_chan = false;
 | 
			
		||||
		} else {
 | 
			
		||||
			if (Conf_PredefChannelsOnly) { /* this server does not allow creation of channels */
 | 
			
		||||
				IRC_WriteStrClient( Client, ERR_BANNEDFROMCHAN_MSG, Client_ID( Client ), channame );
 | 
			
		||||
				/* Try next name, if any */
 | 
			
		||||
				channame = strchr(channame, ',');
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			is_new_chan = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Local client? */
 | 
			
		||||
		if( Client_Type( Client ) == CLIENT_USER )
 | 
			
		||||
		{
 | 
			
		||||
@@ -113,8 +120,8 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
				chan = Channel_Search( channame );
 | 
			
		||||
				assert( chan != NULL );
 | 
			
		||||
 | 
			
		||||
				is_banned = Lists_CheckBanned( target, chan );
 | 
			
		||||
				is_invited = Lists_CheckInvited( target, chan );
 | 
			
		||||
				is_banned = Lists_Check(Channel_GetListBans(chan), target );
 | 
			
		||||
				is_invited = Lists_Check(Channel_GetListInvites(chan), target );
 | 
			
		||||
 | 
			
		||||
				/* Testen, ob Client gebanned ist */
 | 
			
		||||
				if(( is_banned == true) &&  ( is_invited == false ))
 | 
			
		||||
@@ -123,7 +130,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
					IRC_WriteStrClient( Client, ERR_BANNEDFROMCHAN_MSG, Client_ID( Client ), channame );
 | 
			
		||||
 | 
			
		||||
					/* Try next name, if any */
 | 
			
		||||
					channame = strtok( NULL, "," );
 | 
			
		||||
					channame = strchr(channame, ',');
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
@@ -134,7 +141,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
					IRC_WriteStrClient( Client, ERR_INVITEONLYCHAN_MSG, Client_ID( Client ), channame );
 | 
			
		||||
 | 
			
		||||
					/* Try next name, if any */
 | 
			
		||||
					channame = strtok( NULL, "," );
 | 
			
		||||
					channame = strchr(channame, ',');
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
@@ -145,7 +152,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
					IRC_WriteStrClient( Client, ERR_BADCHANNELKEY_MSG, Client_ID( Client ), channame );
 | 
			
		||||
 | 
			
		||||
					/* Try next name, if any */
 | 
			
		||||
					channame = strtok( NULL, "," );
 | 
			
		||||
					channame = strchr(channame, ',');
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
@@ -156,7 +163,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
					IRC_WriteStrClient( Client, ERR_CHANNELISFULL_MSG, Client_ID( Client ), channame );
 | 
			
		||||
 | 
			
		||||
					/* Try next name, if any */
 | 
			
		||||
					channame = strtok( NULL, "," );
 | 
			
		||||
					channame = strchr(channame, ',');
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
@@ -169,14 +176,14 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
			 * commands) in this list become deleted when a user
 | 
			
		||||
			 * joins a channel this way. */
 | 
			
		||||
			chan = Channel_Search( channame );
 | 
			
		||||
			if( chan != NULL ) (void)Lists_CheckInvited( target, chan );
 | 
			
		||||
			if( chan != NULL ) (void)Lists_Check(Channel_GetListInvites(chan), target);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Channel joinen (und ggf. anlegen) */
 | 
			
		||||
		if( ! Channel_Join( target, channame ))
 | 
			
		||||
		{
 | 
			
		||||
			/* naechsten Namen ermitteln */
 | 
			
		||||
			channame = strtok( NULL, "," );
 | 
			
		||||
			channame = strchr(channame, ',');
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		if( ! chan ) chan = Channel_Search( channame );
 | 
			
		||||
@@ -258,8 +265,9 @@ IRC_PART( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
	if (Req->argc < 1 || Req->argc > 2)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
	/* Wer ist der Absender? */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
 | 
			
		||||
@@ -267,18 +275,11 @@ IRC_PART( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	/* Channel-Namen durchgehen */
 | 
			
		||||
	chan = strtok( Req->argv[0], "," );
 | 
			
		||||
	while( chan )
 | 
			
		||||
	{
 | 
			
		||||
		if( ! Channel_Part( target, Client, chan, Req->argc > 1 ? Req->argv[1] : Client_ID( target )))
 | 
			
		||||
		{
 | 
			
		||||
			/* naechsten Namen ermitteln */
 | 
			
		||||
			chan = strtok( NULL, "," );
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
	chan = strtok(Req->argv[0], ",");
 | 
			
		||||
	while (chan) {
 | 
			
		||||
		Channel_Part(target, Client, chan, Req->argc > 1 ? Req->argv[1] : Client_ID(target));
 | 
			
		||||
 | 
			
		||||
		/* naechsten Namen ermitteln */
 | 
			
		||||
		chan = strtok( NULL, "," );
 | 
			
		||||
		chan = strtok(NULL, ",");
 | 
			
		||||
	}
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_PART */
 | 
			
		||||
@@ -491,7 +492,7 @@ IRC_CHANINFO( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
			{
 | 
			
		||||
				if( *ptr == 'l' )
 | 
			
		||||
				{
 | 
			
		||||
					snprintf( l, sizeof( l ), " %ld", Channel_MaxUsers( chan ));
 | 
			
		||||
					snprintf( l, sizeof( l ), " %lu", Channel_MaxUsers( chan ));
 | 
			
		||||
					strlcat( modes_add, l, sizeof( modes_add ));
 | 
			
		||||
				}
 | 
			
		||||
				if( *ptr == 'k' )
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-info.c,v 1.33 2006/05/10 21:24:01 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-info.c,v 1.41.2.1 2008/02/26 12:06:57 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -335,6 +335,41 @@ IRC_NAMES( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
} /* IRC_NAMES */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static unsigned int
 | 
			
		||||
t_diff(time_t *t, const time_t div)
 | 
			
		||||
{
 | 
			
		||||
	time_t diff, remain;
 | 
			
		||||
 | 
			
		||||
	diff = *t / div;
 | 
			
		||||
 | 
			
		||||
	remain = diff * div;
 | 
			
		||||
	*t -= remain;
 | 
			
		||||
 | 
			
		||||
	return diff;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static unsigned int
 | 
			
		||||
uptime_days(time_t *now)
 | 
			
		||||
{
 | 
			
		||||
	return t_diff(now, 60 * 60 * 24);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static unsigned int
 | 
			
		||||
uptime_hrs(time_t *now)
 | 
			
		||||
{
 | 
			
		||||
	return t_diff(now, 60 * 60);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static unsigned int
 | 
			
		||||
uptime_mins(time_t *now)
 | 
			
		||||
{
 | 
			
		||||
	 return t_diff(now, 60);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_STATS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
@@ -342,75 +377,94 @@ IRC_STATS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	CONN_ID con;
 | 
			
		||||
	char query;
 | 
			
		||||
	COMMAND *cmd;
 | 
			
		||||
	time_t time_now;
 | 
			
		||||
	unsigned int days, hrs, mins;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
	if (Req->argc > 2)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
	/* From aus Prefix ermitteln */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
	if (Client_Type(Client) == CLIENT_SERVER)
 | 
			
		||||
		from = Client_Search(Req->prefix);
 | 
			
		||||
	else
 | 
			
		||||
		from = Client;
 | 
			
		||||
 | 
			
		||||
	if( Req->argc == 2 )
 | 
			
		||||
	{
 | 
			
		||||
	if (! from)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix);
 | 
			
		||||
 | 
			
		||||
	if (Req->argc == 2) {
 | 
			
		||||
		/* an anderen Server forwarden */
 | 
			
		||||
		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_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()) {
 | 
			
		||||
			/* Ok, anderer Server ist das Ziel: forwarden */
 | 
			
		||||
			return IRC_WriteStrClientPrefix( target, from, "STATS %s %s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( Req->argc > 0 ) query = Req->argv[0][0] ? Req->argv[0][0] : '*';
 | 
			
		||||
	else query = '*';
 | 
			
		||||
	if (Req->argc > 0)
 | 
			
		||||
		query = Req->argv[0][0] ? Req->argv[0][0] : '*';
 | 
			
		||||
	else
 | 
			
		||||
		query = '*';
 | 
			
		||||
 | 
			
		||||
	switch ( query )
 | 
			
		||||
	{
 | 
			
		||||
	switch (query) {
 | 
			
		||||
		case 'l':	/* Links */
 | 
			
		||||
		case 'L':
 | 
			
		||||
			con = Conn_First( );
 | 
			
		||||
			while( con != NONE )
 | 
			
		||||
			{
 | 
			
		||||
				cl = Conn_GetClient( con );
 | 
			
		||||
				if( cl && (( Client_Type( cl ) == CLIENT_SERVER ) || ( cl == Client )))
 | 
			
		||||
				{
 | 
			
		||||
			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( NULL ) - Conn_StartTime( con )))) return DISCONNECTED;
 | 
			
		||||
					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;
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
#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( NULL ) - Conn_StartTime( con )))) return DISCONNECTED;
 | 
			
		||||
					}
 | 
			
		||||
					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;
 | 
			
		||||
				}
 | 
			
		||||
				con = Conn_Next( con );
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case 'm':	/* IRC-Befehle */
 | 
			
		||||
		case 'm':	/* IRC-Commands */
 | 
			
		||||
		case 'M':
 | 
			
		||||
			cmd = Parse_GetCommandStruct( );
 | 
			
		||||
			while( cmd->name )
 | 
			
		||||
			{
 | 
			
		||||
				if( cmd->lcount > 0 || cmd->rcount > 0 )
 | 
			
		||||
				{
 | 
			
		||||
					if( ! IRC_WriteStrClient( from, RPL_STATSCOMMANDS_MSG, Client_ID( from ), cmd->name, cmd->lcount, cmd->bytes, cmd->rcount )) return DISCONNECTED;
 | 
			
		||||
				}
 | 
			
		||||
				cmd++;
 | 
			
		||||
			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 );
 | 
			
		||||
	IRC_SetPenalty(from, 2);
 | 
			
		||||
	return IRC_WriteStrClient(from, RPL_ENDOFSTATS_MSG, Client_ID(from), query);
 | 
			
		||||
} /* IRC_STATS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -542,7 +596,8 @@ GLOBAL bool
 | 
			
		||||
IRC_WHO( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	bool ok, only_ops;
 | 
			
		||||
	char flags[8], *ptr;
 | 
			
		||||
	char flags[8];
 | 
			
		||||
	const char *ptr;
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	CHANNEL *chan, *cn;
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
@@ -593,7 +648,11 @@ IRC_WHO( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
			if( ok && (( ! only_ops ) || ( strchr( Client_Modes( c ), 'o' ))))
 | 
			
		||||
			{
 | 
			
		||||
				/* Get flags */
 | 
			
		||||
				strcpy( flags, "H" );
 | 
			
		||||
				if (strchr(Client_Modes( c ), 'a'))
 | 
			
		||||
					strcpy(flags, "G"); /* away */
 | 
			
		||||
				else
 | 
			
		||||
					strcpy(flags, "H");
 | 
			
		||||
 | 
			
		||||
				if( strchr( Client_Modes( c ), 'o' )) strlcat( flags, "*", sizeof( flags ));
 | 
			
		||||
 | 
			
		||||
				/* Search suitable channel */
 | 
			
		||||
@@ -706,10 +765,13 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		if( ! IRC_WriteStrClient( from, RPL_WHOISOPERATOR_MSG, Client_ID( from ), Client_ID( c ))) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Idle (only local clients) */
 | 
			
		||||
	if( Client_Conn( c ) > NONE )
 | 
			
		||||
	{
 | 
			
		||||
		if( ! IRC_WriteStrClient( from, RPL_WHOISIDLE_MSG, Client_ID( from ), Client_ID( c ), Conn_GetIdle( Client_Conn ( c )))) return DISCONNECTED;
 | 
			
		||||
	/* Idle and signon time (local clients only!) */
 | 
			
		||||
	if (Client_Conn(c) > NONE ) {
 | 
			
		||||
		if (! IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG,
 | 
			
		||||
			Client_ID(from), Client_ID(c),
 | 
			
		||||
			(unsigned long)Conn_GetIdle(Client_Conn(c)),
 | 
			
		||||
			(unsigned long)Conn_GetSignon(Client_Conn(c))))
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Away? */
 | 
			
		||||
@@ -832,7 +894,10 @@ IRC_WHOWAS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_Send_LUSERS( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	long cnt;
 | 
			
		||||
	unsigned long cnt;
 | 
			
		||||
#ifndef STRICT_RFC
 | 
			
		||||
	unsigned long max;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
@@ -861,27 +926,38 @@ IRC_Send_LUSERS( CLIENT *Client )
 | 
			
		||||
 | 
			
		||||
#ifndef STRICT_RFC
 | 
			
		||||
	/* Maximum number of local users */
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_LOCALUSERS_MSG, Client_ID( Client ), Client_MyUserCount( ), Client_MyMaxUserCount( ))) return DISCONNECTED;
 | 
			
		||||
	cnt = Client_MyUserCount();
 | 
			
		||||
	max = Client_MyMaxUserCount();
 | 
			
		||||
	if (! IRC_WriteStrClient(Client, RPL_LOCALUSERS_MSG, Client_ID(Client),
 | 
			
		||||
			cnt, max, cnt, max))
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
	/* Maximum number of users in the network */
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_NETUSERS_MSG, Client_ID( Client ), Client_UserCount( ), Client_MaxUserCount( ))) return DISCONNECTED;
 | 
			
		||||
	cnt = Client_UserCount();
 | 
			
		||||
	max = Client_MaxUserCount();
 | 
			
		||||
	if(! IRC_WriteStrClient(Client, RPL_NETUSERS_MSG, Client_ID(Client),
 | 
			
		||||
			cnt, max, cnt, max))
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
#endif
 | 
			
		||||
	
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_Send_LUSERS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool Show_MOTD_Start(CLIENT *Client)
 | 
			
		||||
static bool
 | 
			
		||||
Show_MOTD_Start(CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	return IRC_WriteStrClient(Client, RPL_MOTDSTART_MSG,
 | 
			
		||||
		Client_ID( Client ), Client_ID( Client_ThisServer( )));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool Show_MOTD_Sendline(CLIENT *Client, const char *msg)
 | 
			
		||||
static bool
 | 
			
		||||
Show_MOTD_Sendline(CLIENT *Client, const char *msg)
 | 
			
		||||
{
 | 
			
		||||
	return IRC_WriteStrClient(Client, RPL_MOTD_MSG, Client_ID( Client ), msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool Show_MOTD_End(CLIENT *Client)
 | 
			
		||||
static bool
 | 
			
		||||
Show_MOTD_End(CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	return IRC_WriteStrClient( Client, RPL_ENDOFMOTD_MSG, Client_ID( Client ));
 | 
			
		||||
}
 | 
			
		||||
@@ -910,8 +986,10 @@ IRC_Show_MOTD( CLIENT *Client )
 | 
			
		||||
		return IRC_WriteStrClient( Client, ERR_NOMOTD_MSG, Client_ID( Client ) );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!Show_MOTD_Start( Client ))
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
	if (!Show_MOTD_Start( Client )) {
 | 
			
		||||
		fclose(fd);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while (fgets( line, (int)sizeof line, fd )) {
 | 
			
		||||
		ngt_TrimLastChr( line, '\n');
 | 
			
		||||
@@ -1008,10 +1086,12 @@ IRC_Send_WHO( CLIENT *Client, CHANNEL *Chan, bool OnlyOps )
 | 
			
		||||
		if( strchr( Client_Modes( c ), 'i' )) is_visible = false;
 | 
			
		||||
		else is_visible = true;
 | 
			
		||||
 | 
			
		||||
		if( is_member || is_visible )
 | 
			
		||||
		{
 | 
			
		||||
			/* Flags zusammenbasteln */
 | 
			
		||||
			strcpy( flags, "H" );
 | 
			
		||||
		if( is_member || is_visible ) {
 | 
			
		||||
			if (strchr(Client_Modes( c ), 'a'))
 | 
			
		||||
				strcpy(flags, "G"); /* away */
 | 
			
		||||
			else
 | 
			
		||||
				strcpy(flags, "H");
 | 
			
		||||
 | 
			
		||||
			if( strchr( Client_Modes( c ), 'o' )) strlcat( flags, "*", sizeof( flags ));
 | 
			
		||||
			if( strchr( Channel_UserModes( Chan, c ), 'o' )) strlcat( flags, "@", sizeof( flags ));
 | 
			
		||||
			else if( strchr( Channel_UserModes( Chan, c ), 'v' )) strlcat( flags, "+", sizeof( flags ));
 | 
			
		||||
@@ -1030,4 +1110,22 @@ IRC_Send_WHO( CLIENT *Client, CHANNEL *Chan, bool OnlyOps )
 | 
			
		||||
} /* IRC_Send_WHO */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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))
 | 
			
		||||
{
 | 
			
		||||
	if (!IRC_WriteStrClient(Client, RPL_ISUPPORT1_MSG, Client_ID(Client),
 | 
			
		||||
				Conf_MaxJoins))
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
	return IRC_WriteStrClient(Client, RPL_ISUPPORT2_MSG, Client_ID(Client),
 | 
			
		||||
				  CHANNEL_NAME_LEN - 1, Conf_MaxNickLength - 1,
 | 
			
		||||
				  COMMAND_LEN - 23, CLIENT_AWAY_LEN - 1,
 | 
			
		||||
				  COMMAND_LEN - 113);
 | 
			
		||||
} /* IRC_Send_ISUPPORT */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-info.h,v 1.3 2005/03/19 18:43:48 fw Exp $
 | 
			
		||||
 * $Id: irc-info.h,v 1.4 2007/11/21 12:16:36 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * IRC info commands (header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -36,6 +36,7 @@ GLOBAL bool IRC_Send_LUSERS PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL bool IRC_Send_NAMES PARAMS(( CLIENT *Client, CHANNEL *Chan ));
 | 
			
		||||
GLOBAL bool IRC_Show_MOTD PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL bool IRC_Send_WHO PARAMS(( CLIENT *Client, CHANNEL *Chan, bool OnlyOps ));
 | 
			
		||||
GLOBAL bool IRC_Send_ISUPPORT PARAMS(( CLIENT *Client ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-login.c,v 1.49 2005/09/01 10:51:24 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-login.c,v 1.54.2.1 2008/02/05 11:48:37 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -45,101 +45,119 @@ static bool Hello_User PARAMS(( CLIENT *Client ));
 | 
			
		||||
static void Kill_Nick PARAMS(( char *Nick, char *Reason ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the IRC command "PASS".
 | 
			
		||||
 * See RFC 2813 section 4.1.1, and RFC 2812 section 3.1.1.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_PASS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	char *type, *orig_flags;
 | 
			
		||||
	int protohigh, protolow;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Fehler liefern, wenn kein lokaler Client */
 | 
			
		||||
	if( Client_Conn( Client ) <= NONE ) return IRC_WriteStrClient( Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
	/* Return an error if this is not a local client */
 | 
			
		||||
	if (Client_Conn(Client) <= NONE)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
	
 | 
			
		||||
	if(( Client_Type( Client ) == CLIENT_UNKNOWN ) && ( Req->argc == 1))
 | 
			
		||||
	{
 | 
			
		||||
		/* noch nicht registrierte unbekannte Verbindung */
 | 
			
		||||
		Log( LOG_DEBUG, "Connection %d: got PASS command ...", Client_Conn( Client ));
 | 
			
		||||
 | 
			
		||||
		/* Passwort speichern */
 | 
			
		||||
		Client_SetPassword( Client, Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
		Client_SetType( Client, CLIENT_GOTPASS );
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	if (Client_Type(Client) == CLIENT_UNKNOWN && Req->argc == 1) {
 | 
			
		||||
		/* Not yet registered "unknown" connection, PASS with one
 | 
			
		||||
		 * argument: either a regular client, service, or server
 | 
			
		||||
		 * using the old RFC 1459 section 4.1.1 syntax. */
 | 
			
		||||
		LogDebug("Connection %d: got PASS command ...",
 | 
			
		||||
			 Client_Conn(Client));
 | 
			
		||||
	} else if ((Client_Type(Client) == CLIENT_UNKNOWN ||
 | 
			
		||||
		    Client_Type(Client) == CLIENT_UNKNOWNSERVER) &&
 | 
			
		||||
		   (Req->argc == 3 || Req->argc == 4)) {
 | 
			
		||||
		/* Not yet registered "unknown" connection or outgoing server
 | 
			
		||||
		 * link, PASS with three or four argument: server using the
 | 
			
		||||
		 * RFC 2813 section 4.1.1 syntax. */
 | 
			
		||||
		LogDebug("Connection %d: got PASS command (new server link) ...",
 | 
			
		||||
			 Client_Conn(Client));
 | 
			
		||||
	} else if (Client_Type(Client) == CLIENT_UNKNOWN ||
 | 
			
		||||
		   Client_Type(Client) == CLIENT_UNKNOWNSERVER) {
 | 
			
		||||
		/* Unregistered connection, but wrong number of arguments: */
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
	} else {
 | 
			
		||||
		/* Registered connection, PASS command is not allowed! */
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG,
 | 
			
		||||
					  Client_ID(Client));
 | 
			
		||||
	}
 | 
			
		||||
	else if((( Client_Type( Client ) == CLIENT_UNKNOWN ) || ( Client_Type( Client ) == CLIENT_UNKNOWNSERVER )) && (( Req->argc == 3 ) || ( Req->argc == 4 )))
 | 
			
		||||
	{
 | 
			
		||||
		char c2, c4, *type, *impl, *serverver, *flags, *ptr, *ircflags;
 | 
			
		||||
		int protohigh, protolow;
 | 
			
		||||
 | 
			
		||||
		/* noch nicht registrierte Server-Verbindung */
 | 
			
		||||
		Log( LOG_DEBUG, "Connection %d: got PASS command (new server link) ...", Client_Conn( Client ));
 | 
			
		||||
	Client_SetPassword(Client, Req->argv[0]);
 | 
			
		||||
	Client_SetType(Client, CLIENT_GOTPASS);
 | 
			
		||||
 | 
			
		||||
		/* Passwort speichern */
 | 
			
		||||
		Client_SetPassword( Client, Req->argv[0] );
 | 
			
		||||
	/* Protocol version */
 | 
			
		||||
	if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) {
 | 
			
		||||
		int c2, c4;
 | 
			
		||||
 | 
			
		||||
		/* Protokollversion ermitteln */
 | 
			
		||||
		if( strlen( Req->argv[1] ) >= 4 )
 | 
			
		||||
		{
 | 
			
		||||
			c2 = Req->argv[1][2];
 | 
			
		||||
			c4 = Req->argv[1][4];
 | 
			
		||||
		c2 = Req->argv[1][2];
 | 
			
		||||
		c4 = Req->argv[1][4];
 | 
			
		||||
 | 
			
		||||
			Req->argv[1][4] = '\0';
 | 
			
		||||
			protolow = atoi( &Req->argv[1][2] );
 | 
			
		||||
			Req->argv[1][2] = '\0';
 | 
			
		||||
			protohigh = atoi( Req->argv[1] );
 | 
			
		||||
		Req->argv[1][4] = '\0';
 | 
			
		||||
		protolow = atoi(&Req->argv[1][2]);
 | 
			
		||||
		Req->argv[1][2] = '\0';
 | 
			
		||||
		protohigh = atoi(Req->argv[1]);
 | 
			
		||||
			
 | 
			
		||||
			Req->argv[1][2] = c2;
 | 
			
		||||
			Req->argv[1][4] = c4;
 | 
			
		||||
		}			
 | 
			
		||||
		else protohigh = protolow = 0;
 | 
			
		||||
		Req->argv[1][2] = c2;
 | 
			
		||||
		Req->argv[1][4] = c4;
 | 
			
		||||
	} else
 | 
			
		||||
		protohigh = protolow = 0;
 | 
			
		||||
 | 
			
		||||
		/* Protokoll-Typ */
 | 
			
		||||
		if( strlen( Req->argv[1] ) > 4 ) type = &Req->argv[1][4];
 | 
			
		||||
		else type = NULL;
 | 
			
		||||
	/* Protocol type, see doc/Protocol.txt */
 | 
			
		||||
	if (Req->argc >= 2 && strlen(Req->argv[1]) > 4)
 | 
			
		||||
		type = &Req->argv[1][4];
 | 
			
		||||
	else
 | 
			
		||||
		type = NULL;
 | 
			
		||||
	
 | 
			
		||||
	/* Protocol flags/options */
 | 
			
		||||
	if (Req->argc >= 4)
 | 
			
		||||
		orig_flags = Req->argv[3];
 | 
			
		||||
	else
 | 
			
		||||
		orig_flags = "";
 | 
			
		||||
 | 
			
		||||
		/* IRC-Flags (nach RFC 2813) */
 | 
			
		||||
		if( Req->argc >= 4 ) ircflags = Req->argv[3];
 | 
			
		||||
		else ircflags = "";
 | 
			
		||||
	/* Implementation, version and IRC+ flags */
 | 
			
		||||
	if (Req->argc >= 3) {
 | 
			
		||||
		char *impl, *ptr, *serverver, *flags;
 | 
			
		||||
 | 
			
		||||
		/* Implementation, Version und ngIRCd-Flags */
 | 
			
		||||
		impl = Req->argv[2];
 | 
			
		||||
		ptr = strchr( impl, '|' );
 | 
			
		||||
		if( ptr ) *ptr = '\0';
 | 
			
		||||
		ptr = strchr(impl, '|');
 | 
			
		||||
		if (ptr)
 | 
			
		||||
			*ptr = '\0';
 | 
			
		||||
 | 
			
		||||
		if( type && ( strcmp( type, PROTOIRCPLUS ) == 0 ))
 | 
			
		||||
		{
 | 
			
		||||
			/* auf der anderen Seite laeuft ein Server, der
 | 
			
		||||
			 * ebenfalls das IRC+-Protokoll versteht */
 | 
			
		||||
		if (type && strcmp(type, PROTOIRCPLUS) == 0) {
 | 
			
		||||
			/* The peer seems to be a server which supports the
 | 
			
		||||
			 * IRC+ protocol (see doc/Protocol.txt). */
 | 
			
		||||
			serverver = ptr + 1;
 | 
			
		||||
			flags = strchr( serverver, ':' );
 | 
			
		||||
			if( flags )
 | 
			
		||||
			{
 | 
			
		||||
			flags = strchr(serverver, ':');
 | 
			
		||||
			if (flags) {
 | 
			
		||||
				*flags = '\0';
 | 
			
		||||
				flags++;
 | 
			
		||||
			}
 | 
			
		||||
			else flags = "";
 | 
			
		||||
			Log( LOG_INFO, "Peer announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").", impl, serverver, protohigh, protolow, flags );
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* auf der anderen Seite laeuft ein Server, der
 | 
			
		||||
			 * nur das Originalprotokoll unterstuetzt */
 | 
			
		||||
			} else
 | 
			
		||||
				flags = "";
 | 
			
		||||
			Log(LOG_INFO,
 | 
			
		||||
			    "Peer announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").",
 | 
			
		||||
			    impl, serverver, protohigh, protolow, flags);
 | 
			
		||||
		} else {
 | 
			
		||||
			/* The peer seems to be a server supporting the
 | 
			
		||||
			 * "original" IRC protocol (RFC 2813). */
 | 
			
		||||
			serverver = "";
 | 
			
		||||
			if( strchr( ircflags, 'Z' )) flags = "Z";
 | 
			
		||||
			else flags = "";
 | 
			
		||||
			Log( LOG_INFO, "Peer announces itself as \"%s\" using protocol %d.%d (flags: \"%s\").", impl, protohigh, protolow, flags );
 | 
			
		||||
			if (strchr(orig_flags, 'Z'))
 | 
			
		||||
				flags = "Z";
 | 
			
		||||
			else
 | 
			
		||||
				flags = "";
 | 
			
		||||
			Log(LOG_INFO,
 | 
			
		||||
			    "Peer announces itself as \"%s\" using protocol %d.%d (flags: \"%s\").",
 | 
			
		||||
			    impl, protohigh, protolow, flags);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Client_SetType( Client, CLIENT_GOTPASSSERVER );
 | 
			
		||||
		Client_SetFlags( Client, flags );
 | 
			
		||||
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
		Client_SetFlags(Client, flags);
 | 
			
		||||
	}
 | 
			
		||||
	else if(( Client_Type( Client ) == CLIENT_UNKNOWN  ) || ( Client_Type( Client ) == CLIENT_UNKNOWNSERVER ))
 | 
			
		||||
	{
 | 
			
		||||
		/* Falsche Anzahl Parameter? */
 | 
			
		||||
		return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
	}
 | 
			
		||||
	else return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_PASS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -268,13 +286,13 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
						   "NICK :%s", Req->argv[0] );
 | 
			
		||||
			IRC_WriteStrRelatedPrefix( target, target, false,
 | 
			
		||||
						   "NICK :%s", Req->argv[0] );
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			/* Register old nickname for WHOWAS queries */
 | 
			
		||||
			Client_RegisterWhowas( target );
 | 
			
		||||
				
 | 
			
		||||
 | 
			
		||||
			/* Save new nickname */
 | 
			
		||||
			Client_SetID( target, Req->argv[0] );
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			IRC_SetPenalty( target, 2 );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -583,8 +601,8 @@ Hello_User( CLIENT *Client )
 | 
			
		||||
	/* Version and system type */
 | 
			
		||||
#ifdef CVSDATE
 | 
			
		||||
	strlcpy( ver, CVSDATE, sizeof( ver ));
 | 
			
		||||
	strncpy( ver + 4, ver + 5, 2 );
 | 
			
		||||
	strncpy( ver + 6, ver + 8, 3 );
 | 
			
		||||
	memmove( ver + 4, ver + 5, 2 );
 | 
			
		||||
	memmove( ver + 6, ver + 8, 3 );
 | 
			
		||||
	snprintf( vertxt, sizeof( vertxt ), "%s(%s)", PACKAGE_VERSION, ver );
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_YOURHOST_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), vertxt, TARGET_CPU, TARGET_VENDOR, TARGET_OS )) return false;
 | 
			
		||||
#else
 | 
			
		||||
@@ -598,9 +616,10 @@ Hello_User( CLIENT *Client )
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_MYINFO_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), PACKAGE_VERSION, USERMODES, CHANMODES )) return false;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Features */
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_ISUPPORT_MSG, Client_ID( Client ), CLIENT_NICK_LEN - 1,
 | 
			
		||||
			COMMAND_LEN - 23, CLIENT_AWAY_LEN - 1, Conf_MaxJoins )) return DISCONNECTED;
 | 
			
		||||
	/* Features supported by this server (005 numeric, ISUPPORT),
 | 
			
		||||
	 * see <http://www.irc.org/tech_docs/005.html> for details. */
 | 
			
		||||
	if (! IRC_Send_ISUPPORT(Client))
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	Client_SetType( Client, CLIENT_USER );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-mode.c,v 1.45 2006/05/10 21:24:01 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-mode.c,v 1.50.2.1 2008/02/16 11:26:12 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -69,7 +69,7 @@ IRC_MODE( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		if( ! origin ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
	}
 | 
			
		||||
	else origin = Client;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	/* Channel or user mode? */
 | 
			
		||||
	cl = NULL; chan = NULL;
 | 
			
		||||
	if (Client_IsValidNick(Req->argv[0]))
 | 
			
		||||
@@ -164,6 +164,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
 | 
			
		||||
		{
 | 
			
		||||
			case 'i': /* Invisible */
 | 
			
		||||
			case 's': /* Server messages */
 | 
			
		||||
			case 'w': /* Wallops messages */
 | 
			
		||||
				x[0] = *mode_ptr;
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
@@ -268,7 +269,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
 | 
			
		||||
			switch( *mode_ptr )
 | 
			
		||||
			{
 | 
			
		||||
				case 'l':
 | 
			
		||||
					snprintf( argadd, sizeof( argadd ), " %ld", Channel_MaxUsers( Channel ));
 | 
			
		||||
					snprintf( argadd, sizeof( argadd ), " %lu", Channel_MaxUsers( Channel ));
 | 
			
		||||
					strlcat( the_args, argadd, sizeof( the_args ));
 | 
			
		||||
					break;
 | 
			
		||||
				case 'k':
 | 
			
		||||
@@ -316,7 +317,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
 | 
			
		||||
	/* Prepare reply string */
 | 
			
		||||
	if( set ) strcpy( the_modes, "+" );
 | 
			
		||||
	else strcpy( the_modes, "-" );
 | 
			
		||||
	strcpy( the_args, " " );
 | 
			
		||||
	the_args[0] = '\0';
 | 
			
		||||
 | 
			
		||||
	x[1] = '\0';
 | 
			
		||||
	ok = CONNECTED;
 | 
			
		||||
@@ -431,16 +432,21 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case 'P': /* Persistent channel */
 | 
			
		||||
				if( modeok )
 | 
			
		||||
				{
 | 
			
		||||
					if( set && ( ! Client_OperByMe( Client )))
 | 
			
		||||
					{
 | 
			
		||||
						/* Only IRC operators are allowed to set P mode */
 | 
			
		||||
						ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin ));
 | 
			
		||||
					}
 | 
			
		||||
					else x[0] = 'P';
 | 
			
		||||
				}
 | 
			
		||||
				else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
 | 
			
		||||
				if (modeok) {
 | 
			
		||||
					/* Only IRC operators are allowed to
 | 
			
		||||
					 * set the 'P' channel mode! */
 | 
			
		||||
					if (set && ! (Client_OperByMe(Client)
 | 
			
		||||
					    || Client_Type(Client) == CLIENT_SERVER)) {
 | 
			
		||||
						ok = IRC_WriteStrClient(Origin,
 | 
			
		||||
							ERR_NOPRIVILEGES_MSG,
 | 
			
		||||
							Client_ID(Origin));
 | 
			
		||||
					} else
 | 
			
		||||
						x[0] = 'P';
 | 
			
		||||
				} else
 | 
			
		||||
					ok = IRC_WriteStrClient(Origin,
 | 
			
		||||
						ERR_CHANOPRIVSNEEDED_MSG,
 | 
			
		||||
						Client_ID(Origin),
 | 
			
		||||
						Channel_Name(Channel));
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			/* --- Channel user modes --- */
 | 
			
		||||
@@ -477,7 +483,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
 | 
			
		||||
					Req->argv[arg_arg][0] = '\0';
 | 
			
		||||
					arg_arg++;
 | 
			
		||||
				}
 | 
			
		||||
				else Lists_ShowInvites( Origin, Channel );
 | 
			
		||||
				else Channel_ShowInvites( Origin, Channel );
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case 'b': /* Ban lists */
 | 
			
		||||
@@ -493,7 +499,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
 | 
			
		||||
					Req->argv[arg_arg][0] = '\0';
 | 
			
		||||
					arg_arg++;
 | 
			
		||||
				}
 | 
			
		||||
				else Lists_ShowBans( Origin, Channel );
 | 
			
		||||
				else Channel_ShowBans( Origin, Channel );
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			default:
 | 
			
		||||
@@ -522,8 +528,8 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
 | 
			
		||||
				/* Channel-User-Mode */
 | 
			
		||||
				if( Channel_UserModeAdd( Channel, client, x[0] ))
 | 
			
		||||
				{
 | 
			
		||||
					strlcat( the_args, Client_ID( client ), sizeof( the_args ));
 | 
			
		||||
					strlcat( the_args, " ", sizeof( the_args ));
 | 
			
		||||
					strlcat( the_args, Client_ID( client ), sizeof( the_args ));
 | 
			
		||||
					strlcat( the_modes, x, sizeof( the_modes ));
 | 
			
		||||
					Log( LOG_DEBUG, "User \"%s\": Mode change on %s, now \"%s\"", Client_Mask( client ), Channel_Name( Channel ), Channel_UserModes( Channel, client ));
 | 
			
		||||
				}
 | 
			
		||||
@@ -546,8 +552,8 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
 | 
			
		||||
				/* Channel-User-Mode */
 | 
			
		||||
				if( Channel_UserModeDel( Channel, client, x[0] ))
 | 
			
		||||
				{
 | 
			
		||||
					strlcat( the_args, Client_ID( client ), sizeof( the_args ));
 | 
			
		||||
					strlcat( the_args, " ", sizeof( the_args ));
 | 
			
		||||
					strlcat( the_args, Client_ID( client ), sizeof( the_args ));
 | 
			
		||||
					strlcat( the_modes, x, sizeof( the_modes ));
 | 
			
		||||
					Log( LOG_DEBUG, "User \"%s\": Mode change on %s, now \"%s\"", Client_Mask( client ), Channel_Name( Channel ), Channel_UserModes( Channel, client ));
 | 
			
		||||
				}
 | 
			
		||||
@@ -566,8 +572,7 @@ Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
 | 
			
		||||
		/* Are there additional arguments to add? */
 | 
			
		||||
		if( argadd[0] )
 | 
			
		||||
		{
 | 
			
		||||
			len = strlen( the_args ) - 1;
 | 
			
		||||
			if( the_args[len] != ' ' ) strlcat( the_args, " ", sizeof( the_args ));
 | 
			
		||||
			strlcat( the_args, " ", sizeof( the_args ));
 | 
			
		||||
			strlcat( the_args, argadd, sizeof( the_args ));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -580,9 +585,6 @@ chan_exit:
 | 
			
		||||
		len = strlen( the_modes ) - 1;
 | 
			
		||||
		if(( the_modes[len] == '+' ) || ( the_modes[len] == '-' )) the_modes[len] = '\0';
 | 
			
		||||
 | 
			
		||||
		/* Clean up argument string if there are none */
 | 
			
		||||
		if( ! the_args[1] ) the_args[0] = '\0';
 | 
			
		||||
 | 
			
		||||
		if( Client_Type( Client ) == CLIENT_SERVER )
 | 
			
		||||
		{
 | 
			
		||||
			/* Forward mode changes to channel users and other servers */
 | 
			
		||||
@@ -644,11 +646,13 @@ Add_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
 | 
			
		||||
 | 
			
		||||
	mask = Lists_MakeMask( Pattern );
 | 
			
		||||
 | 
			
		||||
	already = Lists_IsInviteEntry( mask, Channel );
 | 
			
		||||
	
 | 
			
		||||
	if( ! Lists_AddInvited( mask, Channel, false )) return CONNECTED;
 | 
			
		||||
	
 | 
			
		||||
	if(( Client_Type( Prefix ) == CLIENT_SERVER ) && ( already == true)) return CONNECTED;
 | 
			
		||||
	already = Lists_CheckDupeMask(Channel_GetListInvites(Channel), mask );
 | 
			
		||||
	if (!already) {
 | 
			
		||||
		if( ! Channel_AddInvite(Channel, mask, false ))
 | 
			
		||||
			return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	if ( already && ( Client_Type( Prefix ) == CLIENT_SERVER ))
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
 | 
			
		||||
	return Send_ListChange( "+I", Prefix, Client, Channel, mask );
 | 
			
		||||
} /* Add_Invite */
 | 
			
		||||
@@ -666,11 +670,13 @@ Add_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
 | 
			
		||||
 | 
			
		||||
	mask = Lists_MakeMask( Pattern );
 | 
			
		||||
 | 
			
		||||
	already = Lists_IsBanEntry( mask, Channel );
 | 
			
		||||
 | 
			
		||||
	if( ! Lists_AddBanned( mask, Channel )) return CONNECTED;
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Prefix ) == CLIENT_SERVER ) && ( already == true)) return CONNECTED;
 | 
			
		||||
	already = Lists_CheckDupeMask(Channel_GetListBans(Channel), mask );
 | 
			
		||||
	if (!already) {
 | 
			
		||||
		if( ! Channel_AddBan(Channel, mask))
 | 
			
		||||
			return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	if ( already && ( Client_Type( Prefix ) == CLIENT_SERVER ))
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
 | 
			
		||||
	return Send_ListChange( "+b", Prefix, Client, Channel, mask );
 | 
			
		||||
} /* Add_Ban */
 | 
			
		||||
@@ -686,7 +692,7 @@ Del_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
 | 
			
		||||
	assert( Pattern != NULL );
 | 
			
		||||
 | 
			
		||||
	mask = Lists_MakeMask( Pattern );
 | 
			
		||||
	Lists_DelInvited( mask, Channel );
 | 
			
		||||
	Lists_Del(Channel_GetListInvites(Channel), mask);
 | 
			
		||||
	return Send_ListChange( "-I", Prefix, Client, Channel, mask );
 | 
			
		||||
} /* Del_Invite */
 | 
			
		||||
 | 
			
		||||
@@ -701,7 +707,7 @@ Del_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, char *Pattern )
 | 
			
		||||
	assert( Pattern != NULL );
 | 
			
		||||
 | 
			
		||||
	mask = Lists_MakeMask( Pattern );
 | 
			
		||||
	Lists_DelBanned( mask, Channel );
 | 
			
		||||
	Lists_Del(Channel_GetListBans(Channel), mask);
 | 
			
		||||
	return Send_ListChange( "-b", Prefix, Client, Channel, mask );
 | 
			
		||||
} /* Del_Ban */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-op.c,v 1.15 2005/04/27 07:39:18 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-op.c,v 1.17 2006/12/07 17:57:20 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -99,17 +99,17 @@ IRC_INVITE( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		if( Channel_IsMemberOf( chan, target )) return IRC_WriteStrClient( from, ERR_USERONCHANNEL_MSG, Client_ID( from ), Req->argv[0], Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
		/* If the target user is banned on that channel: remember invite */
 | 
			
		||||
		if( Lists_CheckBanned( target, chan )) remember = true;
 | 
			
		||||
		if( Lists_Check(Channel_GetListBans(chan), target )) remember = true;
 | 
			
		||||
 | 
			
		||||
		if( remember )
 | 
			
		||||
		{
 | 
			
		||||
			/* We must memember this invite */
 | 
			
		||||
			if( ! Lists_AddInvited( Client_Mask( target ), chan, true)) return CONNECTED;
 | 
			
		||||
		if (remember) {
 | 
			
		||||
			/* We must remember this invite */
 | 
			
		||||
			if( ! Channel_AddInvite(chan, Client_Mask( target ), true))
 | 
			
		||||
				return CONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log( LOG_DEBUG, "User \"%s\" invites \"%s\" to \"%s\" ...", Client_Mask( from ), Req->argv[0], Req->argv[1] );
 | 
			
		||||
	
 | 
			
		||||
	LogDebug("User \"%s\" invites \"%s\" to \"%s\" ...", Client_Mask(from), Req->argv[0], Req->argv[1]);
 | 
			
		||||
 | 
			
		||||
	/* Inform target client */
 | 
			
		||||
	IRC_WriteStrClientPrefix( target, from, "INVITE %s %s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-oper.c,v 1.27 2006/07/23 15:43:18 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-oper.c,v 1.29 2007/08/02 10:14:26 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -191,12 +191,12 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
					  Client_ID(Client));
 | 
			
		||||
 | 
			
		||||
	/* Bad number of parameters? */
 | 
			
		||||
	if ((Req->argc != 2) && (Req->argc != 5))
 | 
			
		||||
	if ((Req->argc != 1) && (Req->argc != 2) && (Req->argc != 5))
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
	/* Invalid port number? */
 | 
			
		||||
	if (atoi(Req->argv[1]) < 1)
 | 
			
		||||
	if ((Req->argc > 1) && atoi(Req->argv[1]) < 1)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
@@ -204,14 +204,22 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
	    "Got CONNECT command from \"%s\" for \"%s\".", Client_Mask(Client),
 | 
			
		||||
	    Req->argv[0]);
 | 
			
		||||
 | 
			
		||||
	if (Req->argc == 2) {
 | 
			
		||||
	switch (Req->argc) {
 | 
			
		||||
	case 1:
 | 
			
		||||
		if (!Conf_EnablePassiveServer(Req->argv[0]))
 | 
			
		||||
			return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
 | 
			
		||||
						  Client_ID(Client),
 | 
			
		||||
						  Req->argv[0]);
 | 
			
		||||
	break;
 | 
			
		||||
	case 2:
 | 
			
		||||
		/* Connect configured server */
 | 
			
		||||
		if (!Conf_EnableServer
 | 
			
		||||
		    (Req->argv[0], (UINT16) atoi(Req->argv[1])))
 | 
			
		||||
			return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
 | 
			
		||||
						  Client_ID(Client),
 | 
			
		||||
						  Req->argv[0]);
 | 
			
		||||
	} else {
 | 
			
		||||
	break;
 | 
			
		||||
	default:
 | 
			
		||||
		/* Add server */
 | 
			
		||||
		if (!Conf_AddServer
 | 
			
		||||
		    (Req->argv[0], (UINT16) atoi(Req->argv[1]), Req->argv[2],
 | 
			
		||||
@@ -255,4 +263,54 @@ IRC_DISCONNECT(CLIENT *Client, REQUEST *Req )
 | 
			
		||||
} /* IRC_CONNECT */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *to, *from;
 | 
			
		||||
	int client_type;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if (Req->argc != 1)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
	client_type = Client_Type(Client);
 | 
			
		||||
	switch (client_type) {
 | 
			
		||||
	case CLIENT_USER:
 | 
			
		||||
		if (!Client_OperByMe(Client))
 | 
			
		||||
			return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG, Client_ID(Client));
 | 
			
		||||
		from = Client;
 | 
			
		||||
		break;
 | 
			
		||||
	case CLIENT_SERVER:
 | 
			
		||||
		from = Client_Search(Req->prefix);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!from)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix);
 | 
			
		||||
 | 
			
		||||
	for (to=Client_First(); to != NULL; to=Client_Next(to)) {
 | 
			
		||||
		if (Client_Conn(to) < 0) /* no local connection or WALLOPS origin */
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		client_type = Client_Type(to);
 | 
			
		||||
		switch (client_type) {
 | 
			
		||||
		case CLIENT_USER:
 | 
			
		||||
			if (Client_HasMode(to, 'w'))
 | 
			
		||||
				IRC_WriteStrClientPrefix(to, from, "WALLOPS :%s", Req->argv[0]);
 | 
			
		||||
			break;
 | 
			
		||||
		case CLIENT_SERVER:
 | 
			
		||||
			if (to != Client)
 | 
			
		||||
				IRC_WriteStrClientPrefix(to, from, "WALLOPS :%s", Req->argv[0]);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-oper.h,v 1.11 2005/03/19 18:43:48 fw Exp $
 | 
			
		||||
 * $Id: irc-oper.h,v 1.12 2007/08/02 10:14:26 fw Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * IRC operator commands (header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -24,6 +24,7 @@ GLOBAL bool IRC_REHASH PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL bool IRC_RESTART PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL bool IRC_CONNECT PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL bool IRC_DISCONNECT PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL bool IRC_WALLOPS PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2006 Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2007 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
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-server.c,v 1.39 2006/04/30 21:31:43 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-server.c,v 1.46 2007/11/21 12:16:36 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -35,33 +35,40 @@ static char UNUSED id[] = "$Id: irc-server.c,v 1.39 2006/04/30 21:31:43 alex Exp
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "numeric.h"
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "irc-info.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "irc-server.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the IRC command "SERVER".
 | 
			
		||||
 * See RFC 2813 section 4.1.2.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	char str[LINE_LEN], *ptr, *modes, *topic;
 | 
			
		||||
	CLIENT *from, *c, *cl;
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	int max_hops, i;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	char str[LINE_LEN], *ptr;
 | 
			
		||||
	CLIENT *from, *c;
 | 
			
		||||
	bool ok;
 | 
			
		||||
	int i;
 | 
			
		||||
	CONN_ID con;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Fehler liefern, wenn kein lokaler Client */
 | 
			
		||||
	if( Client_Conn( Client ) <= NONE ) return IRC_WriteStrClient( Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
	/* Return an error if this is not a local client */
 | 
			
		||||
	if (Client_Conn(Client) <= NONE)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_GOTPASSSERVER )
 | 
			
		||||
	{
 | 
			
		||||
		/* Verbindung soll als Server-Server-Verbindung registriert werden */
 | 
			
		||||
		Log( LOG_DEBUG, "Connection %d: got SERVER command (new server link) ...", Client_Conn( Client ));
 | 
			
		||||
	if (Client_Type(Client) == CLIENT_GOTPASS) {
 | 
			
		||||
		/* We got a PASS command from the peer, and now a SERVER
 | 
			
		||||
		 * command: the peer tries to register itself as a server. */
 | 
			
		||||
		LogDebug("Connection %d: got SERVER command (new server link) ...",
 | 
			
		||||
			Client_Conn(Client));
 | 
			
		||||
 | 
			
		||||
		/* Falsche Anzahl Parameter? */
 | 
			
		||||
		if(( Req->argc != 2 ) && ( Req->argc != 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
@@ -115,10 +122,10 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
			Client_SetToken( Client, atoi( Req->argv[1] ));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" registered (connection %d, 1 hop - direct link).", Client_ID( Client ), con );
 | 
			
		||||
 | 
			
		||||
		Client_SetType( Client, CLIENT_SERVER );
 | 
			
		||||
		Conf_SetServer( i, con );
 | 
			
		||||
		/* Mark this connection as belonging to an configured server */
 | 
			
		||||
		Conf_SetServer(i, con);
 | 
			
		||||
		
 | 
			
		||||
		Client_SetType(Client, CLIENT_UNKNOWNSERVER);
 | 
			
		||||
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
		/* Kompression initialisieren, wenn erforderlich */
 | 
			
		||||
@@ -133,136 +140,23 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		/* maximalen Hop Count ermitteln */
 | 
			
		||||
		max_hops = 0;
 | 
			
		||||
		c = Client_First( );
 | 
			
		||||
		while( c )
 | 
			
		||||
		{
 | 
			
		||||
			if( Client_Hops( c ) > max_hops ) max_hops = Client_Hops( c );
 | 
			
		||||
			c = Client_Next( c );
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		/* Alle bisherigen Server dem neuen Server bekannt machen,
 | 
			
		||||
		 * die bisherigen Server ueber den neuen informierenn */
 | 
			
		||||
		for( i = 0; i < ( max_hops + 1 ); i++ )
 | 
			
		||||
		{
 | 
			
		||||
			c = Client_First( );
 | 
			
		||||
			while( c )
 | 
			
		||||
			{
 | 
			
		||||
				if(( Client_Type( c ) == CLIENT_SERVER ) && ( c != Client ) && ( c != Client_ThisServer( )) && ( Client_Hops( c ) == i ))
 | 
			
		||||
				{
 | 
			
		||||
					if( Client_Conn( c ) > NONE )
 | 
			
		||||
					{
 | 
			
		||||
						/* Dem gefundenen Server gleich den neuen
 | 
			
		||||
						 * Server bekannt machen */
 | 
			
		||||
						if( ! IRC_WriteStrClient( c, "SERVER %s %d %d :%s", Client_ID( Client ), Client_Hops( Client ) + 1, Client_MyToken( Client ), Client_Info( Client ))) return DISCONNECTED;
 | 
			
		||||
					}
 | 
			
		||||
					
 | 
			
		||||
					/* Den neuen Server ueber den alten informieren */
 | 
			
		||||
					if( ! IRC_WriteStrClientPrefix( Client, Client_Hops( c ) == 1 ? Client_ThisServer( ) : Client_Introducer( c ), "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ))) return DISCONNECTED;
 | 
			
		||||
				}
 | 
			
		||||
				c = Client_Next( c );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* alle User dem neuen Server bekannt machen */
 | 
			
		||||
		c = Client_First( );
 | 
			
		||||
		while( c )
 | 
			
		||||
		{
 | 
			
		||||
			if( Client_Type( c ) == CLIENT_USER )
 | 
			
		||||
			{
 | 
			
		||||
				/* User an neuen Server melden */
 | 
			
		||||
				if( ! IRC_WriteStrClient( Client, "NICK %s %d %s %s %d +%s :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_User( c ), Client_Hostname( c ), Client_MyToken( Client_Introducer( c )), Client_Modes( c ), Client_Info( c ))) return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
			c = Client_Next( c );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Channels dem neuen Server bekannt machen */
 | 
			
		||||
		chan = Channel_First( );
 | 
			
		||||
		while( chan )
 | 
			
		||||
		{
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
			/* Send CHANINFO if the peer supports it */
 | 
			
		||||
			if( strchr( Client_Flags( Client ), 'C' ))
 | 
			
		||||
			{
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
				Log( LOG_DEBUG, "Sending CHANINFO commands ..." );
 | 
			
		||||
		if (strchr(Client_Flags(Client), 'H')) {
 | 
			
		||||
			LogDebug("Peer supports IRC+ extended server handshake ...");
 | 
			
		||||
			if (!IRC_Send_ISUPPORT(Client))
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
			return IRC_WriteStrClient(Client, RPL_ENDOFMOTD_MSG,
 | 
			
		||||
						  Client_ID(Client));
 | 
			
		||||
		} else {
 | 
			
		||||
#endif
 | 
			
		||||
				modes = Channel_Modes( chan );
 | 
			
		||||
				topic = Channel_Topic( chan );
 | 
			
		||||
 | 
			
		||||
				if( *modes || *topic )
 | 
			
		||||
				{
 | 
			
		||||
					/* send CHANINFO */
 | 
			
		||||
					if(( ! strchr( Channel_Modes( chan ), 'k' )) && ( ! strchr( Channel_Modes( chan ), 'l' )) && ( ! *topic ))
 | 
			
		||||
					{
 | 
			
		||||
						/* "CHANINFO <chan> +<modes>" */
 | 
			
		||||
						if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s", Channel_Name( chan ), modes )) return DISCONNECTED;
 | 
			
		||||
					}
 | 
			
		||||
					else if(( ! strchr( Channel_Modes( chan ), 'k' )) && ( ! strchr( Channel_Modes( chan ), 'l' )))
 | 
			
		||||
					{
 | 
			
		||||
						/* "CHANINFO <chan> +<modes> :<topic>" */
 | 
			
		||||
						if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s :%s", Channel_Name( chan ), modes, topic )) return DISCONNECTED;
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						/* "CHANINFO <chan> +<modes> <key> <limit> :<topic>" */
 | 
			
		||||
						if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s %s %ld :%s", Channel_Name( chan ), modes, strchr( Channel_Modes( chan ), 'k' ) ? Channel_Key( chan ) : "*", strchr( Channel_Modes( chan ), 'l' ) ? Channel_MaxUsers( chan ) : 0L, topic )) return DISCONNECTED;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			/* alle Member suchen */
 | 
			
		||||
			cl2chan = Channel_FirstMember( chan );
 | 
			
		||||
			snprintf( str, sizeof( str ), "NJOIN %s :", Channel_Name( chan ));
 | 
			
		||||
			while( cl2chan )
 | 
			
		||||
			{
 | 
			
		||||
				cl = Channel_GetClient( cl2chan );
 | 
			
		||||
				assert( cl != NULL );
 | 
			
		||||
 | 
			
		||||
				/* Nick, ggf. mit Modes, anhaengen */
 | 
			
		||||
				if( str[strlen( str ) - 1] != ':' ) strlcat( str, ",", sizeof( str ));
 | 
			
		||||
				if( strchr( Channel_UserModes( chan, cl ), 'v' )) strlcat( str, "+", sizeof( str ));
 | 
			
		||||
				if( strchr( Channel_UserModes( chan, cl ), 'o' )) strlcat( str, "@", sizeof( str ));
 | 
			
		||||
				strlcat( str, Client_ID( cl ), sizeof( str ));
 | 
			
		||||
 | 
			
		||||
				if( strlen( str ) > ( LINE_LEN - CLIENT_NICK_LEN - 8 ))
 | 
			
		||||
				{
 | 
			
		||||
					/* Zeile senden */
 | 
			
		||||
					if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
 | 
			
		||||
					snprintf( str, sizeof( str ), "NJOIN %s :", Channel_Name( chan ));
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				cl2chan = Channel_NextMember( chan, cl2chan );
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* noch Daten da? */
 | 
			
		||||
			if( str[strlen( str ) - 1] != ':')
 | 
			
		||||
			{
 | 
			
		||||
				/* Ja; Also senden ... */
 | 
			
		||||
				if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* Get next channel ... */
 | 
			
		||||
			chan = Channel_Next(chan);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
			if (Conf_MaxNickLength != CLIENT_NICK_LEN_DEFAULT)
 | 
			
		||||
				Log(LOG_CRIT,
 | 
			
		||||
				    "Attention: this server uses a non-standard nick length, but the peer doesn't support the IRC+ extended server handshake!");
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
		if (strchr(Client_Flags(Client), 'L')) {
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
			Log(LOG_DEBUG,
 | 
			
		||||
			    "Synchronizing INVITE- and BAN-lists ...");
 | 
			
		||||
#endif
 | 
			
		||||
			/* Synchronize INVITE- and BAN-lists */
 | 
			
		||||
			if (! Lists_SendInvites(Client))
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
			if (! Lists_SendBans(Client))
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
		return IRC_Num_ENDOFMOTD(Client, Req);
 | 
			
		||||
	}
 | 
			
		||||
	else if( Client_Type( Client ) == CLIENT_SERVER )
 | 
			
		||||
	{
 | 
			
		||||
@@ -306,8 +200,9 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		IRC_WriteStrServersPrefix( Client, from, "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ));
 | 
			
		||||
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	else return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
	} else
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
} /* IRC_SERVER */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-server.h,v 1.5 2005/03/19 18:43:49 fw Exp $
 | 
			
		||||
 * $Id: irc-server.h,v 1.6 2007/11/21 12:16:36 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * IRC commands for server links (header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -22,6 +22,8 @@ GLOBAL bool IRC_SERVER PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL bool IRC_NJOIN PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL bool IRC_SQUIT PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool IRC_ENDOFMOTD_Server PARAMS((CLIENT *Client));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-write.c,v 1.20 2006/05/10 21:24:01 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-write.c,v 1.21 2006/08/12 11:56:24 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -378,7 +378,7 @@ va_dcl
 | 
			
		||||
			}
 | 
			
		||||
			cl2chan = Channel_NextMember( chan, cl2chan );
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		/* naechsten Channel */
 | 
			
		||||
		chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan );
 | 
			
		||||
	}
 | 
			
		||||
@@ -403,12 +403,12 @@ GLOBAL void
 | 
			
		||||
IRC_SetPenalty( CLIENT *Client, time_t Seconds )
 | 
			
		||||
{
 | 
			
		||||
	CONN_ID c;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Seconds > 0 );
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) return;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	c = Client_Conn( Client );
 | 
			
		||||
	if (c > NONE)
 | 
			
		||||
		Conn_SetPenalty(c, Seconds);
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: lists.c,v 1.18 2005/07/31 20:13:08 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: lists.c,v 1.21 2007/01/29 21:13:26 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -35,326 +35,131 @@ static char UNUSED id[] = "$Id: lists.c,v 1.18 2005/07/31 20:13:08 alex Exp $";
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "lists.h"
 | 
			
		||||
 | 
			
		||||
#define MASK_LEN	(2*CLIENT_HOST_LEN)
 | 
			
		||||
 | 
			
		||||
#define MASK_LEN 2*CLIENT_HOST_LEN
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct _C2C
 | 
			
		||||
{
 | 
			
		||||
	struct _C2C *next;
 | 
			
		||||
struct list_elem {
 | 
			
		||||
	struct list_elem *next;
 | 
			
		||||
	char mask[MASK_LEN];
 | 
			
		||||
	CHANNEL *channel;
 | 
			
		||||
	bool onlyonce;
 | 
			
		||||
} C2C;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static C2C *My_Invites, *My_Bans;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static C2C *New_C2C PARAMS(( char *Mask, CHANNEL *Chan, bool OnlyOnce ));
 | 
			
		||||
 | 
			
		||||
static bool Check_List PARAMS(( C2C **Cl2Chan, CLIENT *Client, CHANNEL *Chan ));
 | 
			
		||||
static bool Already_Registered PARAMS(( C2C *Cl2Chan, char *Mask, CHANNEL *Chan ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Lists_Init( void )
 | 
			
		||||
GLOBAL const char *
 | 
			
		||||
Lists_GetMask(const struct list_elem *e)
 | 
			
		||||
{
 | 
			
		||||
	/* Modul initialisieren */
 | 
			
		||||
 | 
			
		||||
	My_Invites = My_Bans = NULL;
 | 
			
		||||
} /* Lists_Init */
 | 
			
		||||
	return e->mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Lists_Exit( void )
 | 
			
		||||
GLOBAL struct list_elem*
 | 
			
		||||
Lists_GetFirst(const struct list_head *h)
 | 
			
		||||
{
 | 
			
		||||
	/* Modul abmelden */
 | 
			
		||||
 | 
			
		||||
	C2C *c2c, *next;
 | 
			
		||||
 | 
			
		||||
	/* Invite-Lists freigeben */
 | 
			
		||||
	c2c = My_Invites;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		next = c2c->next;
 | 
			
		||||
		free( c2c );
 | 
			
		||||
		c2c = next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Ban-Lists freigeben */
 | 
			
		||||
	c2c = My_Bans;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		next = c2c->next;
 | 
			
		||||
		free( c2c );
 | 
			
		||||
		c2c = next;
 | 
			
		||||
	}
 | 
			
		||||
} /* Lists_Exit */
 | 
			
		||||
	return h->first;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Lists_CheckInvited( CLIENT *Client, CHANNEL *Chan )
 | 
			
		||||
GLOBAL struct list_elem*
 | 
			
		||||
Lists_GetNext(const struct list_elem *e)
 | 
			
		||||
{
 | 
			
		||||
	return Check_List( &My_Invites, Client, Chan );
 | 
			
		||||
} /* Lists_CheckInvited */
 | 
			
		||||
	return e->next;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Lists_IsInviteEntry( char *Mask, CHANNEL *Chan )
 | 
			
		||||
bool
 | 
			
		||||
Lists_Add(struct list_head *header, const char *Mask, bool OnlyOnce )
 | 
			
		||||
{
 | 
			
		||||
	struct list_elem *e, *newelem;
 | 
			
		||||
 | 
			
		||||
	assert( header != NULL );
 | 
			
		||||
	assert( Mask != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	
 | 
			
		||||
	return Already_Registered( My_Invites, Mask, Chan );
 | 
			
		||||
} /* Lists_IsInviteEntry */
 | 
			
		||||
 | 
			
		||||
	if (Lists_CheckDupeMask(header, Mask )) return true;
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Lists_AddInvited( char *Mask, CHANNEL *Chan, bool OnlyOnce )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c;
 | 
			
		||||
	e = Lists_GetFirst(header);
 | 
			
		||||
 | 
			
		||||
	assert( Mask != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Already_Registered( My_Invites, Mask, Chan )) return true;
 | 
			
		||||
	
 | 
			
		||||
	c2c = New_C2C( Mask, Chan, OnlyOnce );
 | 
			
		||||
	if( ! c2c )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_ERR, "Can't add new invite list entry!" );
 | 
			
		||||
	newelem = malloc(sizeof(struct list_elem));
 | 
			
		||||
	if( ! newelem ) {
 | 
			
		||||
		Log( LOG_EMERG, "Can't allocate memory for new Ban/Invite entry!" );
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* verketten */
 | 
			
		||||
	c2c->next = My_Invites;
 | 
			
		||||
	My_Invites = c2c;
 | 
			
		||||
	strlcpy( newelem->mask, Mask, sizeof( newelem->mask ));
 | 
			
		||||
	newelem->onlyonce = OnlyOnce;
 | 
			
		||||
	newelem->next = e;
 | 
			
		||||
	header->first = newelem;
 | 
			
		||||
 | 
			
		||||
	Log( LOG_DEBUG, "Added \"%s\" to invite list for \"%s\".", Mask, Channel_Name( Chan ));
 | 
			
		||||
	LogDebug("Added \"%s\" to invite list", Mask);
 | 
			
		||||
	return true;
 | 
			
		||||
} /* Lists_AddInvited */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
Lists_Unlink(struct list_head *header, struct list_elem *p, struct list_elem *victim)
 | 
			
		||||
{
 | 
			
		||||
	assert(victim != NULL);
 | 
			
		||||
	assert(header != NULL);
 | 
			
		||||
 | 
			
		||||
	if (p) p->next = victim->next;
 | 
			
		||||
	else header->first = victim->next;
 | 
			
		||||
 | 
			
		||||
	free(victim);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Lists_DelInvited( char *Mask, CHANNEL *Chan )
 | 
			
		||||
Lists_Del(struct list_head *header, const char *Mask)
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c, *last, *next;
 | 
			
		||||
	struct list_elem *e, *last, *victim;
 | 
			
		||||
 | 
			
		||||
	assert( header != NULL );
 | 
			
		||||
	assert( Mask != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	last = NULL;
 | 
			
		||||
	c2c = My_Invites;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		next = c2c->next;
 | 
			
		||||
		if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 ))
 | 
			
		||||
		{
 | 
			
		||||
			/* dieser Eintrag muss geloescht werden */
 | 
			
		||||
			Log( LOG_DEBUG, "Deleted \"%s\" from invite list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
 | 
			
		||||
			if( last ) last->next = next;
 | 
			
		||||
			else My_Invites = next;
 | 
			
		||||
			free( c2c );
 | 
			
		||||
	e = Lists_GetFirst(header);
 | 
			
		||||
	while( e ) {
 | 
			
		||||
		if(strcasecmp( e->mask, Mask ) == 0 ) {
 | 
			
		||||
			LogDebug("Deleted \"%s\" from list", e->mask);
 | 
			
		||||
			victim = e;
 | 
			
		||||
			e = victim->next;
 | 
			
		||||
			Lists_Unlink(header, last, victim);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		else last = c2c;
 | 
			
		||||
		c2c = next;
 | 
			
		||||
		last = e;
 | 
			
		||||
		e = e->next;
 | 
			
		||||
	}
 | 
			
		||||
} /* Lists_DelInvited */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Lists_ShowInvites( CLIENT *Client, CHANNEL *Channel )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Channel != NULL );
 | 
			
		||||
 | 
			
		||||
	c2c = My_Invites;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		if( c2c->channel == Channel )
 | 
			
		||||
		{
 | 
			
		||||
			/* Eintrag fuer Channel gefunden; ausgeben: */
 | 
			
		||||
			if( ! IRC_WriteStrClient( Client, RPL_INVITELIST_MSG, Client_ID( Client ), Channel_Name( Channel ), c2c->mask )) return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
		c2c = c2c->next;
 | 
			
		||||
	}
 | 
			
		||||
	return IRC_WriteStrClient( Client, RPL_ENDOFINVITELIST_MSG, Client_ID( Client ), Channel_Name( Channel ));
 | 
			
		||||
} /* Lists_ShowInvites */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Lists_SendInvites( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	
 | 
			
		||||
	c2c = My_Invites;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, "MODE %s +I %s", Channel_Name( c2c->channel ), c2c->mask )) return DISCONNECTED;
 | 
			
		||||
		c2c = c2c->next;
 | 
			
		||||
	}
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* Lists_SendInvites */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Lists_SendBans( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	
 | 
			
		||||
	c2c = My_Bans;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, "MODE %s +b %s", Channel_Name( c2c->channel ), c2c->mask )) return DISCONNECTED;
 | 
			
		||||
		c2c = c2c->next;
 | 
			
		||||
	}
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* Lists_SendBans */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Lists_CheckBanned( CLIENT *Client, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	return Check_List( &My_Bans, Client, Chan );
 | 
			
		||||
} /* Lists_CheckBanned */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Lists_IsBanEntry( char *Mask, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	assert( Mask != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	
 | 
			
		||||
	return Already_Registered( My_Bans, Mask, Chan );
 | 
			
		||||
} /* Lists_IsBanEntry */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Lists_AddBanned( char *Mask, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c;
 | 
			
		||||
 | 
			
		||||
	assert( Mask != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Already_Registered( My_Bans, Mask, Chan )) return true;
 | 
			
		||||
 | 
			
		||||
	c2c = New_C2C( Mask, Chan, false );
 | 
			
		||||
	if( ! c2c )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_ERR, "Can't add new ban list entry!" );
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* verketten */
 | 
			
		||||
	c2c->next = My_Bans;
 | 
			
		||||
	My_Bans = c2c;
 | 
			
		||||
 | 
			
		||||
	Log( LOG_DEBUG, "Added \"%s\" to ban list for \"%s\".", Mask, Channel_Name( Chan ));
 | 
			
		||||
	return true;
 | 
			
		||||
} /* Lists_AddBanned */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Lists_DelBanned( char *Mask, CHANNEL *Chan )
 | 
			
		||||
Lists_Free(struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c, *last, *next;
 | 
			
		||||
	struct list_elem *e, *victim;
 | 
			
		||||
 | 
			
		||||
	assert( Mask != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	assert(head != NULL);
 | 
			
		||||
 | 
			
		||||
	last = NULL;
 | 
			
		||||
	c2c = My_Bans;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		next = c2c->next;
 | 
			
		||||
		if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 ))
 | 
			
		||||
		{
 | 
			
		||||
			/* dieser Eintrag muss geloescht werden */
 | 
			
		||||
			Log( LOG_DEBUG, "Deleted \"%s\" from ban list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
 | 
			
		||||
			if( last ) last->next = next;
 | 
			
		||||
			else My_Bans = next;
 | 
			
		||||
			free( c2c );
 | 
			
		||||
		}
 | 
			
		||||
		else last = c2c;
 | 
			
		||||
		c2c = next;
 | 
			
		||||
	e = head->first;
 | 
			
		||||
	head->first = NULL;
 | 
			
		||||
	while (e) {
 | 
			
		||||
		LogDebug("Deleted \"%s\" from invite list" , e->mask);
 | 
			
		||||
		victim = e;
 | 
			
		||||
		e = e->next;
 | 
			
		||||
		free( victim );
 | 
			
		||||
	}
 | 
			
		||||
} /* Lists_DelBanned */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Lists_ShowBans( CLIENT *Client, CHANNEL *Channel )
 | 
			
		||||
Lists_CheckDupeMask(const struct list_head *h, const char *Mask )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Channel != NULL );
 | 
			
		||||
 | 
			
		||||
	c2c = My_Bans;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		if( c2c->channel == Channel )
 | 
			
		||||
		{
 | 
			
		||||
			/* Eintrag fuer Channel gefunden; ausgeben: */
 | 
			
		||||
			if( ! IRC_WriteStrClient( Client, RPL_BANLIST_MSG, Client_ID( Client ), Channel_Name( Channel ), c2c->mask )) return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
		c2c = c2c->next;
 | 
			
		||||
	struct list_elem *e;
 | 
			
		||||
	e = h->first;
 | 
			
		||||
	while (e) {
 | 
			
		||||
		if (strcasecmp( e->mask, Mask ) == 0 )
 | 
			
		||||
			return true;
 | 
			
		||||
		e = e->next;
 | 
			
		||||
	}
 | 
			
		||||
	return IRC_WriteStrClient( Client, RPL_ENDOFBANLIST_MSG, Client_ID( Client ), Channel_Name( Channel ));
 | 
			
		||||
} /* Lists_ShowBans */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Lists_DeleteChannel( CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	/* Channel wurde geloescht, Invite- und Ban-Lists aufraeumen */
 | 
			
		||||
 | 
			
		||||
	C2C *c2c, *last, *next;
 | 
			
		||||
 | 
			
		||||
	/* Invite-List */
 | 
			
		||||
	last = NULL;
 | 
			
		||||
	c2c = My_Invites;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		next = c2c->next;
 | 
			
		||||
		if( c2c->channel == Chan )
 | 
			
		||||
		{
 | 
			
		||||
			/* dieser Eintrag muss geloescht werden */
 | 
			
		||||
			Log( LOG_DEBUG, "Deleted \"%s\" from invite list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
 | 
			
		||||
			if( last ) last->next = next;
 | 
			
		||||
			else My_Invites = next;
 | 
			
		||||
			free( c2c );
 | 
			
		||||
		}
 | 
			
		||||
		else last = c2c;
 | 
			
		||||
		c2c = next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Ban-List */
 | 
			
		||||
	last = NULL;
 | 
			
		||||
	c2c = My_Bans;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		next = c2c->next;
 | 
			
		||||
		if( c2c->channel == Chan )
 | 
			
		||||
		{
 | 
			
		||||
			/* dieser Eintrag muss geloescht werden */
 | 
			
		||||
			Log( LOG_DEBUG, "Deleted \"%s\" from ban list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
 | 
			
		||||
			if( last ) last->next = next;
 | 
			
		||||
			else My_Bans = next;
 | 
			
		||||
			free( c2c );
 | 
			
		||||
		}
 | 
			
		||||
		else last = c2c;
 | 
			
		||||
		c2c = next;
 | 
			
		||||
	}
 | 
			
		||||
} /* Lists_DeleteChannel */
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL char *
 | 
			
		||||
@@ -407,82 +212,30 @@ Lists_MakeMask( char *Pattern )
 | 
			
		||||
} /* Lists_MakeMask */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static C2C *
 | 
			
		||||
New_C2C( char *Mask, CHANNEL *Chan, bool OnlyOnce )
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
Lists_Check( struct list_head *header, CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c;
 | 
			
		||||
	
 | 
			
		||||
	assert( Mask != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	struct list_elem *e, *last;
 | 
			
		||||
 | 
			
		||||
	/* Speicher fuer Eintrag anfordern */
 | 
			
		||||
	c2c = (C2C *)malloc( sizeof( C2C ));
 | 
			
		||||
	if( ! c2c )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_EMERG, "Can't allocate memory! [New_C2C]" );
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	assert( header != NULL );
 | 
			
		||||
 | 
			
		||||
	strlcpy( c2c->mask, Mask, sizeof( c2c->mask ));
 | 
			
		||||
	c2c->channel = Chan;
 | 
			
		||||
	c2c->onlyonce = OnlyOnce;
 | 
			
		||||
 | 
			
		||||
	return c2c;
 | 
			
		||||
} /* New_C2C */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
Check_List( C2C **Cl2Chan, CLIENT *Client, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c, *last;
 | 
			
		||||
 | 
			
		||||
	assert( Cl2Chan != NULL );
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	c2c = *Cl2Chan;
 | 
			
		||||
	e = header->first;
 | 
			
		||||
	last = NULL;
 | 
			
		||||
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		if( c2c->channel == Chan )
 | 
			
		||||
		{
 | 
			
		||||
			/* Ok, richtiger Channel. Passt die Maske? */
 | 
			
		||||
			if( Match( c2c->mask, Client_Mask( Client )))
 | 
			
		||||
			{
 | 
			
		||||
				/* Treffer! */
 | 
			
		||||
				if( c2c->onlyonce )
 | 
			
		||||
				{
 | 
			
		||||
					/* Eintrag loeschen */
 | 
			
		||||
					Log( LOG_DEBUG, "Deleted \"%s\" from %s list for \"%s\".", c2c->mask, *Cl2Chan == My_Invites ? "invite" : "ban", Channel_Name( Chan ));
 | 
			
		||||
					if( last ) last->next = c2c->next;
 | 
			
		||||
					else *Cl2Chan = c2c->next;
 | 
			
		||||
					free( c2c );
 | 
			
		||||
				}
 | 
			
		||||
				return true;
 | 
			
		||||
	while( e ) {
 | 
			
		||||
		if( Match( e->mask, Client_Mask( Client ))) {
 | 
			
		||||
			if( e->onlyonce ) { /* delete entry */
 | 
			
		||||
				LogDebug("Deleted \"%s\" from list", e->mask);
 | 
			
		||||
				Lists_Unlink(header, last, e);
 | 
			
		||||
			}
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		last = c2c;
 | 
			
		||||
		c2c = c2c->next;
 | 
			
		||||
		last = e;
 | 
			
		||||
		e = e->next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false;
 | 
			
		||||
} /* Check_List */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
Already_Registered( C2C *List, char *Mask, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c;
 | 
			
		||||
 | 
			
		||||
	c2c = List;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 )) return true;
 | 
			
		||||
		c2c = c2c->next;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
} /* Already_Registered */
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: lists.h,v 1.12 2005/03/19 18:43:49 fw Exp $
 | 
			
		||||
 * $Id: lists.h,v 1.13 2006/12/07 17:57:20 fw Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Management of IRC lists: ban, invite, ... (header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -16,31 +16,31 @@
 | 
			
		||||
 | 
			
		||||
#ifndef __lists_h__
 | 
			
		||||
#define __lists_h__
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
 | 
			
		||||
struct list_elem;
 | 
			
		||||
 | 
			
		||||
struct list_head {
 | 
			
		||||
	struct list_elem *first;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void Lists_Init PARAMS(( void ));
 | 
			
		||||
GLOBAL void Lists_Exit PARAMS(( void ));
 | 
			
		||||
GLOBAL struct list_elem *Lists_GetFirst PARAMS((const struct list_head *));
 | 
			
		||||
GLOBAL struct list_elem *Lists_GetNext PARAMS((const struct list_elem *));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Lists_CheckInvited PARAMS(( CLIENT *Client, CHANNEL *Chan ));
 | 
			
		||||
GLOBAL bool Lists_AddInvited PARAMS(( char *Mask, CHANNEL *Chan, bool OnlyOnce ));
 | 
			
		||||
GLOBAL void Lists_DelInvited PARAMS(( char *Mask, CHANNEL *Chan ));
 | 
			
		||||
GLOBAL bool Lists_ShowInvites PARAMS(( CLIENT *Client, CHANNEL *Channel ));
 | 
			
		||||
GLOBAL bool Lists_SendInvites PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL bool Lists_IsInviteEntry PARAMS(( char *Mask, CHANNEL *Chan ));
 | 
			
		||||
GLOBAL bool Lists_Check PARAMS((struct list_head *head, CLIENT *client ));
 | 
			
		||||
GLOBAL bool Lists_CheckDupeMask PARAMS((const struct list_head *head, const char *mask ));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Lists_CheckBanned PARAMS(( CLIENT *Client, CHANNEL *Chan ));
 | 
			
		||||
GLOBAL bool Lists_AddBanned PARAMS(( char *Mask, CHANNEL *Chan ));
 | 
			
		||||
GLOBAL void Lists_DelBanned PARAMS(( char *Mask, CHANNEL *Chan ));
 | 
			
		||||
GLOBAL bool Lists_ShowBans PARAMS(( CLIENT *Client, CHANNEL *Channel ));
 | 
			
		||||
GLOBAL bool Lists_SendBans PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL bool Lists_IsBanEntry PARAMS(( char *Mask, CHANNEL *Chan ));
 | 
			
		||||
GLOBAL bool Lists_Add PARAMS((struct list_head *header, const char *Mask, bool OnlyOnce ));
 | 
			
		||||
GLOBAL void Lists_Del PARAMS((struct list_head *head, const char *Mask ));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Lists_DeleteChannel PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL bool Lists_AlreadyRegistered PARAMS(( const struct list_head *head, const char *Mask));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Lists_Free PARAMS(( struct list_head *head ));
 | 
			
		||||
 | 
			
		||||
GLOBAL char *Lists_MakeMask PARAMS(( char *Pattern ));
 | 
			
		||||
 | 
			
		||||
GLOBAL const char *Lists_GetMask PARAMS(( const struct list_elem *e ));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: log.c,v 1.61 2006/07/23 23:23:45 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: log.c,v 1.62 2006/08/05 09:16:21 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -166,25 +166,21 @@ Log_Exit( void )
 | 
			
		||||
 * Log function for debug messages.
 | 
			
		||||
 * This function is only functional when the program is compiled with debug
 | 
			
		||||
 * code enabled; otherwise it is an empty function which the compiler will
 | 
			
		||||
 * hopefully mangle down to "nothing". Therefore you should use LogDebug(...)
 | 
			
		||||
 * in favor to Log(LOG_DEBUG, ...).
 | 
			
		||||
 * hopefully mangle down to "nothing" (see log.h). Therefore you should use
 | 
			
		||||
 * LogDebug(...) in favor to Log(LOG_DEBUG, ...).
 | 
			
		||||
 * @param Format Format string like printf().
 | 
			
		||||
 * @param ... Further arguments.
 | 
			
		||||
 */
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
# ifdef PROTOTYPES
 | 
			
		||||
GLOBAL void
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
LogDebug( const char *Format, ... )
 | 
			
		||||
#else
 | 
			
		||||
LogDebug( UNUSED const char *Format, ... )
 | 
			
		||||
#endif /* DEBUG */
 | 
			
		||||
# else
 | 
			
		||||
GLOBAL void
 | 
			
		||||
LogDebug( Format, va_alist )
 | 
			
		||||
const char *Format;
 | 
			
		||||
va_dcl
 | 
			
		||||
# endif /* PROTOTYPES */
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
{
 | 
			
		||||
	char msg[MAX_LOG_MSG_LEN];
 | 
			
		||||
	va_list ap;
 | 
			
		||||
@@ -199,14 +195,9 @@ va_dcl
 | 
			
		||||
	va_end( ap );
 | 
			
		||||
	Log(LOG_DEBUG, "%s", msg);
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
{
 | 
			
		||||
	/* Do nothing.
 | 
			
		||||
	 * The compiler should optimize this out, please ;-) */
 | 
			
		||||
}
 | 
			
		||||
#endif	/* DEBUG */
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Logging function of ngIRCd.
 | 
			
		||||
 * This function logs messages to the console and/or syslog, whichever is
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: log.h,v 1.19 2006/02/08 17:33:28 fw Exp $
 | 
			
		||||
 * $Id: log.h,v 1.20 2006/08/05 09:16:21 fw Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Logging functions (header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -39,7 +39,13 @@ GLOBAL void Log_Init PARAMS(( bool Daemon_Mode ));
 | 
			
		||||
GLOBAL void Log_Exit PARAMS(( void ));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Log PARAMS(( int Level, 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_Resolver PARAMS(( void ));
 | 
			
		||||
GLOBAL void Log_Exit_Resolver PARAMS(( void ));
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: match.c,v 1.4 2005/07/31 20:13:08 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: match.c,v 1.5 2006/10/06 21:23:47 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -32,8 +32,8 @@ static char UNUSED id[] = "$Id: match.c,v 1.4 2005/07/31 20:13:08 alex Exp $";
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int Matche PARAMS(( char *p, char *t ));
 | 
			
		||||
static int Matche_After_Star PARAMS(( char *p, char *t ));
 | 
			
		||||
static int Matche PARAMS(( const char *p, const char *t ));
 | 
			
		||||
static int Matche_After_Star PARAMS(( const char *p, const char *t ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define MATCH_PATTERN	6	/* bad pattern */
 | 
			
		||||
@@ -45,7 +45,7 @@ static int Matche_After_Star PARAMS(( char *p, char *t ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Match( char *Pattern, char *String )
 | 
			
		||||
Match( const char *Pattern, const char *String )
 | 
			
		||||
{
 | 
			
		||||
	/* Pattern mit String vergleichen */
 | 
			
		||||
	if( Matche( Pattern, String ) == MATCH_VALID ) return true;
 | 
			
		||||
@@ -54,7 +54,7 @@ Match( char *Pattern, char *String )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
Matche( char *p, char *t )
 | 
			
		||||
Matche( const char *p, const char *t )
 | 
			
		||||
{
 | 
			
		||||
	register char range_start, range_end;
 | 
			
		||||
	bool invert;
 | 
			
		||||
@@ -201,7 +201,7 @@ Matche( char *p, char *t )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
Matche_After_Star( char *p, char *t )
 | 
			
		||||
Matche_After_Star( const char *p, const char *t )
 | 
			
		||||
{
 | 
			
		||||
	register int nextp, match = 0;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: match.h,v 1.3 2005/03/19 18:43:49 fw Exp $
 | 
			
		||||
 * $Id: match.h,v 1.4 2006/10/06 21:23:47 fw Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Wildcard pattern matching (header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
#define __match_h__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Match PARAMS(( char *Pattern, char *String ));
 | 
			
		||||
GLOBAL bool Match PARAMS(( const char *Pattern, const char *String ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: messages.h,v 1.67 2005/09/02 12:50:25 alex Exp $
 | 
			
		||||
 * $Id: messages.h,v 1.74 2007/12/11 11:29:44 fw Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * IRC numerics (Header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -22,7 +22,8 @@
 | 
			
		||||
#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_ISUPPORT_MSG		"005 %s NICKLEN=%d TOPICLEN=%d AWAYLEN=%d MAXCHANNELS=%d :are supported on this server"
 | 
			
		||||
#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_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"
 | 
			
		||||
#define RPL_TRACEOPERATOR_MSG		"204 %s Oper 2 :%s"
 | 
			
		||||
@@ -31,18 +32,19 @@
 | 
			
		||||
#define RPL_STATSCOMMANDS_MSG		"212 %s %s %ld %ld %ld"
 | 
			
		||||
#define RPL_ENDOFSTATS_MSG		"219 %s %c :End of STATS report"
 | 
			
		||||
#define RPL_UMODEIS_MSG			"221 %s +%s"
 | 
			
		||||
#define RPL_STATSUPTIME			"242 %s :Server Up %u days %u:%02u:%02u"
 | 
			
		||||
#define RPL_LUSERCLIENT_MSG		"251 %s :There are %ld users and %ld services on %ld servers"
 | 
			
		||||
#define RPL_LUSEROP_MSG			"252 %s %ld :operator(s) online"
 | 
			
		||||
#define RPL_LUSERUNKNOWN_MSG		"253 %s %ld :unknown connection(s)"
 | 
			
		||||
#define RPL_LUSERCHANNELS_MSG		"254 %s %ld :channels formed"
 | 
			
		||||
#define RPL_LUSERME_MSG			"255 %s :I have %ld users, %ld services and %ld servers"
 | 
			
		||||
#define RPL_LUSEROP_MSG			"252 %s %lu :operator(s) online"
 | 
			
		||||
#define RPL_LUSERUNKNOWN_MSG		"253 %s %lu :unknown connection(s)"
 | 
			
		||||
#define RPL_LUSERCHANNELS_MSG		"254 %s %lu :channels formed"
 | 
			
		||||
#define RPL_LUSERME_MSG			"255 %s :I have %lu users, %lu services and %lu servers"
 | 
			
		||||
#define RPL_ADMINME_MSG			"256 %s %s :Administrative info"
 | 
			
		||||
#define RPL_ADMINLOC1_MSG		"257 %s :%s"
 | 
			
		||||
#define RPL_ADMINLOC2_MSG		"258 %s :%s"
 | 
			
		||||
#define RPL_ADMINEMAIL_MSG		"259 %s :%s"
 | 
			
		||||
#define RPL_TRACEEND_MSG		"262 %s %s %s-%s.%s :End of TRACE"
 | 
			
		||||
#define RPL_LOCALUSERS_MSG		"265 %s :Current local users: %ld, Max: %ld"
 | 
			
		||||
#define RPL_NETUSERS_MSG		"266 %s :Current global users: %ld, Max: %ld"
 | 
			
		||||
#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_AWAY_MSG			"301 %s %s :%s"
 | 
			
		||||
#define RPL_USERHOST_MSG		"302 %s :"
 | 
			
		||||
@@ -54,7 +56,7 @@
 | 
			
		||||
#define RPL_WHOISOPERATOR_MSG		"313 %s %s :is an IRC operator"
 | 
			
		||||
#define RPL_WHOWASUSER_MSG		"314 %s %s %s %s * :%s"
 | 
			
		||||
#define RPL_ENDOFWHO_MSG		"315 %s %s :End of WHO list"
 | 
			
		||||
#define RPL_WHOISIDLE_MSG		"317 %s %s %ld :seconds idle"
 | 
			
		||||
#define RPL_WHOISIDLE_MSG		"317 %s %s %lu %lu :seconds idle, signon time"
 | 
			
		||||
#define RPL_ENDOFWHOIS_MSG		"318 %s %s :End of WHOIS list"
 | 
			
		||||
#define RPL_WHOISCHANNELS_MSG		"319 %s %s :"
 | 
			
		||||
#define RPL_LIST_MSG			"322 %s %s %ld :%s"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2006 Alexander Barton (alex@barton.de).
 | 
			
		||||
 * Copyright (c)2001-2007 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
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: ngircd.c,v 1.113 2006/07/23 12:07:33 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: ngircd.c,v 1.117 2007/11/21 12:16:36 alex Exp $";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
@@ -271,7 +271,6 @@ main( int argc, const char *argv[] )
 | 
			
		||||
 | 
			
		||||
		/* Initialize modules, part II: these functions are eventually
 | 
			
		||||
		 * called with already dropped privileges ... */
 | 
			
		||||
		Lists_Init( );
 | 
			
		||||
		Channel_Init( );
 | 
			
		||||
		Client_Init( );
 | 
			
		||||
#ifdef ZEROCONF
 | 
			
		||||
@@ -328,7 +327,6 @@ main( int argc, const char *argv[] )
 | 
			
		||||
#endif
 | 
			
		||||
		Client_Exit( );
 | 
			
		||||
		Channel_Exit( );
 | 
			
		||||
		Lists_Exit( );
 | 
			
		||||
		Log_Exit( );
 | 
			
		||||
	}
 | 
			
		||||
	Pidfile_Delete( );
 | 
			
		||||
@@ -424,6 +422,7 @@ 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;
 | 
			
		||||
@@ -431,17 +430,22 @@ NGIRCd_Rehash( void )
 | 
			
		||||
	/* Close down all listening sockets */
 | 
			
		||||
	Conn_ExitListeners( );
 | 
			
		||||
 | 
			
		||||
	/* Remember old server name */
 | 
			
		||||
	/* Remember old server name and nick name length */
 | 
			
		||||
	strlcpy( old_name, Conf_ServerName, sizeof old_name );
 | 
			
		||||
	old_nicklen = Conf_MaxNickLength;
 | 
			
		||||
 | 
			
		||||
	/* Re-read configuration ... */
 | 
			
		||||
	Conf_Rehash( );
 | 
			
		||||
 | 
			
		||||
	/* Recover old server name: it 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." );
 | 
			
		||||
	/* 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 */
 | 
			
		||||
@@ -548,7 +552,7 @@ static void
 | 
			
		||||
Show_Version( void )
 | 
			
		||||
{
 | 
			
		||||
	puts( NGIRCd_Version );
 | 
			
		||||
	puts( "Copyright (c)2001-2006 Alexander Barton (<alex@barton.de>) and Contributors." );
 | 
			
		||||
	puts( "Copyright (c)2001-2007 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." );
 | 
			
		||||
@@ -799,7 +803,7 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
 | 
			
		||||
			if( chdir( pwd->pw_dir ) == 0 ) 
 | 
			
		||||
				Log( LOG_DEBUG, "Changed working directory to \"%s\" ...", pwd->pw_dir );
 | 
			
		||||
			else 
 | 
			
		||||
				Log( LOG_ERR, "Can't change working directory to \"%s\": %s",
 | 
			
		||||
				Log( LOG_INFO, "Notice: Can't change working directory to \"%s\": %s",
 | 
			
		||||
								pwd->pw_dir, strerror( errno ));
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										334
									
								
								src/ngircd/numeric.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										334
									
								
								src/ngircd/numeric.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,334 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2007 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.
 | 
			
		||||
 *
 | 
			
		||||
 * Handlers for IRC numerics sent to the server
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: numeric.c,v 1.1 2007/11/21 12:20:32 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "lists.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "numeric.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Announce new server in the network
 | 
			
		||||
 * @param Client New server
 | 
			
		||||
 * @param Server Existing server in the network
 | 
			
		||||
 */
 | 
			
		||||
static bool
 | 
			
		||||
Announce_Server(CLIENT * Client, CLIENT * Server)
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
 | 
			
		||||
	if (Client_Conn(Server) > NONE) {
 | 
			
		||||
		/* Announce the new server to the one already registered
 | 
			
		||||
		 * which is directly connected to the local server */
 | 
			
		||||
		if (!IRC_WriteStrClient
 | 
			
		||||
		    (Server, "SERVER %s %d %d :%s", Client_ID(Client),
 | 
			
		||||
		     Client_Hops(Client) + 1, Client_MyToken(Client),
 | 
			
		||||
		     Client_Info(Client)))
 | 
			
		||||
			return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (Client_Hops(Server) == 1)
 | 
			
		||||
		c = Client_ThisServer();
 | 
			
		||||
	else
 | 
			
		||||
		c = Client_Introducer(Server);
 | 
			
		||||
 | 
			
		||||
	/* Inform new server about the one already registered in the network */
 | 
			
		||||
	return IRC_WriteStrClientPrefix(Client, c, "SERVER %s %d %d :%s",
 | 
			
		||||
		Client_ID(Server), Client_Hops(Server) + 1,
 | 
			
		||||
		Client_MyToken(Server), Client_Info(Server));
 | 
			
		||||
} /* Announce_Server */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Announce existing user to a new server
 | 
			
		||||
 * @param Client New server
 | 
			
		||||
 * @param User Existing user in the network
 | 
			
		||||
 */
 | 
			
		||||
static bool
 | 
			
		||||
Announce_User(CLIENT * Client, CLIENT * User)
 | 
			
		||||
{
 | 
			
		||||
	return IRC_WriteStrClient(Client, "NICK %s %d %s %s %d +%s :%s",
 | 
			
		||||
		Client_ID(User), Client_Hops(User) + 1, Client_User(User),
 | 
			
		||||
		Client_Hostname(User), Client_MyToken(Client_Introducer(User)),
 | 
			
		||||
		Client_Modes(User), Client_Info(User));
 | 
			
		||||
} /* Announce_User */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Synchronize invite and ban lists between servers
 | 
			
		||||
 * @param Client New server
 | 
			
		||||
 */
 | 
			
		||||
static bool
 | 
			
		||||
Synchronize_Lists(CLIENT * Client)
 | 
			
		||||
{
 | 
			
		||||
	CHANNEL *c;
 | 
			
		||||
	struct list_head *head;
 | 
			
		||||
	struct list_elem *elem;
 | 
			
		||||
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
 | 
			
		||||
	c = Channel_First();
 | 
			
		||||
	while (c) {
 | 
			
		||||
		/* ban list */
 | 
			
		||||
		head = Channel_GetListBans(c);
 | 
			
		||||
		elem = Lists_GetFirst(head);
 | 
			
		||||
		while (elem) {
 | 
			
		||||
			if (!IRC_WriteStrClient(Client, "MODE %s +b %s",
 | 
			
		||||
						Channel_Name(c),
 | 
			
		||||
						Lists_GetMask(elem))) {
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
			elem = Lists_GetNext(elem);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* invite list */
 | 
			
		||||
		head = Channel_GetListInvites(c);
 | 
			
		||||
		elem = Lists_GetFirst(head);
 | 
			
		||||
		while (elem) {
 | 
			
		||||
			if (!IRC_WriteStrClient(Client, "MODE %s +I %s",
 | 
			
		||||
						Channel_Name(c),
 | 
			
		||||
						Lists_GetMask(elem))) {
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
			elem = Lists_GetNext(elem);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		c = Channel_Next(c);
 | 
			
		||||
	}
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Send CHANINFO commands to a new server (inform it about existing channels).
 | 
			
		||||
 * @param Client New server
 | 
			
		||||
 * @param Chan Channel
 | 
			
		||||
 */
 | 
			
		||||
static bool
 | 
			
		||||
Send_CHANINFO(CLIENT * Client, CHANNEL * Chan)
 | 
			
		||||
{
 | 
			
		||||
	char *modes, *topic;
 | 
			
		||||
	bool has_k, has_l;
 | 
			
		||||
	
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	Log(LOG_DEBUG, "Sending CHANINFO commands ...");
 | 
			
		||||
#endif
 | 
			
		||||
	
 | 
			
		||||
	modes = Channel_Modes(Chan);
 | 
			
		||||
	topic = Channel_Topic(Chan);
 | 
			
		||||
	
 | 
			
		||||
	if (!*modes && !*topic)
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	
 | 
			
		||||
	has_k = strchr(modes, 'k') != NULL;
 | 
			
		||||
	has_l = strchr(modes, 'l') != NULL;
 | 
			
		||||
	
 | 
			
		||||
	/* send CHANINFO */
 | 
			
		||||
	if (!has_k && !has_l) {
 | 
			
		||||
		if (!*topic) {
 | 
			
		||||
			/* "CHANINFO <chan> +<modes>" */
 | 
			
		||||
			return IRC_WriteStrClient(Client, "CHANINFO %s +%s",
 | 
			
		||||
						  Channel_Name(Chan), modes);
 | 
			
		||||
		}
 | 
			
		||||
		/* "CHANINFO <chan> +<modes> :<topic>" */
 | 
			
		||||
		return IRC_WriteStrClient(Client, "CHANINFO %s +%s :%s",
 | 
			
		||||
					  Channel_Name(Chan), modes, topic);
 | 
			
		||||
	}
 | 
			
		||||
	/* "CHANINFO <chan> +<modes> <key> <limit> :<topic>" */
 | 
			
		||||
	return IRC_WriteStrClient(Client, "CHANINFO %s +%s %s %lu :%s",
 | 
			
		||||
				  Channel_Name(Chan), modes,
 | 
			
		||||
				  has_k ? Channel_Key(Chan) : "*",
 | 
			
		||||
				  has_l ? Channel_MaxUsers(Chan) : 0, topic);
 | 
			
		||||
} /* Send_CHANINFO */
 | 
			
		||||
 | 
			
		||||
#endif /* IRCPLUS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle ENDOFMOTD (376) numeric and login remote server.
 | 
			
		||||
 * The peer is either an IRC server (no IRC+ protocol), or we got the
 | 
			
		||||
 * ENDOFMOTD numeric from an IRC+ server. We have to register the new server.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req)
 | 
			
		||||
{
 | 
			
		||||
	char str[LINE_LEN];
 | 
			
		||||
	int max_hops, i;
 | 
			
		||||
	CLIENT *c, *cl;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
 | 
			
		||||
	Client_SetType(Client, CLIENT_SERVER);
 | 
			
		||||
 | 
			
		||||
	Log(LOG_NOTICE | LOG_snotice,
 | 
			
		||||
	    "Server \"%s\" registered (connection %d, 1 hop - direct link).",
 | 
			
		||||
	    Client_ID(Client), Client_Conn(Client));
 | 
			
		||||
 | 
			
		||||
	/* Get highest hop count */
 | 
			
		||||
	max_hops = 0;
 | 
			
		||||
	c = Client_First();
 | 
			
		||||
	while (c) {
 | 
			
		||||
		if (Client_Hops(c) > max_hops)
 | 
			
		||||
			max_hops = Client_Hops(c);
 | 
			
		||||
		c = Client_Next(c);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Inform the new server about all other servers, and announce the
 | 
			
		||||
	 * new server to all the already registered ones. Important: we have
 | 
			
		||||
	 * to do this "in order" and can't introduce servers of which the
 | 
			
		||||
	 * "toplevel server" isn't known already. */
 | 
			
		||||
	for (i = 0; i < (max_hops + 1); i++) {
 | 
			
		||||
		for (c = Client_First(); c != NULL; c = Client_Next(c)) {
 | 
			
		||||
			if (Client_Type(c) != CLIENT_SERVER)
 | 
			
		||||
				continue;	/* not a server */
 | 
			
		||||
			if (Client_Hops(c) != i)
 | 
			
		||||
				continue;	/* not actual "nesting level" */
 | 
			
		||||
			if (c == Client || c == Client_ThisServer())
 | 
			
		||||
				continue;	/* that's us or the peer! */
 | 
			
		||||
 | 
			
		||||
			if (!Announce_Server(Client, c))
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Announce all the users to the new server */
 | 
			
		||||
	c = Client_First();
 | 
			
		||||
	while (c) {
 | 
			
		||||
		if (Client_Type(c) == CLIENT_USER) {
 | 
			
		||||
			if (!Announce_User(Client, c))
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
		c = Client_Next(c);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Announce all channels to the new server */
 | 
			
		||||
	chan = Channel_First();
 | 
			
		||||
	while (chan) {
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
		/* Send CHANINFO if the peer supports it */
 | 
			
		||||
		if (strchr(Client_Flags(Client), 'C')) {
 | 
			
		||||
			if (!Send_CHANINFO(Client, chan))
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		/* Get all the members of this channel */
 | 
			
		||||
		cl2chan = Channel_FirstMember(chan);
 | 
			
		||||
		snprintf(str, sizeof(str), "NJOIN %s :", Channel_Name(chan));
 | 
			
		||||
		while (cl2chan) {
 | 
			
		||||
			cl = Channel_GetClient(cl2chan);
 | 
			
		||||
			assert(cl != NULL);
 | 
			
		||||
 | 
			
		||||
			/* Nick name, with modes (if applicable) */
 | 
			
		||||
			if (str[strlen(str) - 1] != ':')
 | 
			
		||||
				strlcat(str, ",", sizeof(str));
 | 
			
		||||
			if (strchr(Channel_UserModes(chan, cl), 'v'))
 | 
			
		||||
				strlcat(str, "+", sizeof(str));
 | 
			
		||||
			if (strchr(Channel_UserModes(chan, cl), 'o'))
 | 
			
		||||
				strlcat(str, "@", sizeof(str));
 | 
			
		||||
			strlcat(str, Client_ID(cl), sizeof(str));
 | 
			
		||||
 | 
			
		||||
			/* Send the data if the buffer is "full" */
 | 
			
		||||
			if (strlen(str) > (LINE_LEN - CLIENT_NICK_LEN - 8)) {
 | 
			
		||||
				if (!IRC_WriteStrClient(Client, "%s", str))
 | 
			
		||||
					return DISCONNECTED;
 | 
			
		||||
				snprintf(str, sizeof(str), "NJOIN %s :",
 | 
			
		||||
					 Channel_Name(chan));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			cl2chan = Channel_NextMember(chan, cl2chan);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Data left in the buffer? */
 | 
			
		||||
		if (str[strlen(str) - 1] != ':') {
 | 
			
		||||
			/* Yes, send it ... */
 | 
			
		||||
			if (!IRC_WriteStrClient(Client, "%s", str))
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Get next channel ... */
 | 
			
		||||
		chan = Channel_Next(chan);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
	if (strchr(Client_Flags(Client), 'L')) {
 | 
			
		||||
		LogDebug("Synchronizing INVITE- and BAN-lists ...");
 | 
			
		||||
		if (!Synchronize_Lists(Client))
 | 
			
		||||
			return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_Num_ENDOFMOTD */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle ISUPPORT (005) numeric.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_Num_ISUPPORT(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	char *key, *value;
 | 
			
		||||
 | 
			
		||||
	for (i = 1; i < Req->argc - 1; i++) {
 | 
			
		||||
		key = Req->argv[i];
 | 
			
		||||
		value = strchr(key, '=');
 | 
			
		||||
		if (value)
 | 
			
		||||
			*value++ = '\0';
 | 
			
		||||
		else
 | 
			
		||||
			value = "";
 | 
			
		||||
 | 
			
		||||
		if (strcmp("NICKLEN", key) == 0) {
 | 
			
		||||
			if ((unsigned int)atol(value) == Conf_MaxNickLength - 1)
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			/* Nick name length settings are different! */
 | 
			
		||||
			Log(LOG_ERR,
 | 
			
		||||
			    "Peer uses incompatible nick name length (%d/%d)! Disconnecting ...",
 | 
			
		||||
			    Conf_MaxNickLength - 1, atoi(value));
 | 
			
		||||
			Conn_Close(Client_Conn(Client),
 | 
			
		||||
				   "Incompatible nick name length",
 | 
			
		||||
				   NULL, false);
 | 
			
		||||
			return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_Num_ISUPPORT */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										24
									
								
								src/ngircd/numeric.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/ngircd/numeric.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2007 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
 | 
			
		||||
 * 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: numeric.h,v 1.1 2007/11/21 12:20:32 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Handlers for IRC numerics sent to the server (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __numeric_h__
 | 
			
		||||
#define __numeric_h__
 | 
			
		||||
 | 
			
		||||
GLOBAL bool IRC_Num_ENDOFMOTD PARAMS((CLIENT *Client, UNUSED REQUEST *Req));
 | 
			
		||||
GLOBAL bool IRC_Num_ISUPPORT PARAMS((CLIENT *Client, REQUEST *Req));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
@@ -12,7 +12,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: parse.c,v 1.67 2006/04/23 10:37:27 fw Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: parse.c,v 1.69.2.1 2008/02/05 13:11:20 fw Exp $";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
@@ -48,6 +48,7 @@ static char UNUSED id[] = "$Id: parse.c,v 1.67 2006/04/23 10:37:27 fw Exp $";
 | 
			
		||||
#include "irc-oper.h"
 | 
			
		||||
#include "irc-server.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "numeric.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
 | 
			
		||||
@@ -93,6 +94,7 @@ COMMAND My_Commands[] =
 | 
			
		||||
	{ "USER", IRC_USER, 0xFFFF, 0, 0, 0 },
 | 
			
		||||
	{ "USERHOST", IRC_USERHOST, CLIENT_USER, 0, 0, 0 },
 | 
			
		||||
	{ "VERSION", IRC_VERSION, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "WALLOPS", IRC_WALLOPS, CLIENT_USER|CLIENT_SERVER, 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 },
 | 
			
		||||
@@ -102,6 +104,13 @@ COMMAND My_Commands[] =
 | 
			
		||||
	{ NULL, NULL, 0x0, 0, 0, 0 } /* Ende-Marke */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
NUMERIC My_Numerics[] =
 | 
			
		||||
{
 | 
			
		||||
	{ 005, IRC_Num_ISUPPORT },
 | 
			
		||||
	{ 376, IRC_Num_ENDOFMOTD },
 | 
			
		||||
	{ 0, NULL } /* end marker */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void Init_Request PARAMS(( REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
@@ -348,7 +357,8 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
 | 
			
		||||
	char str[LINE_LEN];
 | 
			
		||||
	bool result;
 | 
			
		||||
	COMMAND *cmd;
 | 
			
		||||
	int i;
 | 
			
		||||
	NUMERIC *num;
 | 
			
		||||
	int i, client_type;
 | 
			
		||||
 | 
			
		||||
	assert( Idx >= 0 );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
@@ -357,25 +367,45 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
 | 
			
		||||
	client = Conn_GetClient( Idx );
 | 
			
		||||
	assert( client != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Statuscode? */
 | 
			
		||||
	if(( Client_Type( client ) == CLIENT_SERVER ) && ( strlen( Req->command ) == 3 ) && ( atoi( Req->command ) > 100 ))
 | 
			
		||||
	{
 | 
			
		||||
		/* Command is a status code from an other server */
 | 
			
		||||
	/* Numeric? */
 | 
			
		||||
	if ((Client_Type(client) == CLIENT_SERVER ||
 | 
			
		||||
	     Client_Type(client) == CLIENT_UNKNOWNSERVER)
 | 
			
		||||
	    && strlen(Req->command) == 3 && atoi(Req->command) > 1) {
 | 
			
		||||
		/* Command is a status code ("numeric") from an other server */
 | 
			
		||||
 | 
			
		||||
		/* Determine target */
 | 
			
		||||
		if( Req->argc > 0 ) target = Client_Search( Req->argv[0] );
 | 
			
		||||
		else target = NULL;
 | 
			
		||||
		if( ! target )
 | 
			
		||||
		{
 | 
			
		||||
		if (Req->argc > 0)
 | 
			
		||||
			target = Client_Search( Req->argv[0] );
 | 
			
		||||
		else
 | 
			
		||||
			target = NULL;
 | 
			
		||||
		if (!target) {
 | 
			
		||||
			/* Status code without target!? */
 | 
			
		||||
			if( Req->argc > 0 ) Log( LOG_WARNING, "Unknown target for status code %s: \"%s\"", Req->command, Req->argv[0] );
 | 
			
		||||
			else Log( LOG_WARNING, "Unknown target for status code %s!", Req->command );
 | 
			
		||||
			if (Req->argc > 0)
 | 
			
		||||
				Log(LOG_WARNING,
 | 
			
		||||
				    "Unknown target for status code %s: \"%s\"",
 | 
			
		||||
				    Req->command, Req->argv[0]);
 | 
			
		||||
			else
 | 
			
		||||
				Log(LOG_WARNING,
 | 
			
		||||
				    "Unknown target for status code %s!",
 | 
			
		||||
				    Req->command);
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		if( target == Client_ThisServer( ))
 | 
			
		||||
		{
 | 
			
		||||
			/* This server is the target, ignore it */
 | 
			
		||||
			Log( LOG_DEBUG, "Ignored status code %s from \"%s\".", Req->command, Client_ID( client ));
 | 
			
		||||
		if (target == Client_ThisServer()) {
 | 
			
		||||
			/* This server is the target of the numeric */
 | 
			
		||||
			i = atoi(Req->command);
 | 
			
		||||
 | 
			
		||||
			num = My_Numerics;
 | 
			
		||||
			while (num->numeric > 0) {
 | 
			
		||||
				if (i != num->numeric) {
 | 
			
		||||
					num++;
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				result = (num->function)(client, Req);
 | 
			
		||||
				return result;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			LogDebug("Ignored status code %s from \"%s\".",
 | 
			
		||||
				 Req->command, Client_ID(client));
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -406,6 +436,7 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cmd = My_Commands;
 | 
			
		||||
	client_type = Client_Type(client);
 | 
			
		||||
	while( cmd->name )
 | 
			
		||||
	{
 | 
			
		||||
		/* Befehl suchen */
 | 
			
		||||
@@ -414,7 +445,7 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
 | 
			
		||||
			cmd++; continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if( Client_Type( client ) & cmd->type )
 | 
			
		||||
		if( client_type & cmd->type )
 | 
			
		||||
		{
 | 
			
		||||
			/* Command is allowed for this client: call it and count produced bytes */
 | 
			
		||||
			Conn_ResetWCounter( );
 | 
			
		||||
@@ -422,7 +453,7 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
 | 
			
		||||
			cmd->bytes += Conn_WCounter( );
 | 
			
		||||
 | 
			
		||||
			/* Adjust counters */
 | 
			
		||||
			if( Client_Type( client ) != CLIENT_SERVER ) cmd->lcount++;
 | 
			
		||||
			if( client_type != CLIENT_SERVER ) cmd->lcount++;
 | 
			
		||||
			else cmd->rcount++;
 | 
			
		||||
 | 
			
		||||
			return result;
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: parse.h,v 1.11 2005/03/19 18:43:49 fw Exp $
 | 
			
		||||
 * $Id: parse.h,v 1.12 2007/11/21 12:16:36 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * IRC command parser and validator (header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -33,11 +33,18 @@ typedef struct _COMMAND
 | 
			
		||||
	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 */
 | 
			
		||||
	long bytes;		/* number of bytes created */
 | 
			
		||||
	long lcount, rcount;		/* number of local and remote calls */
 | 
			
		||||
	long bytes;			/* number of bytes created */
 | 
			
		||||
} COMMAND;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct _NUMERIC
 | 
			
		||||
{
 | 
			
		||||
	int numeric;			/* numeric */
 | 
			
		||||
	bool (*function) PARAMS(( CLIENT *Client, REQUEST *Request ));
 | 
			
		||||
} NUMERIC;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Parse_Request PARAMS((CONN_ID Idx, char *Request ));
 | 
			
		||||
 | 
			
		||||
GLOBAL COMMAND *Parse_GetCommandStruct PARAMS(( void ));
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: resolve.c,v 1.24 2006/05/10 21:24:01 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: resolve.c,v 1.28 2008/01/02 11:03:29 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -24,7 +24,6 @@ static char UNUSED id[] = "$Id: resolve.c,v 1.24 2006/05/10 21:24:01 alex Exp $"
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
@@ -36,6 +35,7 @@ static char UNUSED id[] = "$Id: resolve.c,v 1.24 2006/05/10 21:24:01 alex Exp $"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "tool.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
@@ -153,8 +153,8 @@ Do_ResolveAddr( struct sockaddr_in *Addr, int identsock, int w_fd )
 | 
			
		||||
	/* Resolver sub-process: resolve IP address and write result into
 | 
			
		||||
	 * pipe to parent. */
 | 
			
		||||
 | 
			
		||||
	char hostname[HOST_LEN];
 | 
			
		||||
	char ipstr[HOST_LEN];
 | 
			
		||||
	char hostname[CLIENT_HOST_LEN];
 | 
			
		||||
	char ipstr[CLIENT_HOST_LEN];
 | 
			
		||||
	struct hostent *h;
 | 
			
		||||
	size_t len;
 | 
			
		||||
	struct in_addr *addr;
 | 
			
		||||
@@ -169,7 +169,7 @@ Do_ResolveAddr( struct sockaddr_in *Addr, int identsock, int w_fd )
 | 
			
		||||
	Log_Resolver( LOG_DEBUG, "Now resolving %s ...", inet_ntoa( Addr->sin_addr ));
 | 
			
		||||
#endif
 | 
			
		||||
	h = gethostbyaddr( (char *)&Addr->sin_addr, sizeof( Addr->sin_addr ), AF_INET );
 | 
			
		||||
	if (!h) {
 | 
			
		||||
	if (!h || strlen(h->h_name) >= sizeof(hostname)) {
 | 
			
		||||
#ifdef h_errno
 | 
			
		||||
		Log_Resolver( LOG_WARNING, "Can't resolve address \"%s\": %s!", inet_ntoa( Addr->sin_addr ), Get_Error( h_errno ));
 | 
			
		||||
#else
 | 
			
		||||
@@ -313,7 +313,8 @@ register_callback( RES_STAT *s, void (*cbfunc)(int, short))
 | 
			
		||||
			return true;
 | 
			
		||||
 | 
			
		||||
	Log( LOG_CRIT, "Resolver: Could not register callback function: %s!", strerror(errno));
 | 
			
		||||
	Resolve_Shutdown(s);
 | 
			
		||||
	close(s->resolver_fd);
 | 
			
		||||
	Resolve_Init(s);
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -333,40 +334,31 @@ Resolve_Shutdown( RES_STAT *s)
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Read result of resolver sub-process from pipe
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL size_t
 | 
			
		||||
Resolve_Read( RES_STAT *s, void* readbuf, size_t buflen)
 | 
			
		||||
{
 | 
			
		||||
	int err;
 | 
			
		||||
	ssize_t bytes_read;
 | 
			
		||||
 | 
			
		||||
	assert(buflen > 0);
 | 
			
		||||
 | 
			
		||||
	/* Read result from pipe */
 | 
			
		||||
	errno = 0;
 | 
			
		||||
	bytes_read = read(s->resolver_fd, readbuf, buflen);
 | 
			
		||||
	if (bytes_read < 0) {
 | 
			
		||||
		if (errno != EAGAIN) {
 | 
			
		||||
			err = errno;
 | 
			
		||||
			Log( LOG_CRIT, "Resolver: Can't read result: %s!", strerror(err));
 | 
			
		||||
			Resolve_Shutdown(s);
 | 
			
		||||
			errno = err;
 | 
			
		||||
		if (errno == EAGAIN)
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Resolve_Shutdown(s);
 | 
			
		||||
	if (bytes_read == 0) {	/* EOF: lookup failed */
 | 
			
		||||
		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
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Resolve_Shutdown(s);
 | 
			
		||||
	return (size_t)bytes_read;
 | 
			
		||||
}
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								src/portab/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/portab/.cvsignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
.deps
 | 
			
		||||
portabtest
 | 
			
		||||
							
								
								
									
										7
									
								
								src/testsuite/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/testsuite/.cvsignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
T-ngircd
 | 
			
		||||
logs
 | 
			
		||||
ngircd-test.log
 | 
			
		||||
ngircd-test.motd
 | 
			
		||||
tests
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
 | 
			
		||||
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile.am,v 1.14 2004/09/08 09:40:51 alex Exp $
 | 
			
		||||
# $Id: Makefile.am,v 1.15 2007/11/18 15:07:16 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
AUTOMAKE_OPTIONS = ../portab/ansi2knr
 | 
			
		||||
@@ -40,12 +40,15 @@ ngircd-TEST-Binary:
 | 
			
		||||
	[ -f getpid.sh ] || ln -s $(srcdir)/getpid.sh .
 | 
			
		||||
 | 
			
		||||
connect-test: tests.sh
 | 
			
		||||
	rm -f connect-test
 | 
			
		||||
	ln -s $(srcdir)/tests.sh connect-test
 | 
			
		||||
 | 
			
		||||
channel-test: tests.sh
 | 
			
		||||
	rm -f channel-test
 | 
			
		||||
	ln -s $(srcdir)/tests.sh channel-test
 | 
			
		||||
 | 
			
		||||
mode-test: tests.sh
 | 
			
		||||
	rm -f mode-test
 | 
			
		||||
	ln -s $(srcdir)/tests.sh mode-test
 | 
			
		||||
 | 
			
		||||
TESTS = start-server.sh \
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +1,17 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# ngIRCd Test Suite
 | 
			
		||||
# $Id: getpid.sh,v 1.4 2003/08/22 11:31:18 alex Exp $
 | 
			
		||||
# $Id: getpid.sh,v 1.5 2006/08/05 00:15:28 alex Exp $
 | 
			
		||||
 | 
			
		||||
# did we get a name?
 | 
			
		||||
[ $# -ne 1 ] && exit 1
 | 
			
		||||
 | 
			
		||||
# detect flags for "ps" and "head"
 | 
			
		||||
if [ `uname` = "FreeBSD" ]; then
 | 
			
		||||
UNAME=`uname`
 | 
			
		||||
if [ $UNAME = "FreeBSD" -o $UNAME = "SunOS" ]; then
 | 
			
		||||
  PS_FLAGS="-a"; PS_PIDCOL="1"; HEAD_FLAGS="-n 1"
 | 
			
		||||
elif [ `uname` = "A/UX" ]; then
 | 
			
		||||
elif [ $UNAME = "A/UX" ]; then
 | 
			
		||||
  PS_FLAGS="-ae"; PS_PIDCOL="1"; HEAD_FLAGS="-1"
 | 
			
		||||
elif [ `uname` = "GNU" ]; then
 | 
			
		||||
elif [ $UNAME = "GNU" ]; then
 | 
			
		||||
  PS_FLAGS="-ax"; PS_PIDCOL="2"; HEAD_FLAGS="-n 1"
 | 
			
		||||
else
 | 
			
		||||
  PS_FLAGS="-f"; PS_PIDCOL="2"; HEAD_FLAGS="-n 1"
 | 
			
		||||
@@ -19,13 +20,17 @@ else
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# debug output
 | 
			
		||||
#echo "$0: UNAME=$UNAME"
 | 
			
		||||
#echo "$0: PS_FLAGS=$PS_FLAGS"
 | 
			
		||||
#echo "$0: PS_PIDCOL=$PS_PIDCOL"
 | 
			
		||||
#echo "$0: HEAD_FLAGS=$HEAD_FLAGS"
 | 
			
		||||
 | 
			
		||||
# search PID
 | 
			
		||||
ps $PS_FLAGS > procs.tmp
 | 
			
		||||
cat procs.tmp | grep -v "$0" | grep "$1" | awk "{print \$$PS_PIDCOL}" | sort -n > pids.tmp
 | 
			
		||||
cat procs.tmp | \
 | 
			
		||||
  grep -v "$0" | grep "$1" | \
 | 
			
		||||
  awk "{print \$$PS_PIDCOL}" | \
 | 
			
		||||
  sort -n > pids.tmp
 | 
			
		||||
pid=`head $HEAD_FLAGS pids.tmp`
 | 
			
		||||
rm -rf procs.tmp pids.tmp
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
# $Id: mode-test.e,v 1.6 2004/03/10 20:40:06 alex Exp $
 | 
			
		||||
# $Id: mode-test.e,v 1.6.8.1 2008/02/16 11:26:13 fw Exp $
 | 
			
		||||
 | 
			
		||||
spawn telnet localhost 6789
 | 
			
		||||
expect {
 | 
			
		||||
@@ -72,7 +72,7 @@ expect {
 | 
			
		||||
send "mode #channel +v nick\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"@* MODE #channel +v nick"
 | 
			
		||||
	"@* MODE #channel +v nick\r"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "mode #channel +I nick1\r"
 | 
			
		||||
@@ -96,7 +96,7 @@ expect {
 | 
			
		||||
send "mode #channel -vo nick nick\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"@* MODE #channel -vo nick nick"
 | 
			
		||||
	"@* MODE #channel -vo nick nick\r"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "quit\r"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
# $Id: ngircd-test.conf,v 1.4 2003/11/05 23:31:43 alex Exp $
 | 
			
		||||
# $Id: ngircd-test.conf,v 1.5 2007/11/18 15:07:16 alex Exp $
 | 
			
		||||
 | 
			
		||||
[Global]
 | 
			
		||||
	Name = ngircd.test.server
 | 
			
		||||
@@ -7,6 +7,8 @@
 | 
			
		||||
	MotdFile = ngircd-test.motd
 | 
			
		||||
	AdminEMail = admin@irc.server
 | 
			
		||||
	MaxConnectionsIP = 0
 | 
			
		||||
	ServerUID = 1
 | 
			
		||||
	ServerGID = 1
 | 
			
		||||
 | 
			
		||||
[Operator]
 | 
			
		||||
	Name = TestOp
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								src/tool/.cvsignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/tool/.cvsignore
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
Makefile
 | 
			
		||||
Makefile.in
 | 
			
		||||
.deps
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: tool.c,v 1.6 2006/04/09 12:53:07 alex Exp $";
 | 
			
		||||
static char UNUSED id[] = "$Id: tool.c,v 1.8 2007/11/25 18:42:38 fw Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@@ -22,6 +22,8 @@ static char UNUSED id[] = "$Id: tool.c,v 1.6 2006/04/09 12:53:07 alex Exp $";
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "tool.h"
 | 
			
		||||
 | 
			
		||||
@@ -105,4 +107,22 @@ ngt_TrimLastChr( char *String, const char Chr)
 | 
			
		||||
} /* ngt_TrimLastChr */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
ngt_IPStrToBin(const char *ip_str, struct in_addr *inaddr)
 | 
			
		||||
{
 | 
			
		||||
	/* AF is always AF_INET for now */
 | 
			
		||||
#ifdef HAVE_INET_ATON
 | 
			
		||||
	if (inet_aton(ip_str, inaddr) == 0)
 | 
			
		||||
		return false;
 | 
			
		||||
#else
 | 
			
		||||
	inaddr->s_addr = inet_addr(ip_str);
 | 
			
		||||
	if (inaddr->s_addr == (unsigned)-1)
 | 
			
		||||
		return false;
 | 
			
		||||
#endif
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: tool.h,v 1.3 2005/03/19 18:43:53 fw Exp $
 | 
			
		||||
 * $Id: tool.h,v 1.5 2007/11/25 18:42:38 fw Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Tool functions (Header)
 | 
			
		||||
 */
 | 
			
		||||
@@ -16,7 +16,13 @@
 | 
			
		||||
 | 
			
		||||
#ifndef __tool_h__
 | 
			
		||||
#define __tool_h__
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_ARPA_INET_H
 | 
			
		||||
# include <arpa/inet.h>
 | 
			
		||||
#else
 | 
			
		||||
# define PF_INET AF_INET
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
GLOBAL void ngt_TrimLastChr PARAMS((char *String, const char Chr ));
 | 
			
		||||
 | 
			
		||||
@@ -24,7 +30,7 @@ GLOBAL void ngt_TrimStr PARAMS((char *String ));
 | 
			
		||||
 | 
			
		||||
GLOBAL char *ngt_LowerStr PARAMS((char *String ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool ngt_IPStrToBin PARAMS((const char *ip_str, struct in_addr *inaddr));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user