mirror of
				https://github.com/osmarks/ngircd.git
				synced 2025-11-03 23:43:00 +00:00 
			
		
		
		
	Compare commits
	
		
			410 Commits
		
	
	
		
			rel-18
			...
			rel-20-rc2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					a0d57a6afd | ||
| 
						 | 
					c6ae353756 | ||
| 
						 | 
					12768e7a54 | ||
| 
						 | 
					35e2dcff88 | ||
| 
						 | 
					dc89e42ef5 | ||
| 
						 | 
					4a2d74c9ab | ||
| 
						 | 
					cd48b8128e | ||
| 
						 | 
					301d4915bc | ||
| 
						 | 
					8061056cec | ||
| 
						 | 
					44926b7f9f | ||
| 
						 | 
					d11a700589 | ||
| 
						 | 
					0a26079af2 | ||
| 
						 | 
					b6e49f3920 | ||
| 
						 | 
					4123118d5a | ||
| 
						 | 
					e29d198700 | ||
| 
						 | 
					6f531a3c99 | ||
| 
						 | 
					53917fa4b8 | ||
| 
						 | 
					646218e6f4 | ||
| 
						 | 
					4185c4a44a | ||
| 
						 | 
					45b0bb5aff | ||
| 
						 | 
					c7db2f8429 | ||
| 
						 | 
					f0b86e6c26 | ||
| 
						 | 
					7871a904d7 | ||
| 
						 | 
					40e3daf560 | ||
| 
						 | 
					44b7ff02fd | ||
| 
						 | 
					35ed57e6c1 | ||
| 
						 | 
					79731a57f3 | ||
| 
						 | 
					a7f37cebdc | ||
| 
						 | 
					47b99c69cc | ||
| 
						 | 
					757f3497bc | ||
| 
						 | 
					f2455cbe33 | ||
| 
						 | 
					e3f300d323 | ||
| 
						 | 
					497edbaf3e | ||
| 
						 | 
					48326e061a | ||
| 
						 | 
					84e9dcbab0 | ||
| 
						 | 
					30b32e84fe | ||
| 
						 | 
					fb92493376 | ||
| 
						 | 
					eb4f9eac0c | ||
| 
						 | 
					d7b5dd1bbf | ||
| 
						 | 
					b18e81b631 | ||
| 
						 | 
					8ff153d7d4 | ||
| 
						 | 
					32f63abb59 | ||
| 
						 | 
					23572af942 | ||
| 
						 | 
					8d9cfa157a | ||
| 
						 | 
					58abd0777b | ||
| 
						 | 
					3ee98d9f72 | ||
| 
						 | 
					b1a5ade88f | ||
| 
						 | 
					73229249d8 | ||
| 
						 | 
					e0da56fc7b | ||
| 
						 | 
					cdaaae0cb2 | ||
| 
						 | 
					c319fb8eaa | ||
| 
						 | 
					538e612a47 | ||
| 
						 | 
					9d97004a28 | ||
| 
						 | 
					87deb43012 | ||
| 
						 | 
					a9cbb375b7 | ||
| 
						 | 
					161adbb1aa | ||
| 
						 | 
					de2fa78d92 | ||
| 
						 | 
					8bede388af | ||
| 
						 | 
					c9d166747d | ||
| 
						 | 
					56cdc2175c | ||
| 
						 | 
					de453d71cb | ||
| 
						 | 
					23b07bdf50 | ||
| 
						 | 
					9ac94339dc | ||
| 
						 | 
					46b0eef721 | ||
| 
						 | 
					d3ae351236 | ||
| 
						 | 
					4790d78c98 | ||
| 
						 | 
					c66e20ce6e | ||
| 
						 | 
					343a90dc37 | ||
| 
						 | 
					09ab0704f4 | ||
| 
						 | 
					114644cdb0 | ||
| 
						 | 
					cf9f9e1f30 | ||
| 
						 | 
					19ce256a95 | ||
| 
						 | 
					eba53f652c | ||
| 
						 | 
					d8ee498a65 | ||
| 
						 | 
					e3a1a61868 | ||
| 
						 | 
					1a2bdd9e4c | ||
| 
						 | 
					384f965fba | ||
| 
						 | 
					005340c83f | ||
| 
						 | 
					d21afce2b6 | ||
| 
						 | 
					808c291c76 | ||
| 
						 | 
					62a07596d6 | ||
| 
						 | 
					b730b64bbe | ||
| 
						 | 
					3e22fc32f3 | ||
| 
						 | 
					e65a35e964 | ||
| 
						 | 
					78d189fbf7 | ||
| 
						 | 
					8cfb910441 | ||
| 
						 | 
					039a939cb8 | ||
| 
						 | 
					d7d5f4330b | ||
| 
						 | 
					79c1222896 | ||
| 
						 | 
					a3f3a1097b | ||
| 
						 | 
					d4df626d88 | ||
| 
						 | 
					eed8a4ee6e | ||
| 
						 | 
					b1b83831d1 | ||
| 
						 | 
					8e1beae4e7 | ||
| 
						 | 
					baed0618ed | ||
| 
						 | 
					e3e181f4b3 | ||
| 
						 | 
					1f2aa4da6f | ||
| 
						 | 
					fc39146f48 | ||
| 
						 | 
					192e304b94 | ||
| 
						 | 
					1744a8d145 | ||
| 
						 | 
					b12acddf4f | ||
| 
						 | 
					ef82ef4ddb | ||
| 
						 | 
					bb20aeb9bc | ||
| 
						 | 
					e9d0b2f039 | ||
| 
						 | 
					222ecbffbb | ||
| 
						 | 
					ce736fc15b | ||
| 
						 | 
					1413a4886f | ||
| 
						 | 
					cfec819f0d | ||
| 
						 | 
					107bfdc821 | ||
| 
						 | 
					5c160921ff | ||
| 
						 | 
					fe3bef55b7 | ||
| 
						 | 
					5300f0082c | ||
| 
						 | 
					85abfd84be | ||
| 
						 | 
					005ffeaa8c | ||
| 
						 | 
					5c8c6d3c70 | ||
| 
						 | 
					7eb3932d3a | ||
| 
						 | 
					ebf2f991b5 | ||
| 
						 | 
					a451cb22f1 | ||
| 
						 | 
					82bf4eb059 | ||
| 
						 | 
					d53d58fff2 | ||
| 
						 | 
					a072180c92 | ||
| 
						 | 
					0fd9a8505a | ||
| 
						 | 
					b2482b39e4 | ||
| 
						 | 
					74c7d7131f | ||
| 
						 | 
					4dd1c31dc7 | ||
| 
						 | 
					2e13e821f8 | ||
| 
						 | 
					2478c5816b | ||
| 
						 | 
					47ad9afcf3 | ||
| 
						 | 
					67e882d4bb | ||
| 
						 | 
					25c216cbdf | ||
| 
						 | 
					f5441d2170 | ||
| 
						 | 
					0d67be3f30 | ||
| 
						 | 
					f37600ee01 | ||
| 
						 | 
					f38a9035e5 | ||
| 
						 | 
					a12d6ff257 | ||
| 
						 | 
					2205227c3b | ||
| 
						 | 
					d2d867ea36 | ||
| 
						 | 
					b232ae2f17 | ||
| 
						 | 
					53b2acc00b | ||
| 
						 | 
					01b62202b2 | ||
| 
						 | 
					b68bb560e9 | ||
| 
						 | 
					21467c76f1 | ||
| 
						 | 
					33fae67579 | ||
| 
						 | 
					864015fa3f | ||
| 
						 | 
					1d3def0cc6 | ||
| 
						 | 
					e01e8f1cb6 | ||
| 
						 | 
					186ab51137 | ||
| 
						 | 
					74be904018 | ||
| 
						 | 
					298cd9a327 | ||
| 
						 | 
					414bfe65eb | ||
| 
						 | 
					c519ba9920 | ||
| 
						 | 
					fee8ff37b3 | ||
| 
						 | 
					fee591b759 | ||
| 
						 | 
					16f94546f5 | ||
| 
						 | 
					55859c1bef | ||
| 
						 | 
					bcefdef1ea | ||
| 
						 | 
					f79d41e927 | ||
| 
						 | 
					1680ea02da | ||
| 
						 | 
					1aaf54ac24 | ||
| 
						 | 
					a5984c702a | ||
| 
						 | 
					9a82304ae9 | ||
| 
						 | 
					a26e37b746 | ||
| 
						 | 
					c2b39fdede | ||
| 
						 | 
					8349a1c0d9 | ||
| 
						 | 
					360a254be0 | ||
| 
						 | 
					ab1fcebeff | ||
| 
						 | 
					a6dd2e33c2 | ||
| 
						 | 
					9d8974d509 | ||
| 
						 | 
					037b4b76df | ||
| 
						 | 
					be97fa8ab1 | ||
| 
						 | 
					164954a788 | ||
| 
						 | 
					c1d7f6216f | ||
| 
						 | 
					7df4c12da9 | ||
| 
						 | 
					0d5de60584 | ||
| 
						 | 
					4b0f526006 | ||
| 
						 | 
					4cf65b973c | ||
| 
						 | 
					160f728530 | ||
| 
						 | 
					922540306e | ||
| 
						 | 
					d48e440a72 | ||
| 
						 | 
					0709a0f050 | ||
| 
						 | 
					097c72aa65 | ||
| 
						 | 
					7b01bb833f | ||
| 
						 | 
					cfd0bddc30 | ||
| 
						 | 
					b53b12aa5f | ||
| 
						 | 
					d0bb185cf5 | ||
| 
						 | 
					49385a98b2 | ||
| 
						 | 
					b9e6cb3e55 | ||
| 
						 | 
					dffe5a9d60 | ||
| 
						 | 
					d7eb343ea0 | ||
| 
						 | 
					bf5610a3b9 | ||
| 
						 | 
					7bce6780ca | ||
| 
						 | 
					bf121ae95f | ||
| 
						 | 
					7b6b492bdd | ||
| 
						 | 
					aa7db2c0e9 | ||
| 
						 | 
					684e50f0a4 | ||
| 
						 | 
					4a90959cb5 | ||
| 
						 | 
					9b1cf420f1 | ||
| 
						 | 
					e7e47e77a3 | ||
| 
						 | 
					695df6532e | ||
| 
						 | 
					6680b536c4 | ||
| 
						 | 
					a21a7d8b66 | ||
| 
						 | 
					c0d059cd0e | ||
| 
						 | 
					7faa3ed7d6 | ||
| 
						 | 
					c9b152fa41 | ||
| 
						 | 
					ae27571414 | ||
| 
						 | 
					5e5377a063 | ||
| 
						 | 
					884c5bcff1 | ||
| 
						 | 
					3a2fcc32cd | ||
| 
						 | 
					a8aa8c6cbc | ||
| 
						 | 
					f01b09ce84 | ||
| 
						 | 
					2419a701d8 | ||
| 
						 | 
					110be707c3 | ||
| 
						 | 
					b2743af0ed | ||
| 
						 | 
					76565022fb | ||
| 
						 | 
					4602cb9891 | ||
| 
						 | 
					1d7e99531a | ||
| 
						 | 
					f0a9dbe3ad | ||
| 
						 | 
					245782897b | ||
| 
						 | 
					2327b17656 | ||
| 
						 | 
					359732af85 | ||
| 
						 | 
					1dea0d91a0 | ||
| 
						 | 
					d67d077a71 | ||
| 
						 | 
					69be7a85a2 | ||
| 
						 | 
					8ec17063a6 | ||
| 
						 | 
					da4c1ebe81 | ||
| 
						 | 
					bd3a7ccb15 | ||
| 
						 | 
					edfcc2f9d5 | ||
| 
						 | 
					ee362b3bd2 | ||
| 
						 | 
					67bd1bf34f | ||
| 
						 | 
					9f3af061cf | ||
| 
						 | 
					88c3d4896a | ||
| 
						 | 
					7b6ef3bc8e | ||
| 
						 | 
					fbaa751da8 | ||
| 
						 | 
					06b6327875 | ||
| 
						 | 
					0d9740b9fa | ||
| 
						 | 
					e9be3334d1 | ||
| 
						 | 
					0ae74ceaed | ||
| 
						 | 
					17ffda1c8a | ||
| 
						 | 
					0de11ead36 | ||
| 
						 | 
					9d486db460 | ||
| 
						 | 
					257fe922d2 | ||
| 
						 | 
					1068f88377 | ||
| 
						 | 
					9e7360e5fa | ||
| 
						 | 
					273d4bdd32 | ||
| 
						 | 
					27d244dfae | ||
| 
						 | 
					a39a1a5273 | ||
| 
						 | 
					ef392e7d37 | ||
| 
						 | 
					c38751191f | ||
| 
						 | 
					5cbdcf4f0d | ||
| 
						 | 
					3641e51109 | ||
| 
						 | 
					3f46e93ccc | ||
| 
						 | 
					8e3c56e5b2 | ||
| 
						 | 
					e1026d5dd1 | ||
| 
						 | 
					f7bdee5f13 | ||
| 
						 | 
					391aa8d1f7 | ||
| 
						 | 
					89d99e2ff9 | ||
| 
						 | 
					c16133c5ee | ||
| 
						 | 
					4888984429 | ||
| 
						 | 
					44bb22d23e | ||
| 
						 | 
					c7dd5ea0ba | ||
| 
						 | 
					871760583c | ||
| 
						 | 
					bc20f9ec10 | ||
| 
						 | 
					5a200e1543 | ||
| 
						 | 
					d2df7396a8 | ||
| 
						 | 
					3d27073d61 | ||
| 
						 | 
					b6f19ea8fe | ||
| 
						 | 
					8c46067b34 | ||
| 
						 | 
					594fdd02aa | ||
| 
						 | 
					6a308fcb42 | ||
| 
						 | 
					1537c79132 | ||
| 
						 | 
					e0c9931ad8 | ||
| 
						 | 
					eba95bb0d2 | ||
| 
						 | 
					51a6a33056 | ||
| 
						 | 
					6e28f4a7d1 | ||
| 
						 | 
					9882e578e9 | ||
| 
						 | 
					73781c1b38 | ||
| 
						 | 
					f2fa1045e2 | ||
| 
						 | 
					33a165721b | ||
| 
						 | 
					a3a4b5f696 | ||
| 
						 | 
					39412d6486 | ||
| 
						 | 
					c1656256df | ||
| 
						 | 
					1f4711a547 | ||
| 
						 | 
					4d0069c3a8 | ||
| 
						 | 
					12c60a670e | ||
| 
						 | 
					2f7d0c0839 | ||
| 
						 | 
					1afbf71236 | ||
| 
						 | 
					7ed08f01ef | ||
| 
						 | 
					81cc5f82b5 | ||
| 
						 | 
					78a3b4c7d6 | ||
| 
						 | 
					39d630c00d | ||
| 
						 | 
					4fe6b42c53 | ||
| 
						 | 
					d4d8102fc9 | ||
| 
						 | 
					77f68b4fd1 | ||
| 
						 | 
					2f8877ded4 | ||
| 
						 | 
					4bff3daf92 | ||
| 
						 | 
					c5beca8aab | ||
| 
						 | 
					f8405b1a4f | ||
| 
						 | 
					fdfc27265e | ||
| 
						 | 
					a4d1e6007f | ||
| 
						 | 
					9260759cec | ||
| 
						 | 
					c2ac1ad3ba | ||
| 
						 | 
					470d2e2362 | ||
| 
						 | 
					888664435a | ||
| 
						 | 
					98493077a2 | ||
| 
						 | 
					1fa2af5b3a | ||
| 
						 | 
					05cc9bf9b0 | ||
| 
						 | 
					cc06e1ff89 | ||
| 
						 | 
					9fbf592924 | ||
| 
						 | 
					adf92302bf | ||
| 
						 | 
					566a451299 | ||
| 
						 | 
					e0f8ce093a | ||
| 
						 | 
					5e3449a241 | ||
| 
						 | 
					762b0325df | ||
| 
						 | 
					6b62a5ec4f | ||
| 
						 | 
					b24d645ca1 | ||
| 
						 | 
					1bb2fbedcc | ||
| 
						 | 
					3193d5477c | ||
| 
						 | 
					edab86e0f8 | ||
| 
						 | 
					e4006a93e3 | ||
| 
						 | 
					9069380ddf | ||
| 
						 | 
					ab188c1486 | ||
| 
						 | 
					5eb9f2e717 | ||
| 
						 | 
					abfc5c6e27 | ||
| 
						 | 
					565523cbb4 | ||
| 
						 | 
					013298d4c6 | ||
| 
						 | 
					af13732ec7 | ||
| 
						 | 
					408a74b865 | ||
| 
						 | 
					f47904bf95 | ||
| 
						 | 
					70eb8219f5 | ||
| 
						 | 
					9e5b9ddad0 | ||
| 
						 | 
					56b7e67307 | ||
| 
						 | 
					b681aa5b9f | ||
| 
						 | 
					b32f3b76e9 | ||
| 
						 | 
					1a5ed654b4 | ||
| 
						 | 
					9cbb8f3bb8 | ||
| 
						 | 
					e19ce437ca | ||
| 
						 | 
					4e550bf9ef | ||
| 
						 | 
					1d29a59f7e | ||
| 
						 | 
					765c2f26ea | ||
| 
						 | 
					69fa6f268a | ||
| 
						 | 
					43509fd22c | ||
| 
						 | 
					a71abfef4b | ||
| 
						 | 
					8a8e8a3a23 | ||
| 
						 | 
					65befdafaa | ||
| 
						 | 
					15fec92ed7 | ||
| 
						 | 
					1e4a00f94f | ||
| 
						 | 
					338758799d | ||
| 
						 | 
					164e15b8c6 | ||
| 
						 | 
					32bfafafd9 | ||
| 
						 | 
					6ef20e0f9a | ||
| 
						 | 
					e86e193e01 | ||
| 
						 | 
					ae5ebfb9f0 | ||
| 
						 | 
					e9e6224aae | ||
| 
						 | 
					e23f025dd6 | ||
| 
						 | 
					3ca8703309 | ||
| 
						 | 
					fc82efc3e8 | ||
| 
						 | 
					dc9fcb0fb2 | ||
| 
						 | 
					2b95c69ea1 | ||
| 
						 | 
					af70c3dbc9 | ||
| 
						 | 
					1e054e0b82 | ||
| 
						 | 
					06a20b87c4 | ||
| 
						 | 
					fea2194fc0 | ||
| 
						 | 
					872dc5042d | ||
| 
						 | 
					e1315f30fd | ||
| 
						 | 
					0a85c58878 | ||
| 
						 | 
					ee21490887 | ||
| 
						 | 
					8fa92f0a24 | ||
| 
						 | 
					8e193df973 | ||
| 
						 | 
					9d348d00d9 | ||
| 
						 | 
					9e48f3f8f8 | ||
| 
						 | 
					e4a06844a3 | ||
| 
						 | 
					20ccc1bba7 | ||
| 
						 | 
					13d9e0c5a7 | ||
| 
						 | 
					a7911e35af | ||
| 
						 | 
					60812b6fdf | ||
| 
						 | 
					1ea6811616 | ||
| 
						 | 
					d2f54abbed | ||
| 
						 | 
					07dbb73c92 | ||
| 
						 | 
					30796698a9 | ||
| 
						 | 
					f173a974be | ||
| 
						 | 
					8aac366802 | ||
| 
						 | 
					69803d6ff1 | ||
| 
						 | 
					be6994aece | ||
| 
						 | 
					1361b3742d | ||
| 
						 | 
					d3036c74e9 | ||
| 
						 | 
					553e8b6aa3 | ||
| 
						 | 
					51d7674ee7 | ||
| 
						 | 
					1189200d4a | ||
| 
						 | 
					7795b07c53 | ||
| 
						 | 
					d9325e8030 | ||
| 
						 | 
					641045249c | ||
| 
						 | 
					69f81a359a | ||
| 
						 | 
					be03bc672c | ||
| 
						 | 
					160c52400f | ||
| 
						 | 
					0b8acf1205 | ||
| 
						 | 
					88f6fc5fd8 | ||
| 
						 | 
					da897a2a14 | ||
| 
						 | 
					989c9fa531 | ||
| 
						 | 
					2fd42667c2 | ||
| 
						 | 
					2dfa24d2fa | ||
| 
						 | 
					1ed602eb47 | ||
| 
						 | 
					ea725b99b7 | ||
| 
						 | 
					3dc3a03538 | ||
| 
						 | 
					95f0e4033c | ||
| 
						 | 
					409b2c86c8 | ||
| 
						 | 
					d692286d7a | ||
| 
						 | 
					456e55921d | ||
| 
						 | 
					9f3690c39c | ||
| 
						 | 
					6cbe13085d | ||
| 
						 | 
					b7780e3f2a | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -4,11 +4,13 @@ aclocal.m4
 | 
			
		||||
ansi2knr.1
 | 
			
		||||
ansi2knr.c
 | 
			
		||||
ansi2knr.h
 | 
			
		||||
ar-lib
 | 
			
		||||
autom4te.cache
 | 
			
		||||
build-stamp-ngircd*
 | 
			
		||||
config.log
 | 
			
		||||
config.status
 | 
			
		||||
configure
 | 
			
		||||
configure.ac
 | 
			
		||||
configure.lineno
 | 
			
		||||
cscope.out
 | 
			
		||||
debian
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								AUTHORS
									
									
									
									
									
								
							@@ -2,7 +2,7 @@
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
                           http://ngircd.barton.de/
 | 
			
		||||
 | 
			
		||||
               (c)2001-2011 Alexander Barton and Contributors.
 | 
			
		||||
               (c)2001-2012 Alexander Barton and Contributors.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
@@ -10,9 +10,10 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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!
 | 
			
		||||
post a mail to the ngIRCd mailing list: <ngircd-ml@arthur.barton.de> (please
 | 
			
		||||
see <http://ngircd.barton.de/#ml> for details).
 | 
			
		||||
 | 
			
		||||
Don't mail the people listed here directly, if possible!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Main Authors
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										39
									
								
								COPYING
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								COPYING
									
									
									
									
									
								
							@@ -1,12 +1,12 @@
 | 
			
		||||
		    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
		       Version 2, June 1991
 | 
			
		||||
                    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
                       Version 2, June 1991
 | 
			
		||||
 | 
			
		||||
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
 | 
			
		||||
 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
 | 
			
		||||
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 Everyone is permitted to copy and distribute verbatim copies
 | 
			
		||||
 of this license document, but changing it is not allowed.
 | 
			
		||||
 | 
			
		||||
			    Preamble
 | 
			
		||||
                            Preamble
 | 
			
		||||
 | 
			
		||||
  The licenses for most software are designed to take away your
 | 
			
		||||
freedom to share and change it.  By contrast, the GNU General Public
 | 
			
		||||
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users.  This
 | 
			
		||||
General Public License applies to most of the Free Software
 | 
			
		||||
Foundation's software and to any other program whose authors commit to
 | 
			
		||||
using it.  (Some other Free Software Foundation software is covered by
 | 
			
		||||
the GNU Library General Public License instead.)  You can apply it to
 | 
			
		||||
the GNU Lesser General Public License instead.)  You can apply it to
 | 
			
		||||
your programs, too.
 | 
			
		||||
 | 
			
		||||
  When we speak of free software, we are referring to freedom, not
 | 
			
		||||
@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
 | 
			
		||||
 | 
			
		||||
  The precise terms and conditions for copying, distribution and
 | 
			
		||||
modification follow.
 | 
			
		||||
 | 
			
		||||
		    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
 | 
			
		||||
                    GNU GENERAL PUBLIC LICENSE
 | 
			
		||||
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 | 
			
		||||
 | 
			
		||||
  0. This License applies to any program or other work which contains
 | 
			
		||||
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
 | 
			
		||||
    License.  (Exception: if the Program itself is interactive but
 | 
			
		||||
    does not normally print such an announcement, your work based on
 | 
			
		||||
    the Program is not required to print an announcement.)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
These requirements apply to the modified work as a whole.  If
 | 
			
		||||
identifiable sections of that work are not derived from the Program,
 | 
			
		||||
and can be reasonably considered independent and separate works in
 | 
			
		||||
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
 | 
			
		||||
access to copy the source code from the same place counts as
 | 
			
		||||
distribution of the source code, even though third parties are not
 | 
			
		||||
compelled to copy the source along with the object code.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  4. You may not copy, modify, sublicense, or distribute the Program
 | 
			
		||||
except as expressly provided under this License.  Any attempt
 | 
			
		||||
otherwise to copy, modify, sublicense or distribute the Program is
 | 
			
		||||
@@ -225,7 +225,7 @@ impose that choice.
 | 
			
		||||
 | 
			
		||||
This section is intended to make thoroughly clear what is believed to
 | 
			
		||||
be a consequence of the rest of this License.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  8. If the distribution and/or use of the Program is restricted in
 | 
			
		||||
certain countries either by patents or by copyrighted interfaces, the
 | 
			
		||||
original copyright holder who places the Program under this License
 | 
			
		||||
@@ -255,7 +255,7 @@ make exceptions for this.  Our decision will be guided by the two goals
 | 
			
		||||
of preserving the free status of all derivatives of our free software and
 | 
			
		||||
of promoting the sharing and reuse of software generally.
 | 
			
		||||
 | 
			
		||||
			    NO WARRANTY
 | 
			
		||||
                            NO WARRANTY
 | 
			
		||||
 | 
			
		||||
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 | 
			
		||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
 | 
			
		||||
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
 | 
			
		||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 | 
			
		||||
POSSIBILITY OF SUCH DAMAGES.
 | 
			
		||||
 | 
			
		||||
		     END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
	    How to Apply These Terms to Your New Programs
 | 
			
		||||
                     END OF TERMS AND CONDITIONS
 | 
			
		||||
 | 
			
		||||
            How to Apply These Terms to Your New Programs
 | 
			
		||||
 | 
			
		||||
  If you develop a new program, and you want it to be of the greatest
 | 
			
		||||
possible use to the public, the best way to achieve this is to make it
 | 
			
		||||
@@ -303,10 +303,9 @@ the "copyright" line and a pointer to where the full notice is found.
 | 
			
		||||
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
    GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License
 | 
			
		||||
    along with this program; if not, write to the Free Software
 | 
			
		||||
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
    You should have received a copy of the GNU General Public License along
 | 
			
		||||
    with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 | 
			
		||||
 | 
			
		||||
Also add information on how to contact you by electronic and paper mail.
 | 
			
		||||
 | 
			
		||||
@@ -336,5 +335,5 @@ necessary.  Here is a sample; alter the names:
 | 
			
		||||
This General Public License does not permit incorporating your program into
 | 
			
		||||
proprietary programs.  If your program is a subroutine library, you may
 | 
			
		||||
consider it more useful to permit linking proprietary applications with the
 | 
			
		||||
library.  If this is what you want to do, use the GNU Library General
 | 
			
		||||
library.  If this is what you want to do, use the GNU Lesser General
 | 
			
		||||
Public License instead of this License.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										371
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										371
									
								
								ChangeLog
									
									
									
									
									
								
							@@ -2,13 +2,356 @@
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
                           http://ngircd.barton.de/
 | 
			
		||||
 | 
			
		||||
               (c)2001-2011 Alexander Barton and Contributors.
 | 
			
		||||
               (c)2001-2012 Alexander Barton and Contributors.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                               -- ChangeLog --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ngIRCd
 | 
			
		||||
 | 
			
		||||
  ngIRCd 20~rc2 (2012-12-02)
 | 
			
		||||
  - Rework cloaked hostname handling and implement the "METADATA cloakhost"
 | 
			
		||||
    subcommand: Now ngIRCd uses two fields internally, one to store the
 | 
			
		||||
    "real" hostname and one to save the "cloaked" hostname. This allows
 | 
			
		||||
    "foreign servers" (aka "IRC services") to alter the real and cloaked
 | 
			
		||||
    hostnames of clients without problems, even when the user itself issues
 | 
			
		||||
    additional "MODE +x" and "MODE -x" commands.
 | 
			
		||||
  - RPL_UMODEIS: send correct target name, even on server links.
 | 
			
		||||
  - Update platformtest.sh to follow autoconf changes and only generate
 | 
			
		||||
    the "configure" script when it is missing.
 | 
			
		||||
  - Fix the test suite to correctly execute test scripts even when stdout
 | 
			
		||||
    is redirected.
 | 
			
		||||
  - Fix some compiler warnings on NetBSD and OpenBSD.
 | 
			
		||||
 | 
			
		||||
  ngIRCd 20~rc1 (2012-11-11)
 | 
			
		||||
  - Update doc/Services.txt: describe the upcoming version of Anope 1.9.8,
 | 
			
		||||
    then including a protocol module for ngIRCd. And remove our own patches
 | 
			
		||||
    in ./contrib/Anope because they aren't supported any more ...
 | 
			
		||||
  - Implement new "METADATA" command which can be used by remote servers
 | 
			
		||||
    and IRC services to update client metadata like the client info text
 | 
			
		||||
    ("real name"), user name, and hostname, and use this command to
 | 
			
		||||
    configure an cloaked hostname (user mode "+x") on remote servers:
 | 
			
		||||
    This prevents "double cloaking" of hostnames and even cloaked
 | 
			
		||||
    hostnames are in sync on all servers supporting "METADATA" now.
 | 
			
		||||
  - Fix error message when trying to join non-predefined channels and the
 | 
			
		||||
    "PredefChannelsOnly" configuration option is set.
 | 
			
		||||
  - Implement new IRC "SVSNICK" command to allow remote servers (and IRC
 | 
			
		||||
    services) to change nicknames of already registered users. The SVSNICK
 | 
			
		||||
    command itself doesn't change the nickname, but it becomes forwarded
 | 
			
		||||
    to the server to which the user is connected to. And then this server
 | 
			
		||||
    initiates the real nickname changing using regular NICK commands.
 | 
			
		||||
    This allows to run mixed networks with old servers not supporting the
 | 
			
		||||
    SVSNICK command, because SVSNICK commands for nicknames on such servers
 | 
			
		||||
    are silently ignored and don't cause a desynchronization of the network.
 | 
			
		||||
  - Make server reconnect time a little bit more random, so that two
 | 
			
		||||
    servers trying to connect to each other asynchronously don't try this
 | 
			
		||||
    in exactly the same time periods and kick each other off ...
 | 
			
		||||
  - Don't accept connections for servers already being linked: there was a
 | 
			
		||||
    time frame that could result in one connection overwriting the other,
 | 
			
		||||
    e. g. the incoming connection overwriting the status of the outgoing
 | 
			
		||||
    one. And this could lead to all kind of weirdness (even crashes!) later
 | 
			
		||||
    on: now such incoming connections are dropped.
 | 
			
		||||
  - New configuration option "MaxListSize" to configure the maximum number
 | 
			
		||||
    of channels returned by a LIST command. The default is 100, as before.
 | 
			
		||||
  - Implement user mode "b", "block messages": when a user has set mode "b",
 | 
			
		||||
    all private messages and notices to this user are blocked if they don't
 | 
			
		||||
    originate from a registered user, an IRC Op, server or service. The
 | 
			
		||||
    originator gets an error numeric sent back in this case,
 | 
			
		||||
    ERR_NONONREG_MSG (486), which is used by UnrealIRCd, too. (Closes #144)
 | 
			
		||||
  - WHOIS: Not only show RPL_WHOISHOST_MSG to local IRC operators, but show
 | 
			
		||||
    it to all IRC operators in the network. And don't show it to anybody if
 | 
			
		||||
    the "more privacy" configuration option is enabled. (Closes #134)
 | 
			
		||||
  - Test suite: make expect scripts more verbose displaying dots for each
 | 
			
		||||
    reply of the server that it is waiting for.
 | 
			
		||||
  - WHOIS: Implement numeric RPL_WHOISMODES_MSG (379) and show user modes in
 | 
			
		||||
    the reply of the WHOIS command for the user himself or, if MorePrivacy
 | 
			
		||||
    isn't set, for request initiated by an IRC operator. (Closes #129)
 | 
			
		||||
  - Implement channel mode "V" (invite disallow): If the new channel mode
 | 
			
		||||
    "V" is set, the INVITE command becomes invalid and all clients get the
 | 
			
		||||
    new ERR_NOINVITE_MSG (518) reply. (Closes #143)
 | 
			
		||||
  - KICK-protect IRC services.
 | 
			
		||||
  - Implement channel mode "Q" and user mode "q": Both modes protect users
 | 
			
		||||
    from channel kicks: only IRC operators and servers can kick users having
 | 
			
		||||
    mode "q" or in channels with mode "Q". (Closes #141)
 | 
			
		||||
  - Debian: require "telnet" or "telnet-ssl" for building and enable
 | 
			
		||||
    CHARCONV in ngircd-full[-dbg] variants.
 | 
			
		||||
  - Send RPL_REHASHING (382) numeric if a REHASH command was accepted.
 | 
			
		||||
  - Fix spelling and variable names in some log messages.
 | 
			
		||||
  - Allow users to "cloak" their hostname only when the configuration
 | 
			
		||||
    variable "CloakHostModeX" (introduced in 19.2) is set. Otherwise, only
 | 
			
		||||
    IRC operators, other servers, and services are allowed to set the user
 | 
			
		||||
    mode "+x": this prevents regular users from changing their hostmask to
 | 
			
		||||
    the name of the IRC server itself, which confused quite a few people ;-)
 | 
			
		||||
    (Closes #133)
 | 
			
		||||
  - New configuration option "OperChanPAutoOp": If disabled, IRC operators
 | 
			
		||||
    don't become channel operators in persistent channels when joining.
 | 
			
		||||
    Enabled by default, which has been the behavior of ngIRCd up to this
 | 
			
		||||
    patch. (Closes #135)
 | 
			
		||||
  - Allow IRC operators to see secret (+s) channels in LIST command as long
 | 
			
		||||
    as the "MorePrivacy" configuration option isn't enabled in the
 | 
			
		||||
    configuration file. (Closes #136)
 | 
			
		||||
  - Enhance build system: Support new (>=1.12) and old (<=1.11) GNU automake
 | 
			
		||||
    versions, update checks for required and optional features, enable
 | 
			
		||||
    colored test output of automake (if available), rename configure.in to
 | 
			
		||||
    more modern configure.ac, include .mailmap and all build-system files in
 | 
			
		||||
    distribution archives and no longer require a GIT tree to detect the
 | 
			
		||||
    correct version string.
 | 
			
		||||
  - Update documentation: add doc/Contributing.txt and include version
 | 
			
		||||
    numbers in doc/Modes.txt.
 | 
			
		||||
  - Free all listen ports on initialization: now listen ports can be
 | 
			
		||||
    reconfigured on runtime using a configuration reload.
 | 
			
		||||
  - Initialize SSL when needed only, and disable SSL on errors.
 | 
			
		||||
  - Implement new (optional) IRC+ "CHARCONV" command to set a client
 | 
			
		||||
    character set that the server translates all messages to/from UTF-8.
 | 
			
		||||
    This feature requires the "libiconv" library and must be enabled using
 | 
			
		||||
    the new "--with-iconv" option of the ./configure script. See
 | 
			
		||||
    doc/Protocol.txt for details. (Closes #109)
 | 
			
		||||
  - Allow limited punctuation in usernames, for better PAM integration.
 | 
			
		||||
  - Correctly re-initialize signal handlers on RESTART commands.
 | 
			
		||||
  - Show a warning on startup if the configuration file is not a full path:
 | 
			
		||||
    ngIRCd is a long-running process and changes its working directory to
 | 
			
		||||
    "/" to not block mounted filesystems and the like when running as daemon
 | 
			
		||||
    ("not in the foreground"); therefore the path to the configuration file
 | 
			
		||||
    must be relative to "/" (or the chroot() directory), which basically is
 | 
			
		||||
    "not relative", to ensure that "kill -HUP" and the "REHASH" command work
 | 
			
		||||
    as expected later on. (Closes #127)
 | 
			
		||||
  - Make the "&SERVER" channel definable in a [Channel] configuration block,
 | 
			
		||||
    which enables server operators to overwrite the built-in topic and
 | 
			
		||||
    channel modes. (Closes #131)
 | 
			
		||||
  - Don't limit list size of "WHO #channel" commands, because it makes no
 | 
			
		||||
    sense to not return all the users in that channel, so I removed the
 | 
			
		||||
    check. But if there are more than MAX_RPL_WHO(25) replies, the client
 | 
			
		||||
    requesting the list will be "penalized" one second more, then 2 in
 | 
			
		||||
    total. (Closes #125)
 | 
			
		||||
  - Make ngIRCd buildable using the kqueue() IO interface on FreeBSD 4.x.
 | 
			
		||||
  - Fix the "NoticeAuth" configuration option when using SSL connections and
 | 
			
		||||
    enhance the message to show the hostname and IDENT reply of the client.
 | 
			
		||||
  - Introduce numeric RPL_HOSTHIDDEN_MSG (396): This numeric is sent to the
 | 
			
		||||
    client each time it changes its displayed hostname using "MODE +/-x",
 | 
			
		||||
    and if "CloakHost" is set right after the MOTD has been sent.
 | 
			
		||||
  - Fix USERHOST not displaying the correctly cloaked hostname.
 | 
			
		||||
  - Implement user mode "B" ("Bot flag"): it is settable and unsettable by
 | 
			
		||||
    every (non-restricted) client. This is how Unreal and InspIRCd do
 | 
			
		||||
    behave, and so do we :-)
 | 
			
		||||
  - Dynamically allocate memory for connection passwords: This a) saves
 | 
			
		||||
    memory for clients not using passwords at all and b) allows for
 | 
			
		||||
    "arbitrarily" long passwords.
 | 
			
		||||
  - Implement channel mode "M": Only the server, identified users and IRC
 | 
			
		||||
    operators are able to talk in such a channel.
 | 
			
		||||
  - Block nicknames that are reserved for services and are defined using the
 | 
			
		||||
    configuration variable "ServiceMask" in "Server" blocks; And this
 | 
			
		||||
    variable now can handle more than one mask separated by commas.
 | 
			
		||||
  - Now "make uninstall" removes the installed "ngircd.conf" file, if it is
 | 
			
		||||
    still equal to our "sample-ngircd.conf" file and therefore hasn't been
 | 
			
		||||
    modified by the user. If it has been modified, it isn't removed and a
 | 
			
		||||
    notice is displayed to the user. And "make install" now displays a
 | 
			
		||||
    message when no ngircd.conf file exists and the "sample-ngircd.conf"
 | 
			
		||||
    file will be installed as a starting point.
 | 
			
		||||
  - Add contrib/ngircd.service, a systemd service file for ngircd.
 | 
			
		||||
  - Implemented XOP channel user modes: "Half Op" ("+h", prefix "%") can set
 | 
			
		||||
    the channel modes +imntvIbek and kick all +v and normal users; "Admin"
 | 
			
		||||
    ("+a", prefix "&") can set channel modes +imntvIbekoRsz and kick all +o,
 | 
			
		||||
    +h, +v and normal users; and "Owner" ("+q", prefix "~") can set channel
 | 
			
		||||
    modes +imntvIbekoRsz and kick all +a, +o, +h, +v and normal users.
 | 
			
		||||
  - Implement hashed cloaked hostnames for both the "CloakHost" and
 | 
			
		||||
    "CloakHostModeX" configuration options: now the admin can use the new
 | 
			
		||||
    '%x' placeholder to insert a hashed version of the clients hostname,
 | 
			
		||||
    and the new configuration option "CloakHostSalt" defines the salt for
 | 
			
		||||
    the hash function. When "CloakHostSalt" is not set (the default), a
 | 
			
		||||
    random salt will be generated after each server restart. (Closes #133)
 | 
			
		||||
 | 
			
		||||
ngIRCd Release 19.2 (2012-06-19)
 | 
			
		||||
 | 
			
		||||
  - doc/Capabilities.txt: document "multi-prefix" capability
 | 
			
		||||
 | 
			
		||||
  ngIRCd 19.2~rc1 (2012-06-13)
 | 
			
		||||
  - New configuration option "CloakHostModeX" to configure the hostname
 | 
			
		||||
    that gets used for IRC clients which have user mode "+x" enabled.
 | 
			
		||||
    Up to now, the name of the IRC server itself has been used for this,
 | 
			
		||||
    which still is the default when "CloakHostModeX" isn't set.
 | 
			
		||||
  - Correctly handle asynchronously re-established server links: a race
 | 
			
		||||
    condition could let the daemon loose track of an already re-established
 | 
			
		||||
    incoming server link while preparing its own outgoing connection.
 | 
			
		||||
    Peers that both try to connect each other could have been affected.
 | 
			
		||||
  - Log a debug message when SIGUSR2 is handled in debug mode.
 | 
			
		||||
  - Only allow alphanumeric characters in user-supplied user names of
 | 
			
		||||
    USER command and IDENT replies.
 | 
			
		||||
  - Change wording of "TLS initialized" message to make it more consistent.
 | 
			
		||||
  - Don't leak file descriptors on error path when creating "PID files".
 | 
			
		||||
  - Add missing mode "r" to CHANMODES in 005 "ISUPPORT" numeric.
 | 
			
		||||
  - Update doc/Modes.txt and doc/Platforms.txt documents.
 | 
			
		||||
  - contrib/platformtest.sh: correctly detect Open64 C compiler and handle
 | 
			
		||||
    "CC=xxx MAKE=yyy ./platformtest.sh" calling convention.
 | 
			
		||||
  - Add instructions for setting up Atheme IRC services.
 | 
			
		||||
  - Implement support for IRC capability handling, the new "CAP" command,
 | 
			
		||||
    and capablity "multi-prefix" which allows both the NAME and	WHO command
 | 
			
		||||
    handlers to return more than one "class prefix" to the client.
 | 
			
		||||
  - Update Xcode project files: reference missing documentation files.
 | 
			
		||||
  - Fix: Don't ignore "permission denied" errors when enabling chroot.
 | 
			
		||||
  - FAQ: enhance description of chroot setup.
 | 
			
		||||
 | 
			
		||||
ngIRCd Release 19.1 (2012-03-19)
 | 
			
		||||
 | 
			
		||||
  - Fix gcc warning (v4.6.3), initialize "list" variable to NULL.
 | 
			
		||||
  - Fix typos: "recieved" -> "received", "Please not" -> "Please note",
 | 
			
		||||
    and fix lintian(1) warning ""hyphen-used-as-minus-sign", too.
 | 
			
		||||
  - Really include _all_ patches to build the Anope module into the
 | 
			
		||||
    distribution archive ... ooops!
 | 
			
		||||
  - getpid.sh: Fix test case error for Debian using sbuild(1).
 | 
			
		||||
  - Don't log "ngIRCd hello message" two times when starting up.
 | 
			
		||||
 | 
			
		||||
ngIRCd Release 19 (2012-02-29)
 | 
			
		||||
 | 
			
		||||
  - Update build system: bump config.guess and config.sub files used by
 | 
			
		||||
    GNU autoconf/automake to recent versions.
 | 
			
		||||
  - Fix configuration file parser: don't accept "[SSL]" blocks in the
 | 
			
		||||
    configuration file when no SSL support is built in ngIRCd.
 | 
			
		||||
  - Fix building ngIRCd with old gcc versions (e. g. 2.7.2).
 | 
			
		||||
  - Correctly re-open syslog logging after reading of configuration
 | 
			
		||||
    file: Syslog logging has been initialized before reading the
 | 
			
		||||
    configuration, so ngIRCd always used the default facility and ignored
 | 
			
		||||
    the "SyslogFacility" configuration option ...
 | 
			
		||||
    Thanks to Patrik Schindler for reporting this issue!
 | 
			
		||||
 | 
			
		||||
  ngIRCd 19~rc1 (2012-02-12)
 | 
			
		||||
  - Enhance command limits for server links: the limit now is dependent
 | 
			
		||||
    on the number of users connected in the network and higher while
 | 
			
		||||
    servers are joining the network to make the login of servers faster.
 | 
			
		||||
  - Log more information about server synchronization.
 | 
			
		||||
  - Update preliminary ngIRCd protocol module for Anope 1.9.6, which now
 | 
			
		||||
    is the only supported version.
 | 
			
		||||
  - New numeric RPL_WHOISHOST_MSG(378), which returns the DNS host name
 | 
			
		||||
    (if available) and the IP address of a client in the WHOIS reply.
 | 
			
		||||
    Only the user itself and local IRC operators get this numeric.
 | 
			
		||||
  - Implement channel exception list (mode 'e'). This allows a channel
 | 
			
		||||
    operator to define exception masks that allow users to join the
 | 
			
		||||
    channel even when a "ban" would match and prevent them from joining:
 | 
			
		||||
    the exception list (e) overrides the ban list (b).
 | 
			
		||||
  - PRIVMSG and NOTICE: Handle nick!user@host masks case-insensitive.
 | 
			
		||||
  - Implement user mode 'C': If the target user of a PRIVMSG or NOTICE
 | 
			
		||||
    command has the user mode 'C' set, it is required that both sender
 | 
			
		||||
    and receiver are on the same channel. This prevents private flooding
 | 
			
		||||
    by completely unknown clients.
 | 
			
		||||
  - New RPL_WHOISREGNICK_MSG(307) numeric in WHOIS command replies: it
 | 
			
		||||
    indicates if a nickname is registered (if user mode 'R' set).
 | 
			
		||||
  - Limit channel invite, ban, and exception lists to 50 entries and fix
 | 
			
		||||
    duplicate check and error messages when adding already listed entries
 | 
			
		||||
    or deleting no (longer) existing ones.
 | 
			
		||||
  - Fix both ERR_SUMMONDISABLED(445) and ERR_USERSDISABLED(446) replies.
 | 
			
		||||
  - MODE command: correctly return ERR_UNKNOWNMODE(472) numeric for
 | 
			
		||||
    unknown channel modes, instead of ERR_UMODEUNKNOWNFLAG(501).
 | 
			
		||||
  - ISUPPORT(005) numeric: add "O", "R", and "z" modes to "CHANMODES",
 | 
			
		||||
    add "EXCEPTS=e" and "INVEX=I", add "MAXLIST=beI:50".
 | 
			
		||||
  - Limit the number of list items in the reply of LIST (100), WHO (25),
 | 
			
		||||
    WHOIS (10), and WHOWAS (25) commands.
 | 
			
		||||
  - LIST command: compare pattern case insensitive.
 | 
			
		||||
  - Limit the MODE command to handle a maximum number of 5 channel modes
 | 
			
		||||
    that require an argument (+Ibkl) per call and report this number
 | 
			
		||||
    in the ISUPPORT(005) numeric: "MODES=5".
 | 
			
		||||
  - Fix handling of channel mode sequence with/without arguments.
 | 
			
		||||
    For example, don't generate wrong error messages when handling
 | 
			
		||||
    "MODE #chan +IIIIItn *!aa@b *!bb@c *!cc@d *!dd@e *!ee@f".
 | 
			
		||||
  - When sending data on a connection, only try to get the type of
 | 
			
		||||
    the client if there still is one assigned. This could trigger an
 | 
			
		||||
    assertion and end the daemon in some error paths.
 | 
			
		||||
  - Don't try to close already closed/invalid sockets to forked child
 | 
			
		||||
    processes. This could potentially crash the daemon in some cases
 | 
			
		||||
    with IDENT lookups enabled.
 | 
			
		||||
  - WHOIS command: make sure that the reply ends with RPL_ENDOFWHOIS,
 | 
			
		||||
    don't answer queries for IRC servers, make sure mask matching is
 | 
			
		||||
    case-insensitive, and that RPL_ENDOFWHOIS numeric is sent with the
 | 
			
		||||
    unmodified mask (like it has been received from the client).
 | 
			
		||||
  - LINKS command: support <mask> parameter to limit the reply.
 | 
			
		||||
  - Add 1 second penalty for every further target on PRIVMSG/NOTICE
 | 
			
		||||
    commands: this reduces the possibility of flooding channels with
 | 
			
		||||
    commands like "PRIVMSG/NOTICE #a,#n,#c,... :message" a little bit.
 | 
			
		||||
    Problem noticed by Cahata, thanks!
 | 
			
		||||
  - Display correct error message when "Server{UID|GID}" variable in the
 | 
			
		||||
    configuration file is invalid (not a number and no existing user).
 | 
			
		||||
  - Update Copyright notices for 2012 :-)
 | 
			
		||||
  - JOIN command: don't stop handling of channel lists when a single
 | 
			
		||||
    channel cannot be joined (because of bad name, wrong key or channel
 | 
			
		||||
    limit reached), but report an error and continue. And don't check
 | 
			
		||||
    the channel limit and don't report with "too many channels" when
 | 
			
		||||
    trying to join a channel that the client already is a member of.
 | 
			
		||||
  - ISON command: reply with the correct upper-/lowercase nicknames.
 | 
			
		||||
  - New configuration option "PAMIsOptional": when set, clients not
 | 
			
		||||
    sending a password are still allowed to connect: they won't become
 | 
			
		||||
    "identified" and keep the "~" character prepended to their supplied
 | 
			
		||||
    user name. See "man 5 ngircd.conf" for details.
 | 
			
		||||
  - Fixed handling of WHO commands. This fixes two bugs: "WHO <nick>"
 | 
			
		||||
    returned nothing at all if the user was "+i" (reported by Cahata,
 | 
			
		||||
    thanks) and "WHO <nick|nickmask>" returned channel names instead
 | 
			
		||||
    of "*" when the user was member of a (visible) channel.
 | 
			
		||||
  - Fixed some spelling errors in documentation and code comments
 | 
			
		||||
    (Thanks to Christoph Biedl).
 | 
			
		||||
  - contrib/Debian/control: Update and complete "Build-Depends" and
 | 
			
		||||
    update our Debian package descriptions with "official" ones.
 | 
			
		||||
  - Fixed typo in two error messages.
 | 
			
		||||
  - LUSERS reply: only count channels that are visible to the requesting
 | 
			
		||||
    client, so the existence of secret channels is no longer revealed by
 | 
			
		||||
    using LUSERS. Reported by Cahata, thanks!
 | 
			
		||||
  - Unknown user and channel modes no longer stop the mode parser, but
 | 
			
		||||
    are simply ignored. Therefore modes after the unknown one are now
 | 
			
		||||
    handled. This is how ircd2.10/ircd2.11/ircd-seven behave, at least.
 | 
			
		||||
    Reported by Cahata, thanks!
 | 
			
		||||
  - README: Update list of implemented commands.
 | 
			
		||||
  - Log better error messages when rejecting clients.
 | 
			
		||||
  - Implement IRC commands "GLINE" and "KLINE" to ban users. G-Lines are
 | 
			
		||||
    synchronized between server on peering, K-Lines are local only.
 | 
			
		||||
    If you use "*!<user>@<host>" or "*!*@<host>" masks, these connections
 | 
			
		||||
    are blocked even before the user is fully logged in (before PASS,
 | 
			
		||||
    NICK, and USER commands have been processed) and before the child
 | 
			
		||||
    processes for authentication are forked, so resource usage is smaller.
 | 
			
		||||
  - Xcode: update project file for Xcode 4.2 and define HAVE_GAI_STRERROR
 | 
			
		||||
    for Mac OS X Xcode builds.
 | 
			
		||||
  - ./configure: Fix logic and quoting of poll() detection code: only use
 | 
			
		||||
    poll() when poll.h exists as well.
 | 
			
		||||
  - Suppress 'Can't create pre-defined channel: invalid name: ""' message.
 | 
			
		||||
  - whois-test: handle local host name = "localhost.localdomain" using the
 | 
			
		||||
    pattern "localhost*" for valid local host names.
 | 
			
		||||
  - sample-ngircd.conf: show correct default for "PAM" variable: The
 | 
			
		||||
    default of "PAM" is "yes" when ngIRCd has been configured to use it,
 | 
			
		||||
    so show the correct default value in the sample configuration file.
 | 
			
		||||
    (Closes #119)
 | 
			
		||||
  - Update GPL 2 license text to current version.
 | 
			
		||||
  - Only close "unrelated" sockets in forked child processes: This fixes
 | 
			
		||||
    the problem that ngIRCd can't do any IDENT lookups because of the
 | 
			
		||||
    socket has already been closed in the child process.
 | 
			
		||||
    The bug has been introduced starting with ngIRCd 17 ... :-(
 | 
			
		||||
    (commit ID 6ebb31ab35e)
 | 
			
		||||
  - Added doc/Modes.txt: document modes supported by ngIRCd.
 | 
			
		||||
  - Implement user mode "R": indicates that the nickname of this user
 | 
			
		||||
    is "registered". This mode isn't handled by ngIRCd itself, but must
 | 
			
		||||
    be set and unset by IRC services like Anope.
 | 
			
		||||
  - Implement channel mode "R": only registered users (having the user
 | 
			
		||||
    mode "R" set) are allowed to join this channel.
 | 
			
		||||
  - Test suite: bind to loopback (127.0.0.1) interface only.
 | 
			
		||||
  - New 2nd message "Nickname too long" for error code 432.
 | 
			
		||||
  - Xcode: Mac OS X config.h: support 10.5 as well as 10.6/10.7 SDK.
 | 
			
		||||
  - Xcode: exclude more Xcode 4 specific directories in ".gitignore".
 | 
			
		||||
  - Disconnect directly linked servers sending QUIT. Without this,
 | 
			
		||||
    the server becomes removed from the network and the client list,
 | 
			
		||||
    but the connection isn't shut down at all ...
 | 
			
		||||
  - contrib/ngindent: detect "gindent" as GNU indent.
 | 
			
		||||
  - Handle unknown user and channel modes: these modes are saved and
 | 
			
		||||
    forwarded to other servers, but ignored otherwise.
 | 
			
		||||
  - Handle channel user modes 'a', 'h', and 'q' from remote servers.
 | 
			
		||||
    These channel user modes aren't used for anything at the moment,
 | 
			
		||||
    but ngIRCd knows that these three modes are "channel user modes"
 | 
			
		||||
    and not "channel modes", that is that these modes take an "nickname"
 | 
			
		||||
    argument. Like unknown user and channel modes, these modes are saved
 | 
			
		||||
    and forwarded to other servers, but ignored otherwise.
 | 
			
		||||
  - Correctly inform clients when other servers change their user modes.
 | 
			
		||||
    This is required for some services to work correctly.
 | 
			
		||||
  - Test suite: make getpid.sh work even when run as root.
 | 
			
		||||
  - Spoofed prefixes: close connection on non-server links only.
 | 
			
		||||
    On server-links, spoofed prefixes can happen because of the
 | 
			
		||||
    asynchronous nature of the IRC protocol. So don't break server-
 | 
			
		||||
    links, only log a message and ignore the command. (Closes #113)
 | 
			
		||||
 | 
			
		||||
ngIRCd Release 18 (2011-07-10)
 | 
			
		||||
 | 
			
		||||
  - Update timestamp of ngircd(8) manual page.
 | 
			
		||||
@@ -82,10 +425,10 @@ ngIRCd Release 18 (2011-07-10)
 | 
			
		||||
    variable description.
 | 
			
		||||
  - Don't use "the.net" in sample-ngircd.conf, use "example.net".
 | 
			
		||||
  - Terminate incoming connections on HTTP commands "GET" and "POST".
 | 
			
		||||
  - New configuration option "CloakHost": when set, this hostname is used for
 | 
			
		||||
    every client instead of the real DNS hostname (or IP address).
 | 
			
		||||
  - New configuration option "CloakHost": when set, this host name is used for
 | 
			
		||||
    every client instead of the real DNS host name (or IP address).
 | 
			
		||||
  - New configuration option "CloakUserToNick": when enabled, ngIRCd sets
 | 
			
		||||
    every clients' user name to their nick name and hides the user name
 | 
			
		||||
    every clients' user name to their nickname and hides the user name
 | 
			
		||||
    supplied by the IRC client.
 | 
			
		||||
  - doc/Protocol.txt: Update description of the CHANINFO and WEBIRC commands.
 | 
			
		||||
  - Doxygen'ify (document) much more source files; code cleanup ...
 | 
			
		||||
@@ -188,7 +531,7 @@ ngIRCd Release 17 (2010-11-07)
 | 
			
		||||
  - configure script: correctly indent IPv6 yes/no summary output.
 | 
			
		||||
  - Don't reset My_Connections[Idx].lastping when reading data, so the
 | 
			
		||||
    client lag debug-output is working again.
 | 
			
		||||
  - Implement user mode "x": hostname cloaking (closes: #102).
 | 
			
		||||
  - Implement user mode "x": host name cloaking (closes: #102).
 | 
			
		||||
  - Make configure switch "--docdir" work (closes: #108).
 | 
			
		||||
  - Reformat and update FAQ.txt a little bit.
 | 
			
		||||
  - INSTALL: mention SSL, IPv6, and changed handling of MotdFile.
 | 
			
		||||
@@ -293,7 +636,7 @@ ngIRCd Release 14.1 (2009-05-05)
 | 
			
		||||
  - Allow ping timeout quit messages to show the timeout value.
 | 
			
		||||
  - Fix error handling on compressed links.
 | 
			
		||||
  - Fix server list announcement.
 | 
			
		||||
  - Do not remove hostnames from info text.
 | 
			
		||||
  - Do not remove host names from info text.
 | 
			
		||||
 | 
			
		||||
ngIRCd Release 14 (2009-04-20)
 | 
			
		||||
 | 
			
		||||
@@ -389,7 +732,7 @@ ngIRCd 0.12.0 (2008-05-13)
 | 
			
		||||
  - RPL_WHOREPLY messages generated by IRC_WHO didn't include flags (*,@,+).
 | 
			
		||||
    (Dana Dahlstrom)
 | 
			
		||||
  - IRC_WHO now supports search patterns and will test this against user
 | 
			
		||||
    nickname/servername/hostname, etc. as required by RFC 2812, Section 3.6.1.
 | 
			
		||||
    nickname/server name/host name, etc. as required by RFC 2812, Section 3.6.1.
 | 
			
		||||
    (reported by Dana Dahlstrom)
 | 
			
		||||
  - Add test cases for "WHO" command. (Dana Dahlstrom)
 | 
			
		||||
  - Implement RFC 2812 handling of "0" argument to 'JOIN': must be treated
 | 
			
		||||
@@ -412,12 +755,12 @@ ngIRCd 0.11.0 (2008-01-15)
 | 
			
		||||
    ngircd to crash [from HEAD]. (CVE-2008-0285)
 | 
			
		||||
  
 | 
			
		||||
  ngIRCd 0.11.0-pre1 (2008-01-02)
 | 
			
		||||
  - Use dotted-decimal IP address if hostname is >= 64.
 | 
			
		||||
  - Use dotted-decimal IP address if host name is >= 64.
 | 
			
		||||
  - Add support for /STAT u (server uptime) command.
 | 
			
		||||
  - New [Server] configuration Option "Bind" allows to specify
 | 
			
		||||
    the source IP address 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!
 | 
			
		||||
    length of user nicknames. Note: must be unique in an IRC network!
 | 
			
		||||
  - Enhanced the IRC+ protocol to support an enhanced "server handshake" and
 | 
			
		||||
    enable server to recognize numeric 005 (ISUPPORT) and 376 (ENDOFMOTD).
 | 
			
		||||
    See doc/Protocol.txt for details.
 | 
			
		||||
@@ -638,7 +981,7 @@ ngIRCd 0.8.0 (2004-06-26)
 | 
			
		||||
    original ircd exactly: the unnecessary but missing ":" before the last
 | 
			
		||||
    parameter has been added.
 | 
			
		||||
  - Fixed TRACE: don't output "Serv" lines for ourself; display more info.
 | 
			
		||||
  - Results of the resolver (hostnames and IDENT names) are discarded after
 | 
			
		||||
  - Results of the resolver (host names and IDENT names) are discarded after
 | 
			
		||||
    the client is successfully registered with the server.
 | 
			
		||||
  - Better logging while establishing and shutting down connections.
 | 
			
		||||
  - The type of service (TOS) of all sockets is set to "interactive" now.
 | 
			
		||||
@@ -797,7 +1140,7 @@ ngIRCd 0.6.0, 2002-12-24
 | 
			
		||||
    werden (beide Server versuchen sich dann gegenseitig zu connectieren).
 | 
			
		||||
  - Test-Suite und Dokumentation an A/UX angepasst.
 | 
			
		||||
  - unter HP-UX definiert das configure-Script nun _XOPEN_SOURCE_EXTENDED.
 | 
			
		||||
  - Server identifizieren sich nun mit asyncronen Passwoertern, d.h. das
 | 
			
		||||
  - Server identifizieren sich nun mit asynchronen Passwoertern, d.h. das
 | 
			
		||||
    Passwort, welches A an B schickt, kann ein anderes sein als das, welches
 | 
			
		||||
    B als Antwort an A sendet. In der Konfig.-Datei, Abschnitt "Server",
 | 
			
		||||
    wurde "Password" dazu durch "MyPassword" und "PeerPassword" ersetzt.
 | 
			
		||||
@@ -927,7 +1270,7 @@ ngIRCd 0.5.0, 20.09.2002
 | 
			
		||||
  - Protokoll- und Server-ID bei PASS-Befehlen auf neues Format umgestellt;
 | 
			
		||||
    bei empfangenen PASS-Befehlen werden diese zudem nun auch ausgewertet.
 | 
			
		||||
    Die unterstuetzten Flags sind in doc/Protocol.txt beschrieben.
 | 
			
		||||
  - mit dem neuen Befehl CHANINFO syncronisieren Server, die das IRC+-
 | 
			
		||||
  - mit dem neuen Befehl CHANINFO synchronisieren Server, die das IRC+-
 | 
			
		||||
    Protokoll unterstuetzen, Channel-Modes und Topics.
 | 
			
		||||
  - neue Option "--disable-ircplus" fuer das configure-Script, um das
 | 
			
		||||
    IRC+-Protokoll abzuschalten (per Default ist es aktiviert).
 | 
			
		||||
@@ -1032,7 +1375,7 @@ ngIRCd 0.3.0, 02.03.2002
 | 
			
		||||
  - PRIVMSG beachtet nun die Channel-Modes "n" und "m".
 | 
			
		||||
  - AWAY implementiert. PRIVMSG, MODE, USERHOST und WHOIS angepasst.
 | 
			
		||||
  - der ngIRCd unterstuetzt nun Channel-Topics (TOPIC-Befehl).
 | 
			
		||||
  - ausgehende Server-Verbindungen werden nun asyncron connectiert und
 | 
			
		||||
  - ausgehende Server-Verbindungen werden nun asynchron connectiert und
 | 
			
		||||
    blockieren nicht mehr den ganzen Server, wenn die Gegenseite nicht
 | 
			
		||||
    erreicht werden kann (bis zum Timeout konnten Minuten vergehen!).
 | 
			
		||||
  - Wert der Konfigurations-Variable "ConnectRetry" wird besser beachtet.
 | 
			
		||||
@@ -1111,7 +1454,7 @@ ngIRCd 0.0.2, 06.01.2002
 | 
			
		||||
  - NICK kann nun die Gross- und Kleinschreibung eines Nicks aendern.
 | 
			
		||||
  - ein Server-Passwort ist nun konfigurierbar.
 | 
			
		||||
  - neue Befehle: ERROR, SERVER, NJOIN (nur als "Fake"), SQUIT.
 | 
			
		||||
  - Asyncroner Resolver Hostname->IP implementiert.
 | 
			
		||||
  - Asynchroner Resolver Hostname->IP implementiert.
 | 
			
		||||
  - Server-Links teilweise implementiert: bisher kann der ngIRCd jedoch
 | 
			
		||||
    nur "leafed server" sein, d.h. keine "Client-Server" haben. Einige
 | 
			
		||||
    Befehle sind auch noch nicht (optimal) angepasst: PRIVMSG funktioniert
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										47
									
								
								INSTALL
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								INSTALL
									
									
									
									
									
								
							@@ -2,7 +2,7 @@
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
                           http://ngircd.barton.de/
 | 
			
		||||
 | 
			
		||||
               (c)2001-2011 Alexander Barton and Contributors.
 | 
			
		||||
               (c)2001-2012 Alexander Barton and Contributors.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
@@ -12,6 +12,14 @@
 | 
			
		||||
I. Upgrade Information
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Differences to version 19.x
 | 
			
		||||
 | 
			
		||||
- Starting with ngIRCd 20, users can "cloak" their hostname only when the
 | 
			
		||||
  configuration variable "CloakHostModeX" (introduced in 19.2) is set.
 | 
			
		||||
  Otherwise, only IRC opertators, other servers, and services are allowed to
 | 
			
		||||
  set mode +x. This prevents regular users from changing their hostmask to
 | 
			
		||||
  the name of the IRC server itself, which confused quite a few people ;-)
 | 
			
		||||
 | 
			
		||||
Differences to version 17
 | 
			
		||||
 | 
			
		||||
- Support for ZeroConf/Bonjour/Rendezvous service registration has been
 | 
			
		||||
@@ -93,7 +101,8 @@ automake ("configure") should be no problem.
 | 
			
		||||
The normal installation procedure after getting (and expanding) the source
 | 
			
		||||
files (using a distribution archive or GIT) is as following:
 | 
			
		||||
 | 
			
		||||
  1) ./autogen.sh	[only necessary when using GIT]
 | 
			
		||||
  0) Satisfy prerequisites
 | 
			
		||||
  1) ./autogen.sh  [only necessary when using GIT]
 | 
			
		||||
  2) ./configure
 | 
			
		||||
  3) make
 | 
			
		||||
  4) make install
 | 
			
		||||
@@ -114,6 +123,30 @@ possible options will be installed there. You'll find its template in the
 | 
			
		||||
doc/ directory: sample-ngircd.conf.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
0): Satisfy prerequisites
 | 
			
		||||
 | 
			
		||||
When building from source, you'll need some other software to build ngIRCd:
 | 
			
		||||
for example a working C compiler, make tool, GNU automake and autoconf (only
 | 
			
		||||
when not using a distribution archive), and a few libraries depending on the
 | 
			
		||||
features you want to compile in (like IDENT support, SSL, and PAM).
 | 
			
		||||
 | 
			
		||||
If you are using one of the "big" operating systems or Linux distributions,
 | 
			
		||||
you can use the following commands to install all the required packages to
 | 
			
		||||
build the sources including all optional features and to run the test suite:
 | 
			
		||||
 | 
			
		||||
* RedHat / Fedora based distributions:
 | 
			
		||||
 | 
			
		||||
  yum install \
 | 
			
		||||
    autoconf automake expect gcc glibc-devel gnutls-devel \
 | 
			
		||||
    libident-devel make pam-devel tcp_wrappers-devel telnet zlib-devel
 | 
			
		||||
 | 
			
		||||
* Debian / Ubuntu based distributions:
 | 
			
		||||
 | 
			
		||||
  apt-get install \
 | 
			
		||||
    autoconf automake build-essential expect libgnutls-dev \
 | 
			
		||||
    libident-dev libpam-dev libwrap0-dev libz-dev telnet
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
1): "autogen.sh"
 | 
			
		||||
 | 
			
		||||
The first step, autogen.sh, is only necessary if the configure-script isn't
 | 
			
		||||
@@ -124,10 +157,14 @@ This step is therefore only interesting for developers.
 | 
			
		||||
 | 
			
		||||
autogen.sh produces the Makefile.in's, which are necessary for the configure
 | 
			
		||||
script itself, and some more files for make. To run autogen.sh you'll need
 | 
			
		||||
GNU autoconf and GNU automake (use recent versions! autoconf 2.53 and
 | 
			
		||||
automake 1.6.1 are known to work).
 | 
			
		||||
GNU autoconf and GNU automake: at least autoconf 2.61 and automake 1.10 are
 | 
			
		||||
requird, newer is better. But don't use automake 1.12 or newer for creating
 | 
			
		||||
distribution archives: it will work but lack "de-ANSI-fucation" support in the
 | 
			
		||||
generated Makefile's! Stick with automake 1.11.x for this purpose ...
 | 
			
		||||
So automake 1.11.x and autoconf 2.67+ is recommended.
 | 
			
		||||
 | 
			
		||||
Again: "end users" do not need this step!
 | 
			
		||||
Again: "end users" do not need this step and neither need GNU autoconf nor GNU
 | 
			
		||||
automake at all!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
2): "./configure"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								Makefile.am
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
 | 
			
		||||
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 | 
			
		||||
#
 | 
			
		||||
# This program is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -13,24 +13,26 @@ AUTOMAKE_OPTIONS = gnu
 | 
			
		||||
 | 
			
		||||
SUBDIRS = doc src man contrib
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = autogen.sh configure.ng .mailmap
 | 
			
		||||
 | 
			
		||||
clean-local:
 | 
			
		||||
	rm -f build-stamp*
 | 
			
		||||
	rm -rf ngircd.dest
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -rf autom4te.cache
 | 
			
		||||
	rm -f Makefile.in Makefile aclocal.m4 configure
 | 
			
		||||
	rm -f mkinstalldirs missing depcomp install-sh
 | 
			
		||||
	rm -f Makefile.in Makefile aclocal.m4 configure configure.ac
 | 
			
		||||
	rm -f ar-lib mkinstalldirs missing depcomp install-sh
 | 
			
		||||
	rm -f config.log debian
 | 
			
		||||
 | 
			
		||||
testsuite:
 | 
			
		||||
	make -C src/testsuite check
 | 
			
		||||
	cd src/testsuite && make check
 | 
			
		||||
 | 
			
		||||
lint:
 | 
			
		||||
	make -C src/ngircd lint
 | 
			
		||||
	cd src/ngircd && make lint
 | 
			
		||||
 | 
			
		||||
srcdoc:
 | 
			
		||||
	make -C doc srcdoc
 | 
			
		||||
	cd doc && make srcdoc
 | 
			
		||||
 | 
			
		||||
have-xcodebuild:
 | 
			
		||||
	@xcodebuild -project contrib/MacOSX/ngIRCd.xcodeproj -list \
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										187
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										187
									
								
								NEWS
									
									
									
									
									
								
							@@ -2,12 +2,177 @@
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
                           http://ngircd.barton.de/
 | 
			
		||||
 | 
			
		||||
               (c)2001-2011 Alexander Barton and Contributors.
 | 
			
		||||
               (c)2001-2012 Alexander Barton and Contributors.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                                  -- NEWS --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ngIRCd
 | 
			
		||||
 | 
			
		||||
  ngIRCd 20~rc2 (2012-12-02)
 | 
			
		||||
  - Rework cloaked hostname handling and implement the "METADATA cloakhost"
 | 
			
		||||
    subcommand: Now ngIRCd uses two fields internally, one to store the
 | 
			
		||||
    "real" hostname and one to save the "cloaked" hostname. This allows
 | 
			
		||||
    "foreign servers" (aka "IRC services") to alter the real and cloaked
 | 
			
		||||
    hostnames of clients without problems, even when the user itself issues
 | 
			
		||||
    additional "MODE +x" and "MODE -x" commands.
 | 
			
		||||
 | 
			
		||||
  ngIRCd 20~rc1 (2012-11-11)
 | 
			
		||||
  - Update doc/Services.txt: describe the upcoming version of Anope 1.9.8,
 | 
			
		||||
    then including a protocol module for ngIRCd. And remove our own patches
 | 
			
		||||
    in ./contrib/Anope because they aren't supported any more ...
 | 
			
		||||
  - Implement new "METADATA" command which can be used by remote servers
 | 
			
		||||
    and IRC services to update client metadata like the client info text
 | 
			
		||||
    ("real name"), user name, and hostname, and use this command to
 | 
			
		||||
    configure an cloaked hostname (user mode "+x") on remote servers:
 | 
			
		||||
    This prevents "double cloaking" of hostnames and even cloaked
 | 
			
		||||
    hostnames are in sync on all servers supporting "METADATA" now.
 | 
			
		||||
  - Implement new IRC "SVSNICK" command to allow remote servers (and IRC
 | 
			
		||||
    services) to change nicknames of already registered users. The SVSNICK
 | 
			
		||||
    command itself doesn't change the nickname, but it becomes forwarded
 | 
			
		||||
    to the server to which the user is connected to. And then this server
 | 
			
		||||
    initiates the real nickname changing using regular NICK commands.
 | 
			
		||||
    This allows to run mixed networks with old servers not supporting the
 | 
			
		||||
    SVSNICK command, because SVSNICK commands for nicknames on such servers
 | 
			
		||||
    are silently ignored and don't cause a desynchronization of the network.
 | 
			
		||||
  - New configuration option "MaxListSize" to configure the maximum number
 | 
			
		||||
    of channels returned by a LIST command. The default is 100, as before.
 | 
			
		||||
  - Implement user mode "b", "block messages": when a user has set mode "b",
 | 
			
		||||
    all private messages and notices to this user are blocked if they don't
 | 
			
		||||
    originate from a registered user, an IRC Op, server or service. The
 | 
			
		||||
    originator gets an error numeric sent back in this case,
 | 
			
		||||
    ERR_NONONREG_MSG (486), which is used by UnrealIRCd, too. (Closes #144)
 | 
			
		||||
  - Implement channel mode "V" (invite disallow): If the new channel mode
 | 
			
		||||
    "V" is set, the INVITE command becomes invalid and all clients get the
 | 
			
		||||
    new ERR_NOINVITE_MSG (518) reply. (Closes #143)
 | 
			
		||||
  - Implement channel mode "Q" and user mode "q": Both modes protect users
 | 
			
		||||
    from channel kicks: only IRC operators and servers can kick users having
 | 
			
		||||
    mode "q" or in channels with mode "Q". (Closes #141)
 | 
			
		||||
  - Allow users to "cloak" their hostname only when the configuration
 | 
			
		||||
    variable "CloakHostModeX" (introduced in 19.2) is set. Otherwise, only
 | 
			
		||||
    IRC operators, other servers, and services are allowed to set the user
 | 
			
		||||
    mode "+x": this prevents regular users from changing their hostmask to
 | 
			
		||||
    the name of the IRC server itself, which confused quite a few people ;-)
 | 
			
		||||
    (Closes #133)
 | 
			
		||||
  - New configuration option "OperChanPAutoOp": If disabled, IRC operators
 | 
			
		||||
    don't become channel operators in persistent channels when joining.
 | 
			
		||||
    Enabled by default, which has been the behavior of ngIRCd up to this
 | 
			
		||||
    patch. (Closes #135)
 | 
			
		||||
  - Allow IRC operators to see secret (+s) channels in LIST command as long
 | 
			
		||||
    as the "MorePrivacy" configuration option isn't enabled in the
 | 
			
		||||
    configuration file. (Closes #136)
 | 
			
		||||
  - Implement new (optional) IRC+ "CHARCONV" command to set a client
 | 
			
		||||
    character set that the server translates all messages to/from UTF-8.
 | 
			
		||||
    This feature requires the "libiconv" library and must be enabled using
 | 
			
		||||
    the new "--with-iconv" option of the ./configure script. See
 | 
			
		||||
    doc/Protocol.txt for details. (Closes #109)
 | 
			
		||||
  - Implement user mode "B" ("Bot flag"): it is settable and unsettable by
 | 
			
		||||
    every (non-restricted) client. This is how Unreal and InspIRCd do
 | 
			
		||||
    behave, and so do we :-)
 | 
			
		||||
  - Implement channel mode "M": Only the server, identified users and IRC
 | 
			
		||||
    operators are able to talk in such a channel.
 | 
			
		||||
  - Block nicknames that are reserved for services and are defined using the
 | 
			
		||||
    configuration variable "ServiceMask" in "Server" blocks; And this
 | 
			
		||||
    variable now can handle more than one mask separated by commas.
 | 
			
		||||
  - Implemented XOP channel user modes: "Half Op" ("+h", prefix "%") can set
 | 
			
		||||
    the channel modes +imntvIbek and kick all +v and normal users; "Admin"
 | 
			
		||||
    ("+a", prefix "&") can set channel modes +imntvIbekoRsz and kick all +o,
 | 
			
		||||
    +h, +v and normal users; and "Owner" ("+q", prefix "~") can set channel
 | 
			
		||||
    modes +imntvIbekoRsz and kick all +a, +o, +h, +v and normal users.
 | 
			
		||||
  - Implement hashed cloaked hostnames for both the "CloakHost" and
 | 
			
		||||
    "CloakHostModeX" configuration options: now the admin can use the new
 | 
			
		||||
    '%x' placeholder to insert a hashed version of the clients hostname,
 | 
			
		||||
    and the new configuration option "CloakHostSalt" defines the salt for
 | 
			
		||||
    the hash function. When "CloakHostSalt" is not set (the default), a
 | 
			
		||||
    random salt will be generated after each server restart.
 | 
			
		||||
 | 
			
		||||
ngIRCd Release 19.2 (2012-06-19)
 | 
			
		||||
 | 
			
		||||
  ngIRCd 19.2~rc1 (2012-06-13)
 | 
			
		||||
  - New configuration option "CloakHostModeX" to configure the hostname
 | 
			
		||||
    that gets used for IRC clients which have user mode "+x" enabled.
 | 
			
		||||
    Up to now, the name of the IRC server itself has been used for this,
 | 
			
		||||
    which still is the default when "CloakHostModeX" isn't set.
 | 
			
		||||
  - Add instructions for setting up Atheme IRC services.
 | 
			
		||||
  - Implement support for IRC capability handling, the new "CAP" command,
 | 
			
		||||
    and capablity "multi-prefix" which allows both the NAME and	WHO command
 | 
			
		||||
    handlers to return more than one "class prefix" to the client.
 | 
			
		||||
 | 
			
		||||
ngIRCd Release 19.1 (2012-03-19)
 | 
			
		||||
 | 
			
		||||
  - Really include _all_ patches to build the Anope module into the
 | 
			
		||||
    distribution archive ... ooops!
 | 
			
		||||
 | 
			
		||||
ngIRCd Release 19 (2012-02-29)
 | 
			
		||||
 | 
			
		||||
  ngIRCd 19~rc1 (2012-02-12)
 | 
			
		||||
  - Update preliminary ngIRCd protocol module for Anope 1.9.6, which now
 | 
			
		||||
    is the only supported version.
 | 
			
		||||
  - New numeric RPL_WHOISHOST_MSG(378), which returns the DNS host name
 | 
			
		||||
    (if available) and the IP address of a client in the WHOIS reply.
 | 
			
		||||
    Only the user itself and local IRC operators get this numeric.
 | 
			
		||||
  - Implement channel exception list (mode 'e'). This allows a channel
 | 
			
		||||
    operator to define exception masks that allow users to join the
 | 
			
		||||
    channel even when a "ban" would match and prevent them from joining:
 | 
			
		||||
    the exception list (e) overrides the ban list (b).
 | 
			
		||||
  - Implement user mode 'C': If the target user of a PRIVMSG or NOTICE
 | 
			
		||||
    command has the user mode 'C' set, it is required that both sender
 | 
			
		||||
    and receiver are on the same channel. This prevents private flooding
 | 
			
		||||
    by completely unknown clients.
 | 
			
		||||
  - New RPL_WHOISREGNICK_MSG(307) numeric in WHOIS command replies: it
 | 
			
		||||
    indicates if a nickname is registered (if user mode 'R' set).
 | 
			
		||||
  - Limit channel invite, ban, and exception lists to 50 entries and fix
 | 
			
		||||
    duplicate check and error messages when adding already listed entries
 | 
			
		||||
    or deleting no (longer) existing ones.
 | 
			
		||||
  - Limit the number of list items in the reply of LIST (100), WHO (25),
 | 
			
		||||
    WHOIS (10), and WHOWAS (25) commands.
 | 
			
		||||
  - Limit the MODE command to handle a maximum number of 5 channel modes
 | 
			
		||||
    that require an argument (+Ibkl) per call and report this number
 | 
			
		||||
    in the ISUPPORT(005) numeric: "MODES=5".
 | 
			
		||||
  - LINKS command: support <mask> parameter to limit the reply.
 | 
			
		||||
  - Add 1 second penalty for every further target on PRIVMSG/NOTICE
 | 
			
		||||
    commands: this reduces the possibility of flooding channels with
 | 
			
		||||
    commands like "PRIVMSG/NOTICE #a,#n,#c,... :message" a little bit.
 | 
			
		||||
    Problem noticed by Cahata, thanks!
 | 
			
		||||
  - New configuration option "PAMIsOptional": when set, clients not
 | 
			
		||||
    sending a password are still allowed to connect: they won't become
 | 
			
		||||
    "identified" and keep the "~" character prepended to their supplied
 | 
			
		||||
    user name. See "man 5 ngircd.conf" for details.
 | 
			
		||||
  - Fixed handling of WHO commands. This fixes two bugs: "WHO <nick>"
 | 
			
		||||
    returned nothing at all if the user was "+i" (reported by Cahata,
 | 
			
		||||
    thanks) and "WHO <nick|nickmask>" returned channel names instead
 | 
			
		||||
    of "*" when the user was member of a (visible) channel.
 | 
			
		||||
  - LUSERS reply: only count channels that are visible to the requesting
 | 
			
		||||
    client, so the existence of secret channels is no longer revealed by
 | 
			
		||||
    using LUSERS. Reported by Cahata, thanks!
 | 
			
		||||
  - Unknown user and channel modes no longer stop the mode parser, but
 | 
			
		||||
    are simply ignored. Therefore modes after the unknown one are now
 | 
			
		||||
    handled. This is how ircd2.10/ircd2.11/ircd-seven behave, at least.
 | 
			
		||||
    Reported by Cahata, thanks!
 | 
			
		||||
  - Implement IRC commands "GLINE" and "KLINE" to ban users. G-Lines are
 | 
			
		||||
    synchronized between server on peering, K-Lines are local only.
 | 
			
		||||
    If you use "*!<user>@<host>" or "*!*@<host>" masks, these connections
 | 
			
		||||
    are blocked even before the user is fully logged in (before PASS,
 | 
			
		||||
    NICK, and USER commands have been processed) and before the child
 | 
			
		||||
    processes for authentication are forked, so resource usage is smaller.
 | 
			
		||||
  - Added doc/Modes.txt: document modes supported by ngIRCd.
 | 
			
		||||
  - Implement user mode "R": indicates that the nickname of this user
 | 
			
		||||
    is "registered". This mode isn't handled by ngIRCd itself, but must
 | 
			
		||||
    be set and unset by IRC services like Anope.
 | 
			
		||||
  - Implement channel mode "R": only registered users (having the user
 | 
			
		||||
    mode "R" set) are allowed to join this channel.
 | 
			
		||||
  - Test suite: bind to loopback (127.0.0.1) interface only.
 | 
			
		||||
  - Handle unknown user and channel modes: these modes are saved and
 | 
			
		||||
    forwarded to other servers, but ignored otherwise.
 | 
			
		||||
  - Handle channel user modes 'a', 'h', and 'q' from remote servers.
 | 
			
		||||
    These channel user modes aren't used for anything at the moment,
 | 
			
		||||
    but ngIRCd knows that these three modes are "channel user modes"
 | 
			
		||||
    and not "channel modes", that is that these modes take an "nickname"
 | 
			
		||||
    argument. Like unknown user and channel modes, these modes are saved
 | 
			
		||||
    and forwarded to other servers, but ignored otherwise.
 | 
			
		||||
 | 
			
		||||
ngIRCd Release 18 (2011-07-10)
 | 
			
		||||
 | 
			
		||||
  - Add preliminary ngIRCd protocol module for Anope 1.9 to contrib/Anope/.
 | 
			
		||||
@@ -60,10 +225,10 @@ ngIRCd Release 18 (2011-07-10)
 | 
			
		||||
    (booleans, text strings, integer numbers) and add type information to each
 | 
			
		||||
    variable description.
 | 
			
		||||
  - Terminate incoming connections on HTTP commands "GET" and "POST".
 | 
			
		||||
  - New configuration option "CloakHost": when set, this hostname is used for
 | 
			
		||||
    every client instead of the real DNS hostname (or IP address).
 | 
			
		||||
  - New configuration option "CloakHost": when set, this host name is used for
 | 
			
		||||
    every client instead of the real DNS host name (or IP address).
 | 
			
		||||
  - New configuration option "CloakUserToNick": when enabled, ngIRCd sets
 | 
			
		||||
    every clients' user name to their nick name and hides the user name
 | 
			
		||||
    every clients' user name to their nickname and hides the user name
 | 
			
		||||
    supplied by the IRC client.
 | 
			
		||||
  - Make write buffers bigger, but flush early. Before this change, a client
 | 
			
		||||
    got disconnected if the buffer flushing at 4k failed, now regular clients
 | 
			
		||||
@@ -113,7 +278,7 @@ ngIRCd Release 17 (2010-11-07)
 | 
			
		||||
  - Enable the daemon to disable and enable "debug mode" on runtime using
 | 
			
		||||
    signal SIGUSR1, when debug code is compiled in, not only on startup
 | 
			
		||||
    using the command line parameters.
 | 
			
		||||
  - Implement user mode "x": hostname cloaking (closes: #102).
 | 
			
		||||
  - Implement user mode "x": host name cloaking (closes: #102).
 | 
			
		||||
  - Change MOTD file handling: ngIRCd now caches the contens of the MOTD
 | 
			
		||||
    file, so the daemon now requires a HUP signal or REHASH command to
 | 
			
		||||
    re-read the MOTD file when its content changed.
 | 
			
		||||
@@ -218,7 +383,7 @@ ngIRCd 0.12.0 (2008-05-13)
 | 
			
		||||
  - Implemented IRC commands INFO, SUMMON (dummy), and USERS (dummy) and
 | 
			
		||||
    enhanced test suite to check these commands. (Dana Dahlstrom)
 | 
			
		||||
  - IRC_WHO now supports search patterns and will test this against user
 | 
			
		||||
    nickname/servername/hostname, etc. as required by RFC 2812, Section 3.6.1.
 | 
			
		||||
    nickname/server name/host name, etc. as required by RFC 2812, Section 3.6.1.
 | 
			
		||||
    (reported by Dana Dahlstrom)
 | 
			
		||||
  - Implement RFC 2812 handling of "0" argument to 'JOIN': must be treated
 | 
			
		||||
    as if the user had sent PART commands for all channels the user is a
 | 
			
		||||
@@ -231,7 +396,7 @@ ngIRCd 0.11.0 (2008-01-15)
 | 
			
		||||
  - New [Server] configuration Option "Bind" allows to specify
 | 
			
		||||
    the source IP address 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!
 | 
			
		||||
    length of user nicknames. 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,
 | 
			
		||||
@@ -351,7 +516,7 @@ ngIRCd 0.6.0, 2002-12-24
 | 
			
		||||
    ausgehende Verbindung zu diesem auufzubauen. Dadurch kann nun auf beiden
 | 
			
		||||
    Servern in der Konfiguration ein Port fuer den Connect konfiguriert
 | 
			
		||||
    werden (beide Server versuchen sich dann gegenseitig zu connectieren).
 | 
			
		||||
  - Server identifizieren sich nun mit asyncronen Passwoertern, d.h. das
 | 
			
		||||
  - Server identifizieren sich nun mit asynchronen Passwoertern, d.h. das
 | 
			
		||||
    Passwort, welches A an B schickt, kann ein anderes sein als das, welches
 | 
			
		||||
    B als Antwort an A sendet. In der Konfig.-Datei, Abschnitt "Server",
 | 
			
		||||
    wurde "Password" dazu durch "MyPassword" und "PeerPassword" ersetzt.
 | 
			
		||||
@@ -377,7 +542,7 @@ ngIRCd 0.5.0, 20.09.2002
 | 
			
		||||
    Konfiguration "sample-ngircd.conf") und bleiben auch dann bestehen,
 | 
			
		||||
    wenn kein User mehr im Channel ist.
 | 
			
		||||
  - neue IRC-Befehle: KICK, INVITE, ADMIN, CHANINFO; LIST wurde erweitert.
 | 
			
		||||
    Mit dem neuen Befehl CHANINFO syncronisieren Server, die das IRC+-
 | 
			
		||||
    Mit dem neuen Befehl CHANINFO synchronisieren Server, die das IRC+-
 | 
			
		||||
    Protokoll unterstuetzen, Channel-Modes und Topics. Fuer den ADMIN-Befehl
 | 
			
		||||
    gibt es neue Konfigurationsoptionen (Sektion "Global"): "AdminInfo1",
 | 
			
		||||
    "AdminInfo2" und "AdminEMail".
 | 
			
		||||
@@ -463,7 +628,3 @@ ngIRCd 0.0.2, 06.01.2002
 | 
			
		||||
ngIRCd 0.0.1, 31.12.2001
 | 
			
		||||
 | 
			
		||||
  - erste oeffentliche Version von ngIRCd als "public preview" :-)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: NEWS,v 1.88 2008/02/26 22:05:42 fw Exp $
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										45
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								README
									
									
									
									
									
								
							@@ -2,7 +2,7 @@
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
                           http://ngircd.barton.de/
 | 
			
		||||
 | 
			
		||||
               (c)2001-2011 Alexander Barton and Contributors.
 | 
			
		||||
               (c)2001-2012 Alexander Barton and Contributors.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
@@ -12,11 +12,15 @@
 | 
			
		||||
I. Introduction
 | 
			
		||||
~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
ngIRCd is an Open Source server for the Internet Relay Chat (IRC), which
 | 
			
		||||
is developed and published under the terms of the GNU General Public
 | 
			
		||||
Licence (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.
 | 
			
		||||
ngIRCd is a free, portable and lightweight Internet Relay Chat server for
 | 
			
		||||
small or private networks, developed under the GNU General Public License
 | 
			
		||||
(GPL; please see the file COPYING for details). It is simple to configure,
 | 
			
		||||
can cope with dynamic IP addresses, and supports IPv6 as well as SSL. It is
 | 
			
		||||
written from scratch and not based on the original IRCd.
 | 
			
		||||
 | 
			
		||||
The name ngIRCd means next generation IRC daemon, which is a little bit
 | 
			
		||||
exaggerated: lightweight Internet Relay Chat server most probably would be a
 | 
			
		||||
better name :-)
 | 
			
		||||
 | 
			
		||||
Please see the INSTALL document for installation and upgrade information!
 | 
			
		||||
 | 
			
		||||
@@ -33,22 +37,24 @@ used in real IRC networks.
 | 
			
		||||
 | 
			
		||||
Implemented IRC-commands are:
 | 
			
		||||
 | 
			
		||||
ADMIN, AWAY, CHANINFO, CONNECT, DIE, DISCONNECT, ERROR, HELP, INFO, INVITE,
 | 
			
		||||
ISON, JOIN, KICK, KILL, LINKS, LIST, LUSERS, MODE, MOTD, NAMES, NICK, NJOIN,
 | 
			
		||||
NOTICE, OPER, PART, PASS, PING, PONG, PRIVMSG, QUIT, REHASH, RESTART, SERVER,
 | 
			
		||||
SERVICE, SERVLIST, SQUERY, SQUIT,  STATS, SUMMON, TIME, TOPIC, TRACE, USER,
 | 
			
		||||
USERHOST, USERS, VERSION, WALLOPS, WEBIRC, WHO, WHOIS, WHOWAS.
 | 
			
		||||
 | 
			
		||||
ADMIN, AWAY, CHANINFO, CONNECT, DIE, DISCONNECT, ERROR, GLINE, HELP, INFO,
 | 
			
		||||
INVITE, ISON, JOIN, KICK, KILL, KLINE, LINKS, LIST, LUSERS, MODE, MOTD,
 | 
			
		||||
NAMES, NICK, NJOIN, NOTICE, OPER, PART, PASS, PING, PONG, PRIVMSG, QUIT,
 | 
			
		||||
REHASH, RESTART, SERVER, SERVICE, SERVLIST, SQUERY, SQUIT, STATS, SUMMON,
 | 
			
		||||
TIME, TOPIC, TRACE, USER, USERHOST, USERS, VERSION, WALLOPS, WEBIRC, WHO,
 | 
			
		||||
WHOIS, WHOWAS.
 | 
			
		||||
 | 
			
		||||
III. Features (or: why use ngIRCd?)
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
- no problems with servers which have dynamic IP addresses
 | 
			
		||||
- simple, easy understandable configuration file,
 | 
			
		||||
- freely published open-source C source code,
 | 
			
		||||
- ngIRCd will be developed on in the future.
 | 
			
		||||
- well arranged (lean) configuration file
 | 
			
		||||
- simple to build/install, configure and maintain
 | 
			
		||||
- supports IPv6 and SSL
 | 
			
		||||
- no problems with servers that have dynamic IP addresses
 | 
			
		||||
- freely available, modern, portable and tidy C-source
 | 
			
		||||
- wide field of supported platforms, including AIX, A/UX, FreeBSD, HP-UX,
 | 
			
		||||
  IRIX, Linux, Mac OS X, NetBSD, OpenBSD, Solaris, and Windows with Cygwin.
 | 
			
		||||
- ngIRCd is being actively developed since 2001.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
IV. Documentation
 | 
			
		||||
@@ -68,7 +74,7 @@ releases there.
 | 
			
		||||
If you are interested in the latest development versions (which are not
 | 
			
		||||
always stable), then please read the section about "GIT" on the homepage and
 | 
			
		||||
the file "doc/GIT.txt" which describes the use of GIT, the version control
 | 
			
		||||
system used by ngIRCd (homepage: http://git.or.cz/).
 | 
			
		||||
system used by ngIRCd (homepage: http://git-scm.com/).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
VI. Bugs
 | 
			
		||||
@@ -82,5 +88,6 @@ 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 the ngIRCd mailing list: <ngircd-ml@arthur.ath.cx> (please see
 | 
			
		||||
<http://ngircd.barton.de/support.php#ml> for details).
 | 
			
		||||
mail to the ngIRCd mailing list: <ngircd-ml@arthur.barton.de> (please see
 | 
			
		||||
<http://ngircd.barton.de/support.php#ml> for details) or join the ngIRCd
 | 
			
		||||
IRC channel: <irc://irc.barton.de/ngircd>.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										68
									
								
								autogen.sh
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								autogen.sh
									
									
									
									
									
								
							@@ -1,7 +1,7 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001-2008 Alexander Barton <alex@barton.de>
 | 
			
		||||
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 | 
			
		||||
#
 | 
			
		||||
# This program is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -16,6 +16,11 @@
 | 
			
		||||
# GNU autoconf. It tries to be smart in finding the correct/usable/available
 | 
			
		||||
# installed versions of these tools on your system.
 | 
			
		||||
#
 | 
			
		||||
# In addition, it enables or disables the "de-ANSI-fication" support of GNU
 | 
			
		||||
# automake, which is supported up to autoconf 1.11.x an has been removed
 | 
			
		||||
# in automake 1.12 -- make sure to use a version of automake supporting it
 | 
			
		||||
# when generating distribution archives!
 | 
			
		||||
#
 | 
			
		||||
# The following strategy is used for each of aclocal, autoheader, automake,
 | 
			
		||||
# and autoconf: first, "tool" (the regular name of the tool, e. g. "autoconf"
 | 
			
		||||
# or "automake") is checked. If this fails, "tool<major><minor>" (for example
 | 
			
		||||
@@ -98,6 +103,12 @@ Notfound()
 | 
			
		||||
	exit 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Run()
 | 
			
		||||
{
 | 
			
		||||
	[ "$VERBOSE" = "1" ] && echo " - running \"$@\" ..."
 | 
			
		||||
	$@
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# Reset locale settings to suppress warning messages of Perl
 | 
			
		||||
unset LC_ALL
 | 
			
		||||
unset LANG
 | 
			
		||||
@@ -123,19 +134,18 @@ fi
 | 
			
		||||
 | 
			
		||||
# Try to detect the needed tools when no environment variable already
 | 
			
		||||
# specifies one:
 | 
			
		||||
echo "Searching tools ..."
 | 
			
		||||
echo "Searching for required tools ..."
 | 
			
		||||
[ -z "$ACLOCAL" ] && ACLOCAL=`Search aclocal 1`
 | 
			
		||||
[ "$VERBOSE" = "1" ] && echo "ACLOCAL=$ACLOCAL"
 | 
			
		||||
[ "$VERBOSE" = "1" ] && echo " - ACLOCAL=$ACLOCAL"
 | 
			
		||||
[ -z "$AUTOHEADER" ] && AUTOHEADER=`Search autoheader 2`
 | 
			
		||||
[ "$VERBOSE" = "1" ] && echo "AUTOHEADER=$AUTOHEADER"
 | 
			
		||||
[ "$VERBOSE" = "1" ] && echo " - AUTOHEADER=$AUTOHEADER"
 | 
			
		||||
[ -z "$AUTOMAKE" ] && AUTOMAKE=`Search automake 1`
 | 
			
		||||
[ "$VERBOSE" = "1" ] && echo "AUTOMAKE=$AUTOMAKE"
 | 
			
		||||
[ "$VERBOSE" = "1" ] && echo " - AUTOMAKE=$AUTOMAKE"
 | 
			
		||||
[ -z "$AUTOCONF" ] && AUTOCONF=`Search autoconf 2`
 | 
			
		||||
[ "$VERBOSE" = "1" ] && echo "AUTOCONF=$AUTOCONF"
 | 
			
		||||
[ "$VERBOSE" = "1" ] && echo " - AUTOCONF=$AUTOCONF"
 | 
			
		||||
 | 
			
		||||
# Call ./configure when parameters have been passed to this script and
 | 
			
		||||
# GO isn't already defined.
 | 
			
		||||
[ -z "$GO" -a $# -gt 0 ] && GO=1
 | 
			
		||||
[ $# -gt 0 ] && CONFIGURE_ARGS=" $@" || CONFIGURE_ARGS=""
 | 
			
		||||
[ -z "$GO" -a -n "$CONFIGURE_ARGS" ] && GO=1
 | 
			
		||||
 | 
			
		||||
# Verify that all tools have been found
 | 
			
		||||
[ -z "$ACLOCAL" ] && Notfound aclocal
 | 
			
		||||
@@ -143,14 +153,41 @@ echo "Searching tools ..."
 | 
			
		||||
[ -z "$AUTOMAKE" ] && Notfound automake
 | 
			
		||||
[ -z "$AUTOCONF" ] && Notfound autoconf
 | 
			
		||||
 | 
			
		||||
AM_VERSION=`$AUTOMAKE --version|head -n 1|egrep -o "([1-9]\.[0-9]+(\.[0-9]+)*)"`
 | 
			
		||||
ifs=$IFS; IFS="."; set $AM_VERSION; IFS=$ifs
 | 
			
		||||
AM_MAJOR="$1"; AM_MINOR="$2"; AM_PATCHLEVEL="$3"
 | 
			
		||||
 | 
			
		||||
AM_MAKEFILES="src/ipaddr/Makefile.ng src/ngircd/Makefile.ng src/testsuite/Makefile.ng src/tool/Makefile.ng"
 | 
			
		||||
 | 
			
		||||
if [ "$AM_MAJOR" -eq "1" -a "$AM_MINOR" -lt "12" ]; then
 | 
			
		||||
	# automake < 1.12 => automatic de-ANSI-fication support available
 | 
			
		||||
	echo "Enabling de-ANSI-fication support (automake $AM_VERSION) ..."
 | 
			
		||||
	sed -e "s|^__ng_PROTOTYPES__|AM_C_PROTOTYPES|g" configure.ng >configure.ac
 | 
			
		||||
	DEANSI_START=""
 | 
			
		||||
	DEANSI_END=""
 | 
			
		||||
else
 | 
			
		||||
	# automake >= 1.12 => no de-ANSI-fication support available
 | 
			
		||||
	echo "Disabling de-ANSI-fication support (automake $AM_VERSION) ..."
 | 
			
		||||
	sed -e "s|^__ng_PROTOTYPES__|AC_C_PROTOTYPES|g" configure.ng >configure.ac
 | 
			
		||||
	DEANSI_START="#"
 | 
			
		||||
	DEANSI_END="	# disabled by ./autogen.sh script"
 | 
			
		||||
fi
 | 
			
		||||
sed -e "s|^__ng_Makefile_am_template__|${DEANSI_START}AUTOMAKE_OPTIONS = ansi2knr${DEANSI_END}|g" \
 | 
			
		||||
	src/portab/Makefile.ng >src/portab/Makefile.am
 | 
			
		||||
for makefile_ng in $AM_MAKEFILES; do
 | 
			
		||||
	makefile_am=`echo "$makefile_ng" | sed -e "s|\.ng\$|\.am|g"`
 | 
			
		||||
	sed -e "s|^__ng_Makefile_am_template__|${DEANSI_START}AUTOMAKE_OPTIONS = ../portab/ansi2knr${DEANSI_END}|g" \
 | 
			
		||||
		$makefile_ng >$makefile_am
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
export ACLOCAL AUTOHEADER AUTOMAKE AUTOCONF
 | 
			
		||||
 | 
			
		||||
# Generate files
 | 
			
		||||
echo "Generating files ..."
 | 
			
		||||
$ACLOCAL && \
 | 
			
		||||
	$AUTOHEADER && \
 | 
			
		||||
	$AUTOMAKE --add-missing && \
 | 
			
		||||
	$AUTOCONF --force
 | 
			
		||||
echo "Generating files using GNU $AUTOCONF and $AUTOMAKE ..."
 | 
			
		||||
Run $ACLOCAL && \
 | 
			
		||||
	Run $AUTOCONF && \
 | 
			
		||||
	Run $AUTOHEADER && \
 | 
			
		||||
	Run $AUTOMAKE --add-missing --no-force
 | 
			
		||||
 | 
			
		||||
if [ $? -eq 0 -a -x ./configure ]; then
 | 
			
		||||
	# Success: if we got some parameters we call ./configure and pass
 | 
			
		||||
@@ -158,8 +195,7 @@ if [ $? -eq 0 -a -x ./configure ]; then
 | 
			
		||||
	NAME=`grep PACKAGE_STRING= configure | cut -d"'" -f2`
 | 
			
		||||
	if [ "$GO" = "1" ]; then
 | 
			
		||||
		[ -n "$PREFIX" ] && p=" --prefix=$PREFIX" || p=""
 | 
			
		||||
		[ -n "$*" ] && a=" $*" || a=""
 | 
			
		||||
		c="./configure${p}${a}"
 | 
			
		||||
		c="./configure${p}${CONFIGURE_ARGS}"
 | 
			
		||||
		echo "Okay, autogen.sh for $NAME done."
 | 
			
		||||
		echo "Calling \"$c\" ..."
 | 
			
		||||
		$c
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										561
									
								
								config.guess
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										561
									
								
								config.guess
									
									
									
									
										vendored
									
									
								
							@@ -1,10 +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, 2006, 2007, 2008
 | 
			
		||||
#   Free Software Foundation, Inc.
 | 
			
		||||
#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
 | 
			
		||||
#   2011, 2012 Free Software Foundation, Inc.
 | 
			
		||||
 | 
			
		||||
timestamp='2008-01-23'
 | 
			
		||||
timestamp='2012-08-14'
 | 
			
		||||
 | 
			
		||||
# 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
 | 
			
		||||
@@ -17,9 +17,7 @@ timestamp='2008-01-23'
 | 
			
		||||
# General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU General Public License
 | 
			
		||||
# along with this program; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
 | 
			
		||||
# 02110-1301, USA.
 | 
			
		||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
#
 | 
			
		||||
# As a special exception to the GNU General Public License, if you
 | 
			
		||||
# distribute this file as part of a program that contains a
 | 
			
		||||
@@ -27,16 +25,16 @@ timestamp='2008-01-23'
 | 
			
		||||
# the same distribution terms that you use for the rest of that program.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Originally written by Per Bothner <per@bothner.com>.
 | 
			
		||||
# Please send patches to <config-patches@gnu.org>.  Submit a context
 | 
			
		||||
# diff and a properly formatted ChangeLog entry.
 | 
			
		||||
# Originally written by Per Bothner.  Please send patches (context
 | 
			
		||||
# diff format) to <config-patches@gnu.org> and include a ChangeLog
 | 
			
		||||
# entry.
 | 
			
		||||
#
 | 
			
		||||
# This script attempts to guess a canonical system name similar to
 | 
			
		||||
# config.sub.  If it succeeds, it prints the system name on stdout, and
 | 
			
		||||
# exits with 0.  Otherwise, it exits with 1.
 | 
			
		||||
#
 | 
			
		||||
# The plan is that this can be called by configure scripts if you
 | 
			
		||||
# don't specify an explicit build system type.
 | 
			
		||||
# You can get the latest version of this script from:
 | 
			
		||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
 | 
			
		||||
 | 
			
		||||
me=`echo "$0" | sed -e 's,.*/,,'`
 | 
			
		||||
 | 
			
		||||
@@ -56,8 +54,9 @@ version="\
 | 
			
		||||
GNU config.guess ($timestamp)
 | 
			
		||||
 | 
			
		||||
Originally written by Per Bothner.
 | 
			
		||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
 | 
			
		||||
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 | 
			
		||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
 | 
			
		||||
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
 | 
			
		||||
Free Software Foundation, Inc.
 | 
			
		||||
 | 
			
		||||
This is free software; see the source for copying conditions.  There is NO
 | 
			
		||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
 | 
			
		||||
@@ -144,7 +143,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 | 
			
		||||
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 | 
			
		||||
    *:NetBSD:*:*)
 | 
			
		||||
	# NetBSD (nbsd) targets should (where applicable) match one or
 | 
			
		||||
	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
 | 
			
		||||
	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
 | 
			
		||||
	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
 | 
			
		||||
	# switched to ELF, *-*-netbsd* would select the old
 | 
			
		||||
	# object file format.  This provides both forward
 | 
			
		||||
@@ -170,7 +169,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 | 
			
		||||
	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
 | 
			
		||||
		eval $set_cc_for_build
 | 
			
		||||
		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
 | 
			
		||||
			| grep __ELF__ >/dev/null
 | 
			
		||||
			| grep -q __ELF__
 | 
			
		||||
		then
 | 
			
		||||
		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
 | 
			
		||||
		    # Return netbsd for either.  FIX?
 | 
			
		||||
@@ -180,7 +179,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 | 
			
		||||
		fi
 | 
			
		||||
		;;
 | 
			
		||||
	    *)
 | 
			
		||||
	        os=netbsd
 | 
			
		||||
		os=netbsd
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
	# The OS release
 | 
			
		||||
@@ -201,6 +200,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 | 
			
		||||
	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
 | 
			
		||||
	echo "${machine}-${os}${release}"
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *:Bitrig:*:*)
 | 
			
		||||
	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
 | 
			
		||||
	echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *:OpenBSD:*:*)
 | 
			
		||||
	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
 | 
			
		||||
	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
 | 
			
		||||
@@ -223,7 +226,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 | 
			
		||||
		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
 | 
			
		||||
		;;
 | 
			
		||||
	*5.*)
 | 
			
		||||
	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
 | 
			
		||||
		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
	# According to Compaq, /usr/sbin/psrinfo has been available on
 | 
			
		||||
@@ -269,7 +272,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 | 
			
		||||
	# A Xn.n version is an unreleased experimental baselevel.
 | 
			
		||||
	# 1.2 uses "1.2" for uname -r.
 | 
			
		||||
	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
 | 
			
		||||
	exit ;;
 | 
			
		||||
	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
 | 
			
		||||
	exitcode=$?
 | 
			
		||||
	trap '' 0
 | 
			
		||||
	exit $exitcode ;;
 | 
			
		||||
    Alpha\ *:Windows_NT*:*)
 | 
			
		||||
	# How do we know it's Interix rather than the generic POSIX subsystem?
 | 
			
		||||
	# Should we change UNAME_MACHINE based on the output of uname instead
 | 
			
		||||
@@ -295,7 +301,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 | 
			
		||||
	echo s390-ibm-zvmoe
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *:OS400:*:*)
 | 
			
		||||
        echo powerpc-ibm-os400
 | 
			
		||||
	echo powerpc-ibm-os400
 | 
			
		||||
	exit ;;
 | 
			
		||||
    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
 | 
			
		||||
	echo arm-acorn-riscix${UNAME_RELEASE}
 | 
			
		||||
@@ -324,14 +330,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 | 
			
		||||
	case `/usr/bin/uname -p` in
 | 
			
		||||
	    sparc) echo sparc-icl-nx7; exit ;;
 | 
			
		||||
	esac ;;
 | 
			
		||||
    s390x:SunOS:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
 | 
			
		||||
	exit ;;
 | 
			
		||||
    sun4H:SunOS:5.*:*)
 | 
			
		||||
	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
 | 
			
		||||
	exit ;;
 | 
			
		||||
    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
 | 
			
		||||
	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
 | 
			
		||||
	echo i386-pc-auroraux${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
 | 
			
		||||
	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
 | 
			
		||||
	eval $set_cc_for_build
 | 
			
		||||
	SUN_ARCH="i386"
 | 
			
		||||
	# If there is a compiler, see if it is configured for 64-bit objects.
 | 
			
		||||
	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
 | 
			
		||||
	# This test works for both compilers.
 | 
			
		||||
	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
 | 
			
		||||
	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
 | 
			
		||||
		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
 | 
			
		||||
		grep IS_64BIT_ARCH >/dev/null
 | 
			
		||||
	    then
 | 
			
		||||
		SUN_ARCH="x86_64"
 | 
			
		||||
	    fi
 | 
			
		||||
	fi
 | 
			
		||||
	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
 | 
			
		||||
	exit ;;
 | 
			
		||||
    sun4*:SunOS:6*:*)
 | 
			
		||||
	# According to config.sub, this is the proper way to canonicalize
 | 
			
		||||
@@ -375,23 +400,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 | 
			
		||||
    # MiNT.  But MiNT is downward compatible to TOS, so this should
 | 
			
		||||
    # be no problem.
 | 
			
		||||
    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
 | 
			
		||||
        echo m68k-atari-mint${UNAME_RELEASE}
 | 
			
		||||
	echo m68k-atari-mint${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
 | 
			
		||||
	echo m68k-atari-mint${UNAME_RELEASE}
 | 
			
		||||
        exit ;;
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
 | 
			
		||||
        echo m68k-atari-mint${UNAME_RELEASE}
 | 
			
		||||
	echo m68k-atari-mint${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
 | 
			
		||||
        echo m68k-milan-mint${UNAME_RELEASE}
 | 
			
		||||
        exit ;;
 | 
			
		||||
	echo m68k-milan-mint${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
 | 
			
		||||
        echo m68k-hades-mint${UNAME_RELEASE}
 | 
			
		||||
        exit ;;
 | 
			
		||||
	echo m68k-hades-mint${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
 | 
			
		||||
        echo m68k-unknown-mint${UNAME_RELEASE}
 | 
			
		||||
        exit ;;
 | 
			
		||||
	echo m68k-unknown-mint${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    m68k:machten:*:*)
 | 
			
		||||
	echo m68k-apple-machten${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
@@ -461,8 +486,8 @@ EOF
 | 
			
		||||
	echo m88k-motorola-sysv3
 | 
			
		||||
	exit ;;
 | 
			
		||||
    AViiON:dgux:*:*)
 | 
			
		||||
        # DG/UX returns AViiON for all architectures
 | 
			
		||||
        UNAME_PROCESSOR=`/usr/bin/uname -p`
 | 
			
		||||
	# DG/UX returns AViiON for all architectures
 | 
			
		||||
	UNAME_PROCESSOR=`/usr/bin/uname -p`
 | 
			
		||||
	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
 | 
			
		||||
	then
 | 
			
		||||
	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
 | 
			
		||||
@@ -475,7 +500,7 @@ EOF
 | 
			
		||||
	else
 | 
			
		||||
	    echo i586-dg-dgux${UNAME_RELEASE}
 | 
			
		||||
	fi
 | 
			
		||||
 	exit ;;
 | 
			
		||||
	exit ;;
 | 
			
		||||
    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
 | 
			
		||||
	echo m88k-dolphin-sysv3
 | 
			
		||||
	exit ;;
 | 
			
		||||
@@ -532,7 +557,7 @@ EOF
 | 
			
		||||
		echo rs6000-ibm-aix3.2
 | 
			
		||||
	fi
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *:AIX:*:[456])
 | 
			
		||||
    *:AIX:*:[4567])
 | 
			
		||||
	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
 | 
			
		||||
	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
 | 
			
		||||
		IBM_ARCH=rs6000
 | 
			
		||||
@@ -575,52 +600,52 @@ EOF
 | 
			
		||||
	    9000/[678][0-9][0-9])
 | 
			
		||||
		if [ -x /usr/bin/getconf ]; then
 | 
			
		||||
		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
 | 
			
		||||
                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
 | 
			
		||||
                    case "${sc_cpu_version}" in
 | 
			
		||||
                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
 | 
			
		||||
                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
 | 
			
		||||
                      532)                      # CPU_PA_RISC2_0
 | 
			
		||||
                        case "${sc_kernel_bits}" in
 | 
			
		||||
                          32) HP_ARCH="hppa2.0n" ;;
 | 
			
		||||
                          64) HP_ARCH="hppa2.0w" ;;
 | 
			
		||||
		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
 | 
			
		||||
		    case "${sc_cpu_version}" in
 | 
			
		||||
		      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
 | 
			
		||||
		      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
 | 
			
		||||
		      532)                      # CPU_PA_RISC2_0
 | 
			
		||||
			case "${sc_kernel_bits}" in
 | 
			
		||||
			  32) HP_ARCH="hppa2.0n" ;;
 | 
			
		||||
			  64) HP_ARCH="hppa2.0w" ;;
 | 
			
		||||
			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
 | 
			
		||||
                        esac ;;
 | 
			
		||||
                    esac
 | 
			
		||||
			esac ;;
 | 
			
		||||
		    esac
 | 
			
		||||
		fi
 | 
			
		||||
		if [ "${HP_ARCH}" = "" ]; then
 | 
			
		||||
		    eval $set_cc_for_build
 | 
			
		||||
		    sed 's/^              //' << EOF >$dummy.c
 | 
			
		||||
		    sed 's/^		//' << EOF >$dummy.c
 | 
			
		||||
 | 
			
		||||
              #define _HPUX_SOURCE
 | 
			
		||||
              #include <stdlib.h>
 | 
			
		||||
              #include <unistd.h>
 | 
			
		||||
		#define _HPUX_SOURCE
 | 
			
		||||
		#include <stdlib.h>
 | 
			
		||||
		#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
              int main ()
 | 
			
		||||
              {
 | 
			
		||||
              #if defined(_SC_KERNEL_BITS)
 | 
			
		||||
                  long bits = sysconf(_SC_KERNEL_BITS);
 | 
			
		||||
              #endif
 | 
			
		||||
                  long cpu  = sysconf (_SC_CPU_VERSION);
 | 
			
		||||
		int main ()
 | 
			
		||||
		{
 | 
			
		||||
		#if defined(_SC_KERNEL_BITS)
 | 
			
		||||
		    long bits = sysconf(_SC_KERNEL_BITS);
 | 
			
		||||
		#endif
 | 
			
		||||
		    long cpu  = sysconf (_SC_CPU_VERSION);
 | 
			
		||||
 | 
			
		||||
                  switch (cpu)
 | 
			
		||||
              	{
 | 
			
		||||
              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
 | 
			
		||||
              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
 | 
			
		||||
              	case CPU_PA_RISC2_0:
 | 
			
		||||
              #if defined(_SC_KERNEL_BITS)
 | 
			
		||||
              	    switch (bits)
 | 
			
		||||
              		{
 | 
			
		||||
              		case 64: puts ("hppa2.0w"); break;
 | 
			
		||||
              		case 32: puts ("hppa2.0n"); break;
 | 
			
		||||
              		default: puts ("hppa2.0"); break;
 | 
			
		||||
              		} break;
 | 
			
		||||
              #else  /* !defined(_SC_KERNEL_BITS) */
 | 
			
		||||
              	    puts ("hppa2.0"); break;
 | 
			
		||||
              #endif
 | 
			
		||||
              	default: puts ("hppa1.0"); break;
 | 
			
		||||
              	}
 | 
			
		||||
                  exit (0);
 | 
			
		||||
              }
 | 
			
		||||
		    switch (cpu)
 | 
			
		||||
			{
 | 
			
		||||
			case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
 | 
			
		||||
			case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
 | 
			
		||||
			case CPU_PA_RISC2_0:
 | 
			
		||||
		#if defined(_SC_KERNEL_BITS)
 | 
			
		||||
			    switch (bits)
 | 
			
		||||
				{
 | 
			
		||||
				case 64: puts ("hppa2.0w"); break;
 | 
			
		||||
				case 32: puts ("hppa2.0n"); break;
 | 
			
		||||
				default: puts ("hppa2.0"); break;
 | 
			
		||||
				} break;
 | 
			
		||||
		#else  /* !defined(_SC_KERNEL_BITS) */
 | 
			
		||||
			    puts ("hppa2.0"); break;
 | 
			
		||||
		#endif
 | 
			
		||||
			default: puts ("hppa1.0"); break;
 | 
			
		||||
			}
 | 
			
		||||
		    exit (0);
 | 
			
		||||
		}
 | 
			
		||||
EOF
 | 
			
		||||
		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
 | 
			
		||||
		    test -z "$HP_ARCH" && HP_ARCH=hppa
 | 
			
		||||
@@ -640,7 +665,7 @@ EOF
 | 
			
		||||
	    # => hppa64-hp-hpux11.23
 | 
			
		||||
 | 
			
		||||
	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
 | 
			
		||||
		grep __LP64__ >/dev/null
 | 
			
		||||
		grep -q __LP64__
 | 
			
		||||
	    then
 | 
			
		||||
		HP_ARCH="hppa2.0w"
 | 
			
		||||
	    else
 | 
			
		||||
@@ -711,22 +736,22 @@ EOF
 | 
			
		||||
	exit ;;
 | 
			
		||||
    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
 | 
			
		||||
	echo c1-convex-bsd
 | 
			
		||||
        exit ;;
 | 
			
		||||
	exit ;;
 | 
			
		||||
    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
 | 
			
		||||
	if getsysinfo -f scalar_acc
 | 
			
		||||
	then echo c32-convex-bsd
 | 
			
		||||
	else echo c2-convex-bsd
 | 
			
		||||
	fi
 | 
			
		||||
        exit ;;
 | 
			
		||||
	exit ;;
 | 
			
		||||
    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
 | 
			
		||||
	echo c34-convex-bsd
 | 
			
		||||
        exit ;;
 | 
			
		||||
	exit ;;
 | 
			
		||||
    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
 | 
			
		||||
	echo c38-convex-bsd
 | 
			
		||||
        exit ;;
 | 
			
		||||
	exit ;;
 | 
			
		||||
    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
 | 
			
		||||
	echo c4-convex-bsd
 | 
			
		||||
        exit ;;
 | 
			
		||||
	exit ;;
 | 
			
		||||
    CRAY*Y-MP:*:*:*)
 | 
			
		||||
	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
 | 
			
		||||
	exit ;;
 | 
			
		||||
@@ -750,14 +775,14 @@ EOF
 | 
			
		||||
	exit ;;
 | 
			
		||||
    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
 | 
			
		||||
	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
 | 
			
		||||
        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
 | 
			
		||||
        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
 | 
			
		||||
        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 | 
			
		||||
        exit ;;
 | 
			
		||||
	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
 | 
			
		||||
	FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
 | 
			
		||||
	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 | 
			
		||||
	exit ;;
 | 
			
		||||
    5000:UNIX_System_V:4.*:*)
 | 
			
		||||
        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
 | 
			
		||||
        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
 | 
			
		||||
        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 | 
			
		||||
	FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
 | 
			
		||||
	FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
 | 
			
		||||
	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
 | 
			
		||||
@@ -769,34 +794,39 @@ EOF
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *:FreeBSD:*:*)
 | 
			
		||||
	case ${UNAME_MACHINE} in
 | 
			
		||||
	    pc98)
 | 
			
		||||
		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
 | 
			
		||||
	UNAME_PROCESSOR=`/usr/bin/uname -p`
 | 
			
		||||
	case ${UNAME_PROCESSOR} in
 | 
			
		||||
	    amd64)
 | 
			
		||||
		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
 | 
			
		||||
	    *)
 | 
			
		||||
		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
 | 
			
		||||
		echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
 | 
			
		||||
	esac
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*:CYGWIN*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-cygwin
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *:MINGW64*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-mingw64
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *:MINGW*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-mingw32
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*:MSYS*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-msys
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*:windows32*:*)
 | 
			
		||||
    	# uname -m includes "-pc" on this system.
 | 
			
		||||
    	echo ${UNAME_MACHINE}-mingw32
 | 
			
		||||
	# uname -m includes "-pc" on this system.
 | 
			
		||||
	echo ${UNAME_MACHINE}-mingw32
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*:PW*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-pw32
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *:Interix*:[3456]*)
 | 
			
		||||
    	case ${UNAME_MACHINE} in
 | 
			
		||||
    *:Interix*:*)
 | 
			
		||||
	case ${UNAME_MACHINE} in
 | 
			
		||||
	    x86)
 | 
			
		||||
		echo i586-pc-interix${UNAME_RELEASE}
 | 
			
		||||
		exit ;;
 | 
			
		||||
	    EM64T | authenticamd)
 | 
			
		||||
	    authenticamd | genuineintel | EM64T)
 | 
			
		||||
		echo x86_64-unknown-interix${UNAME_RELEASE}
 | 
			
		||||
		exit ;;
 | 
			
		||||
	    IA64)
 | 
			
		||||
@@ -806,6 +836,9 @@ EOF
 | 
			
		||||
    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
 | 
			
		||||
	echo i${UNAME_MACHINE}-pc-mks
 | 
			
		||||
	exit ;;
 | 
			
		||||
    8664:Windows_NT:*)
 | 
			
		||||
	echo x86_64-pc-mks
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
 | 
			
		||||
	# How do we know it's Interix rather than the generic POSIX subsystem?
 | 
			
		||||
	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
 | 
			
		||||
@@ -835,92 +868,13 @@ EOF
 | 
			
		||||
    i*86:Minix:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-minix
 | 
			
		||||
	exit ;;
 | 
			
		||||
    arm*:Linux:*:*)
 | 
			
		||||
	eval $set_cc_for_build
 | 
			
		||||
	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
 | 
			
		||||
	    | grep -q __ARM_EABI__
 | 
			
		||||
	then
 | 
			
		||||
	    echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	else
 | 
			
		||||
	    echo ${UNAME_MACHINE}-unknown-linux-gnueabi
 | 
			
		||||
	fi
 | 
			
		||||
	exit ;;
 | 
			
		||||
    avr32*:Linux:*:*)
 | 
			
		||||
    aarch64:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    cris:Linux:*:*)
 | 
			
		||||
	echo cris-axis-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    crisv32:Linux:*:*)
 | 
			
		||||
	echo crisv32-axis-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    frv:Linux:*:*)
 | 
			
		||||
    	echo frv-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    ia64:Linux:*:*)
 | 
			
		||||
    aarch64_be:Linux:*:*)
 | 
			
		||||
	UNAME_MACHINE=aarch64_be
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    m32r*:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    m68*:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    mips:Linux:*:*)
 | 
			
		||||
	eval $set_cc_for_build
 | 
			
		||||
	sed 's/^	//' << EOF >$dummy.c
 | 
			
		||||
	#undef CPU
 | 
			
		||||
	#undef mips
 | 
			
		||||
	#undef mipsel
 | 
			
		||||
	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
 | 
			
		||||
	CPU=mipsel
 | 
			
		||||
	#else
 | 
			
		||||
	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
 | 
			
		||||
	CPU=mips
 | 
			
		||||
	#else
 | 
			
		||||
	CPU=
 | 
			
		||||
	#endif
 | 
			
		||||
	#endif
 | 
			
		||||
EOF
 | 
			
		||||
	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
 | 
			
		||||
	    /^CPU/{
 | 
			
		||||
		s: ::g
 | 
			
		||||
		p
 | 
			
		||||
	    }'`"
 | 
			
		||||
	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
 | 
			
		||||
	;;
 | 
			
		||||
    mips64:Linux:*:*)
 | 
			
		||||
	eval $set_cc_for_build
 | 
			
		||||
	sed 's/^	//' << EOF >$dummy.c
 | 
			
		||||
	#undef CPU
 | 
			
		||||
	#undef mips64
 | 
			
		||||
	#undef mips64el
 | 
			
		||||
	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
 | 
			
		||||
	CPU=mips64el
 | 
			
		||||
	#else
 | 
			
		||||
	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
 | 
			
		||||
	CPU=mips64
 | 
			
		||||
	#else
 | 
			
		||||
	CPU=
 | 
			
		||||
	#endif
 | 
			
		||||
	#endif
 | 
			
		||||
EOF
 | 
			
		||||
	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
 | 
			
		||||
	    /^CPU/{
 | 
			
		||||
		s: ::g
 | 
			
		||||
		p
 | 
			
		||||
	    }'`"
 | 
			
		||||
	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
 | 
			
		||||
	;;
 | 
			
		||||
    or32:Linux:*:*)
 | 
			
		||||
	echo or32-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    ppc:Linux:*:*)
 | 
			
		||||
	echo powerpc-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    ppc64:Linux:*:*)
 | 
			
		||||
	echo powerpc64-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    alpha:Linux:*:*)
 | 
			
		||||
	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
 | 
			
		||||
	  EV5)   UNAME_MACHINE=alphaev5 ;;
 | 
			
		||||
@@ -930,11 +884,90 @@ EOF
 | 
			
		||||
	  EV6)   UNAME_MACHINE=alphaev6 ;;
 | 
			
		||||
	  EV67)  UNAME_MACHINE=alphaev67 ;;
 | 
			
		||||
	  EV68*) UNAME_MACHINE=alphaev68 ;;
 | 
			
		||||
        esac
 | 
			
		||||
	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
 | 
			
		||||
	esac
 | 
			
		||||
	objdump --private-headers /bin/sh | grep -q ld.so.1
 | 
			
		||||
	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    arm*:Linux:*:*)
 | 
			
		||||
	eval $set_cc_for_build
 | 
			
		||||
	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
 | 
			
		||||
	    | grep -q __ARM_EABI__
 | 
			
		||||
	then
 | 
			
		||||
	    echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	else
 | 
			
		||||
	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
 | 
			
		||||
		| grep -q __ARM_PCS_VFP
 | 
			
		||||
	    then
 | 
			
		||||
		echo ${UNAME_MACHINE}-unknown-linux-gnueabi
 | 
			
		||||
	    else
 | 
			
		||||
		echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
 | 
			
		||||
	    fi
 | 
			
		||||
	fi
 | 
			
		||||
	exit ;;
 | 
			
		||||
    avr32*:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    cris:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-axis-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    crisv32:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-axis-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    frv:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    hexagon:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*86:Linux:*:*)
 | 
			
		||||
	LIBC=gnu
 | 
			
		||||
	eval $set_cc_for_build
 | 
			
		||||
	sed 's/^	//' << EOF >$dummy.c
 | 
			
		||||
	#ifdef __dietlibc__
 | 
			
		||||
	LIBC=dietlibc
 | 
			
		||||
	#endif
 | 
			
		||||
EOF
 | 
			
		||||
	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
 | 
			
		||||
	echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
 | 
			
		||||
	exit ;;
 | 
			
		||||
    ia64:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    m32r*:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    m68*:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    mips:Linux:*:* | mips64:Linux:*:*)
 | 
			
		||||
	eval $set_cc_for_build
 | 
			
		||||
	sed 's/^	//' << EOF >$dummy.c
 | 
			
		||||
	#undef CPU
 | 
			
		||||
	#undef ${UNAME_MACHINE}
 | 
			
		||||
	#undef ${UNAME_MACHINE}el
 | 
			
		||||
	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
 | 
			
		||||
	CPU=${UNAME_MACHINE}el
 | 
			
		||||
	#else
 | 
			
		||||
	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
 | 
			
		||||
	CPU=${UNAME_MACHINE}
 | 
			
		||||
	#else
 | 
			
		||||
	CPU=
 | 
			
		||||
	#endif
 | 
			
		||||
	#endif
 | 
			
		||||
EOF
 | 
			
		||||
	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
 | 
			
		||||
	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
 | 
			
		||||
	;;
 | 
			
		||||
    or32:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    padre:Linux:*:*)
 | 
			
		||||
	echo sparc-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    parisc64:Linux:*:* | hppa64:Linux:*:*)
 | 
			
		||||
	echo hppa64-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    parisc:Linux:*:* | hppa:Linux:*:*)
 | 
			
		||||
	# Look for CPU level
 | 
			
		||||
	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
 | 
			
		||||
@@ -943,14 +976,17 @@ EOF
 | 
			
		||||
	  *)    echo hppa-unknown-linux-gnu ;;
 | 
			
		||||
	esac
 | 
			
		||||
	exit ;;
 | 
			
		||||
    parisc64:Linux:*:* | hppa64:Linux:*:*)
 | 
			
		||||
	echo hppa64-unknown-linux-gnu
 | 
			
		||||
    ppc64:Linux:*:*)
 | 
			
		||||
	echo powerpc64-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    ppc:Linux:*:*)
 | 
			
		||||
	echo powerpc-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    s390:Linux:*:* | s390x:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-ibm-linux
 | 
			
		||||
	exit ;;
 | 
			
		||||
    sh64*:Linux:*:*)
 | 
			
		||||
    	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    sh*:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
@@ -958,78 +994,18 @@ EOF
 | 
			
		||||
    sparc:Linux:*:* | sparc64:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    tile*:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    vax:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-dec-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    x86_64:Linux:*:*)
 | 
			
		||||
	echo x86_64-unknown-linux-gnu
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit ;;
 | 
			
		||||
    xtensa*:Linux:*:*)
 | 
			
		||||
    	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	echo ${UNAME_MACHINE}-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
 | 
			
		||||
	# problems with other programs or directories called `ld' in the path.
 | 
			
		||||
	# Set LC_ALL=C to ensure ld outputs messages in English.
 | 
			
		||||
	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
 | 
			
		||||
			 | sed -ne '/supported targets:/!d
 | 
			
		||||
				    s/[ 	][ 	]*/ /g
 | 
			
		||||
				    s/.*supported targets: *//
 | 
			
		||||
				    s/ .*//
 | 
			
		||||
				    p'`
 | 
			
		||||
        case "$ld_supported_targets" in
 | 
			
		||||
	  elf32-i386)
 | 
			
		||||
		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
 | 
			
		||||
		;;
 | 
			
		||||
	  a.out-i386-linux)
 | 
			
		||||
		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
 | 
			
		||||
		exit ;;
 | 
			
		||||
	  coff-i386)
 | 
			
		||||
		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
 | 
			
		||||
		exit ;;
 | 
			
		||||
	  "")
 | 
			
		||||
		# Either a pre-BFD a.out linker (linux-gnuoldld) or
 | 
			
		||||
		# one that does not give us useful --help.
 | 
			
		||||
		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
 | 
			
		||||
		exit ;;
 | 
			
		||||
	esac
 | 
			
		||||
	# Determine whether the default compiler is a.out or elf
 | 
			
		||||
	eval $set_cc_for_build
 | 
			
		||||
	sed 's/^	//' << EOF >$dummy.c
 | 
			
		||||
	#include <features.h>
 | 
			
		||||
	#ifdef __ELF__
 | 
			
		||||
	# ifdef __GLIBC__
 | 
			
		||||
	#  if __GLIBC__ >= 2
 | 
			
		||||
	LIBC=gnu
 | 
			
		||||
	#  else
 | 
			
		||||
	LIBC=gnulibc1
 | 
			
		||||
	#  endif
 | 
			
		||||
	# else
 | 
			
		||||
	LIBC=gnulibc1
 | 
			
		||||
	# endif
 | 
			
		||||
	#else
 | 
			
		||||
	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
 | 
			
		||||
	LIBC=gnu
 | 
			
		||||
	#else
 | 
			
		||||
	LIBC=gnuaout
 | 
			
		||||
	#endif
 | 
			
		||||
	#endif
 | 
			
		||||
	#ifdef __dietlibc__
 | 
			
		||||
	LIBC=dietlibc
 | 
			
		||||
	#endif
 | 
			
		||||
EOF
 | 
			
		||||
	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
 | 
			
		||||
	    /^LIBC/{
 | 
			
		||||
		s: ::g
 | 
			
		||||
		p
 | 
			
		||||
	    }'`"
 | 
			
		||||
	test x"${LIBC}" != x && {
 | 
			
		||||
		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
 | 
			
		||||
		exit
 | 
			
		||||
	}
 | 
			
		||||
	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
 | 
			
		||||
	;;
 | 
			
		||||
    i*86:DYNIX/ptx:4*:*)
 | 
			
		||||
	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
 | 
			
		||||
	# earlier versions are messed up and put the nodename in both
 | 
			
		||||
@@ -1037,11 +1013,11 @@ EOF
 | 
			
		||||
	echo i386-sequent-sysv4
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*86:UNIX_SV:4.2MP:2.*)
 | 
			
		||||
        # Unixware is an offshoot of SVR4, but it has its own version
 | 
			
		||||
        # number series starting with 2...
 | 
			
		||||
        # I am not positive that other SVR4 systems won't match this,
 | 
			
		||||
	# Unixware is an offshoot of SVR4, but it has its own version
 | 
			
		||||
	# number series starting with 2...
 | 
			
		||||
	# I am not positive that other SVR4 systems won't match this,
 | 
			
		||||
	# I just have to hope.  -- rms.
 | 
			
		||||
        # Use sysv4.2uw... so that sysv4* matches it.
 | 
			
		||||
	# Use sysv4.2uw... so that sysv4* matches it.
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*86:OS/2:*:*)
 | 
			
		||||
@@ -1058,7 +1034,7 @@ EOF
 | 
			
		||||
    i*86:syllable:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-syllable
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
 | 
			
		||||
    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
 | 
			
		||||
	echo i386-unknown-lynxos${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*86:*DOS:*:*)
 | 
			
		||||
@@ -1073,7 +1049,7 @@ EOF
 | 
			
		||||
	fi
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*86:*:5:[678]*)
 | 
			
		||||
    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
 | 
			
		||||
	# UnixWare 7.x, OpenUNIX and OpenServer 6.
 | 
			
		||||
	case `/bin/uname -X | grep "^Machine"` in
 | 
			
		||||
	    *486*)	     UNAME_MACHINE=i486 ;;
 | 
			
		||||
	    *Pentium)	     UNAME_MACHINE=i586 ;;
 | 
			
		||||
@@ -1101,10 +1077,13 @@ EOF
 | 
			
		||||
	exit ;;
 | 
			
		||||
    pc:*:*:*)
 | 
			
		||||
	# Left here for compatibility:
 | 
			
		||||
        # uname -m prints for DJGPP always 'pc', but it prints nothing about
 | 
			
		||||
        # the processor, so we play safe by assuming i386.
 | 
			
		||||
	echo i386-pc-msdosdjgpp
 | 
			
		||||
        exit ;;
 | 
			
		||||
	# uname -m prints for DJGPP always 'pc', but it prints nothing about
 | 
			
		||||
	# the processor, so we play safe by assuming i586.
 | 
			
		||||
	# Note: whatever this is, it MUST be the same as what config.sub
 | 
			
		||||
	# prints for the "djgpp" host, or else GDB configury will decide that
 | 
			
		||||
	# this is a cross-build.
 | 
			
		||||
	echo i586-pc-msdosdjgpp
 | 
			
		||||
	exit ;;
 | 
			
		||||
    Intel:Mach:3*:*)
 | 
			
		||||
	echo i386-pc-mach3
 | 
			
		||||
	exit ;;
 | 
			
		||||
@@ -1139,8 +1118,18 @@ EOF
 | 
			
		||||
	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
 | 
			
		||||
	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
 | 
			
		||||
    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
 | 
			
		||||
        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
 | 
			
		||||
          && { echo i486-ncr-sysv4; exit; } ;;
 | 
			
		||||
	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
 | 
			
		||||
	  && { echo i486-ncr-sysv4; exit; } ;;
 | 
			
		||||
    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
 | 
			
		||||
	OS_REL='.3'
 | 
			
		||||
	test -r /etc/.relid \
 | 
			
		||||
	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
 | 
			
		||||
	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
 | 
			
		||||
	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
 | 
			
		||||
	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
 | 
			
		||||
	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
 | 
			
		||||
	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
 | 
			
		||||
	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
 | 
			
		||||
    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
 | 
			
		||||
	echo m68k-unknown-lynxos${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
@@ -1153,7 +1142,7 @@ EOF
 | 
			
		||||
    rs6000:LynxOS:2.*:*)
 | 
			
		||||
	echo rs6000-unknown-lynxos${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
 | 
			
		||||
    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
 | 
			
		||||
	echo powerpc-unknown-lynxos${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    SM[BE]S:UNIX_SV:*:*)
 | 
			
		||||
@@ -1173,10 +1162,10 @@ EOF
 | 
			
		||||
		echo ns32k-sni-sysv
 | 
			
		||||
	fi
 | 
			
		||||
	exit ;;
 | 
			
		||||
    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
 | 
			
		||||
                      # says <Richard.M.Bartel@ccMail.Census.GOV>
 | 
			
		||||
        echo i586-unisys-sysv4
 | 
			
		||||
        exit ;;
 | 
			
		||||
    PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
 | 
			
		||||
			# says <Richard.M.Bartel@ccMail.Census.GOV>
 | 
			
		||||
	echo i586-unisys-sysv4
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *:UNIX_System_V:4*:FTX*)
 | 
			
		||||
	# From Gerald Hewes <hewes@openmarket.com>.
 | 
			
		||||
	# How about differentiating between stratus architectures? -djm
 | 
			
		||||
@@ -1202,11 +1191,11 @@ EOF
 | 
			
		||||
	exit ;;
 | 
			
		||||
    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
 | 
			
		||||
	if [ -d /usr/nec ]; then
 | 
			
		||||
	        echo mips-nec-sysv${UNAME_RELEASE}
 | 
			
		||||
		echo mips-nec-sysv${UNAME_RELEASE}
 | 
			
		||||
	else
 | 
			
		||||
	        echo mips-unknown-sysv${UNAME_RELEASE}
 | 
			
		||||
		echo mips-unknown-sysv${UNAME_RELEASE}
 | 
			
		||||
	fi
 | 
			
		||||
        exit ;;
 | 
			
		||||
	exit ;;
 | 
			
		||||
    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
 | 
			
		||||
	echo powerpc-be-beos
 | 
			
		||||
	exit ;;
 | 
			
		||||
@@ -1216,6 +1205,12 @@ EOF
 | 
			
		||||
    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
 | 
			
		||||
	echo i586-pc-beos
 | 
			
		||||
	exit ;;
 | 
			
		||||
    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
 | 
			
		||||
	echo i586-pc-haiku
 | 
			
		||||
	exit ;;
 | 
			
		||||
    x86_64:Haiku:*:*)
 | 
			
		||||
	echo x86_64-unknown-haiku
 | 
			
		||||
	exit ;;
 | 
			
		||||
    SX-4:SUPER-UX:*:*)
 | 
			
		||||
	echo sx4-nec-superux${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
@@ -1243,6 +1238,16 @@ EOF
 | 
			
		||||
    *:Darwin:*:*)
 | 
			
		||||
	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
 | 
			
		||||
	case $UNAME_PROCESSOR in
 | 
			
		||||
	    i386)
 | 
			
		||||
		eval $set_cc_for_build
 | 
			
		||||
		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
 | 
			
		||||
		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
 | 
			
		||||
		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
 | 
			
		||||
		      grep IS_64BIT_ARCH >/dev/null
 | 
			
		||||
		  then
 | 
			
		||||
		      UNAME_PROCESSOR="x86_64"
 | 
			
		||||
		  fi
 | 
			
		||||
		fi ;;
 | 
			
		||||
	    unknown) UNAME_PROCESSOR=powerpc ;;
 | 
			
		||||
	esac
 | 
			
		||||
	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
 | 
			
		||||
@@ -1258,7 +1263,10 @@ EOF
 | 
			
		||||
    *:QNX:*:4*)
 | 
			
		||||
	echo i386-pc-qnx
 | 
			
		||||
	exit ;;
 | 
			
		||||
    NSE-?:NONSTOP_KERNEL:*:*)
 | 
			
		||||
    NEO-?:NONSTOP_KERNEL:*:*)
 | 
			
		||||
	echo neo-tandem-nsk${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    NSE-*:NONSTOP_KERNEL:*:*)
 | 
			
		||||
	echo nse-tandem-nsk${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    NSR-?:NONSTOP_KERNEL:*:*)
 | 
			
		||||
@@ -1303,13 +1311,13 @@ EOF
 | 
			
		||||
	echo pdp10-unknown-its
 | 
			
		||||
	exit ;;
 | 
			
		||||
    SEI:*:*:SEIUX)
 | 
			
		||||
        echo mips-sei-seiux${UNAME_RELEASE}
 | 
			
		||||
	echo mips-sei-seiux${UNAME_RELEASE}
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *:DragonFly:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
 | 
			
		||||
	exit ;;
 | 
			
		||||
    *:*VMS:*:*)
 | 
			
		||||
    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
 | 
			
		||||
	UNAME_MACHINE=`(uname -p) 2>/dev/null`
 | 
			
		||||
	case "${UNAME_MACHINE}" in
 | 
			
		||||
	    A*) echo alpha-dec-vms ; exit ;;
 | 
			
		||||
	    I*) echo ia64-dec-vms ; exit ;;
 | 
			
		||||
@@ -1324,11 +1332,14 @@ EOF
 | 
			
		||||
    i*86:rdos:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-rdos
 | 
			
		||||
	exit ;;
 | 
			
		||||
    i*86:AROS:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-aros
 | 
			
		||||
	exit ;;
 | 
			
		||||
    x86_64:VMkernel:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-esx
 | 
			
		||||
	exit ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
#echo '(No uname command or uname output not recognized.)' 1>&2
 | 
			
		||||
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
 | 
			
		||||
 | 
			
		||||
eval $set_cc_for_build
 | 
			
		||||
cat >$dummy.c <<EOF
 | 
			
		||||
#ifdef _SEQUENT_
 | 
			
		||||
@@ -1346,11 +1357,11 @@ main ()
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
  printf ("m68k-sony-newsos%s\n",
 | 
			
		||||
#ifdef NEWSOS4
 | 
			
		||||
          "4"
 | 
			
		||||
	"4"
 | 
			
		||||
#else
 | 
			
		||||
	  ""
 | 
			
		||||
	""
 | 
			
		||||
#endif
 | 
			
		||||
         ); exit (0);
 | 
			
		||||
	); exit (0);
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										284
									
								
								config.sub
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										284
									
								
								config.sub
									
									
									
									
										vendored
									
									
								
							@@ -1,10 +1,10 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
# Configuration validation subroutine script.
 | 
			
		||||
#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 | 
			
		||||
#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
 | 
			
		||||
#   Free Software Foundation, Inc.
 | 
			
		||||
#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
 | 
			
		||||
#   2011, 2012 Free Software Foundation, Inc.
 | 
			
		||||
 | 
			
		||||
timestamp='2008-01-16'
 | 
			
		||||
timestamp='2012-08-18'
 | 
			
		||||
 | 
			
		||||
# This file is (in principle) common to ALL GNU software.
 | 
			
		||||
# The presence of a machine in this file suggests that SOME GNU software
 | 
			
		||||
@@ -21,9 +21,7 @@ timestamp='2008-01-16'
 | 
			
		||||
# GNU General Public License for more details.
 | 
			
		||||
#
 | 
			
		||||
# You should have received a copy of the GNU General Public License
 | 
			
		||||
# along with this program; if not, write to the Free Software
 | 
			
		||||
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
 | 
			
		||||
# 02110-1301, USA.
 | 
			
		||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
#
 | 
			
		||||
# As a special exception to the GNU General Public License, if you
 | 
			
		||||
# distribute this file as part of a program that contains a
 | 
			
		||||
@@ -32,13 +30,16 @@ timestamp='2008-01-16'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Please send patches to <config-patches@gnu.org>.  Submit a context
 | 
			
		||||
# diff and a properly formatted ChangeLog entry.
 | 
			
		||||
# diff and a properly formatted GNU ChangeLog entry.
 | 
			
		||||
#
 | 
			
		||||
# Configuration subroutine to validate and canonicalize a configuration type.
 | 
			
		||||
# Supply the specified configuration type as an argument.
 | 
			
		||||
# If it is invalid, we print an error message on stderr and exit with code 1.
 | 
			
		||||
# Otherwise, we print the canonical config type on stdout and succeed.
 | 
			
		||||
 | 
			
		||||
# You can get the latest version of this script from:
 | 
			
		||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
 | 
			
		||||
 | 
			
		||||
# This file is supposed to be the same for all GNU packages
 | 
			
		||||
# and recognize all the CPU types, system types and aliases
 | 
			
		||||
# that are meaningful with *any* GNU software.
 | 
			
		||||
@@ -72,8 +73,9 @@ Report bugs and patches to <config-patches@gnu.org>."
 | 
			
		||||
version="\
 | 
			
		||||
GNU config.sub ($timestamp)
 | 
			
		||||
 | 
			
		||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
 | 
			
		||||
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 | 
			
		||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
 | 
			
		||||
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
 | 
			
		||||
Free Software Foundation, Inc.
 | 
			
		||||
 | 
			
		||||
This is free software; see the source for copying conditions.  There is NO
 | 
			
		||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
 | 
			
		||||
@@ -120,12 +122,18 @@ esac
 | 
			
		||||
# Here we must recognize all the valid KERNEL-OS combinations.
 | 
			
		||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 | 
			
		||||
case $maybe_os in
 | 
			
		||||
  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
 | 
			
		||||
  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
 | 
			
		||||
  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
 | 
			
		||||
  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
 | 
			
		||||
  knetbsd*-gnu* | netbsd*-gnu* | \
 | 
			
		||||
  kopensolaris*-gnu* | \
 | 
			
		||||
  storm-chaos* | os2-emx* | rtmk-nova*)
 | 
			
		||||
    os=-$maybe_os
 | 
			
		||||
    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
 | 
			
		||||
    ;;
 | 
			
		||||
  android-linux)
 | 
			
		||||
    os=-linux-android
 | 
			
		||||
    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
 | 
			
		||||
    ;;
 | 
			
		||||
  *)
 | 
			
		||||
    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
 | 
			
		||||
    if [ $basic_machine != $1 ]
 | 
			
		||||
@@ -148,10 +156,13 @@ case $os in
 | 
			
		||||
	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
 | 
			
		||||
	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
 | 
			
		||||
	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
 | 
			
		||||
	-apple | -axis | -knuth | -cray)
 | 
			
		||||
	-apple | -axis | -knuth | -cray | -microblaze)
 | 
			
		||||
		os=
 | 
			
		||||
		basic_machine=$1
 | 
			
		||||
		;;
 | 
			
		||||
	-bluegene*)
 | 
			
		||||
		os=-cnk
 | 
			
		||||
		;;
 | 
			
		||||
	-sim | -cisco | -oki | -wec | -winbond)
 | 
			
		||||
		os=
 | 
			
		||||
		basic_machine=$1
 | 
			
		||||
@@ -166,10 +177,10 @@ case $os in
 | 
			
		||||
		os=-chorusos
 | 
			
		||||
		basic_machine=$1
 | 
			
		||||
		;;
 | 
			
		||||
 	-chorusrdb)
 | 
			
		||||
 		os=-chorusrdb
 | 
			
		||||
	-chorusrdb)
 | 
			
		||||
		os=-chorusrdb
 | 
			
		||||
		basic_machine=$1
 | 
			
		||||
 		;;
 | 
			
		||||
		;;
 | 
			
		||||
	-hiux*)
 | 
			
		||||
		os=-hiuxwe2
 | 
			
		||||
		;;
 | 
			
		||||
@@ -214,6 +225,12 @@ case $os in
 | 
			
		||||
	-isc*)
 | 
			
		||||
		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
 | 
			
		||||
		;;
 | 
			
		||||
	-lynx*178)
 | 
			
		||||
		os=-lynxos178
 | 
			
		||||
		;;
 | 
			
		||||
	-lynx*5)
 | 
			
		||||
		os=-lynxos5
 | 
			
		||||
		;;
 | 
			
		||||
	-lynx*)
 | 
			
		||||
		os=-lynxos
 | 
			
		||||
		;;
 | 
			
		||||
@@ -238,24 +255,32 @@ case $basic_machine in
 | 
			
		||||
	# Some are omitted here because they have special meanings below.
 | 
			
		||||
	1750a | 580 \
 | 
			
		||||
	| a29k \
 | 
			
		||||
	| aarch64 | aarch64_be \
 | 
			
		||||
	| 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 | avr32 \
 | 
			
		||||
        | be32 | be64 \
 | 
			
		||||
	| bfin \
 | 
			
		||||
	| c4x | clipper \
 | 
			
		||||
	| d10v | d30v | dlx | dsp16xx \
 | 
			
		||||
	| epiphany \
 | 
			
		||||
	| fido | fr30 | frv \
 | 
			
		||||
	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 | 
			
		||||
	| hexagon \
 | 
			
		||||
	| i370 | i860 | i960 | ia64 \
 | 
			
		||||
	| ip2k | iq2000 \
 | 
			
		||||
	| le32 | le64 \
 | 
			
		||||
	| lm32 \
 | 
			
		||||
	| m32c | m32r | m32rle | m68000 | m68k | m88k \
 | 
			
		||||
	| maxq | mb | microblaze | mcore | mep \
 | 
			
		||||
	| maxq | mb | microblaze | mcore | mep | metag \
 | 
			
		||||
	| mips | mipsbe | mipseb | mipsel | mipsle \
 | 
			
		||||
	| mips16 \
 | 
			
		||||
	| mips64 | mips64el \
 | 
			
		||||
	| mips64vr | mips64vrel \
 | 
			
		||||
	| mips64octeon | mips64octeonel \
 | 
			
		||||
	| mips64orion | mips64orionel \
 | 
			
		||||
	| mips64r5900 | mips64r5900el \
 | 
			
		||||
	| mips64vr | mips64vrel \
 | 
			
		||||
	| mips64vr4100 | mips64vr4100el \
 | 
			
		||||
	| mips64vr4300 | mips64vr4300el \
 | 
			
		||||
	| mips64vr5000 | mips64vr5000el \
 | 
			
		||||
@@ -268,29 +293,42 @@ case $basic_machine in
 | 
			
		||||
	| mipsisa64sr71k | mipsisa64sr71kel \
 | 
			
		||||
	| mipstx39 | mipstx39el \
 | 
			
		||||
	| mn10200 | mn10300 \
 | 
			
		||||
	| moxie \
 | 
			
		||||
	| mt \
 | 
			
		||||
	| msp430 \
 | 
			
		||||
	| nds32 | nds32le | nds32be \
 | 
			
		||||
	| nios | nios2 \
 | 
			
		||||
	| ns16k | ns32k \
 | 
			
		||||
	| open8 \
 | 
			
		||||
	| or32 \
 | 
			
		||||
	| pdp10 | pdp11 | pj | pjl \
 | 
			
		||||
	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
 | 
			
		||||
	| powerpc | powerpc64 | powerpc64le | powerpcle \
 | 
			
		||||
	| pyramid \
 | 
			
		||||
	| rl78 | rx \
 | 
			
		||||
	| score \
 | 
			
		||||
	| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
 | 
			
		||||
	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
 | 
			
		||||
	| sh64 | sh64le \
 | 
			
		||||
	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
 | 
			
		||||
	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
 | 
			
		||||
	| spu | strongarm \
 | 
			
		||||
	| tahoe | thumb | tic4x | tic80 | tron \
 | 
			
		||||
	| v850 | v850e \
 | 
			
		||||
	| spu \
 | 
			
		||||
	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
 | 
			
		||||
	| ubicom32 \
 | 
			
		||||
	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
 | 
			
		||||
	| we32k \
 | 
			
		||||
	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
 | 
			
		||||
	| z8k)
 | 
			
		||||
	| x86 | xc16x | xstormy16 | xtensa \
 | 
			
		||||
	| z8k | z80)
 | 
			
		||||
		basic_machine=$basic_machine-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	m6811 | m68hc11 | m6812 | m68hc12)
 | 
			
		||||
		# Motorola 68HC11/12.
 | 
			
		||||
	c54x)
 | 
			
		||||
		basic_machine=tic54x-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	c55x)
 | 
			
		||||
		basic_machine=tic55x-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	c6x)
 | 
			
		||||
		basic_machine=tic6x-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
 | 
			
		||||
		basic_machine=$basic_machine-unknown
 | 
			
		||||
		os=-none
 | 
			
		||||
		;;
 | 
			
		||||
@@ -300,6 +338,21 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=mt-unknown
 | 
			
		||||
		;;
 | 
			
		||||
 | 
			
		||||
	strongarm | thumb | xscale)
 | 
			
		||||
		basic_machine=arm-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	xgate)
 | 
			
		||||
		basic_machine=$basic_machine-unknown
 | 
			
		||||
		os=-none
 | 
			
		||||
		;;
 | 
			
		||||
	xscaleeb)
 | 
			
		||||
		basic_machine=armeb-unknown
 | 
			
		||||
		;;
 | 
			
		||||
 | 
			
		||||
	xscaleel)
 | 
			
		||||
		basic_machine=armel-unknown
 | 
			
		||||
		;;
 | 
			
		||||
 | 
			
		||||
	# We use `pc' rather than `unknown'
 | 
			
		||||
	# because (1) that's what they normally are, and
 | 
			
		||||
	# (2) the word "unknown" tends to confuse beginning users.
 | 
			
		||||
@@ -314,29 +367,36 @@ case $basic_machine in
 | 
			
		||||
	# Recognize the basic CPU types with company name.
 | 
			
		||||
	580-* \
 | 
			
		||||
	| a29k-* \
 | 
			
		||||
	| aarch64-* | aarch64_be-* \
 | 
			
		||||
	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
 | 
			
		||||
	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
 | 
			
		||||
	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
 | 
			
		||||
	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
 | 
			
		||||
	| avr-* | avr32-* \
 | 
			
		||||
	| be32-* | be64-* \
 | 
			
		||||
	| bfin-* | bs2000-* \
 | 
			
		||||
	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
 | 
			
		||||
	| c[123]* | c30-* | [cjt]90-* | c4x-* \
 | 
			
		||||
	| clipper-* | craynv-* | cydra-* \
 | 
			
		||||
	| d10v-* | d30v-* | dlx-* \
 | 
			
		||||
	| elxsi-* \
 | 
			
		||||
	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
 | 
			
		||||
	| h8300-* | h8500-* \
 | 
			
		||||
	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
 | 
			
		||||
	| hexagon-* \
 | 
			
		||||
	| i*86-* | i860-* | i960-* | ia64-* \
 | 
			
		||||
	| ip2k-* | iq2000-* \
 | 
			
		||||
	| le32-* | le64-* \
 | 
			
		||||
	| lm32-* \
 | 
			
		||||
	| m32c-* | m32r-* | m32rle-* \
 | 
			
		||||
	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
 | 
			
		||||
	| m88110-* | m88k-* | maxq-* | mcore-* \
 | 
			
		||||
	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
 | 
			
		||||
	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
 | 
			
		||||
	| mips16-* \
 | 
			
		||||
	| mips64-* | mips64el-* \
 | 
			
		||||
	| mips64vr-* | mips64vrel-* \
 | 
			
		||||
	| mips64octeon-* | mips64octeonel-* \
 | 
			
		||||
	| mips64orion-* | mips64orionel-* \
 | 
			
		||||
	| mips64r5900-* | mips64r5900el-* \
 | 
			
		||||
	| mips64vr-* | mips64vrel-* \
 | 
			
		||||
	| mips64vr4100-* | mips64vr4100el-* \
 | 
			
		||||
	| mips64vr4300-* | mips64vr4300el-* \
 | 
			
		||||
	| mips64vr5000-* | mips64vr5000el-* \
 | 
			
		||||
@@ -351,27 +411,32 @@ case $basic_machine in
 | 
			
		||||
	| mmix-* \
 | 
			
		||||
	| mt-* \
 | 
			
		||||
	| msp430-* \
 | 
			
		||||
	| nds32-* | nds32le-* | nds32be-* \
 | 
			
		||||
	| nios-* | nios2-* \
 | 
			
		||||
	| none-* | np1-* | ns16k-* | ns32k-* \
 | 
			
		||||
	| open8-* \
 | 
			
		||||
	| orion-* \
 | 
			
		||||
	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 | 
			
		||||
	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
 | 
			
		||||
	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
 | 
			
		||||
	| pyramid-* \
 | 
			
		||||
	| romp-* | rs6000-* \
 | 
			
		||||
	| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
 | 
			
		||||
	| rl78-* | romp-* | rs6000-* | rx-* \
 | 
			
		||||
	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
 | 
			
		||||
	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
 | 
			
		||||
	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
 | 
			
		||||
	| sparclite-* \
 | 
			
		||||
	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
 | 
			
		||||
	| tahoe-* | thumb-* \
 | 
			
		||||
	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
 | 
			
		||||
	| tahoe-* \
 | 
			
		||||
	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
 | 
			
		||||
	| tile*-* \
 | 
			
		||||
	| tron-* \
 | 
			
		||||
	| v850-* | v850e-* | vax-* \
 | 
			
		||||
	| ubicom32-* \
 | 
			
		||||
	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
 | 
			
		||||
	| vax-* \
 | 
			
		||||
	| we32k-* \
 | 
			
		||||
	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
 | 
			
		||||
	| x86-* | x86_64-* | xc16x-* | xps100-* \
 | 
			
		||||
	| xstormy16-* | xtensa*-* \
 | 
			
		||||
	| ymp-* \
 | 
			
		||||
	| z8k-*)
 | 
			
		||||
	| z8k-* | z80-*)
 | 
			
		||||
		;;
 | 
			
		||||
	# Recognize the basic CPU types without company name, with glob match.
 | 
			
		||||
	xtensa*)
 | 
			
		||||
@@ -393,7 +458,7 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=a29k-amd
 | 
			
		||||
		os=-udi
 | 
			
		||||
		;;
 | 
			
		||||
    	abacus)
 | 
			
		||||
	abacus)
 | 
			
		||||
		basic_machine=abacus-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	adobe68k)
 | 
			
		||||
@@ -439,6 +504,10 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=m68k-apollo
 | 
			
		||||
		os=-bsd
 | 
			
		||||
		;;
 | 
			
		||||
	aros)
 | 
			
		||||
		basic_machine=i386-pc
 | 
			
		||||
		os=-aros
 | 
			
		||||
		;;
 | 
			
		||||
	aux)
 | 
			
		||||
		basic_machine=m68k-apple
 | 
			
		||||
		os=-aux
 | 
			
		||||
@@ -455,10 +524,27 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		os=-linux
 | 
			
		||||
		;;
 | 
			
		||||
	bluegene*)
 | 
			
		||||
		basic_machine=powerpc-ibm
 | 
			
		||||
		os=-cnk
 | 
			
		||||
		;;
 | 
			
		||||
	c54x-*)
 | 
			
		||||
		basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	c55x-*)
 | 
			
		||||
		basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	c6x-*)
 | 
			
		||||
		basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	c90)
 | 
			
		||||
		basic_machine=c90-cray
 | 
			
		||||
		os=-unicos
 | 
			
		||||
		;;
 | 
			
		||||
	cegcc)
 | 
			
		||||
		basic_machine=arm-unknown
 | 
			
		||||
		os=-cegcc
 | 
			
		||||
		;;
 | 
			
		||||
	convex-c1)
 | 
			
		||||
		basic_machine=c1-convex
 | 
			
		||||
		os=-bsd
 | 
			
		||||
@@ -487,7 +573,7 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=craynv-cray
 | 
			
		||||
		os=-unicosmp
 | 
			
		||||
		;;
 | 
			
		||||
	cr16)
 | 
			
		||||
	cr16 | cr16-*)
 | 
			
		||||
		basic_machine=cr16-unknown
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
@@ -526,6 +612,10 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=m88k-motorola
 | 
			
		||||
		os=-sysv3
 | 
			
		||||
		;;
 | 
			
		||||
	dicos)
 | 
			
		||||
		basic_machine=i686-pc
 | 
			
		||||
		os=-dicos
 | 
			
		||||
		;;
 | 
			
		||||
	djgpp)
 | 
			
		||||
		basic_machine=i586-pc
 | 
			
		||||
		os=-msdosdjgpp
 | 
			
		||||
@@ -641,7 +731,6 @@ case $basic_machine in
 | 
			
		||||
	i370-ibm* | ibm*)
 | 
			
		||||
		basic_machine=i370-ibm
 | 
			
		||||
		;;
 | 
			
		||||
# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
 | 
			
		||||
	i*86v32)
 | 
			
		||||
		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
 | 
			
		||||
		os=-sysv32
 | 
			
		||||
@@ -699,6 +788,13 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=ns32k-utek
 | 
			
		||||
		os=-sysv
 | 
			
		||||
		;;
 | 
			
		||||
	microblaze)
 | 
			
		||||
		basic_machine=microblaze-xilinx
 | 
			
		||||
		;;
 | 
			
		||||
	mingw64)
 | 
			
		||||
		basic_machine=x86_64-pc
 | 
			
		||||
		os=-mingw64
 | 
			
		||||
		;;
 | 
			
		||||
	mingw32)
 | 
			
		||||
		basic_machine=i386-pc
 | 
			
		||||
		os=-mingw32
 | 
			
		||||
@@ -735,10 +831,18 @@ case $basic_machine in
 | 
			
		||||
	ms1-*)
 | 
			
		||||
		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
 | 
			
		||||
		;;
 | 
			
		||||
	msys)
 | 
			
		||||
		basic_machine=i386-pc
 | 
			
		||||
		os=-msys
 | 
			
		||||
		;;
 | 
			
		||||
	mvs)
 | 
			
		||||
		basic_machine=i370-ibm
 | 
			
		||||
		os=-mvs
 | 
			
		||||
		;;
 | 
			
		||||
	nacl)
 | 
			
		||||
		basic_machine=le32-unknown
 | 
			
		||||
		os=-nacl
 | 
			
		||||
		;;
 | 
			
		||||
	ncr3000)
 | 
			
		||||
		basic_machine=i486-ncr
 | 
			
		||||
		os=-sysv4
 | 
			
		||||
@@ -803,6 +907,12 @@ case $basic_machine in
 | 
			
		||||
	np1)
 | 
			
		||||
		basic_machine=np1-gould
 | 
			
		||||
		;;
 | 
			
		||||
	neo-tandem)
 | 
			
		||||
		basic_machine=neo-tandem
 | 
			
		||||
		;;
 | 
			
		||||
	nse-tandem)
 | 
			
		||||
		basic_machine=nse-tandem
 | 
			
		||||
		;;
 | 
			
		||||
	nsr-tandem)
 | 
			
		||||
		basic_machine=nsr-tandem
 | 
			
		||||
		;;
 | 
			
		||||
@@ -885,9 +995,10 @@ case $basic_machine in
 | 
			
		||||
		;;
 | 
			
		||||
	power)	basic_machine=power-ibm
 | 
			
		||||
		;;
 | 
			
		||||
	ppc)	basic_machine=powerpc-unknown
 | 
			
		||||
	ppc | ppcbe)	basic_machine=powerpc-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
	ppc-* | ppcbe-*)
 | 
			
		||||
		basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	ppcle | powerpclittle | ppc-le | powerpc-little)
 | 
			
		||||
		basic_machine=powerpcle-unknown
 | 
			
		||||
@@ -981,6 +1092,9 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=i860-stratus
 | 
			
		||||
		os=-sysv4
 | 
			
		||||
		;;
 | 
			
		||||
	strongarm-* | thumb-*)
 | 
			
		||||
		basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	sun2)
 | 
			
		||||
		basic_machine=m68000-sun
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1037,20 +1151,8 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=t90-cray
 | 
			
		||||
		os=-unicos
 | 
			
		||||
		;;
 | 
			
		||||
	tic54x | c54x*)
 | 
			
		||||
		basic_machine=tic54x-unknown
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	tic55x | c55x*)
 | 
			
		||||
		basic_machine=tic55x-unknown
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	tic6x | c6x*)
 | 
			
		||||
		basic_machine=tic6x-unknown
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	tile*)
 | 
			
		||||
		basic_machine=tile-unknown
 | 
			
		||||
		basic_machine=$basic_machine-unknown
 | 
			
		||||
		os=-linux-gnu
 | 
			
		||||
		;;
 | 
			
		||||
	tx39)
 | 
			
		||||
@@ -1120,6 +1222,9 @@ case $basic_machine in
 | 
			
		||||
	xps | xps100)
 | 
			
		||||
		basic_machine=xps100-honeywell
 | 
			
		||||
		;;
 | 
			
		||||
	xscale-* | xscalee[bl]-*)
 | 
			
		||||
		basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
 | 
			
		||||
		;;
 | 
			
		||||
	ymp)
 | 
			
		||||
		basic_machine=ymp-cray
 | 
			
		||||
		os=-unicos
 | 
			
		||||
@@ -1128,6 +1233,10 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=z8k-unknown
 | 
			
		||||
		os=-sim
 | 
			
		||||
		;;
 | 
			
		||||
	z80-*-coff)
 | 
			
		||||
		basic_machine=z80-unknown
 | 
			
		||||
		os=-sim
 | 
			
		||||
		;;
 | 
			
		||||
	none)
 | 
			
		||||
		basic_machine=none-none
 | 
			
		||||
		os=-none
 | 
			
		||||
@@ -1166,7 +1275,7 @@ case $basic_machine in
 | 
			
		||||
	we32k)
 | 
			
		||||
		basic_machine=we32k-att
 | 
			
		||||
		;;
 | 
			
		||||
	sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
 | 
			
		||||
	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
 | 
			
		||||
		basic_machine=sh-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
 | 
			
		||||
@@ -1213,9 +1322,12 @@ esac
 | 
			
		||||
if [ x"$os" != x"" ]
 | 
			
		||||
then
 | 
			
		||||
case $os in
 | 
			
		||||
        # First match some system type aliases
 | 
			
		||||
        # that might get confused with valid system types.
 | 
			
		||||
	# First match some system type aliases
 | 
			
		||||
	# that might get confused with valid system types.
 | 
			
		||||
	# -solaris* is a basic system type, with this one exception.
 | 
			
		||||
	-auroraux)
 | 
			
		||||
		os=-auroraux
 | 
			
		||||
		;;
 | 
			
		||||
	-solaris1 | -solaris1.*)
 | 
			
		||||
		os=`echo $os | sed -e 's|solaris1|sunos4|'`
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1236,21 +1348,23 @@ case $os in
 | 
			
		||||
	# Each alternative MUST END IN A *, to match a version number.
 | 
			
		||||
	# -sysv* is not here because it comes later, after sysvr4.
 | 
			
		||||
	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
 | 
			
		||||
	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
 | 
			
		||||
	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
 | 
			
		||||
	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
 | 
			
		||||
	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
 | 
			
		||||
	      | -sym* | -kopensolaris* \
 | 
			
		||||
	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
 | 
			
		||||
	      | -aos* \
 | 
			
		||||
	      | -aos* | -aros* \
 | 
			
		||||
	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 | 
			
		||||
	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
 | 
			
		||||
	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
 | 
			
		||||
	      | -openbsd* | -solidbsd* \
 | 
			
		||||
	      | -bitrig* | -openbsd* | -solidbsd* \
 | 
			
		||||
	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
 | 
			
		||||
	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
 | 
			
		||||
	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
 | 
			
		||||
	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
 | 
			
		||||
	      | -chorusos* | -chorusrdb* \
 | 
			
		||||
	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
 | 
			
		||||
	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
 | 
			
		||||
	      | -chorusos* | -chorusrdb* | -cegcc* \
 | 
			
		||||
	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
 | 
			
		||||
	      | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
 | 
			
		||||
	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
 | 
			
		||||
	      | -uxpv* | -beos* | -mpeix* | -udk* \
 | 
			
		||||
	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 | 
			
		||||
	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 | 
			
		||||
@@ -1258,7 +1372,7 @@ case $os in
 | 
			
		||||
	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 | 
			
		||||
	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 | 
			
		||||
	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
 | 
			
		||||
	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
 | 
			
		||||
	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
 | 
			
		||||
	# Remember, each alternative MUST END IN *, to match a version number.
 | 
			
		||||
		;;
 | 
			
		||||
	-qnx*)
 | 
			
		||||
@@ -1297,7 +1411,7 @@ case $os in
 | 
			
		||||
	-opened*)
 | 
			
		||||
		os=-openedition
 | 
			
		||||
		;;
 | 
			
		||||
        -os400*)
 | 
			
		||||
	-os400*)
 | 
			
		||||
		os=-os400
 | 
			
		||||
		;;
 | 
			
		||||
	-wince*)
 | 
			
		||||
@@ -1346,7 +1460,7 @@ case $os in
 | 
			
		||||
	-sinix*)
 | 
			
		||||
		os=-sysv4
 | 
			
		||||
		;;
 | 
			
		||||
        -tpf*)
 | 
			
		||||
	-tpf*)
 | 
			
		||||
		os=-tpf
 | 
			
		||||
		;;
 | 
			
		||||
	-triton*)
 | 
			
		||||
@@ -1388,6 +1502,11 @@ case $os in
 | 
			
		||||
	-zvmoe)
 | 
			
		||||
		os=-zvmoe
 | 
			
		||||
		;;
 | 
			
		||||
	-dicos*)
 | 
			
		||||
		os=-dicos
 | 
			
		||||
		;;
 | 
			
		||||
	-nacl*)
 | 
			
		||||
		;;
 | 
			
		||||
	-none)
 | 
			
		||||
		;;
 | 
			
		||||
	*)
 | 
			
		||||
@@ -1410,10 +1529,10 @@ else
 | 
			
		||||
# system, and we'll never get to this point.
 | 
			
		||||
 | 
			
		||||
case $basic_machine in
 | 
			
		||||
        score-*)
 | 
			
		||||
	score-*)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
        spu-*)
 | 
			
		||||
	spu-*)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	*-acorn)
 | 
			
		||||
@@ -1425,8 +1544,20 @@ case $basic_machine in
 | 
			
		||||
	arm*-semi)
 | 
			
		||||
		os=-aout
 | 
			
		||||
		;;
 | 
			
		||||
        c4x-* | tic4x-*)
 | 
			
		||||
        	os=-coff
 | 
			
		||||
	c4x-* | tic4x-*)
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	hexagon-*)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	tic54x-*)
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	tic55x-*)
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	tic6x-*)
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	# This must come before the *-dec entry.
 | 
			
		||||
	pdp10-*)
 | 
			
		||||
@@ -1446,14 +1577,11 @@ case $basic_machine in
 | 
			
		||||
		;;
 | 
			
		||||
	m68000-sun)
 | 
			
		||||
		os=-sunos3
 | 
			
		||||
		# This also exists in the configure program, but was not the
 | 
			
		||||
		# default.
 | 
			
		||||
		# os=-sunos4
 | 
			
		||||
		;;
 | 
			
		||||
	m68*-cisco)
 | 
			
		||||
		os=-aout
 | 
			
		||||
		;;
 | 
			
		||||
        mep-*)
 | 
			
		||||
	mep-*)
 | 
			
		||||
		os=-elf
 | 
			
		||||
		;;
 | 
			
		||||
	mips*-cisco)
 | 
			
		||||
@@ -1480,7 +1608,7 @@ case $basic_machine in
 | 
			
		||||
	*-ibm)
 | 
			
		||||
		os=-aix
 | 
			
		||||
		;;
 | 
			
		||||
    	*-knuth)
 | 
			
		||||
	*-knuth)
 | 
			
		||||
		os=-mmixware
 | 
			
		||||
		;;
 | 
			
		||||
	*-wec)
 | 
			
		||||
@@ -1585,7 +1713,7 @@ case $basic_machine in
 | 
			
		||||
			-sunos*)
 | 
			
		||||
				vendor=sun
 | 
			
		||||
				;;
 | 
			
		||||
			-aix*)
 | 
			
		||||
			-cnk*|-aix*)
 | 
			
		||||
				vendor=ibm
 | 
			
		||||
				;;
 | 
			
		||||
			-beos*)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
 | 
			
		||||
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 | 
			
		||||
#
 | 
			
		||||
# This program is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -9,46 +9,60 @@
 | 
			
		||||
# Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
define(VERSION_ID,esyscmd(git describe|sed -e 's/rel-//g'|sed -e 's/-/~/'|tr -d \\n))
 | 
			
		||||
define(VERSION_ID,esyscmd([
 | 
			
		||||
	V=`git describe 2>/dev/null | sed -e 's/rel-//g' | sed -e 's/-/~/'`;
 | 
			
		||||
	[ -z "$V" -a -r configure ] \
 | 
			
		||||
		&& V=`grep "PACKAGE_STRING=" configure | cut -d"'" -f2 | cut -d' ' -f2`
 | 
			
		||||
	( [ -n "$V" ] && echo "$V" || echo "??" ) | tr -d '\n';
 | 
			
		||||
]))
 | 
			
		||||
 | 
			
		||||
m4_ifdef([AM_SILENT_RULES],
 | 
			
		||||
	[m4_define([ng_color_tests], [color-tests])],
 | 
			
		||||
	[m4_define([ng_color_tests], [])])
 | 
			
		||||
 | 
			
		||||
# -- Initialisation --
 | 
			
		||||
 | 
			
		||||
AC_PREREQ(2.50)
 | 
			
		||||
AC_INIT(ngircd, VERSION_ID)
 | 
			
		||||
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
 | 
			
		||||
AC_CANONICAL_TARGET
 | 
			
		||||
AM_INIT_AUTOMAKE(1.6)
 | 
			
		||||
AM_CONFIG_HEADER(src/config.h)
 | 
			
		||||
AC_PREREQ([2.61])
 | 
			
		||||
AC_INIT([ngIRCd], VERSION_ID,
 | 
			
		||||
	[ngircd-ml@ngircd.barton.de], [ngircd], [http://ngircd.barton.de/])
 | 
			
		||||
 | 
			
		||||
AC_CONFIG_SRCDIR([src/ngircd/ngircd.c])
 | 
			
		||||
AC_CONFIG_HEADER([src/config.h])
 | 
			
		||||
AC_CANONICAL_HOST
 | 
			
		||||
 | 
			
		||||
AM_INIT_AUTOMAKE([-Wall 1.10 ]ng_color_tests)
 | 
			
		||||
 | 
			
		||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 | 
			
		||||
 | 
			
		||||
# -- Templates for config.h --
 | 
			
		||||
 | 
			
		||||
AH_TEMPLATE([DEBUG], [Define if debug-mode should be enabled])
 | 
			
		||||
AH_TEMPLATE([HAVE_sockaddr_in_len], [Define if sockaddr_in.sin_len exists])
 | 
			
		||||
AH_TEMPLATE([HAVE_socklen_t], [Define if socklen_t exists])
 | 
			
		||||
AH_TEMPLATE([ICONV], [Define if libiconv can be used, e.g. for CHARCONV])
 | 
			
		||||
AH_TEMPLATE([IDENTAUTH], [Define if the server should do IDENT requests])
 | 
			
		||||
AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used])
 | 
			
		||||
AH_TEMPLATE([PAM], [Define if PAM should be used])
 | 
			
		||||
AH_TEMPLATE([SNIFFER], [Define if IRC sniffer should be enabled])
 | 
			
		||||
AH_TEMPLATE([STRICT_RFC], [Define if ngIRCd should behave strict RFC compliant])
 | 
			
		||||
AH_TEMPLATE([SYSLOG], [Define if syslog should be used for logging])
 | 
			
		||||
AH_TEMPLATE([ZLIB], [Define if zlib compression should be enabled])
 | 
			
		||||
AH_TEMPLATE([TCPWRAP], [Define if TCP wrappers should be used])
 | 
			
		||||
AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used])
 | 
			
		||||
AH_TEMPLATE([WANT_IPV6], [Define if IPV6 protocol should be enabled])
 | 
			
		||||
AH_TEMPLATE([IDENTAUTH], [Define if the server should do IDENT requests])
 | 
			
		||||
AH_TEMPLATE([PAM], [Define if PAM should be used])
 | 
			
		||||
AH_TEMPLATE([HAVE_sockaddr_in_len], [Define if sockaddr_in.sin_len exists])
 | 
			
		||||
AH_TEMPLATE([ZLIB], [Define if zlib compression should be enabled])
 | 
			
		||||
 | 
			
		||||
AH_TEMPLATE([TARGET_OS], [Target operating system name])
 | 
			
		||||
AH_TEMPLATE([TARGET_VENDOR], [Target system vendor])
 | 
			
		||||
AH_TEMPLATE([TARGET_CPU], [Target CPU name])
 | 
			
		||||
AH_TEMPLATE([HOST_OS], [Target operating system name])
 | 
			
		||||
AH_TEMPLATE([HOST_VENDOR], [Target system vendor])
 | 
			
		||||
AH_TEMPLATE([HOST_CPU], [Target CPU name])
 | 
			
		||||
 | 
			
		||||
# -- C Compiler --
 | 
			
		||||
 | 
			
		||||
AC_PROG_CC
 | 
			
		||||
AC_PROG_CC_STDC
 | 
			
		||||
AC_C_PROTOTYPES
 | 
			
		||||
 | 
			
		||||
# -- Helper programs --
 | 
			
		||||
 | 
			
		||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
 | 
			
		||||
 | 
			
		||||
AC_PROG_AWK
 | 
			
		||||
AC_PROG_INSTALL
 | 
			
		||||
AC_PROG_LN_S
 | 
			
		||||
@@ -57,9 +71,9 @@ AC_PROG_RANLIB
 | 
			
		||||
 | 
			
		||||
# -- Compiler Features --
 | 
			
		||||
 | 
			
		||||
AM_C_PROTOTYPES
 | 
			
		||||
AC_C_CONST
 | 
			
		||||
AC_C_INLINE
 | 
			
		||||
__ng_PROTOTYPES__
 | 
			
		||||
 | 
			
		||||
# -- Hard coded system and compiler dependencies/features/options ... --
 | 
			
		||||
 | 
			
		||||
@@ -85,7 +99,7 @@ if test "$GCC" = "yes"; then
 | 
			
		||||
	GCC_STACK_PROTECT_CC
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
case "$target_os" in
 | 
			
		||||
case "$host_os" in
 | 
			
		||||
	hpux*)
 | 
			
		||||
		# This is HP/UX, we need to define _XOPEN_SOURCE_EXTENDED
 | 
			
		||||
		# (tested with HP/UX 11.11)
 | 
			
		||||
@@ -101,28 +115,20 @@ CFLAGS="$CFLAGS -DSYSCONFDIR='\"\$(sysconfdir)\"'"
 | 
			
		||||
# -- Headers --
 | 
			
		||||
 | 
			
		||||
AC_HEADER_STDC
 | 
			
		||||
AC_HEADER_TIME
 | 
			
		||||
AC_HEADER_SYS_WAIT
 | 
			
		||||
AC_HEADER_TIME
 | 
			
		||||
 | 
			
		||||
# Required header files
 | 
			
		||||
AC_CHECK_HEADERS([ \
 | 
			
		||||
	ctype.h errno.h fcntl.h netdb.h netinet/in.h netinet/in_systm.h \
 | 
			
		||||
	stdlib.h string.h strings.h sys/socket.h sys/time.h unistd.h \
 | 
			
		||||
	fcntl.h netdb.h netinet/in.h netinet/in_systm.h stdlib.h string.h \
 | 
			
		||||
	strings.h sys/socket.h sys/time.h unistd.h \
 | 
			
		||||
	],,AC_MSG_ERROR([required C header missing!]))
 | 
			
		||||
 | 
			
		||||
AC_CHECK_HEADERS([ \
 | 
			
		||||
	arpa/inet.h ctype.h malloc.h netinet/ip.h stdbool.h stddef.h varargs.h \
 | 
			
		||||
	],[],[],[[
 | 
			
		||||
	#ifdef HAVE_SYS_TYPES_H
 | 
			
		||||
		#include <sys/types.h>
 | 
			
		||||
	#endif
 | 
			
		||||
	#ifdef HAVE_SYS_SOCKET_H
 | 
			
		||||
		#include <sys/socket.h>
 | 
			
		||||
	#endif
 | 
			
		||||
	#ifdef HAVE_NETINET_IN_H
 | 
			
		||||
		#include <netinet/in.h>
 | 
			
		||||
	#endif
 | 
			
		||||
	]]
 | 
			
		||||
)
 | 
			
		||||
# Optional header files
 | 
			
		||||
AC_CHECK_HEADERS_ONCE([ \
 | 
			
		||||
	arpa/inet.h inttypes.h malloc.h netinet/ip.h stdbool.h stddef.h \
 | 
			
		||||
	stdint.h varargs.h \
 | 
			
		||||
	])
 | 
			
		||||
 | 
			
		||||
# -- Datatypes --
 | 
			
		||||
 | 
			
		||||
@@ -139,31 +145,50 @@ AC_TRY_COMPILE([
 | 
			
		||||
	AC_MSG_RESULT(no)
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
AC_TYPE_PID_T
 | 
			
		||||
AC_TYPE_SIGNAL
 | 
			
		||||
AC_TYPE_SIZE_T
 | 
			
		||||
AC_TYPE_SSIZE_T
 | 
			
		||||
AC_TYPE_UID_T
 | 
			
		||||
AC_TYPE_UINT16_T
 | 
			
		||||
AC_TYPE_UINT32_T
 | 
			
		||||
AC_TYPE_UINT8_T
 | 
			
		||||
 | 
			
		||||
AC_CHECK_MEMBER([struct sockaddr_in.sin_len], AC_DEFINE(HAVE_sockaddr_in_len),,
 | 
			
		||||
 [#include <arpa/inet.h>])
 | 
			
		||||
 | 
			
		||||
# -- Libraries --
 | 
			
		||||
 | 
			
		||||
# A/UX needs this.
 | 
			
		||||
AC_CHECK_LIB(UTIL,memmove)
 | 
			
		||||
# needed on solaris. GNU libc also has a libnsl, but we do not need it.
 | 
			
		||||
AC_SEARCH_LIBS(gethostbyname,nsl)
 | 
			
		||||
AC_CHECK_LIB(socket,bind)
 | 
			
		||||
# memmove: A/UX libUTIL
 | 
			
		||||
AC_SEARCH_LIBS([memmove], [UTIL], [], [
 | 
			
		||||
	AC_MSG_ERROR([unable to find the memmove() function])
 | 
			
		||||
])
 | 
			
		||||
# gethostbyname: Solaris libnsl
 | 
			
		||||
AC_SEARCH_LIBS([gethostbyname], [bind nsl network], [], [
 | 
			
		||||
	AC_MSG_ERROR([unable to find the gethostbyname() function])
 | 
			
		||||
])
 | 
			
		||||
# bind: SVR4 libsocket
 | 
			
		||||
AC_SEARCH_LIBS([bind], [socket network], [], [
 | 
			
		||||
	AC_MSG_ERROR([unable to find the bind() function])
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
# -- Functions --
 | 
			
		||||
 | 
			
		||||
AC_FUNC_FORK
 | 
			
		||||
AC_FUNC_STRFTIME
 | 
			
		||||
 | 
			
		||||
# Required functions
 | 
			
		||||
AC_CHECK_FUNCS([ \
 | 
			
		||||
	bind gethostbyaddr gethostbyname gethostname inet_ntoa \
 | 
			
		||||
	setsid setsockopt socket strcasecmp waitpid],,AC_MSG_ERROR([required function missing!]))
 | 
			
		||||
	alarm dup2 endpwent gethostbyaddr gethostbyname gethostname \
 | 
			
		||||
	gettimeofday inet_ntoa memmove memset setsid socket strcasecmp \
 | 
			
		||||
	strchr strcspn strerror strncasecmp strrchr strspn strstr \
 | 
			
		||||
	],,
 | 
			
		||||
	AC_MSG_ERROR([required function missing!]))
 | 
			
		||||
 | 
			
		||||
AC_CHECK_FUNCS(getaddrinfo getnameinfo inet_aton sigaction sigprocmask snprintf \
 | 
			
		||||
 vsnprintf strdup strlcpy strlcat strtok_r)
 | 
			
		||||
# Optional functions
 | 
			
		||||
AC_CHECK_FUNCS_ONCE([ \
 | 
			
		||||
	gai_strerror getaddrinfo getnameinfo inet_aton sigaction sigprocmask \
 | 
			
		||||
	snprintf vsnprintf strdup strlcpy strlcat strtok_r waitpid])
 | 
			
		||||
 | 
			
		||||
# -- Configuration options --
 | 
			
		||||
 | 
			
		||||
@@ -171,22 +196,20 @@ AC_CHECK_FUNCS(getaddrinfo getnameinfo inet_aton sigaction sigprocmask snprintf
 | 
			
		||||
 | 
			
		||||
x_syslog_on=no
 | 
			
		||||
AC_ARG_WITH(syslog,
 | 
			
		||||
	[  --without-syslog        disable syslog (autodetected by default)],
 | 
			
		||||
	AS_HELP_STRING([--without-syslog],
 | 
			
		||||
		       [disable syslog (autodetected by default)]),
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
				CPPFLAGS="-I$withval/include $CPPFLAGS"
 | 
			
		||||
				LDFLAGS="-L$withval/lib $LDFLAGS"
 | 
			
		||||
			fi
 | 
			
		||||
			AC_CHECK_LIB(be, syslog)
 | 
			
		||||
			AC_CHECK_FUNCS(syslog, x_syslog_on=yes,
 | 
			
		||||
			AC_SEARCH_LIBS([syslog], [be], [x_syslog_on=yes], [
 | 
			
		||||
				AC_MSG_ERROR([Can't enable syslog!])
 | 
			
		||||
			)
 | 
			
		||||
			])
 | 
			
		||||
		fi
 | 
			
		||||
	],
 | 
			
		||||
	[
 | 
			
		||||
		AC_CHECK_LIB(be, syslog)
 | 
			
		||||
		AC_CHECK_FUNCS(syslog, x_syslog_on=yes)
 | 
			
		||||
	[	AC_SEARCH_LIBS([syslog], [be], [x_syslog_on=yes])
 | 
			
		||||
	]
 | 
			
		||||
)
 | 
			
		||||
if test "$x_syslog_on" = "yes"; then
 | 
			
		||||
@@ -198,7 +221,8 @@ fi
 | 
			
		||||
 | 
			
		||||
x_zlib_on=no
 | 
			
		||||
AC_ARG_WITH(zlib,
 | 
			
		||||
	[  --without-zlib          disable zlib compression (autodetected by default)],
 | 
			
		||||
	AS_HELP_STRING([--without-zlib],
 | 
			
		||||
		       [disable zlib compression (autodetected by default)]),
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
@@ -225,7 +249,8 @@ fi
 | 
			
		||||
x_io_backend=none
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH(select,
 | 
			
		||||
	[  --without-select        disable select IO support (autodetected by default)],
 | 
			
		||||
	AS_HELP_STRING([--without-select],
 | 
			
		||||
		       [disable select IO support (autodetected by default)]),
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
@@ -243,25 +268,35 @@ AC_ARG_WITH(select,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH(poll,
 | 
			
		||||
	[  --without-poll          disable poll support (autodetected by default)],
 | 
			
		||||
	AS_HELP_STRING([--without-poll],
 | 
			
		||||
		       [disable poll support (autodetected by default)]),
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "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_CHECK_FUNCS(poll, [
 | 
			
		||||
				AC_CHECK_HEADERS(poll.h,
 | 
			
		||||
					x_io_backend=poll\(\),
 | 
			
		||||
					AC_MSG_ERROR(
 | 
			
		||||
					     [Can't enable poll IO support!])
 | 
			
		||||
				)
 | 
			
		||||
			], [
 | 
			
		||||
				AC_MSG_ERROR([Can't enable poll IO support!])
 | 
			
		||||
			)
 | 
			
		||||
			])
 | 
			
		||||
		fi
 | 
			
		||||
	],
 | 
			
		||||
	[
 | 
			
		||||
		AC_CHECK_FUNCS(poll, x_io_backend=poll\(\))
 | 
			
		||||
		AC_CHECK_FUNCS(poll, [
 | 
			
		||||
			AC_CHECK_HEADERS(poll.h, x_io_backend=poll\(\))
 | 
			
		||||
		])
 | 
			
		||||
	]
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH(devpoll,
 | 
			
		||||
	[  --without-devpoll       disable /dev/poll IO support (autodetected by default)],
 | 
			
		||||
	AS_HELP_STRING([--without-devpoll],
 | 
			
		||||
		       [disable /dev/poll IO support (autodetected by default)]),
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
@@ -278,7 +313,8 @@ AC_ARG_WITH(devpoll,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH(epoll,
 | 
			
		||||
	[  --without-epoll         disable epoll IO support (autodetected by default)],
 | 
			
		||||
	AS_HELP_STRING([--without-epoll],
 | 
			
		||||
		       [disable epoll IO support (autodetected by default)]),
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
@@ -296,7 +332,8 @@ AC_ARG_WITH(epoll,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH(kqueue,
 | 
			
		||||
	[  --without-kqueue        disable kqueue IO support (autodetected by default)],
 | 
			
		||||
	AS_HELP_STRING([--without-kqueue],
 | 
			
		||||
		       [disable kqueue IO support (autodetected by default)]),
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
@@ -330,13 +367,14 @@ else
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test "$x_io_backend" = "none"; then
 | 
			
		||||
	AC_MSG_ERROR([No useabe IO API activated/found!?])
 | 
			
		||||
	AC_MSG_ERROR([No useable IO API activated/found!?])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# use SSL?
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH(openssl,
 | 
			
		||||
	[  --with-openssl          enable SSL support using OpenSSL],
 | 
			
		||||
	AS_HELP_STRING([--with-openssl],
 | 
			
		||||
		       [enable SSL support using OpenSSL]),
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
@@ -353,7 +391,8 @@ AC_ARG_WITH(openssl,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
AC_ARG_WITH(gnutls,
 | 
			
		||||
	[  --with-gnutls           enable SSL support using gnutls],
 | 
			
		||||
	AS_HELP_STRING([--with-gnutls],
 | 
			
		||||
		       [enable SSL support using gnutls]),
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
@@ -383,7 +422,8 @@ fi
 | 
			
		||||
 | 
			
		||||
x_tcpwrap_on=no
 | 
			
		||||
AC_ARG_WITH(tcp-wrappers,
 | 
			
		||||
	[  --with-tcp-wrappers     enable TCP wrappers support],
 | 
			
		||||
	AS_HELP_STRING([--with-tcp-wrappers],
 | 
			
		||||
		       [enable TCP wrappers support]),
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
@@ -414,7 +454,8 @@ int deny_severity = 0;
 | 
			
		||||
 | 
			
		||||
x_identauth_on=no
 | 
			
		||||
AC_ARG_WITH(ident,
 | 
			
		||||
	[  --with-ident            enable "IDENT" ("AUTH") protocol support],
 | 
			
		||||
	AS_HELP_STRING([--with-ident],
 | 
			
		||||
		       [enable "IDENT" ("AUTH") protocol support]),
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
@@ -437,7 +478,8 @@ fi
 | 
			
		||||
 | 
			
		||||
x_pam_on=no
 | 
			
		||||
AC_ARG_WITH(pam,
 | 
			
		||||
	[  --with-pam              enable user authentication using PAM],
 | 
			
		||||
	AS_HELP_STRING([--with-pam],
 | 
			
		||||
		       [enable user authentication using PAM]),
 | 
			
		||||
	[	if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
@@ -464,17 +506,42 @@ fi
 | 
			
		||||
 | 
			
		||||
x_ircplus_on=yes
 | 
			
		||||
AC_ARG_ENABLE(ircplus,
 | 
			
		||||
	[  --disable-ircplus       disable IRC+ protocol],
 | 
			
		||||
	AS_HELP_STRING([--disable-ircplus],
 | 
			
		||||
		       [disable IRC+ protocol]),
 | 
			
		||||
	if test "$enableval" = "no"; then x_ircplus_on=no; fi
 | 
			
		||||
)
 | 
			
		||||
if test "$x_ircplus_on" = "yes"; then
 | 
			
		||||
	AC_DEFINE(IRCPLUS, 1)
 | 
			
		||||
 | 
			
		||||
	# Compile in iconv support?
 | 
			
		||||
	# We only check for it when IRC+ is enabled, because the IRC+ command
 | 
			
		||||
	# CHARCONV is the only function depending on it.
 | 
			
		||||
	x_iconv_on=no
 | 
			
		||||
	AC_ARG_WITH(iconv,
 | 
			
		||||
		[  --with-iconv            enable character conversation using libiconv],
 | 
			
		||||
		[ if test "$withval" != "no"; then
 | 
			
		||||
			if test "$withval" != "yes"; then
 | 
			
		||||
				CFLAGS="-I$withval/include $CFLAGS"
 | 
			
		||||
				CPPFLAGS="-I$withval/include $CPPFLAGS"
 | 
			
		||||
				LDFLAGS="-L$withval/lib $LDFLAGS"
 | 
			
		||||
			fi
 | 
			
		||||
			AC_CHECK_LIB(iconv, iconv_open)
 | 
			
		||||
			AC_CHECK_FUNCS(iconv_open, x_iconv_on=yes,
 | 
			
		||||
				AC_MSG_ERROR([Can't enable libiconv support!])
 | 
			
		||||
			)
 | 
			
		||||
		  fi
 | 
			
		||||
		]
 | 
			
		||||
	)
 | 
			
		||||
	if test "$x_iconv_on" = "yes"; then
 | 
			
		||||
		AC_DEFINE(ICONV, 1)
 | 
			
		||||
	fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# enable support for IPv6?
 | 
			
		||||
x_ipv6_on=no
 | 
			
		||||
AC_ARG_ENABLE(ipv6,
 | 
			
		||||
	[  --enable-ipv6           enable IPv6 protocol support],
 | 
			
		||||
	AS_HELP_STRING([--enable-ipv6],
 | 
			
		||||
		       [enable IPv6 protocol support]),
 | 
			
		||||
	if test "$enableval" = "yes"; then x_ipv6_on=yes; fi
 | 
			
		||||
)
 | 
			
		||||
if test "$x_ipv6_on" = "yes"; then
 | 
			
		||||
@@ -490,7 +557,8 @@ fi
 | 
			
		||||
 | 
			
		||||
x_sniffer_on=no; x_debug_on=no
 | 
			
		||||
AC_ARG_ENABLE(sniffer,
 | 
			
		||||
	[  --enable-sniffer        enable IRC traffic sniffer (enables debug mode)],
 | 
			
		||||
	AS_HELP_STRING([--enable-sniffer],
 | 
			
		||||
		       [enable IRC traffic sniffer (enables debug mode)]),
 | 
			
		||||
	if test "$enableval" = "yes"; then
 | 
			
		||||
		AC_DEFINE(SNIFFER, 1)
 | 
			
		||||
		x_sniffer_on=yes; x_debug_on=yes
 | 
			
		||||
@@ -500,7 +568,8 @@ AC_ARG_ENABLE(sniffer,
 | 
			
		||||
# enable additional debugging code?
 | 
			
		||||
 | 
			
		||||
AC_ARG_ENABLE(debug,
 | 
			
		||||
	[  --enable-debug          show additional debug output],
 | 
			
		||||
	AS_HELP_STRING([--enable-debug],
 | 
			
		||||
		       [show additional debug output]),
 | 
			
		||||
	if test "$enableval" = "yes"; then x_debug_on=yes; fi
 | 
			
		||||
)
 | 
			
		||||
if test "$x_debug_on" = "yes"; then
 | 
			
		||||
@@ -513,7 +582,8 @@ fi
 | 
			
		||||
 | 
			
		||||
x_strict_rfc_on=no
 | 
			
		||||
AC_ARG_ENABLE(strict-rfc,
 | 
			
		||||
	[  --enable-strict-rfc     strict RFC conformance -- may break clients!],
 | 
			
		||||
	AS_HELP_STRING([--enable-strict-rfc],
 | 
			
		||||
		       [strict RFC conformance -- may break clients!]),
 | 
			
		||||
	if test "$enableval" = "yes"; then
 | 
			
		||||
		AC_DEFINE(STRICT_RFC, 1)
 | 
			
		||||
		x_strict_rfc_on=yes
 | 
			
		||||
@@ -522,9 +592,9 @@ AC_ARG_ENABLE(strict-rfc,
 | 
			
		||||
 | 
			
		||||
# -- Definitions --
 | 
			
		||||
 | 
			
		||||
AC_DEFINE_UNQUOTED(TARGET_CPU, "$target_cpu" )
 | 
			
		||||
AC_DEFINE_UNQUOTED(TARGET_VENDOR, "$target_vendor" )
 | 
			
		||||
AC_DEFINE_UNQUOTED(TARGET_OS, "$target_os" )
 | 
			
		||||
AC_DEFINE_UNQUOTED(HOST_CPU, "$host_cpu" )
 | 
			
		||||
AC_DEFINE_UNQUOTED(HOST_VENDOR, "$host_vendor" )
 | 
			
		||||
AC_DEFINE_UNQUOTED(HOST_OS, "$host_os" )
 | 
			
		||||
 | 
			
		||||
# Add additional CFLAGS, eventually specified on the command line, but after
 | 
			
		||||
# running this configure script. Useful for "-Werror" for example.
 | 
			
		||||
@@ -532,25 +602,26 @@ test -n "$CFLAGS_END" && CFLAGS="$CFLAGS $CFLAGS_END"
 | 
			
		||||
 | 
			
		||||
# -- Generate files --
 | 
			
		||||
 | 
			
		||||
AC_OUTPUT([ \
 | 
			
		||||
AC_CONFIG_FILES([ \
 | 
			
		||||
	Makefile \
 | 
			
		||||
	doc/Makefile \
 | 
			
		||||
	doc/src/Makefile \
 | 
			
		||||
	src/Makefile \
 | 
			
		||||
	src/portab/Makefile \
 | 
			
		||||
	src/ipaddr/Makefile \
 | 
			
		||||
	src/tool/Makefile \
 | 
			
		||||
	src/ngircd/Makefile \
 | 
			
		||||
	src/testsuite/Makefile \
 | 
			
		||||
	man/Makefile \
 | 
			
		||||
	contrib/Makefile \
 | 
			
		||||
	contrib/Anope/Makefile \
 | 
			
		||||
	contrib/Debian/Makefile \
 | 
			
		||||
	contrib/MacOSX/Makefile \
 | 
			
		||||
	contrib/MacOSX/ngIRCd.xcodeproj/Makefile \
 | 
			
		||||
	contrib/MacOSX/ngIRCd.pmdoc/Makefile \
 | 
			
		||||
	contrib/MacOSX/ngIRCd.xcodeproj/Makefile \
 | 
			
		||||
	contrib/Makefile \
 | 
			
		||||
	doc/Makefile \
 | 
			
		||||
	doc/src/Makefile \
 | 
			
		||||
	man/Makefile \
 | 
			
		||||
	src/ipaddr/Makefile \
 | 
			
		||||
	src/Makefile \
 | 
			
		||||
	src/ngircd/Makefile \
 | 
			
		||||
	src/portab/Makefile \
 | 
			
		||||
	src/testsuite/Makefile \
 | 
			
		||||
	src/tool/Makefile \
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
AC_OUTPUT
 | 
			
		||||
 | 
			
		||||
type dpkg >/dev/null 2>&1
 | 
			
		||||
if test $? -eq 0; then
 | 
			
		||||
	# Generate debian/ link if the dpkg command exists
 | 
			
		||||
@@ -572,8 +643,7 @@ C=`eval echo ${sysconfdir}` ; C=`eval echo ${C}`
 | 
			
		||||
M=`eval echo ${mandir}` ; M=`eval echo ${M}`
 | 
			
		||||
D=`eval echo ${docdir}` ; D=`eval echo ${D}`
 | 
			
		||||
 | 
			
		||||
echo "             Target: ${target}"
 | 
			
		||||
test "$target" != "$host" && echo "               Host: ${host}"
 | 
			
		||||
echo "               Host: ${host}"
 | 
			
		||||
echo "           Compiler: ${CC}"
 | 
			
		||||
test -n "$CFLAGS"	&& echo "     Compiler flags: ${CFLAGS}"
 | 
			
		||||
test -n "$CPPFLAGS"	&& echo " Preprocessor flags: ${CPPFLAGS}"
 | 
			
		||||
@@ -636,6 +706,17 @@ test "$x_pam_on" = "yes" \
 | 
			
		||||
echo $ECHO_N "        SSL support: $ECHO_C"
 | 
			
		||||
echo "$x_ssl_lib"
 | 
			
		||||
 | 
			
		||||
echo $ECHO_N "   libiconv support: $ECHO_C"
 | 
			
		||||
	echo "$x_iconv_on"
 | 
			
		||||
 | 
			
		||||
echo
 | 
			
		||||
 | 
			
		||||
if ! grep "^AUTOMAKE_OPTIONS = ../portab/ansi2knr" src/ngircd/Makefile.am >/dev/null 2>&1; then
 | 
			
		||||
	echo "WARNING:"
 | 
			
		||||
	echo "This GNU automake generated build system does not support \"de-ANSI-fication\","
 | 
			
		||||
	echo "therefore don't use it to generate \"official\" distribution archives!"
 | 
			
		||||
	echo "(Most probably you want to use GNU automake 1.11.x for this purpose ...)"
 | 
			
		||||
	echo
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
@@ -1,496 +0,0 @@
 | 
			
		||||
From bc5023fdba8091ab7eee29fe0deeca6843159743 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Alexander Barton <alex@barton.de>
 | 
			
		||||
Date: Mon, 16 May 2011 18:23:01 +0200
 | 
			
		||||
Subject: [PATCH 1/2] Revert "Removed ngircd as we've decided not to support it at this time"
 | 
			
		||||
 | 
			
		||||
This reverts commit 605b5d57171d2f0fac56ee2ee3e1b1bbdadeb24f and re-enables
 | 
			
		||||
the ngIRCd protocol module for Anope.
 | 
			
		||||
---
 | 
			
		||||
 modules/protocol/ngircd.cpp |  475 +++++++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 1 files changed, 475 insertions(+), 0 deletions(-)
 | 
			
		||||
 create mode 100644 modules/protocol/ngircd.cpp
 | 
			
		||||
 | 
			
		||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
 | 
			
		||||
new file mode 100644
 | 
			
		||||
index 0000000..6e1f21f
 | 
			
		||||
--- /dev/null
 | 
			
		||||
+++ b/modules/protocol/ngircd.cpp
 | 
			
		||||
@@ -0,0 +1,475 @@
 | 
			
		||||
+/* ngIRCd IRCD functions
 | 
			
		||||
+ *
 | 
			
		||||
+ * (C) 2003-2011 Anope Team
 | 
			
		||||
+ * Contact us at team@anope.org
 | 
			
		||||
+ *
 | 
			
		||||
+ * Please read COPYING and README for further details.
 | 
			
		||||
+ *
 | 
			
		||||
+ * Based on the original code of Epona by Lara.
 | 
			
		||||
+ * Based on the original code of Services by Andy Church.
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+#include "services.h"
 | 
			
		||||
+#include "modules.h"
 | 
			
		||||
+
 | 
			
		||||
+IRCDVar myIrcd[] = {
 | 
			
		||||
+	{"ngIRCd",	/* ircd name */
 | 
			
		||||
+	 "+oi",		/* Modes used by pseudoclients */
 | 
			
		||||
+	 0,		/* SVSNICK */
 | 
			
		||||
+	 0,		/* Vhost */
 | 
			
		||||
+	 0,		/* Supports SNlines */
 | 
			
		||||
+	 0,		/* Supports SQlines */
 | 
			
		||||
+	 0,		/* Supports SZlines */
 | 
			
		||||
+	 0,		/* Join 2 Message */
 | 
			
		||||
+	 0,		/* Chan SQlines */
 | 
			
		||||
+	 1,		/* Quit on Kill */
 | 
			
		||||
+	 0,		/* vidents */
 | 
			
		||||
+	 0,		/* svshold */
 | 
			
		||||
+	 0,		/* time stamp on mode */
 | 
			
		||||
+	 0,		/* UMODE */
 | 
			
		||||
+	 0,		/* O:LINE */
 | 
			
		||||
+	 0,		/* No Knock requires +i */
 | 
			
		||||
+	 0,		/* Can remove User Channel Modes with SVSMODE */
 | 
			
		||||
+	 0,		/* Sglines are not enforced until user reconnects */
 | 
			
		||||
+	 0,		/* ts6 */
 | 
			
		||||
+	 "$",		/* TLD Prefix for Global */
 | 
			
		||||
+	 20,		/* Max number of modes we can send per line */
 | 
			
		||||
+	 0,		/* IRCd sends a SSL users certificate fingerprint */
 | 
			
		||||
+	 }
 | 
			
		||||
+	,
 | 
			
		||||
+	{NULL}
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+/* PASS */
 | 
			
		||||
+class ngIRCdProto : public IRCDProto
 | 
			
		||||
+{
 | 
			
		||||
+	void SendAkill(User *u, const XLine *x)
 | 
			
		||||
+	{
 | 
			
		||||
+		if (SGLine && u == NULL)
 | 
			
		||||
+			for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end();)
 | 
			
		||||
+			{
 | 
			
		||||
+				u = it->second;
 | 
			
		||||
+				++it;
 | 
			
		||||
+				if (SGLine->Check(u) != NULL)
 | 
			
		||||
+					break;
 | 
			
		||||
+			}
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	void SendAkillDel(const XLine*) { }
 | 
			
		||||
+
 | 
			
		||||
+	void SendGlobopsInternal(const BotInfo *source, const Anope::string &buf)
 | 
			
		||||
+	{
 | 
			
		||||
+		send_cmd(source ? source->nick : Config->ServerName, "WALLOPS :%s", buf.c_str());
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	void SendJoin(BotInfo *user, Channel *c, const ChannelStatus *status)
 | 
			
		||||
+	{
 | 
			
		||||
+		send_cmd(user->nick, "JOIN %s", c->name.c_str());
 | 
			
		||||
+		if (status)
 | 
			
		||||
+			for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
 | 
			
		||||
+				if (status->HasFlag(ModeManager::ChannelModes[i]->Name))
 | 
			
		||||
+					c->SetMode(user, ModeManager::ChannelModes[i], user->nick, false);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	void SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf)
 | 
			
		||||
+	{
 | 
			
		||||
+		send_cmd(source ? source->nick : Config->ServerName, "KILL %s :%s", user->nick.c_str(), buf.c_str());
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	/* SERVER name hop descript */
 | 
			
		||||
+	void SendServer(const Server *server)
 | 
			
		||||
+	{
 | 
			
		||||
+		send_cmd("", "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str());
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	void SendConnect()
 | 
			
		||||
+	{
 | 
			
		||||
+		send_cmd("", "PASS %s 0210-IRC+ Anope|%s:CLHSo P", uplink_server->password.c_str(), Anope::VersionShort().c_str());
 | 
			
		||||
+		/* Make myself known to myself in the serverlist */
 | 
			
		||||
+		SendServer(Me);
 | 
			
		||||
+		/* finish the enhanced server handshake and register the connection */
 | 
			
		||||
+		this->SendNumeric(Config->ServerName, 376, "*", ":End of MOTD command");
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	// Received: :dev.anope.de NICK DukeP 1 ~DukePyro p57ABF9C9.dip.t-dialin.net 1 +i :DukePyrolator
 | 
			
		||||
+	void SendClientIntroduction(const User *u, const Anope::string &modes)
 | 
			
		||||
+	{
 | 
			
		||||
+		EnforceQlinedNick(u->nick, "");
 | 
			
		||||
+		send_cmd(Config->ServerName, "NICK %s 1 %s %s 1 %s :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), modes.c_str(), u->realname.c_str());
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	void SendPartInternal(const BotInfo *bi, const Channel *chan, const Anope::string &buf)
 | 
			
		||||
+	{
 | 
			
		||||
+		if (!buf.empty())
 | 
			
		||||
+			send_cmd(bi->nick, "PART %s :%s", chan->name.c_str(), buf.c_str());
 | 
			
		||||
+		else
 | 
			
		||||
+			send_cmd(bi->nick, "PART %s", chan->name.c_str());
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	void SendModeInternal(const BotInfo *bi, const Channel *dest, const Anope::string &buf)
 | 
			
		||||
+	{
 | 
			
		||||
+		send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", dest->name.c_str(), buf.c_str());
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf)
 | 
			
		||||
+	{
 | 
			
		||||
+		send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", u->nick.c_str(), buf.c_str());
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	void SendKickInternal(const BotInfo *bi, const Channel *chan, const User *user, const Anope::string &buf)
 | 
			
		||||
+	{
 | 
			
		||||
+		if (!buf.empty())
 | 
			
		||||
+			send_cmd(bi->nick, "KICK %s %s :%s", chan->name.c_str(), user->nick.c_str(), buf.c_str());
 | 
			
		||||
+		else
 | 
			
		||||
+			send_cmd(bi->nick, "KICK %s %s", chan->name.c_str(), user->nick.c_str());
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	void SendNoticeChanopsInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf)
 | 
			
		||||
+	{
 | 
			
		||||
+		send_cmd(source ? source->nick : Config->s_ChanServ, "NOTICE @%s :%s", dest->name.c_str(), buf.c_str());
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	/* INVITE */
 | 
			
		||||
+	void SendInvite(BotInfo *source, const Anope::string &chan, const Anope::string &nick)
 | 
			
		||||
+	{
 | 
			
		||||
+		send_cmd(source->nick, "INVITE %s %s", nick.c_str(), chan.c_str());
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	void SendChannel(Channel *c)
 | 
			
		||||
+	{
 | 
			
		||||
+		Anope::string mlock_modes = get_mlock_modes(c->ci, true);
 | 
			
		||||
+		if (mlock_modes.empty())
 | 
			
		||||
+			mlock_modes = "+";
 | 
			
		||||
+		send_cmd(Config->ServerName, "CHANINFO %s %s", c->name.c_str(), mlock_modes.c_str());
 | 
			
		||||
+	}
 | 
			
		||||
+	void SendTopic(BotInfo *bi, Channel *c)
 | 
			
		||||
+	{
 | 
			
		||||
+		send_cmd(bi->nick, "TOPIC %s :%s", c->name.c_str(), c->topic.c_str());
 | 
			
		||||
+	}
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+class ngIRCdIRCdMessage : public IRCdMessage
 | 
			
		||||
+{
 | 
			
		||||
+ public:
 | 
			
		||||
+	bool OnSJoin(const Anope::string&, const std::vector<Anope::string>&) { return false; }
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * Received: :dev.anope.de MODE #anope +b *!*@*aol*
 | 
			
		||||
+	 */
 | 
			
		||||
+	bool OnMode(const Anope::string &source, const std::vector<Anope::string> ¶ms)
 | 
			
		||||
+	{
 | 
			
		||||
+		if (params.size() < 2)
 | 
			
		||||
+			return true;
 | 
			
		||||
+
 | 
			
		||||
+		Anope::string modes = params[1];
 | 
			
		||||
+		for (unsigned i = 2; i < params.size(); ++i)
 | 
			
		||||
+			modes += " " + params[i];
 | 
			
		||||
+
 | 
			
		||||
+		if (params[0][0] == '#' || params[0][0] == '&')
 | 
			
		||||
+			do_cmode(source, params[0], modes, "");
 | 
			
		||||
+		else
 | 
			
		||||
+			do_umode(params[0], params[1]);
 | 
			
		||||
+
 | 
			
		||||
+		return true;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	  Received: :DukeP_ NICK :test2
 | 
			
		||||
+	  Received: :dev.anope.de NICK DukeP_ 1 ~DukePyro ip-2-201-236-154.web.vodafone.de 1 + :DukePyrolator
 | 
			
		||||
+	  source = nickname on nickchange, servername on newuser
 | 
			
		||||
+	  params[0] = nick
 | 
			
		||||
+	  params[1] = <unknown>
 | 
			
		||||
+	  params[2] = username
 | 
			
		||||
+	  params[3] = host
 | 
			
		||||
+	  params[4] = <unknown>
 | 
			
		||||
+	  params[5] = modes
 | 
			
		||||
+	  params[6] = info
 | 
			
		||||
+	*/
 | 
			
		||||
+	bool OnNick(const Anope::string &source, const std::vector<Anope::string> ¶ms)
 | 
			
		||||
+	{
 | 
			
		||||
+		if (params.size() == 1)
 | 
			
		||||
+		{
 | 
			
		||||
+			// we have a nickchange
 | 
			
		||||
+			do_nick(source, params[0], "", "", "", "", Anope::CurTime, "", "", "", "");
 | 
			
		||||
+		}
 | 
			
		||||
+		else if (params.size() == 7)
 | 
			
		||||
+		{
 | 
			
		||||
+			// a new user is connecting to the network
 | 
			
		||||
+			User *user = do_nick("", params[0], params[2], params[3], source, params[6], Anope::CurTime, "", "", "", params[5]);
 | 
			
		||||
+			if (user)
 | 
			
		||||
+				validate_user(user);
 | 
			
		||||
+		}
 | 
			
		||||
+		else
 | 
			
		||||
+		{
 | 
			
		||||
+			Log() << "Received NICK with invalid number of parameters. source = " << source << "param[0] = " << params[0] << "params.size() = " << params.size();
 | 
			
		||||
+		}
 | 
			
		||||
+		return true;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	bool OnServer(const Anope::string &source, const std::vector<Anope::string> ¶ms)
 | 
			
		||||
+	{
 | 
			
		||||
+		if (params.size() == 3)
 | 
			
		||||
+			do_server("", params[0], 0, params[2], params[1]);
 | 
			
		||||
+		else
 | 
			
		||||
+			do_server(source, params[0], params[1].is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0, params[3], params[2]);
 | 
			
		||||
+		return true;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	bool OnTopic(const Anope::string &source, const std::vector<Anope::string> ¶ms)
 | 
			
		||||
+	{
 | 
			
		||||
+		Channel *c = findchan(params[0]);
 | 
			
		||||
+		if (!c)
 | 
			
		||||
+		{
 | 
			
		||||
+			Log() << "TOPIC for nonexistant channel " << params[0];
 | 
			
		||||
+			return true;
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		c->ChangeTopicInternal(source, params[1]);
 | 
			
		||||
+		return true;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * <@po||ux> DukeP: RFC 2813, 4.2.1: the JOIN command on server-server links
 | 
			
		||||
+	 * separates the modes ("o") with ASCII 7, not space. And you can't see ASCII 7.
 | 
			
		||||
+	 *
 | 
			
		||||
+	 * if a user joins a new channel, the ircd sends <channelname>\7<umode>
 | 
			
		||||
+	 */
 | 
			
		||||
+	bool OnJoin (const Anope::string &source, const std::vector<Anope::string> ¶ms)
 | 
			
		||||
+	{
 | 
			
		||||
+		if (!params.empty())
 | 
			
		||||
+		{
 | 
			
		||||
+			size_t pos = params[0].find('\7');
 | 
			
		||||
+			if (pos != Anope::string::npos)
 | 
			
		||||
+			{
 | 
			
		||||
+				Anope::string channel = params[0].substr(0, pos);
 | 
			
		||||
+				Anope::string mode = '+' + params[0].substr(pos, params[0].length()) + " " + source;
 | 
			
		||||
+				do_join(source, channel, "");
 | 
			
		||||
+				do_cmode(source, channel, mode, "");
 | 
			
		||||
+			}
 | 
			
		||||
+			else
 | 
			
		||||
+				do_join(source, params[0], "");
 | 
			
		||||
+		}
 | 
			
		||||
+		return true;
 | 
			
		||||
+	}
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * CHANINFO <chan> +<modes>
 | 
			
		||||
+ * CHANINFO <chan> +<modes> :<topic>
 | 
			
		||||
+ * CHANINFO <chan> +<modes> <key> <limit> :<topic>
 | 
			
		||||
+ */
 | 
			
		||||
+bool event_chaninfo(const Anope::string &source, const std::vector<Anope::string> ¶ms)
 | 
			
		||||
+{
 | 
			
		||||
+
 | 
			
		||||
+	Channel *c = findchan(params[0]);
 | 
			
		||||
+	if (!c)
 | 
			
		||||
+		c = new Channel(params[0]);
 | 
			
		||||
+
 | 
			
		||||
+	Anope::string modes = params[1];
 | 
			
		||||
+	
 | 
			
		||||
+	if (params.size() == 3)
 | 
			
		||||
+	{
 | 
			
		||||
+		c->ChangeTopicInternal(source, params[2], Anope::CurTime);
 | 
			
		||||
+	} 
 | 
			
		||||
+	else if (params.size() == 5)
 | 
			
		||||
+	{
 | 
			
		||||
+		for (size_t i = 0, end = params[1].length(); i < end; ++i)
 | 
			
		||||
+		{
 | 
			
		||||
+			switch(params[1][i])
 | 
			
		||||
+			{
 | 
			
		||||
+				case 'k':
 | 
			
		||||
+					modes += " " + params[2];
 | 
			
		||||
+					continue;
 | 
			
		||||
+				case 'l':
 | 
			
		||||
+					modes += " " + params[3];
 | 
			
		||||
+					continue;
 | 
			
		||||
+			}
 | 
			
		||||
+		}
 | 
			
		||||
+		c->ChangeTopicInternal(source, params[4], Anope::CurTime);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	c->SetModesInternal(NULL, modes);
 | 
			
		||||
+
 | 
			
		||||
+	return true;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * Received: :dev.anope.de NJOIN #test :DukeP2,@DukeP
 | 
			
		||||
+ */
 | 
			
		||||
+bool event_njoin(const Anope::string &source, const std::vector<Anope::string> ¶ms)
 | 
			
		||||
+{
 | 
			
		||||
+	Channel *c = findchan(params[0]);
 | 
			
		||||
+	commasepstream sep(params[1]);
 | 
			
		||||
+	Anope::string buf;
 | 
			
		||||
+
 | 
			
		||||
+	if (!c)
 | 
			
		||||
+	{
 | 
			
		||||
+		c = new Channel(params[0], Anope::CurTime);
 | 
			
		||||
+		c->SetFlag(CH_SYNCING);
 | 
			
		||||
+	}
 | 
			
		||||
+	
 | 
			
		||||
+	while (sep.GetToken(buf))
 | 
			
		||||
+	{
 | 
			
		||||
+		std::list<ChannelMode *> Status;
 | 
			
		||||
+		char ch;
 | 
			
		||||
+
 | 
			
		||||
+		/* Get prefixes from the nick */
 | 
			
		||||
+		while ((ch = ModeManager::GetStatusChar(buf[0])))
 | 
			
		||||
+		{
 | 
			
		||||
+			buf.erase(buf.begin());
 | 
			
		||||
+			ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
 | 
			
		||||
+			if (!cm)
 | 
			
		||||
+			{
 | 
			
		||||
+				Log() << "Received unknown mode prefix " << ch << " in NJOIN string.";
 | 
			
		||||
+				continue;
 | 
			
		||||
+			}
 | 
			
		||||
+			Status.push_back(cm);
 | 
			
		||||
+		}
 | 
			
		||||
+		User *u = finduser(buf);
 | 
			
		||||
+		if (!u)
 | 
			
		||||
+		{
 | 
			
		||||
+			Log(LOG_DEBUG) << "NJOIN for nonexistant user " << buf << " on " << c->name;
 | 
			
		||||
+			continue;
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		EventReturn MOD_RESULT;
 | 
			
		||||
+		FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c));
 | 
			
		||||
+
 | 
			
		||||
+		/* Add the user to the Channel */
 | 
			
		||||
+		c->JoinUser(u);
 | 
			
		||||
+
 | 
			
		||||
+		/* Update their status internally on the channel
 | 
			
		||||
+		 * This will enforce secureops etc on the user
 | 
			
		||||
+		 */
 | 
			
		||||
+		for (std::list<ChannelMode *>::iterator it = Status.begin(), it_end = Status.end(); it != it_end; ++it)
 | 
			
		||||
+			c->SetModeInternal(*it, buf);
 | 
			
		||||
+		/* Now set whatever modes this user is allowed to have on the channel */
 | 
			
		||||
+		chan_set_correct_modes(u, c, 1);
 | 
			
		||||
+
 | 
			
		||||
+		/* Check to see if modules want the user to join, if they do
 | 
			
		||||
+		 * check to see if they are allowed to join (CheckKick will kick/ban them)
 | 
			
		||||
+		 * Don't trigger OnJoinChannel event then as the user will be destroyed
 | 
			
		||||
+		 */
 | 
			
		||||
+		if (MOD_RESULT != EVENT_STOP && c->ci && c->ci->CheckKick(u))
 | 
			
		||||
+			continue;
 | 
			
		||||
+
 | 
			
		||||
+		FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c));
 | 
			
		||||
+	} /* while */
 | 
			
		||||
+
 | 
			
		||||
+	if (c->HasFlag(CH_SYNCING))
 | 
			
		||||
+	{
 | 
			
		||||
+		c->UnsetFlag(CH_SYNCING);
 | 
			
		||||
+		c->Sync();
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return true;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+bool event_kick(const Anope::string &source, const std::vector<Anope::string> ¶ms)
 | 
			
		||||
+{
 | 
			
		||||
+	if (params.size() > 2)
 | 
			
		||||
+		do_kick(source, params[0], params[1], params[2]);
 | 
			
		||||
+	return true;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+bool event_pass(const Anope::string &source, const std::vector<Anope::string> ¶ms)
 | 
			
		||||
+{
 | 
			
		||||
+	return true;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+bool event_005(const Anope::string &source, const std::vector<Anope::string> ¶ms)
 | 
			
		||||
+{
 | 
			
		||||
+	size_t pos;
 | 
			
		||||
+	Anope::string name, data;
 | 
			
		||||
+	for (unsigned i = 0, end = params.size(); i < end; ++i)
 | 
			
		||||
+	{
 | 
			
		||||
+		pos = params[i].find('=');
 | 
			
		||||
+		if (pos != Anope::string::npos)
 | 
			
		||||
+		{
 | 
			
		||||
+			name = params[i].substr(0, pos);
 | 
			
		||||
+			data = params[i].substr(pos+1, params[i].length());
 | 
			
		||||
+			if (name == "NICKLEN")
 | 
			
		||||
+			{
 | 
			
		||||
+				unsigned newlen = convertTo<unsigned>(data);
 | 
			
		||||
+				if (Config->NickLen != newlen)
 | 
			
		||||
+				{
 | 
			
		||||
+					Log() << "Config->NickLen changed from " << Config->NickLen << " to " << newlen;
 | 
			
		||||
+					Config->NickLen = newlen;
 | 
			
		||||
+				}
 | 
			
		||||
+			}
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
+	return true;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+bool event_442(const Anope::string &source, const std::vector<Anope::string> ¶ms)
 | 
			
		||||
+{
 | 
			
		||||
+	return true;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+bool event_376(const Anope::string &source, const std::vector<Anope::string> ¶ms)
 | 
			
		||||
+{
 | 
			
		||||
+	return true;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+
 | 
			
		||||
+class ProtongIRCd : public Module
 | 
			
		||||
+{
 | 
			
		||||
+	Message message_kick, message_pass, message_njoin, message_chaninfo, message_005, 
 | 
			
		||||
+		message_442, message_376;
 | 
			
		||||
+	
 | 
			
		||||
+	ngIRCdProto ircd_proto;
 | 
			
		||||
+	ngIRCdIRCdMessage ircd_message;
 | 
			
		||||
+
 | 
			
		||||
+	void AddModes()
 | 
			
		||||
+	{
 | 
			
		||||
+		/* Add user modes */
 | 
			
		||||
+		ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a'));
 | 
			
		||||
+		ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i'));
 | 
			
		||||
+		ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o'));
 | 
			
		||||
+		ModeManager::AddUserMode(new UserMode(UMODE_RESTRICTED, 'r'));
 | 
			
		||||
+		ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's'));
 | 
			
		||||
+		ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
 | 
			
		||||
+		ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
 | 
			
		||||
+
 | 
			
		||||
+		/* b/e/I */
 | 
			
		||||
+		ModeManager::AddChannelMode(new ChannelModeBan(CMODE_BAN, 'b'));
 | 
			
		||||
+		ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
 | 
			
		||||
+
 | 
			
		||||
+		/* v/h/o/a/q */
 | 
			
		||||
+		ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
 | 
			
		||||
+		ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
 | 
			
		||||
+
 | 
			
		||||
+		/* Add channel modes */
 | 
			
		||||
+		// channel modes: biIklmnoPstvz
 | 
			
		||||
+		ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
 | 
			
		||||
+		ModeManager::AddChannelMode(new ChannelModeKey('k'));
 | 
			
		||||
+		ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l'));
 | 
			
		||||
+		ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
 | 
			
		||||
+		ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
 | 
			
		||||
+		ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P'));
 | 
			
		||||
+		ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
 | 
			
		||||
+		ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
 | 
			
		||||
+		ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z'));
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+ public:
 | 
			
		||||
+	ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator),
 | 
			
		||||
+		message_kick("KICK", event_kick), message_pass("PASS", event_pass),
 | 
			
		||||
+		message_njoin("NJOIN", event_njoin), message_chaninfo("CHANINFO", event_chaninfo),
 | 
			
		||||
+		message_005("005", event_005), message_442("442", event_442), message_376("376", event_376)
 | 
			
		||||
+	{
 | 
			
		||||
+		this->SetAuthor("Anope");
 | 
			
		||||
+		this->SetType(PROTOCOL);
 | 
			
		||||
+		
 | 
			
		||||
+		Capab.SetFlag(CAPAB_QS);
 | 
			
		||||
+
 | 
			
		||||
+		pmodule_ircd_var(myIrcd);
 | 
			
		||||
+		pmodule_ircd_proto(&this->ircd_proto);
 | 
			
		||||
+		pmodule_ircd_message(&this->ircd_message);
 | 
			
		||||
+
 | 
			
		||||
+		this->AddModes();
 | 
			
		||||
+	}
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+MODULE_INIT(ProtongIRCd)
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.5
 | 
			
		||||
 | 
			
		||||
@@ -1,60 +0,0 @@
 | 
			
		||||
From 1ea1dd2095e63cef34edbebb729edc687f410a96 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Alexander Barton <alex@barton.de>
 | 
			
		||||
Date: Mon, 16 May 2011 18:26:56 +0200
 | 
			
		||||
Subject: [PATCH 2/2] ngircd: whitespace fixes
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 modules/protocol/ngircd.cpp |   12 ++++++------
 | 
			
		||||
 1 files changed, 6 insertions(+), 6 deletions(-)
 | 
			
		||||
 | 
			
		||||
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
 | 
			
		||||
index 6e1f21f..e546d05 100644
 | 
			
		||||
--- a/modules/protocol/ngircd.cpp
 | 
			
		||||
+++ b/modules/protocol/ngircd.cpp
 | 
			
		||||
@@ -266,11 +266,11 @@ bool event_chaninfo(const Anope::string &source, const std::vector<Anope::string
 | 
			
		||||
 		c = new Channel(params[0]);
 | 
			
		||||
 
 | 
			
		||||
 	Anope::string modes = params[1];
 | 
			
		||||
-	
 | 
			
		||||
+
 | 
			
		||||
 	if (params.size() == 3)
 | 
			
		||||
 	{
 | 
			
		||||
 		c->ChangeTopicInternal(source, params[2], Anope::CurTime);
 | 
			
		||||
-	} 
 | 
			
		||||
+	}
 | 
			
		||||
 	else if (params.size() == 5)
 | 
			
		||||
 	{
 | 
			
		||||
 		for (size_t i = 0, end = params[1].length(); i < end; ++i)
 | 
			
		||||
@@ -307,7 +307,7 @@ bool event_njoin(const Anope::string &source, const std::vector<Anope::string> &
 | 
			
		||||
 		c = new Channel(params[0], Anope::CurTime);
 | 
			
		||||
 		c->SetFlag(CH_SYNCING);
 | 
			
		||||
 	}
 | 
			
		||||
-	
 | 
			
		||||
+
 | 
			
		||||
 	while (sep.GetToken(buf))
 | 
			
		||||
 	{
 | 
			
		||||
 		std::list<ChannelMode *> Status;
 | 
			
		||||
@@ -415,9 +415,9 @@ bool event_376(const Anope::string &source, const std::vector<Anope::string> &pa
 | 
			
		||||
 
 | 
			
		||||
 class ProtongIRCd : public Module
 | 
			
		||||
 {
 | 
			
		||||
-	Message message_kick, message_pass, message_njoin, message_chaninfo, message_005, 
 | 
			
		||||
+	Message message_kick, message_pass, message_njoin, message_chaninfo, message_005,
 | 
			
		||||
 		message_442, message_376;
 | 
			
		||||
-	
 | 
			
		||||
+
 | 
			
		||||
 	ngIRCdProto ircd_proto;
 | 
			
		||||
 	ngIRCdIRCdMessage ircd_message;
 | 
			
		||||
 
 | 
			
		||||
@@ -461,7 +461,7 @@ class ProtongIRCd : public Module
 | 
			
		||||
 	{
 | 
			
		||||
 		this->SetAuthor("Anope");
 | 
			
		||||
 		this->SetType(PROTOCOL);
 | 
			
		||||
-		
 | 
			
		||||
+
 | 
			
		||||
 		Capab.SetFlag(CAPAB_QS);
 | 
			
		||||
 
 | 
			
		||||
 		pmodule_ircd_var(myIrcd);
 | 
			
		||||
-- 
 | 
			
		||||
1.7.2.5
 | 
			
		||||
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
 | 
			
		||||
#
 | 
			
		||||
# This program is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
# the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
# (at your option) any later version.
 | 
			
		||||
# Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = \
 | 
			
		||||
	README \
 | 
			
		||||
	0001-Revert-Removed-ngircd.patch \
 | 
			
		||||
	0002-ngircd-whitespace-fixes.patch
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
@@ -1,36 +0,0 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
                           http://ngircd.barton.de/
 | 
			
		||||
 | 
			
		||||
               (c)2001-2011 Alexander Barton and Contributors.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                          -- contrib/Anope/README --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
This directory contains two preliminary patches that (re-) add a ngIRCd
 | 
			
		||||
protocol module to the Anope 1.9 development branch. It has been tested
 | 
			
		||||
with Anope 1.9.4, there is no guarantee that it will work with other
 | 
			
		||||
versions as Anope 1.9.x is under heavy development ...
 | 
			
		||||
 | 
			
		||||
To build this Anope protocol module, you have to
 | 
			
		||||
 | 
			
		||||
 - Download the Anope 1.9.x sources (tested with 1.9.4),
 | 
			
		||||
 - Patch in the ngIRCd protocol module,
 | 
			
		||||
 - Build and install Anope as usual,
 | 
			
		||||
 - Configure Anope as usual, use "ngircd" as protocol module.
 | 
			
		||||
 | 
			
		||||
So the command sequence can be something like this:
 | 
			
		||||
 | 
			
		||||
 $ tar xzf anope-1.9.4-source.tar.gz
 | 
			
		||||
 $ cd anope-1.9.4-source
 | 
			
		||||
 $ patch -p1 < .../ngircd/contrib/Anope/0001-Revert-Removed-ngircd.patch
 | 
			
		||||
 $ patch -p1 < .../ngircd/contrib/Anope/0002-ngircd-whitespace-fixes.patch
 | 
			
		||||
 $ ./Config
 | 
			
		||||
 $ cd build
 | 
			
		||||
 $ make
 | 
			
		||||
 $ make install
 | 
			
		||||
 | 
			
		||||
Please have a look at the file doc/Services.txt for more information about
 | 
			
		||||
how to set up ngIRCd and Anope.
 | 
			
		||||
@@ -1,3 +1,45 @@
 | 
			
		||||
ngircd (20~rc2-0ab1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New "upstream" release candidate 2 for ngIRCd Release 20.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Sun, 02 Dec 2012 18:51:06 +0100
 | 
			
		||||
 | 
			
		||||
ngircd (20~rc1-0ab1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New "upstream" release candidate 1 for ngIRCd Release 20.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Sun, 11 Nov 2012 16:03:32 +0100
 | 
			
		||||
 | 
			
		||||
ngircd (19.2-0ab1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New "upstream" release: ngIRCd 19.2.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Tue, 19 Jun 2012 11:03:12 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (19.2~rc1-0ab1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New "upstream" release candidate 1 for ngIRC Release 19.2.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Wed, 13 Jun 2012 10:59:34 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (19.1-0ab1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New "upstream" release: ngIRCd 19.1.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Mon, 19 Mar 2012 19:18:28 +0100
 | 
			
		||||
 | 
			
		||||
ngircd (19-0ab1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New "upstream" release: ngIRCd 19.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Wed, 29 Feb 2012 17:34:08 +0100
 | 
			
		||||
 | 
			
		||||
ngircd (19~rc1-0ab1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New "upstream" release candidate 1 for ngIRCd Release 19.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Sun, 12 Feb 2012 17:47:51 +0100
 | 
			
		||||
 | 
			
		||||
ngircd (18-0ab1) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New "upstream" release: ngIRCd 18.
 | 
			
		||||
 
 | 
			
		||||
@@ -2,64 +2,60 @@ Source: ngircd
 | 
			
		||||
Section: net
 | 
			
		||||
Priority: optional
 | 
			
		||||
Maintainer: Alexander Barton <alex@barton.de>
 | 
			
		||||
Build-Depends: debhelper (>> 4.0.0), libz-dev, libwrap0-dev, libident-dev, libgnutls-dev, libpam0g-dev
 | 
			
		||||
Build-Depends: debhelper (>> 4.0.0),
 | 
			
		||||
    autotools-dev,
 | 
			
		||||
    expect,
 | 
			
		||||
    libz-dev,
 | 
			
		||||
    libwrap0-dev,
 | 
			
		||||
    libident-dev,
 | 
			
		||||
    libgnutls-dev,
 | 
			
		||||
    libpam0g-dev,
 | 
			
		||||
    telnet | telnet-ssl,
 | 
			
		||||
Standards-Version: 3.9.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
 | 
			
		||||
 IRCd like many others.
 | 
			
		||||
Description: lightweight Internet Relay Chat server
 | 
			
		||||
 This package provides ngIRCd, a portable and lightweight Internet Relay
 | 
			
		||||
 Chat server for small or private networks, developed under the GNU
 | 
			
		||||
 General Public License (GPL). It is simple to configure, can cope with
 | 
			
		||||
 dynamic IP addresses, and supports IPv6 as well as SSL. It is written
 | 
			
		||||
 from scratch and not based on the original IRCd.
 | 
			
		||||
 .
 | 
			
		||||
 This package contains the "standard distribution", including support for
 | 
			
		||||
 syslog logging and compressed server-links using zlib. Please have a look
 | 
			
		||||
 at the "ngircd-full" package if you need advanced functionality like support
 | 
			
		||||
 for IPv6 or SSL.
 | 
			
		||||
 .
 | 
			
		||||
 Advantages of ngIRCd:
 | 
			
		||||
  - no problems with servers using changing/non-static IP addresses.
 | 
			
		||||
  - small and lean configuration file.
 | 
			
		||||
  - free, modern and open source C code.
 | 
			
		||||
  - still under active development.
 | 
			
		||||
 .
 | 
			
		||||
 ngIRCd is compatible to the "original" ircd 2.10.3p3, so you can run
 | 
			
		||||
 mixed networks.
 | 
			
		||||
 | 
			
		||||
Package: ngircd-full
 | 
			
		||||
Architecture: any
 | 
			
		||||
Depends: ${shlibs:Depends}, ${misc:Depends}
 | 
			
		||||
Provides: ircd
 | 
			
		||||
Conflicts: ngircd, ngircd-dbg
 | 
			
		||||
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
 | 
			
		||||
 IRCd like many others.
 | 
			
		||||
Description: lightweight Internet Relay Chat server
 | 
			
		||||
 This package provides ngIRCd, a portable and lightweight Internet Relay
 | 
			
		||||
 Chat server for small or private networks, developed under the GNU
 | 
			
		||||
 General Public License (GPL). It is simple to configure, can cope with
 | 
			
		||||
 dynamic IP addresses, and supports IPv6 as well as SSL. It is written
 | 
			
		||||
 from scratch and not based on the original IRCd.
 | 
			
		||||
 .
 | 
			
		||||
 In addition to the features of the "standard package", this package
 | 
			
		||||
 includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
 | 
			
		||||
 SSL encrypted client and server links.
 | 
			
		||||
 .
 | 
			
		||||
 Advantages of ngIRCd:
 | 
			
		||||
  - no problems with servers using changing/non-static IP addresses.
 | 
			
		||||
  - small and lean configuration file.
 | 
			
		||||
  - free, modern and open source C code.
 | 
			
		||||
  - still under active development.
 | 
			
		||||
 .
 | 
			
		||||
 ngIRCd is compatible to the "original" ircd 2.10.3p3, so you can run
 | 
			
		||||
 mixed networks.
 | 
			
		||||
 | 
			
		||||
Package: ngircd-full-dbg
 | 
			
		||||
Architecture: any
 | 
			
		||||
Depends: ${shlibs:Depends}, ${misc:Depends}
 | 
			
		||||
Provides: ircd
 | 
			
		||||
Conflicts: ngircd, ngircd-full
 | 
			
		||||
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
 | 
			
		||||
 IRCd like many others.
 | 
			
		||||
Description: lightweight Internet Relay Chat server
 | 
			
		||||
 This package provides ngIRCd, a portable and lightweight Internet Relay
 | 
			
		||||
 Chat server for small or private networks, developed under the GNU
 | 
			
		||||
 General Public License (GPL). It is simple to configure, can cope with
 | 
			
		||||
 dynamic IP addresses, and supports IPv6 as well as SSL. It is written
 | 
			
		||||
 from scratch and not based on the original IRCd.
 | 
			
		||||
 .
 | 
			
		||||
 In addition to the features of the "standard package", this package
 | 
			
		||||
 includes support for TCP wrappers, IDENT requests, the IPv6 protocol and
 | 
			
		||||
@@ -67,12 +63,3 @@ Description: A lightweight daemon for the Internet Relay Chat (IRC)
 | 
			
		||||
 .
 | 
			
		||||
 And in addition to the "full" variant, the binaries contained in this
 | 
			
		||||
 package are build with debug code and contain debug symbols.
 | 
			
		||||
 .
 | 
			
		||||
 Advantages of ngIRCd:
 | 
			
		||||
  - no problems with servers using changing/non-static IP addresses.
 | 
			
		||||
  - small and lean configuration file.
 | 
			
		||||
  - free, modern and open source C code.
 | 
			
		||||
  - still under active development.
 | 
			
		||||
 .
 | 
			
		||||
 ngIRCd is compatible to the "original" ircd 2.10.3p3, so you can run
 | 
			
		||||
 mixed networks.
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
#!/usr/bin/make -f
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001-2009 Alexander Barton <alex@barton.de>
 | 
			
		||||
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 | 
			
		||||
#
 | 
			
		||||
# This program is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -53,7 +53,8 @@ configure-ngircd-full: configure
 | 
			
		||||
	  --sysconfdir=/etc/ngircd \
 | 
			
		||||
	  --mandir=\$${prefix}/share/man \
 | 
			
		||||
	  --with-syslog --with-zlib \
 | 
			
		||||
	  --with-gnutls --with-ident --with-tcp-wrappers --with-pam \
 | 
			
		||||
	  --with-gnutls --with-iconv --with-ident --with-tcp-wrappers \
 | 
			
		||||
	  --with-pam \
 | 
			
		||||
	  --enable-ipv6
 | 
			
		||||
 | 
			
		||||
configure-ngircd-full-dbg: configure
 | 
			
		||||
@@ -66,7 +67,8 @@ configure-ngircd-full-dbg: configure
 | 
			
		||||
	  --mandir=\$${prefix}/share/man \
 | 
			
		||||
	  --enable-debug --enable-sniffer \
 | 
			
		||||
	  --with-syslog --with-zlib \
 | 
			
		||||
	  --with-gnutls --with-ident --with-tcp-wrappers --with-pam \
 | 
			
		||||
	  --with-gnutls --with-iconv --with-ident --with-tcp-wrappers \
 | 
			
		||||
	  --with-pam \
 | 
			
		||||
	  --enable-ipv6
 | 
			
		||||
 | 
			
		||||
build:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2010 Alexander Barton (alex@barton.de).
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -11,7 +11,8 @@
 | 
			
		||||
 * Static configuration file for Mac OS X Xcode project
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define PACKAGE_NAME "ngircd"
 | 
			
		||||
#define PACKAGE_NAME "ngIRCd"
 | 
			
		||||
#define PACKAGE "ngircd"
 | 
			
		||||
#ifndef VERSION
 | 
			
		||||
#define VERSION "??("__DATE__")"
 | 
			
		||||
#endif
 | 
			
		||||
@@ -51,6 +52,9 @@
 | 
			
		||||
/* Define if PAM should be used */
 | 
			
		||||
#define PAM 1
 | 
			
		||||
 | 
			
		||||
/* Define if libiconv can be used, e.g. for CHARCONV */
 | 
			
		||||
#define ICONV 1
 | 
			
		||||
 | 
			
		||||
/* -- Supported features -- */
 | 
			
		||||
 | 
			
		||||
/* Define if SSP C support is enabled. */
 | 
			
		||||
@@ -74,6 +78,10 @@
 | 
			
		||||
/* Define to 1 if you have the <netinet/ip.h> header file. */
 | 
			
		||||
#define HAVE_NETINET_IP_H 1
 | 
			
		||||
 | 
			
		||||
/* Define to 1 if you have the `gai_strerror' function. */
 | 
			
		||||
#define HAVE_GAI_STRERROR 1
 | 
			
		||||
/* Define to 1 if you have the `iconv_open' function. */
 | 
			
		||||
#define HAVE_ICONV_OPEN 1
 | 
			
		||||
/* Define to 1 if you have the `kqueue' function. */
 | 
			
		||||
#define HAVE_KQUEUE 1
 | 
			
		||||
/* Define to 1 if you have the `inet_ntoa' function. */
 | 
			
		||||
@@ -96,6 +104,8 @@
 | 
			
		||||
#define HAVE_GETNAMEINFO 1
 | 
			
		||||
/* Define to 1 if you have the `sigaction' function. */
 | 
			
		||||
#define HAVE_SIGACTION 1
 | 
			
		||||
/* Define to 1 if you have the `setsid' function. */
 | 
			
		||||
#define HAVE_SETSID 1
 | 
			
		||||
 | 
			
		||||
/* Define if socklen_t exists */
 | 
			
		||||
#define HAVE_socklen_t 1
 | 
			
		||||
@@ -103,10 +113,15 @@
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
/* Define to 1 if you have the `pam_authenticate' function. */
 | 
			
		||||
#define HAVE_PAM_AUTHENTICATE 1
 | 
			
		||||
#if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1060)
 | 
			
		||||
/* Define to 1 if you have the <pam/pam_appl.h> header file. */
 | 
			
		||||
#define HAVE_PAM_PAM_APPL_H 1
 | 
			
		||||
/* Mac OS X <10.6 doesn't have pam_fail_delay() */
 | 
			
		||||
#define NO_PAM_FAIL_DELAY 1
 | 
			
		||||
#else
 | 
			
		||||
/* Define to 1 if you have the <security/pam_appl.h> header file. */
 | 
			
		||||
#define HAVE_SECURITY_PAM_APPL_H 1
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -156,7 +156,7 @@ Each version is given a distinguishing version number.  If the Program specifies
 | 
			
		||||
{\colortbl;\red255\green255\blue255;}
 | 
			
		||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
 | 
			
		||||
 | 
			
		||||
\f0\fs26 \cf0 Please not:\
 | 
			
		||||
\f0\fs26 \cf0 Please note:\
 | 
			
		||||
\
 | 
			
		||||
\pard\tx260\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\li260\fi-260\ql\qnatural\pardirnatural
 | 
			
		||||
\cf0 \'95	You 
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								contrib/MacOSX/ngIRCd.xcodeproj/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								contrib/MacOSX/ngIRCd.xcodeproj/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +1,4 @@
 | 
			
		||||
project.xcworkspace
 | 
			
		||||
xcuserdata
 | 
			
		||||
*.mode1v3
 | 
			
		||||
*.pbxuser
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
	archiveVersion = 1;
 | 
			
		||||
	classes = {
 | 
			
		||||
	};
 | 
			
		||||
	objectVersion = 44;
 | 
			
		||||
	objectVersion = 46;
 | 
			
		||||
	objects = {
 | 
			
		||||
 | 
			
		||||
/* Begin PBXBuildFile section */
 | 
			
		||||
@@ -36,10 +36,18 @@
 | 
			
		||||
		FA322DBE0CEF7766001761B3 /* tool.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D330CEF74B1001761B3 /* tool.c */; };
 | 
			
		||||
		FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA322DC00CEF77CB001761B3 /* libz.dylib */; };
 | 
			
		||||
		FA407F2E0DB159F400271AF1 /* ng_ipaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */; };
 | 
			
		||||
		FA4F165A164836B100DBD011 /* irc-metadata.c in Sources */ = {isa = PBXBuildFile; fileRef = FA4F1659164836B100DBD011 /* irc-metadata.c */; };
 | 
			
		||||
		FA6BBC631605F0AC0004247A /* conn-encoding.c in Sources */ = {isa = PBXBuildFile; fileRef = FA6BBC5F1605F0AB0004247A /* conn-encoding.c */; };
 | 
			
		||||
		FA6BBC641605F0AC0004247A /* irc-encoding.c in Sources */ = {isa = PBXBuildFile; fileRef = FA6BBC611605F0AC0004247A /* irc-encoding.c */; };
 | 
			
		||||
		FA6BBC661605F6D60004247A /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA6BBC651605F6D60004247A /* libiconv.dylib */; };
 | 
			
		||||
		FA85178C0FA061EC006A1F5A /* op.c in Sources */ = {isa = PBXBuildFile; fileRef = FA85178B0FA061EC006A1F5A /* op.c */; };
 | 
			
		||||
		FA99428C10E82A27007F27ED /* proc.c in Sources */ = {isa = PBXBuildFile; fileRef = FA99428B10E82A27007F27ED /* proc.c */; };
 | 
			
		||||
		FAA3D27B0F139CDC00B2447E /* conn-ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA3D2790F139CDC00B2447E /* conn-ssl.c */; };
 | 
			
		||||
		FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */ = {isa = PBXBuildFile; fileRef = FAA97C55124A271400D5BBA9 /* sighandlers.c */; };
 | 
			
		||||
		FAACD5F514A6099C006ED74F /* class.c in Sources */ = {isa = PBXBuildFile; fileRef = FAACD5F314A6099C006ED74F /* class.c */; };
 | 
			
		||||
		FAD5853215271AAB00328741 /* client-cap.c in Sources */ = {isa = PBXBuildFile; fileRef = FAD5853015271AAB00328741 /* client-cap.c */; };
 | 
			
		||||
		FAD5853515271AB800328741 /* irc-cap.c in Sources */ = {isa = PBXBuildFile; fileRef = FAD5853315271AB800328741 /* irc-cap.c */; };
 | 
			
		||||
		FAD5853815272C2600328741 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = FAD5853615272C2500328741 /* login.c */; };
 | 
			
		||||
		FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */ = {isa = PBXBuildFile; fileRef = FAE5CC2D0CF2308A007D69B6 /* numeric.c */; };
 | 
			
		||||
/* End PBXBuildFile section */
 | 
			
		||||
 | 
			
		||||
@@ -170,7 +178,6 @@
 | 
			
		||||
		FA322D8E0CEF7523001761B3 /* ngIRCd.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = ngIRCd.xcodeproj; sourceTree = "<group>"; };
 | 
			
		||||
		FA322D910CEF7523001761B3 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
 | 
			
		||||
		FA322D920CEF7523001761B3 /* ngindent */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngindent; sourceTree = "<group>"; };
 | 
			
		||||
		FA322D930CEF7523001761B3 /* ngircd.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = ngircd.sh; sourceTree = "<group>"; };
 | 
			
		||||
		FA322D940CEF7523001761B3 /* ngircd.spec */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = ngircd.spec; sourceTree = "<group>"; };
 | 
			
		||||
		FA322D950CEF7523001761B3 /* README */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
 | 
			
		||||
		FA322D960CEF7523001761B3 /* systrace.policy */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = systrace.policy; sourceTree = "<group>"; };
 | 
			
		||||
@@ -196,6 +203,17 @@
 | 
			
		||||
		FA407F2C0DB159F400271AF1 /* ng_ipaddr.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; name = ng_ipaddr.c; path = ipaddr/ng_ipaddr.c; sourceTree = "<group>"; };
 | 
			
		||||
		FA407F2D0DB159F400271AF1 /* ng_ipaddr.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; name = ng_ipaddr.h; path = ipaddr/ng_ipaddr.h; sourceTree = "<group>"; };
 | 
			
		||||
		FA407F380DB15AC700271AF1 /* GIT.txt */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text; path = GIT.txt; sourceTree = "<group>"; };
 | 
			
		||||
		FA4B08E513E7F8FB00765BA3 /* ngircd-bsd.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "ngircd-bsd.sh"; sourceTree = "<group>"; };
 | 
			
		||||
		FA4B08E613E7F91700765BA3 /* ngIRCd-Logo.gif */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = "ngIRCd-Logo.gif"; sourceTree = "<group>"; };
 | 
			
		||||
		FA4B08E713E7F91700765BA3 /* ngircd-redhat.init */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "ngircd-redhat.init"; sourceTree = "<group>"; };
 | 
			
		||||
		FA4B08E813E7F91C00765BA3 /* platformtest.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = platformtest.sh; sourceTree = "<group>"; };
 | 
			
		||||
		FA4F1659164836B100DBD011 /* irc-metadata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "irc-metadata.c"; sourceTree = "<group>"; };
 | 
			
		||||
		FA4F165C164836BF00DBD011 /* irc-metadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "irc-metadata.h"; sourceTree = "<group>"; };
 | 
			
		||||
		FA6BBC5F1605F0AB0004247A /* conn-encoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "conn-encoding.c"; sourceTree = "<group>"; };
 | 
			
		||||
		FA6BBC601605F0AC0004247A /* conn-encoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "conn-encoding.h"; sourceTree = "<group>"; };
 | 
			
		||||
		FA6BBC611605F0AC0004247A /* irc-encoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "irc-encoding.c"; sourceTree = "<group>"; };
 | 
			
		||||
		FA6BBC621605F0AC0004247A /* irc-encoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "irc-encoding.h"; sourceTree = "<group>"; };
 | 
			
		||||
		FA6BBC651605F6D60004247A /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = ../../../../../../../usr/lib/libiconv.dylib; sourceTree = "<group>"; };
 | 
			
		||||
		FA77849A133FB9FF00740057 /* sample-ngircd.conf.tmpl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "sample-ngircd.conf.tmpl"; sourceTree = "<group>"; };
 | 
			
		||||
		FA85178A0FA061EC006A1F5A /* op.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = op.h; sourceTree = "<group>"; };
 | 
			
		||||
		FA85178B0FA061EC006A1F5A /* op.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = op.c; sourceTree = "<group>"; };
 | 
			
		||||
@@ -225,6 +243,21 @@
 | 
			
		||||
		FAA3D28B0F139D2E00B2447E /* preinstall.sh */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = text.script.sh; path = preinstall.sh; sourceTree = "<group>"; };
 | 
			
		||||
		FAA97C55124A271400D5BBA9 /* sighandlers.c */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.c; path = sighandlers.c; sourceTree = "<group>"; };
 | 
			
		||||
		FAA97C56124A271400D5BBA9 /* sighandlers.h */ = {isa = PBXFileReference; fileEncoding = 5; lastKnownFileType = sourcecode.c.h; path = sighandlers.h; sourceTree = "<group>"; };
 | 
			
		||||
		FAACD5F314A6099C006ED74F /* class.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = class.c; sourceTree = "<group>"; };
 | 
			
		||||
		FAACD5F414A6099C006ED74F /* class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = class.h; sourceTree = "<group>"; };
 | 
			
		||||
		FAD5852F15271A7800328741 /* Capabilities.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Capabilities.txt; sourceTree = "<group>"; };
 | 
			
		||||
		FAD5853015271AAB00328741 /* client-cap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "client-cap.c"; sourceTree = "<group>"; };
 | 
			
		||||
		FAD5853115271AAB00328741 /* client-cap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "client-cap.h"; sourceTree = "<group>"; };
 | 
			
		||||
		FAD5853315271AB800328741 /* irc-cap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "irc-cap.c"; sourceTree = "<group>"; };
 | 
			
		||||
		FAD5853415271AB800328741 /* irc-cap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "irc-cap.h"; sourceTree = "<group>"; };
 | 
			
		||||
		FAD5853615272C2500328741 /* login.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = login.c; sourceTree = "<group>"; };
 | 
			
		||||
		FAD5853715272C2500328741 /* login.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = login.h; sourceTree = "<group>"; };
 | 
			
		||||
		FAE22BD215270EA300F1A5AB /* Bopm.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Bopm.txt; sourceTree = "<group>"; };
 | 
			
		||||
		FAE22BD415270EA300F1A5AB /* Contributing.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Contributing.txt; sourceTree = "<group>"; };
 | 
			
		||||
		FAE22BD515270EB500F1A5AB /* HowToRelease.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = HowToRelease.txt; sourceTree = "<group>"; };
 | 
			
		||||
		FAE22BD615270EB500F1A5AB /* Modes.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Modes.txt; sourceTree = "<group>"; };
 | 
			
		||||
		FAE22BD715270EB500F1A5AB /* PAM.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = PAM.txt; sourceTree = "<group>"; };
 | 
			
		||||
		FAE22BD815270EC400F1A5AB /* README-Interix.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "README-Interix.txt"; sourceTree = "<group>"; };
 | 
			
		||||
		FAE5CC2C0CF2308A007D69B6 /* numeric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = numeric.h; sourceTree = "<group>"; };
 | 
			
		||||
		FAE5CC2D0CF2308A007D69B6 /* numeric.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = numeric.c; sourceTree = "<group>"; };
 | 
			
		||||
/* End PBXFileReference section */
 | 
			
		||||
@@ -236,6 +269,7 @@
 | 
			
		||||
			files = (
 | 
			
		||||
				FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */,
 | 
			
		||||
				FA2D567B11EA1AB300D37A35 /* libpam.dylib in Frameworks */,
 | 
			
		||||
				FA6BBC661605F6D60004247A /* libiconv.dylib in Frameworks */,
 | 
			
		||||
			);
 | 
			
		||||
			runOnlyForDeploymentPostprocessing = 0;
 | 
			
		||||
		};
 | 
			
		||||
@@ -261,8 +295,9 @@
 | 
			
		||||
				FA322D600CEF750F001761B3 /* configure.in */,
 | 
			
		||||
				FA322D630CEF750F001761B3 /* Makefile.am */,
 | 
			
		||||
				1AB674ADFE9D54B511CA2CBB /* Products */,
 | 
			
		||||
				FA322DC00CEF77CB001761B3 /* libz.dylib */,
 | 
			
		||||
				FA6BBC651605F6D60004247A /* libiconv.dylib */,
 | 
			
		||||
				FA2D567A11EA1AB300D37A35 /* libpam.dylib */,
 | 
			
		||||
				FA322DC00CEF77CB001761B3 /* libz.dylib */,
 | 
			
		||||
			);
 | 
			
		||||
			name = ngIRCd;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
@@ -292,34 +327,49 @@
 | 
			
		||||
		FA322CD70CEF74B1001761B3 /* ngircd */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				FAA3D2780F139CDC00B2447E /* conf-ssl.h */,
 | 
			
		||||
				FAA3D2790F139CDC00B2447E /* conn-ssl.c */,
 | 
			
		||||
				FAA3D27A0F139CDC00B2447E /* conn-ssl.h */,
 | 
			
		||||
				FA322D020CEF74B1001761B3 /* Makefile.am */,
 | 
			
		||||
				FA322CD90CEF74B1001761B3 /* array.c */,
 | 
			
		||||
				FA322CDA0CEF74B1001761B3 /* array.h */,
 | 
			
		||||
				FA322CDB0CEF74B1001761B3 /* channel.c */,
 | 
			
		||||
				FA322CDC0CEF74B1001761B3 /* channel.h */,
 | 
			
		||||
				FAACD5F314A6099C006ED74F /* class.c */,
 | 
			
		||||
				FAACD5F414A6099C006ED74F /* class.h */,
 | 
			
		||||
				FA322CDD0CEF74B1001761B3 /* client.c */,
 | 
			
		||||
				FA322CDE0CEF74B1001761B3 /* client.h */,
 | 
			
		||||
				FAD5853015271AAB00328741 /* client-cap.c */,
 | 
			
		||||
				FAD5853115271AAB00328741 /* client-cap.h */,
 | 
			
		||||
				FA322CDF0CEF74B1001761B3 /* conf.c */,
 | 
			
		||||
				FA322CE00CEF74B1001761B3 /* conf.h */,
 | 
			
		||||
				FAA3D2780F139CDC00B2447E /* conf-ssl.h */,
 | 
			
		||||
				FA322CE50CEF74B1001761B3 /* conn.c */,
 | 
			
		||||
				FA322CE60CEF74B1001761B3 /* conn.h */,
 | 
			
		||||
				FA6BBC5F1605F0AB0004247A /* conn-encoding.c */,
 | 
			
		||||
				FA6BBC601605F0AC0004247A /* conn-encoding.h */,
 | 
			
		||||
				FA322CE10CEF74B1001761B3 /* conn-func.c */,
 | 
			
		||||
				FA322CE20CEF74B1001761B3 /* conn-func.h */,
 | 
			
		||||
				FA322CE30CEF74B1001761B3 /* conn-zip.c */,
 | 
			
		||||
				FA322CE40CEF74B1001761B3 /* conn-zip.h */,
 | 
			
		||||
				FA322CE50CEF74B1001761B3 /* conn.c */,
 | 
			
		||||
				FA322CE60CEF74B1001761B3 /* conn.h */,
 | 
			
		||||
				FAA3D2790F139CDC00B2447E /* conn-ssl.c */,
 | 
			
		||||
				FAA3D27A0F139CDC00B2447E /* conn-ssl.h */,
 | 
			
		||||
				FA322CE70CEF74B1001761B3 /* defines.h */,
 | 
			
		||||
				FA322CE80CEF74B1001761B3 /* hash.c */,
 | 
			
		||||
				FA322CE90CEF74B1001761B3 /* hash.h */,
 | 
			
		||||
				FA322CEA0CEF74B1001761B3 /* io.c */,
 | 
			
		||||
				FA322CEB0CEF74B1001761B3 /* io.h */,
 | 
			
		||||
				FA322CFC0CEF74B1001761B3 /* irc.c */,
 | 
			
		||||
				FA322CFD0CEF74B1001761B3 /* irc.h */,
 | 
			
		||||
				FAD5853315271AB800328741 /* irc-cap.c */,
 | 
			
		||||
				FAD5853415271AB800328741 /* irc-cap.h */,
 | 
			
		||||
				FA322CEC0CEF74B1001761B3 /* irc-channel.c */,
 | 
			
		||||
				FA322CED0CEF74B1001761B3 /* irc-channel.h */,
 | 
			
		||||
				FA6BBC611605F0AC0004247A /* irc-encoding.c */,
 | 
			
		||||
				FA6BBC621605F0AC0004247A /* irc-encoding.h */,
 | 
			
		||||
				FA322CEE0CEF74B1001761B3 /* irc-info.c */,
 | 
			
		||||
				FA322CEF0CEF74B1001761B3 /* irc-info.h */,
 | 
			
		||||
				FA322CF00CEF74B1001761B3 /* irc-login.c */,
 | 
			
		||||
				FA322CF10CEF74B1001761B3 /* irc-login.h */,
 | 
			
		||||
				FA4F1659164836B100DBD011 /* irc-metadata.c */,
 | 
			
		||||
				FA4F165C164836BF00DBD011 /* irc-metadata.h */,
 | 
			
		||||
				FA322CF20CEF74B1001761B3 /* irc-mode.c */,
 | 
			
		||||
				FA322CF30CEF74B1001761B3 /* irc-mode.h */,
 | 
			
		||||
				FA322CF40CEF74B1001761B3 /* irc-op.c */,
 | 
			
		||||
@@ -330,13 +380,12 @@
 | 
			
		||||
				FA322CF90CEF74B1001761B3 /* irc-server.h */,
 | 
			
		||||
				FA322CFA0CEF74B1001761B3 /* irc-write.c */,
 | 
			
		||||
				FA322CFB0CEF74B1001761B3 /* irc-write.h */,
 | 
			
		||||
				FA322CFC0CEF74B1001761B3 /* irc.c */,
 | 
			
		||||
				FA322CFD0CEF74B1001761B3 /* irc.h */,
 | 
			
		||||
				FA322CFE0CEF74B1001761B3 /* lists.c */,
 | 
			
		||||
				FA322CFF0CEF74B1001761B3 /* lists.h */,
 | 
			
		||||
				FA322D000CEF74B1001761B3 /* log.c */,
 | 
			
		||||
				FA322D010CEF74B1001761B3 /* log.h */,
 | 
			
		||||
				FA322D020CEF74B1001761B3 /* Makefile.am */,
 | 
			
		||||
				FAD5853615272C2500328741 /* login.c */,
 | 
			
		||||
				FAD5853715272C2500328741 /* login.h */,
 | 
			
		||||
				FA322D030CEF74B1001761B3 /* match.c */,
 | 
			
		||||
				FA322D040CEF74B1001761B3 /* match.h */,
 | 
			
		||||
				FA322D050CEF74B1001761B3 /* messages.h */,
 | 
			
		||||
@@ -346,6 +395,8 @@
 | 
			
		||||
				FAE5CC2C0CF2308A007D69B6 /* numeric.h */,
 | 
			
		||||
				FA85178B0FA061EC006A1F5A /* op.c */,
 | 
			
		||||
				FA85178A0FA061EC006A1F5A /* op.h */,
 | 
			
		||||
				FA2D564911EA158B00D37A35 /* pam.c */,
 | 
			
		||||
				FA2D564811EA158B00D37A35 /* pam.h */,
 | 
			
		||||
				FA322D080CEF74B1001761B3 /* parse.c */,
 | 
			
		||||
				FA322D090CEF74B1001761B3 /* parse.h */,
 | 
			
		||||
				FA99428B10E82A27007F27ED /* proc.c */,
 | 
			
		||||
@@ -354,8 +405,6 @@
 | 
			
		||||
				FA322D0D0CEF74B1001761B3 /* resolve.h */,
 | 
			
		||||
				FAA97C55124A271400D5BBA9 /* sighandlers.c */,
 | 
			
		||||
				FAA97C56124A271400D5BBA9 /* sighandlers.h */,
 | 
			
		||||
				FA2D564811EA158B00D37A35 /* pam.h */,
 | 
			
		||||
				FA2D564911EA158B00D37A35 /* pam.c */,
 | 
			
		||||
			);
 | 
			
		||||
			path = ngircd;
 | 
			
		||||
			sourceTree = "<group>";
 | 
			
		||||
@@ -432,8 +481,11 @@
 | 
			
		||||
				FA322D730CEF7523001761B3 /* MacOSX */,
 | 
			
		||||
				FA322D910CEF7523001761B3 /* Makefile.am */,
 | 
			
		||||
				FA322D920CEF7523001761B3 /* ngindent */,
 | 
			
		||||
				FA322D930CEF7523001761B3 /* ngircd.sh */,
 | 
			
		||||
				FA4B08E513E7F8FB00765BA3 /* ngircd-bsd.sh */,
 | 
			
		||||
				FA4B08E613E7F91700765BA3 /* ngIRCd-Logo.gif */,
 | 
			
		||||
				FA4B08E713E7F91700765BA3 /* ngircd-redhat.init */,
 | 
			
		||||
				FA322D940CEF7523001761B3 /* ngircd.spec */,
 | 
			
		||||
				FA4B08E813E7F91C00765BA3 /* platformtest.sh */,
 | 
			
		||||
				FA322D950CEF7523001761B3 /* README */,
 | 
			
		||||
				FA322D960CEF7523001761B3 /* systrace.policy */,
 | 
			
		||||
			);
 | 
			
		||||
@@ -552,18 +604,25 @@
 | 
			
		||||
		FA322D970CEF752C001761B3 /* doc */ = {
 | 
			
		||||
			isa = PBXGroup;
 | 
			
		||||
			children = (
 | 
			
		||||
				FAA3D2800F139D1500B2447E /* Services.txt */,
 | 
			
		||||
				FA407F380DB15AC700271AF1 /* GIT.txt */,
 | 
			
		||||
				FA322D9A0CEF752C001761B3 /* FAQ.txt */,
 | 
			
		||||
				FA322D9B0CEF752C001761B3 /* Makefile.am */,
 | 
			
		||||
				FAE22BD215270EA300F1A5AB /* Bopm.txt */,
 | 
			
		||||
				FAD5852F15271A7800328741 /* Capabilities.txt */,
 | 
			
		||||
				FAE22BD415270EA300F1A5AB /* Contributing.txt */,
 | 
			
		||||
				FA322D9A0CEF752C001761B3 /* FAQ.txt */,
 | 
			
		||||
				FA407F380DB15AC700271AF1 /* GIT.txt */,
 | 
			
		||||
				FAE22BD515270EB500F1A5AB /* HowToRelease.txt */,
 | 
			
		||||
				FAE22BD615270EB500F1A5AB /* Modes.txt */,
 | 
			
		||||
				FAE22BD715270EB500F1A5AB /* PAM.txt */,
 | 
			
		||||
				FA322D9C0CEF752C001761B3 /* Platforms.txt */,
 | 
			
		||||
				FA322D9D0CEF752C001761B3 /* Protocol.txt */,
 | 
			
		||||
				FA322D9E0CEF752C001761B3 /* README-AUX.txt */,
 | 
			
		||||
				FA322D9F0CEF752C001761B3 /* README-BeOS.txt */,
 | 
			
		||||
				FAE22BD815270EC400F1A5AB /* README-Interix.txt */,
 | 
			
		||||
				FA322DA00CEF752C001761B3 /* RFC.txt */,
 | 
			
		||||
				FAA3D2800F139D1500B2447E /* Services.txt */,
 | 
			
		||||
				FA322DA90CEF752C001761B3 /* SSL.txt */,
 | 
			
		||||
				FA77849A133FB9FF00740057 /* sample-ngircd.conf.tmpl */,
 | 
			
		||||
				FA322DA20CEF752C001761B3 /* src */,
 | 
			
		||||
				FA322DA90CEF752C001761B3 /* SSL.txt */,
 | 
			
		||||
			);
 | 
			
		||||
			name = doc;
 | 
			
		||||
			path = ../../doc;
 | 
			
		||||
@@ -641,8 +700,11 @@
 | 
			
		||||
/* Begin PBXProject section */
 | 
			
		||||
		08FB7793FE84155DC02AAC07 /* Project object */ = {
 | 
			
		||||
			isa = PBXProject;
 | 
			
		||||
			attributes = {
 | 
			
		||||
				LastUpgradeCheck = 0430;
 | 
			
		||||
			};
 | 
			
		||||
			buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "ngIRCd" */;
 | 
			
		||||
			compatibilityVersion = "Xcode 3.0";
 | 
			
		||||
			compatibilityVersion = "Xcode 3.2";
 | 
			
		||||
			developmentRegion = English;
 | 
			
		||||
			hasScannedForEncodings = 1;
 | 
			
		||||
			knownRegions = (
 | 
			
		||||
@@ -703,6 +765,13 @@
 | 
			
		||||
				FA99428C10E82A27007F27ED /* proc.c in Sources */,
 | 
			
		||||
				FA2D564A11EA158B00D37A35 /* pam.c in Sources */,
 | 
			
		||||
				FAA97C57124A271400D5BBA9 /* sighandlers.c in Sources */,
 | 
			
		||||
				FAACD5F514A6099C006ED74F /* class.c in Sources */,
 | 
			
		||||
				FAD5853215271AAB00328741 /* client-cap.c in Sources */,
 | 
			
		||||
				FAD5853515271AB800328741 /* irc-cap.c in Sources */,
 | 
			
		||||
				FAD5853815272C2600328741 /* login.c in Sources */,
 | 
			
		||||
				FA6BBC631605F0AC0004247A /* conn-encoding.c in Sources */,
 | 
			
		||||
				FA6BBC641605F0AC0004247A /* irc-encoding.c in Sources */,
 | 
			
		||||
				FA4F165A164836B100DBD011 /* irc-metadata.c in Sources */,
 | 
			
		||||
			);
 | 
			
		||||
			runOnlyForDeploymentPostprocessing = 0;
 | 
			
		||||
		};
 | 
			
		||||
@@ -713,6 +782,7 @@
 | 
			
		||||
			isa = XCBuildConfiguration;
 | 
			
		||||
			buildSettings = {
 | 
			
		||||
				GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
 | 
			
		||||
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 | 
			
		||||
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 | 
			
		||||
				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
 | 
			
		||||
				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 | 
			
		||||
@@ -731,20 +801,20 @@
 | 
			
		||||
				GCC_WARN_UNUSED_PARAMETER = YES;
 | 
			
		||||
				GCC_WARN_UNUSED_VALUE = YES;
 | 
			
		||||
				INSTALL_PATH = /usr/local/bin;
 | 
			
		||||
				PRODUCT_NAME = ngIRCd;
 | 
			
		||||
				PRODUCT_NAME = ngircd;
 | 
			
		||||
			};
 | 
			
		||||
			name = Default;
 | 
			
		||||
		};
 | 
			
		||||
		1DEB928B08733DD80010E9CD /* Default */ = {
 | 
			
		||||
			isa = XCBuildConfiguration;
 | 
			
		||||
			buildSettings = {
 | 
			
		||||
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1)";
 | 
			
		||||
				ARCHS_STANDARD_32_64_BIT_PRE_XCODE_3_1 = "x86_64 i386 ppc";
 | 
			
		||||
				GCC_VERSION = 4.0;
 | 
			
		||||
				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
 | 
			
		||||
				CODE_SIGN_IDENTITY = "";
 | 
			
		||||
				GCC_VERSION = "";
 | 
			
		||||
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 | 
			
		||||
				GCC_WARN_UNUSED_VARIABLE = YES;
 | 
			
		||||
				PREBINDING = NO;
 | 
			
		||||
				SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk";
 | 
			
		||||
				MACOSX_DEPLOYMENT_TARGET = 10.6;
 | 
			
		||||
				SDKROOT = "";
 | 
			
		||||
			};
 | 
			
		||||
			name = Default;
 | 
			
		||||
		};
 | 
			
		||||
@@ -754,11 +824,11 @@
 | 
			
		||||
				ARCHS = "$(NATIVE_ARCH_ACTUAL)";
 | 
			
		||||
				GCC_DEBUGGING_SYMBOLS = full;
 | 
			
		||||
				GCC_OPTIMIZATION_LEVEL = 0;
 | 
			
		||||
				GCC_VERSION = 4.0;
 | 
			
		||||
				GCC_VERSION = "";
 | 
			
		||||
				GCC_WARN_ABOUT_RETURN_TYPE = YES;
 | 
			
		||||
				GCC_WARN_UNUSED_VARIABLE = YES;
 | 
			
		||||
				MACOSX_DEPLOYMENT_TARGET = 10.6;
 | 
			
		||||
				ONLY_ACTIVE_ARCH = YES;
 | 
			
		||||
				PREBINDING = NO;
 | 
			
		||||
				SDKROOT = "";
 | 
			
		||||
			};
 | 
			
		||||
			name = Debug;
 | 
			
		||||
@@ -767,6 +837,7 @@
 | 
			
		||||
			isa = XCBuildConfiguration;
 | 
			
		||||
			buildSettings = {
 | 
			
		||||
				GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
 | 
			
		||||
				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
 | 
			
		||||
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
 | 
			
		||||
				GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
 | 
			
		||||
				GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
 | 
			
		||||
@@ -785,7 +856,7 @@
 | 
			
		||||
				GCC_WARN_UNUSED_PARAMETER = YES;
 | 
			
		||||
				GCC_WARN_UNUSED_VALUE = YES;
 | 
			
		||||
				INSTALL_PATH = /usr/local/bin;
 | 
			
		||||
				PRODUCT_NAME = ngIRCd;
 | 
			
		||||
				PRODUCT_NAME = ngircd;
 | 
			
		||||
			};
 | 
			
		||||
			name = Debug;
 | 
			
		||||
		};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
 | 
			
		||||
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 | 
			
		||||
#
 | 
			
		||||
# This program is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -9,10 +9,17 @@
 | 
			
		||||
# Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
SUBDIRS = Anope Debian MacOSX
 | 
			
		||||
SUBDIRS = Debian MacOSX
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = README ngircd.spec systrace.policy ngindent ngircd-bsd.sh \
 | 
			
		||||
	ngIRCd-Logo.gif ngircd-redhat.init platformtest.sh
 | 
			
		||||
EXTRA_DIST = README \
 | 
			
		||||
	ngindent \
 | 
			
		||||
	ngircd-bsd.sh \
 | 
			
		||||
	ngIRCd-Logo.gif \
 | 
			
		||||
	ngircd-redhat.init \
 | 
			
		||||
	ngircd.service \
 | 
			
		||||
	ngircd.spec \
 | 
			
		||||
	platformtest.sh \
 | 
			
		||||
	systrace.policy
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in
 | 
			
		||||
 
 | 
			
		||||
@@ -9,9 +9,6 @@
 | 
			
		||||
                            -- Contributions --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Anope/
 | 
			
		||||
 - A preliminary patch that adds a ngIRCd protocol module to Anope 1.9.
 | 
			
		||||
 | 
			
		||||
Debian/
 | 
			
		||||
 - Various files for building Debian GNU/Linux packages (".deb's").
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ INDENTARGS="-kr -i8 -ts8 -l80 -c3 -cd41 -ss -ncs -psl"
 | 
			
		||||
 | 
			
		||||
# check if indent(1) is available
 | 
			
		||||
type indent >/dev/null 2>&1 && INDENT="indent"
 | 
			
		||||
type gindent >/dev/null 2>&1 && INDENT="gindent"
 | 
			
		||||
type gnuindent >/dev/null 2>&1 && INDENT="gnuindent"
 | 
			
		||||
 | 
			
		||||
if [ -z "$INDENT" ]; then
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								contrib/ngircd.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								contrib/ngircd.service
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Next Generation IRC Daemon
 | 
			
		||||
After=network.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
# don't daemonize to simplify stuff
 | 
			
		||||
ExecStart=/usr/sbin/ngircd -n
 | 
			
		||||
ExecReload=/bin/kill -HUP $MAINPID
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
%define name    ngircd
 | 
			
		||||
%define version 18
 | 
			
		||||
%define version 20~rc2
 | 
			
		||||
%define release 1
 | 
			
		||||
%define prefix  %{_prefix}
 | 
			
		||||
 | 
			
		||||
@@ -15,18 +15,19 @@ BuildRoot:    %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 | 
			
		||||
BuildRequires:  zlib-devel, openssl-devel
 | 
			
		||||
 | 
			
		||||
%description
 | 
			
		||||
ngIRCd is a free open source daemon for the Internet Relay Chat (IRC),
 | 
			
		||||
developed under the GNU General Public License (GPL). It's written from
 | 
			
		||||
scratch and is not based upon the original IRCd like many others.
 | 
			
		||||
This package provides ngIRCd, a portable and lightweight Internet Relay
 | 
			
		||||
Chat server for small or private networks, developed under the GNU
 | 
			
		||||
General Public License (GPL). It is simple to configure, can cope with
 | 
			
		||||
dynamic IP addresses, and supports IPv6 as well as SSL. It is written
 | 
			
		||||
from scratch and not based on the original IRCd.
 | 
			
		||||
 | 
			
		||||
Advantages:
 | 
			
		||||
 - no problems with servers using changing/non-static IP addresses.
 | 
			
		||||
 - small and lean configuration file.
 | 
			
		||||
 - free, modern and open source C code.
 | 
			
		||||
 - still under active development.
 | 
			
		||||
 | 
			
		||||
ngIRCd is compatible to the "original" ircd 2.10.3p3, so you can run
 | 
			
		||||
mixed networks.
 | 
			
		||||
 - well arranged (lean) configuration file
 | 
			
		||||
 - simple to build/install, configure and maintain
 | 
			
		||||
 - supports IPv6 and SSL
 | 
			
		||||
 - no problems with servers that have dynamic IP addresses
 | 
			
		||||
 - freely available, modern, portable and tidy C-source
 | 
			
		||||
 - ngIRCd is being actively developed since 11 years.
 | 
			
		||||
 | 
			
		||||
%prep
 | 
			
		||||
%setup -q
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
 | 
			
		||||
# Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors
 | 
			
		||||
#
 | 
			
		||||
# This program is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -21,13 +21,16 @@ PLATFORM=
 | 
			
		||||
COMPILER="unknown"
 | 
			
		||||
VERSION="unknown"
 | 
			
		||||
DATE=`date "+%y-%m-%d"`
 | 
			
		||||
 | 
			
		||||
CONFIGURE=
 | 
			
		||||
MAKE=
 | 
			
		||||
CHECK=
 | 
			
		||||
RUN=
 | 
			
		||||
COMMENT=
 | 
			
		||||
 | 
			
		||||
R_CONFIGURE=
 | 
			
		||||
R_MAKE=
 | 
			
		||||
R_CHECK=
 | 
			
		||||
R_RUN=
 | 
			
		||||
 | 
			
		||||
[ -n "$MAKE" ] || MAKE="make"
 | 
			
		||||
export MAKE CC
 | 
			
		||||
 | 
			
		||||
while [ $# -gt 0 ]; do
 | 
			
		||||
	case "$1" in
 | 
			
		||||
		"-v")
 | 
			
		||||
@@ -51,8 +54,8 @@ if [ $? -ne 0 ]; then
 | 
			
		||||
	cd ..
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
echo "$NAME: Checking for \"./autogen.sh\" script ..."
 | 
			
		||||
if [ -r ./autogen.sh ]; then
 | 
			
		||||
echo "$NAME: Checking for \"./configure\" script ..."
 | 
			
		||||
if [ ! -e ./configure ]; then
 | 
			
		||||
	echo "$NAME: Running \"./autogen.sh\" ..."
 | 
			
		||||
	[ -n "$VERBOSE" ] && ./autogen.sh || ./autogen.sh >/dev/null
 | 
			
		||||
fi
 | 
			
		||||
@@ -61,20 +64,20 @@ if [ -r ./configure ]; then
 | 
			
		||||
	echo "$NAME: Running \"./configure\" script ..."
 | 
			
		||||
	[ -n "$VERBOSE" ] && ./configure || ./configure >/dev/null
 | 
			
		||||
	if [ $? -eq 0 -a -r ./Makefile ]; then
 | 
			
		||||
		CONFIGURE=1
 | 
			
		||||
		echo "$NAME: Running \"make\" ..."
 | 
			
		||||
		[ -n "$VERBOSE" ] && make || make >/dev/null
 | 
			
		||||
		R_CONFIGURE=1
 | 
			
		||||
		echo "$NAME: Running \"$MAKE\" ..."
 | 
			
		||||
		[ -n "$VERBOSE" ] && "$MAKE" || "$MAKE" >/dev/null
 | 
			
		||||
		if [ $? -eq 0 -a -x src/ngircd/ngircd ]; then
 | 
			
		||||
			MAKE=1
 | 
			
		||||
			echo "$NAME: Running \"make check\" ..."
 | 
			
		||||
			[ -n "$VERBOSE" ] && make check || make check >/dev/null
 | 
			
		||||
			R_MAKE=1
 | 
			
		||||
			echo "$NAME: Running \"$MAKE check\" ..."
 | 
			
		||||
			[ -n "$VERBOSE" ] && "$MAKE" check || "$MAKE" check >/dev/null
 | 
			
		||||
			if [ $? -eq 0 ]; then
 | 
			
		||||
				CHECK=1
 | 
			
		||||
				RUN=$CHECK
 | 
			
		||||
				R_CHECK=1
 | 
			
		||||
				R_RUN=$R_CHECK
 | 
			
		||||
			else
 | 
			
		||||
				./src/ngircd/ngircd --help 2>/dev/null \
 | 
			
		||||
				 | grep "^ngircd" >/dev/null
 | 
			
		||||
				[ $? -eq 0 ] && RUN=1
 | 
			
		||||
				 | grep "^ngIRCd" >/dev/null
 | 
			
		||||
				[ $? -eq 0 ] && R_RUN=1
 | 
			
		||||
			fi
 | 
			
		||||
		fi
 | 
			
		||||
	fi
 | 
			
		||||
@@ -82,9 +85,9 @@ fi
 | 
			
		||||
 | 
			
		||||
# Get target platform information
 | 
			
		||||
if [ -r "src/config.h" ]; then
 | 
			
		||||
	CPU=`grep "TARGET_CPU" "src/config.h" | cut -d'"' -f2`
 | 
			
		||||
	OS=`grep "TARGET_OS" "src/config.h" | cut -d'"' -f2`
 | 
			
		||||
	VENDOR=`grep "TARGET_VENDOR" "src/config.h" | cut -d'"' -f2`
 | 
			
		||||
	CPU=`grep "HOST_CPU" "src/config.h" | cut -d'"' -f2`
 | 
			
		||||
	OS=`grep "HOST_OS" "src/config.h" | cut -d'"' -f2`
 | 
			
		||||
	VENDOR=`grep "HOST_VENDOR" "src/config.h" | cut -d'"' -f2`
 | 
			
		||||
	PLATFORM="$CPU/$VENDOR/$OS"
 | 
			
		||||
fi
 | 
			
		||||
if [ -z "$PLATFORM" ]; then
 | 
			
		||||
@@ -96,9 +99,14 @@ if [ -r "Makefile" ]; then
 | 
			
		||||
	CC=$(grep "^CC = " Makefile | cut -d' ' -f3)
 | 
			
		||||
	$CC --version 2>&1 | grep -i "GCC" >/dev/null
 | 
			
		||||
	if [ $? -eq 0 ]; then
 | 
			
		||||
		COMPILER=$($CC --version | head -1 \
 | 
			
		||||
		  | cut -d')' -f2 | cut -d' ' -f2)
 | 
			
		||||
		COMPILER="gcc $COMPILER"
 | 
			
		||||
		$CC --version 2>&1 | grep -i "Open64" >/dev/null
 | 
			
		||||
		if [ $? -eq 0 ]; then
 | 
			
		||||
			COMPILER="Open64"
 | 
			
		||||
		else
 | 
			
		||||
			COMPILER=$($CC --version | head -1 \
 | 
			
		||||
			  | cut -d')' -f2 | cut -d' ' -f2)
 | 
			
		||||
			COMPILER="gcc $COMPILER"
 | 
			
		||||
		fi
 | 
			
		||||
	else
 | 
			
		||||
		case "$CC" in
 | 
			
		||||
		  gcc*)
 | 
			
		||||
@@ -130,10 +138,10 @@ else
 | 
			
		||||
	[ $? -eq 0 ] && COMMENT="(3)"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
[ -n "$CONFIGURE" ] && C="Y" || C="N"
 | 
			
		||||
[ -n "$MAKE" ] && M="Y" || M="N"
 | 
			
		||||
[ -n "$CHECK" ] && T="Y" || T="N"
 | 
			
		||||
[ -n "$RUN" ] && R="Y" || R="N"
 | 
			
		||||
[ -n "$R_CONFIGURE" ] && C="Y" || C="N"
 | 
			
		||||
[ -n "$R_MAKE" ] && M="Y" || M="N"
 | 
			
		||||
[ -n "$R_CHECK" ] && T="Y" || T="N"
 | 
			
		||||
[ -n "$R_RUN" ] && R="Y" || R="N"
 | 
			
		||||
[ -n "$COMMENT" ] && COMMENT=" $COMMENT"
 | 
			
		||||
 | 
			
		||||
echo
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								doc/Capabilities.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								doc/Capabilities.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
                           http://ngircd.barton.de/
 | 
			
		||||
 | 
			
		||||
               (c)2001-2012 Alexander Barton and Contributors.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                            -- Capabilities.txt --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
This document lists and describes the "IRC capabilities" that ngIRCd supports
 | 
			
		||||
and can be requested by a IRC/IRCv3 client that supports the "CAP" command.
 | 
			
		||||
 | 
			
		||||
ngIRCd implements the "IRC Client Capabilities Extension" as described here:
 | 
			
		||||
<http://www.leeh.co.uk/draft-mitchell-irc-capabilities-02.html>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
I. Supported Capabilities
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
* "multi-prefix"
 | 
			
		||||
 | 
			
		||||
   When requested, the multi-prefix client capability will cause the IRC
 | 
			
		||||
   server to send all possible prefixes which apply to a user in NAMES and
 | 
			
		||||
   WHO output.
 | 
			
		||||
 | 
			
		||||
   See <http://ircv3.atheme.org/extensions/multi-prefix-3.1>.
 | 
			
		||||
							
								
								
									
										14
									
								
								doc/FAQ.txt
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								doc/FAQ.txt
									
									
									
									
									
								
							@@ -64,11 +64,19 @@ A: ngIRCd does not write its own log file. Instead, ngIRCd uses syslog(3).
 | 
			
		||||
 | 
			
		||||
Q: I cannot connect to remote peers when I use the chroot option, the
 | 
			
		||||
   following is logged: "Can't resolve example.com: unknown error!".
 | 
			
		||||
A: see next question blow ...
 | 
			
		||||
 | 
			
		||||
Q: When running ngIRCd inside a chroot, no IP addresses can be translated
 | 
			
		||||
   in DNS names, errors like "Name or service not known" are logged.
 | 
			
		||||
A: On Linux/glibc with chroot enabled you need to put some libraries inside
 | 
			
		||||
   the chroot as well, notably libnss_dns; maybe others. Unfortunately, even
 | 
			
		||||
   linking ngIRCd statically does not help this. The only known workaround
 | 
			
		||||
   is to either disable chroot support or to link against dietlibc instead
 | 
			
		||||
   of glibc. (tnx to Sebastian Siewior)
 | 
			
		||||
   linking ngIRCd statically does not help this. So you can either copy
 | 
			
		||||
   all the required files into the chroot directory:
 | 
			
		||||
     $ mkdir -p ./chroot/etc ./chroot/lib
 | 
			
		||||
     $ cp -a /etc/hosts /etc/resolv.conf /etc/nsswitch.conf ./chroot/etc/
 | 
			
		||||
     $ cp -a /lib/libresolv* /lib/libnss_* ./chroot/lib/
 | 
			
		||||
   Or you can try to link ngIRCd against an other C library (like dietlibc)
 | 
			
		||||
   that doesn't depend on NSS modules and/or these files.
 | 
			
		||||
 | 
			
		||||
Q: I have added an [Oper] section, how do i log on as IRC operator?
 | 
			
		||||
A: You can use the /OPER command in your IRC client to become an IRC operator.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										37
									
								
								doc/GIT.txt
									
									
									
									
									
								
							
							
						
						
									
										37
									
								
								doc/GIT.txt
									
									
									
									
									
								
							@@ -9,13 +9,23 @@
 | 
			
		||||
                                 -- GIT.txt --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
The source code of ngIRCd is maintained using git, the stupid content
 | 
			
		||||
tracker.
 | 
			
		||||
The source code of ngIRCd is maintained using GIT, an distributed version
 | 
			
		||||
control system. Homepage including documentation: <http://git-scm.com/>.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
I. Getting the source code
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
To access the source tree anonymously, run:
 | 
			
		||||
I. Viewing the source code online
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
The ngIRCd "GITweb" interface allows you to browse the GIT repository and
 | 
			
		||||
to see all individual files, tags, branches, commits etc.:
 | 
			
		||||
 | 
			
		||||
 <http://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd.git>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
II. Getting the source code
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
To access (copy, clone) the source tree repository anonymously, run:
 | 
			
		||||
 | 
			
		||||
 $ git clone git://ngircd.barton.de/ngircd.git
 | 
			
		||||
 | 
			
		||||
@@ -23,23 +33,23 @@ Thereby a new folder "ngircd" will be created containing all the individual
 | 
			
		||||
source files.
 | 
			
		||||
 | 
			
		||||
The newly created directory ("ngircd") is the "working directory", all
 | 
			
		||||
git commands will be executed from within this directory in the future.
 | 
			
		||||
GIT commands will be executed from within this directory in the future.
 | 
			
		||||
 | 
			
		||||
Please note: When checking out a fresh copy of ngIRCd using git, the
 | 
			
		||||
Please note: When checking out a fresh copy of ngIRCd using GIT, the
 | 
			
		||||
configure script doesn't exist; you have to run the autogen.sh shell script
 | 
			
		||||
(which is included in the source tree) to generate it. This requires you to
 | 
			
		||||
have GNU automake and GNU autoconf installed on your system. Please see the
 | 
			
		||||
file INSTALL for details!
 | 
			
		||||
 | 
			
		||||
To update the git tree:
 | 
			
		||||
To update the local GIT repository:
 | 
			
		||||
 | 
			
		||||
 $ git pull
 | 
			
		||||
 | 
			
		||||
This retrieves all changes and merges them into the current branch.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
II. Contributing
 | 
			
		||||
~~~~~~~~~~~~~~~~
 | 
			
		||||
III. Contributing
 | 
			
		||||
~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Patches should be sent to the ngircd mailing list. List homepage:
 | 
			
		||||
http://arthur.barton.de/mailman/listinfo/ngircd-ml
 | 
			
		||||
@@ -48,7 +58,8 @@ If you do not want to send them to the list, you can also mail them
 | 
			
		||||
to Alex Barton, <alex@barton.de>.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
III. Write Access
 | 
			
		||||
~~~~~~~~~~~~~~~~~
 | 
			
		||||
If you want to contribute a couple of patches and write access to the git
 | 
			
		||||
IV. Write Access
 | 
			
		||||
~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
If you want to contribute a couple of patches and write access to the GIT
 | 
			
		||||
repository would be handy, please contact Alex Barton, <alex@barton.de>.
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ a) Make sure the source tree is in a releasable state ;-)
 | 
			
		||||
 | 
			
		||||
b) Make sure you have working versions of GNU autoconf and GNU automake
 | 
			
		||||
   installed on the system you use for generating the release:
 | 
			
		||||
   as of October 2010 we are using GNU autoconf 2.61 and GNU automake 1.10.1
 | 
			
		||||
   as of October 2010 we are using GNU autoconf 2.67 and GNU automake 1.11.1
 | 
			
		||||
   which seem to work just fine.
 | 
			
		||||
 | 
			
		||||
c) Update the files describing the new release:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,25 +1,38 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 | 
			
		||||
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 | 
			
		||||
#
 | 
			
		||||
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
# der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
# herausgegeben, weitergeben und/oder modifizieren, entweder unter Version 2
 | 
			
		||||
# der Lizenz oder (wenn Sie es wuenschen) jeder spaeteren Version.
 | 
			
		||||
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
 | 
			
		||||
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
 | 
			
		||||
# 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.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
.tmpl:
 | 
			
		||||
	sed \
 | 
			
		||||
	$(AM_V_GEN)sed \
 | 
			
		||||
	    -e s@:ETCDIR:@${sysconfdir}@ \
 | 
			
		||||
	    <$< >$@
 | 
			
		||||
 | 
			
		||||
SUFFIXES = .tmpl
 | 
			
		||||
 | 
			
		||||
static_docs = Bopm.txt FAQ.txt GIT.txt HowToRelease.txt PAM.txt Platforms.txt \
 | 
			
		||||
	Protocol.txt README-AUX.txt README-BeOS.txt README-Interix.txt RFC.txt \
 | 
			
		||||
	SSL.txt Services.txt
 | 
			
		||||
static_docs = \
 | 
			
		||||
	Bopm.txt \
 | 
			
		||||
	Capabilities.txt \
 | 
			
		||||
	Contributing.txt \
 | 
			
		||||
	FAQ.txt \
 | 
			
		||||
	GIT.txt \
 | 
			
		||||
	HowToRelease.txt \
 | 
			
		||||
	Modes.txt \
 | 
			
		||||
	PAM.txt \
 | 
			
		||||
	Platforms.txt \
 | 
			
		||||
	Protocol.txt \
 | 
			
		||||
	README-AUX.txt \
 | 
			
		||||
	README-BeOS.txt \
 | 
			
		||||
	README-Interix.txt \
 | 
			
		||||
	RFC.txt \
 | 
			
		||||
	Services.txt \
 | 
			
		||||
	SSL.txt
 | 
			
		||||
 | 
			
		||||
doc_templates = sample-ngircd.conf.tmpl
 | 
			
		||||
 | 
			
		||||
@@ -40,8 +53,8 @@ all: $(generated_docs)
 | 
			
		||||
 | 
			
		||||
install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
 | 
			
		||||
	$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
 | 
			
		||||
	if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
 | 
			
		||||
	  $(INSTALL) -m 600 -c sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; \
 | 
			
		||||
	@if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
 | 
			
		||||
	  make install-config; \
 | 
			
		||||
	 fi
 | 
			
		||||
	$(mkinstalldirs) $(DESTDIR)$(docdir)
 | 
			
		||||
	for f in $(static_docs) $(toplevel_docs); do \
 | 
			
		||||
@@ -51,10 +64,30 @@ install-data-hook: $(static_docs) $(toplevel_docs) $(generated_docs)
 | 
			
		||||
	  $(INSTALL) -m 644 -c $$f $(DESTDIR)$(docdir)/; \
 | 
			
		||||
	 done
 | 
			
		||||
 | 
			
		||||
install-config:
 | 
			
		||||
	$(INSTALL) -m 600 -c sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf
 | 
			
		||||
	@echo; \
 | 
			
		||||
	 echo " ** NOTE: Installed sample configuration file:"; \
 | 
			
		||||
	 echo " ** \"$(DESTDIR)$(sysconfdir)/ngircd.conf\""; \
 | 
			
		||||
	 echo
 | 
			
		||||
 | 
			
		||||
uninstall-hook:
 | 
			
		||||
	rm -rf $(DESTDIR)$(docdir)
 | 
			
		||||
	@if cmp --silent sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; then \
 | 
			
		||||
	  make uninstall-config; \
 | 
			
		||||
	 else \
 | 
			
		||||
	  echo; \
 | 
			
		||||
	  echo " ** NOTE: Not uninstalling changed configuration file:"; \
 | 
			
		||||
	  echo " ** \"$(DESTDIR)$(sysconfdir)/ngircd.conf\""; \
 | 
			
		||||
	  echo; \
 | 
			
		||||
	 fi
 | 
			
		||||
 | 
			
		||||
uninstall-config:
 | 
			
		||||
	rm -f $(DESTDIR)$(sysconfdir)/ngircd.conf
 | 
			
		||||
 | 
			
		||||
srcdoc:
 | 
			
		||||
	make -C src srcdoc
 | 
			
		||||
 | 
			
		||||
.PHONY: install-config uninstall-config srcdoc
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										88
									
								
								doc/Modes.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								doc/Modes.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
                           http://ngircd.barton.de/
 | 
			
		||||
 | 
			
		||||
               (c)2001-2012 Alexander Barton and Contributors.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                               -- Modes.txt --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
This document lists the different user modes, channel modes, and channel
 | 
			
		||||
user modes that ngIRCd supports.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
I. User Modes
 | 
			
		||||
~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
User modes are attributes a user has in the network, regardless of the
 | 
			
		||||
channels he is using at the moment.
 | 
			
		||||
 | 
			
		||||
  mode	since	description
 | 
			
		||||
 | 
			
		||||
  a	0.3.0	User is away.
 | 
			
		||||
  b	20	User blocks private messages and notices.
 | 
			
		||||
  B	20	User is flagged as a "bot".
 | 
			
		||||
  c	17	IRC operator wants to receive connect/disconnect NOTICEs.
 | 
			
		||||
  C	19	Only users that share a channel are allowed to send messages.
 | 
			
		||||
  i	0.0.1	User is "invisible".
 | 
			
		||||
  o	0.0.1	User is IRC operator.
 | 
			
		||||
  q	20	User is protected, can not be kicked from a channel.
 | 
			
		||||
  r	0.0.1	User is restricted.
 | 
			
		||||
  R (1)	19	User is registered (e.g. by NickServ).
 | 
			
		||||
  s	0.4.0	User wants to receive server notices.
 | 
			
		||||
  w	0.11.0	User wants to receive WALLOPS messages.
 | 
			
		||||
  x	17	Hostname of this user is "cloaked".
 | 
			
		||||
 | 
			
		||||
II. Channel Modes
 | 
			
		||||
~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Channel modes are attributes of specific channels which are valid for all
 | 
			
		||||
users joined (or trying to join) to this channel. Some modes add and remove
 | 
			
		||||
users to lists (e.g. "invite list", "ban list"), others have parameters
 | 
			
		||||
(like "channel key"), most are simple flags (like "moderated").
 | 
			
		||||
 | 
			
		||||
  mode	since	description
 | 
			
		||||
 | 
			
		||||
  b	0.5.0	Add/remove a host mask to the ban list.
 | 
			
		||||
  e	19	Add/remove a host mask to the exception list.
 | 
			
		||||
  i	0.5.0	Channel is "invite only".
 | 
			
		||||
  I	0.5.0	Add/remove a host mask to the invite list.
 | 
			
		||||
  k	0.6.0	Channel has a "key" (a password).
 | 
			
		||||
  l	0.6.0	Channel has a user limit.
 | 
			
		||||
  m	0.3.0	Channel is moderated, only "voiced" users can send messages.
 | 
			
		||||
  M	20	Only registered users (and IRC Ops) can send messages.
 | 
			
		||||
  n	0.3.0	Channel doesn't allow messages of users not being members.
 | 
			
		||||
  O	18	Only IRC operators are allowed to join this channel.
 | 
			
		||||
  P	0.5.0	Channel is "persistent".
 | 
			
		||||
  Q	20	Nobody can be kicked from the channel.
 | 
			
		||||
  r (1)	19	Channel is "registered" (e.g. by ChanServ).
 | 
			
		||||
  R	19	Only registered users are allowed to join this channel.
 | 
			
		||||
  s	0.9.0	Channel is "secret".
 | 
			
		||||
  t	0.3.0	Only ChanOps are allowed to modify the channel topic.
 | 
			
		||||
  V	20	Channel doesn't allow invites.
 | 
			
		||||
  z	16	Only users connected via SSL are allowed to join the channel.
 | 
			
		||||
 | 
			
		||||
III. Channel User Modes
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Channel user modes are attributes that a particular user has in a specific
 | 
			
		||||
channel of which he is a member.
 | 
			
		||||
 | 
			
		||||
  mode	since	description
 | 
			
		||||
 | 
			
		||||
  q	20	User is channel owner can only be set by a service, other
 | 
			
		||||
		owner and irc op. Can promote other users to q, a, o, h, v.
 | 
			
		||||
  a	20	User is channel admin and can promote other users to v, h, o
 | 
			
		||||
  o	0.2.0	User is channel operator and can op/kick/... other members.
 | 
			
		||||
  h	20	User is half op and can set channel modes imntvIbek and kick
 | 
			
		||||
		voiced and normal users.
 | 
			
		||||
  v	0.2.0	User is "voiced" and can speak even if channel is moderated.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Notes
 | 
			
		||||
~~~~~
 | 
			
		||||
 | 
			
		||||
(1) This mode is not set by ngIRCd itself but by services. ngIRCd handles
 | 
			
		||||
    the mode transparently and possibly adjusts its behaviour.
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
                           http://ngircd.barton.de/
 | 
			
		||||
 | 
			
		||||
               (c)2001-2011 Alexander Barton and Contributors.
 | 
			
		||||
               (c)2001-2012 Alexander Barton and Contributors.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
@@ -26,56 +26,65 @@ 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)
 | 
			
		||||
armv6l/unkn./linux-gnueabi  gcc 4.4.5    19.1       12-06-04 goetz  Y Y Y Y (5)
 | 
			
		||||
armv7l/unkn./linux-gnueabi  gcc 4.4.3    19.1       12-04-29 goetz  Y Y Y Y (5)
 | 
			
		||||
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    13~rc1     08-12-02 alex   Y Y Y Y
 | 
			
		||||
hppa2.0w-hp-hpux11.11       gcc 4.2.3    14.1       09-07-22 goetz  Y Y Y Y
 | 
			
		||||
i386/apple/darwin9.7.0      gcc 4.0.1    14.1       09-08-04 alex   Y Y Y Y (3)
 | 
			
		||||
i386/apple/darwin10.7.0     gcc 4.2.1    18         11-07-05 alex   Y Y Y Y (3)
 | 
			
		||||
i386/apple/darwin11.0.0     gcc 4.2.1    18         11-07-02 alex   Y Y Y Y (3)
 | 
			
		||||
i386/apple/darwin10.8.0     gcc 4.2.1    19         12-02-26 alex   Y Y Y Y (3)
 | 
			
		||||
i386/apple/darwin11.3.0     gcc 4.2.1    19         12-02-26 alex   Y Y Y Y (3)
 | 
			
		||||
i386/pc/solaris2.9          gcc 3.2.2    CVSHEAD    04-02-24 alex   Y Y Y Y
 | 
			
		||||
i386/pc/solaris2.11         gcc 3.4.3    18         11-07-10 alex   Y Y N Y (4)
 | 
			
		||||
i386/pc/solaris2.11         gcc 3.4.3    19         12-02-26 alex   Y Y N Y (4)
 | 
			
		||||
i386/pc/solaris2.11         gcc 4.2.3    19.1       12-05-29 goetz  Y Y Y Y (4)
 | 
			
		||||
i386/unknown/freebsd5.2.1   gcc 3.3.3    0.8.0      04-05-30 alex   Y Y Y Y
 | 
			
		||||
i386/unknown/freebsd6.2     gcc 3.4.6    18         11-07-10 alex   Y Y Y Y (3)
 | 
			
		||||
i386/unknown/freebsd7.3     gcc 4.2.1    18         11-07-1ß alex   Y Y Y Y (3)
 | 
			
		||||
i686/unknown/gnu0.3         gcc 4.4.5    18         11-07-10 alex   Y Y Y Y
 | 
			
		||||
i386/unknown/freebsd6.2     gcc 3.4.6    20~rc1     12-11-13 alex   Y Y Y Y (3)
 | 
			
		||||
i386/unknown/freebsd7.3     gcc 4.2.1    20~rc1     12-11-13 alex   Y Y Y Y (3)
 | 
			
		||||
i686/unknown/gnu0.3         gcc 4.4.5    19         12-02-29 alex   Y Y Y Y
 | 
			
		||||
i686/unkn./kfreebsd7.2-gnu  gcc 4.3.4    15         09-12-02 alex   Y Y Y Y (3)
 | 
			
		||||
i386/unknown/netbsdelf1.6.2 gcc 2.95.3   18         11-07-10 goetz  Y Y Y Y
 | 
			
		||||
i386/unknown/netbsdelf3.0.1 gcc 3.3.3    0.10.0-p1  06-08-30 alex   Y Y Y Y (3)
 | 
			
		||||
i386/unknown/netbsdelf4.0   gcc 4.1.2    18         11-07-10 alex   Y Y Y Y (3)
 | 
			
		||||
i386/unknown/netbsdelf5.0.2 gcc 4.1.3    18         11-07-10 alex   Y Y Y Y (3)
 | 
			
		||||
i386/unknown/netbsdelf4.0   gcc 4.1.2    19         12-02-29 alex   Y Y Y Y (3)
 | 
			
		||||
i386/unknown/netbsdelf5.0.2 gcc 4.1.3    19         12-02-26 alex   Y Y Y Y (3)
 | 
			
		||||
i386/unknown/openbsd3.9     gcc 3.3.5    0.10.0-p1  06-08-30 alex   Y Y Y Y (3)
 | 
			
		||||
i386/unknown/openbsd4.1     gcc 3.3.5    16         10-04-11 alex   Y Y Y Y (3)
 | 
			
		||||
i586/pc/interix3.5          gcc 3.3      18         11-07-10 alex   Y Y N Y
 | 
			
		||||
i586/pc/haiku               gcc 2.95.3   19.2~138   12-10-11 user   Y Y N N
 | 
			
		||||
i586/pc/interix3.5          gcc 3.3      19         12-02-29 alex   Y Y N Y
 | 
			
		||||
i686/pc/cygwin              gcc 3.3.1    0.8.0      04-05-30 alex   Y Y N Y
 | 
			
		||||
i686/pc/linux-gnu           gcc 2.7.2    19.1       12-05-30 goetz  Y Y Y Y (1)
 | 
			
		||||
i686/pc/linux-gnu           gcc 2.95.4   0.8.0      04-05-30 alex   Y Y Y Y (1)
 | 
			
		||||
i686/pc/linux-gnu           gcc 3.3.5    14.1       09-08-04 alex   Y Y Y Y (1)
 | 
			
		||||
i386/pc/linux-gnu           gcc 4.1.2    13~rc1     08-12-05 alex   Y Y Y Y (1)
 | 
			
		||||
i686/pc/linux-gnu           gcc 4.3.2    14.1       09-08-04 alex   Y Y Y Y (1)
 | 
			
		||||
m68k/apple/aux3.0.1         gcc 2.7.2    17         10-11-07 alex   Y Y N Y
 | 
			
		||||
m68k/apple/aux3.0.1         Orig. A/UX   17         10-11-07 alex   Y Y N Y (2)
 | 
			
		||||
m68k/apple/aux3.1.1         gcc 2.7.2    18         11-07-02 alex   Y Y N Y
 | 
			
		||||
m68k/apple/aux3.1.1         Orig. A/UX   18         11-07-02 alex   Y Y N Y (2)
 | 
			
		||||
m68k/apple/aux3.1.1         gcc 2.7.2    19         12-02-26 alex   Y Y N Y
 | 
			
		||||
m68k/apple/aux3.1.1         Orig. A/UX   19         12-02-26 alex   Y Y N 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 ? ?
 | 
			
		||||
mipsel/unknown/linux-gnu    gcc 4.1.2    18         11-07-05 goetz  Y Y N Y (1)
 | 
			
		||||
mipsel/unknown/linux-gnu    gcc 4.4.5    18         11-07-30 goetz  Y Y Y Y (1)
 | 
			
		||||
powerpc/apple/darwin6.5     gcc 3.1      0.7.x-CVS  03-04-23 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/darwin7.9.0   gcc 3.3      19.1       12-05-22 goetz  Y Y Y Y (3)
 | 
			
		||||
powerpc/apple/darwin8.11.0  gcc 4.0.1    18         11-07-02 goetz  Y Y Y Y (3)
 | 
			
		||||
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
 | 
			
		||||
x86_64/unknown/freebsd8.1   gcc 4.2.1    18         11-07-10 alex   Y Y Y Y (3)
 | 
			
		||||
x86_64/unknown/linux-gnu    gcc 4.4.5    18         11-07-02 alex   Y Y Y Y (1)
 | 
			
		||||
x86_64/unknown/openbsd4.7   gcc 3.3.5    18         11-07-10 alex   Y Y Y Y (3)
 | 
			
		||||
x86_64/apple/darwin12.2.0   gcc 4.2.1    20~rc1     12-11-13 alex   Y Y Y Y (3)
 | 
			
		||||
x86_64/unknown/freebsd8.1   gcc 4.2.1    20~rc1     12-11-13 alex   Y Y Y Y (3)
 | 
			
		||||
x86_64/unkn./freebsd8.1-gnu gcc 4.4.5    19         12-02-26 alex   Y Y Y Y (3)
 | 
			
		||||
x86_64/unknown/linux-gnu    gcc 4.4.5    20~rc1     12-02-26 alex   Y Y Y Y (1)
 | 
			
		||||
x86_64/unknown/openbsd4.7   gcc 3.3.5    20~rc1     12-02-26 alex   Y Y Y Y (3)
 | 
			
		||||
x86_64/unknown/openbsd4.8   gcc 4.2.1    20~rc1     12-11-13 alex   Y Y Y Y (3)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Notes
 | 
			
		||||
~~~~~
 | 
			
		||||
 | 
			
		||||
(1) i686/pc/linux-gnu & x86_64/unknown/linux-gnu:
 | 
			
		||||
(1) */*/linux-gnu (Linux platforms):
 | 
			
		||||
    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 (starting with 2.95.x and up to
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,8 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
                           http://ngircd.barton.de/
 | 
			
		||||
 | 
			
		||||
                        (c)2001-2008 Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
               (c)2001-2012 Alexander Barton and Contributors.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
@@ -82,11 +81,17 @@ The following <serverflags> are defined at the moment:
 | 
			
		||||
- H: The server supports the "enhanced server handshake", see section II.2
 | 
			
		||||
     for a detailed description.
 | 
			
		||||
 | 
			
		||||
- M: Changing client "metadata" (hostname, real name, ...) using the
 | 
			
		||||
     METADATA command is supported.
 | 
			
		||||
 | 
			
		||||
- o: IRC operators are allowed to change channel- and channel-user-modes
 | 
			
		||||
     even if they aren't channel-operator of the affected channel.
 | 
			
		||||
 | 
			
		||||
- S: The server supports the SERVICE command (on this link).
 | 
			
		||||
 | 
			
		||||
- X: Server supports XOP channel modes (owner, admin, halfop) and supports
 | 
			
		||||
     these user prefixes in CHANINFO commands, for example.
 | 
			
		||||
 | 
			
		||||
- Z: Compressed server links are supported by the server.
 | 
			
		||||
 | 
			
		||||
Example for a complete <flags> string: "ngircd|0.7.5:CZ".
 | 
			
		||||
@@ -134,7 +139,7 @@ protocol which allows at max 15 arguments per command).
 | 
			
		||||
Please see <http://www.irc.org/tech_docs/005.html> for details.
 | 
			
		||||
 | 
			
		||||
The information exchanged using ISUPPORT can be used to detect configuration
 | 
			
		||||
incompatibilities (different maximum nick name length, for example) and
 | 
			
		||||
incompatibilities (different maximum nickname length, for example) and
 | 
			
		||||
therefore to disconnect the peer prior to registering it in the network.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -181,3 +186,69 @@ first command sent to the server, even before USER and NICK commands!
 | 
			
		||||
The <password> must be set in the server configuration file to prevent
 | 
			
		||||
unauthorized clients to fake their identity; it is an arbitrary string.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
II.5 Client character encoding conversion
 | 
			
		||||
 | 
			
		||||
     Command: CHARCONV
 | 
			
		||||
  Parameters: <client-charset>
 | 
			
		||||
     Used by: registered clients
 | 
			
		||||
     Replies: RPL_IP_CHARCONV, ERR_IP_CHARCONV
 | 
			
		||||
 | 
			
		||||
A client can set its character set encoding using the CHARCONV command:
 | 
			
		||||
after receiving such a command, the server translates all message data
 | 
			
		||||
received from the client using the set <client-charset> to the server
 | 
			
		||||
encoding (UTF-8), and all message data which is to be sent to the client
 | 
			
		||||
from the server encoding (UTF-8) to <client-charset>.
 | 
			
		||||
 | 
			
		||||
The list of supported client character sets is implementation dependent.
 | 
			
		||||
 | 
			
		||||
If a client sets its <client-charset> to the server encoding (UTF-8),
 | 
			
		||||
it disables all conversions; the connection behaves as if no CHARCONV
 | 
			
		||||
command has been sent at all in this session.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
II.6 Update client "metadata"
 | 
			
		||||
 | 
			
		||||
     Command: METADATA
 | 
			
		||||
  Parameters: <target> <key> <value>
 | 
			
		||||
     Used by: servers only
 | 
			
		||||
 | 
			
		||||
The METADATA command is used on server-links to update "metadata" information
 | 
			
		||||
of clients, like the hostname, the info text ("real name"), or the user name.
 | 
			
		||||
 | 
			
		||||
The server updates its client database according to the received <key> and
 | 
			
		||||
<value> parameters, and passes the METADATA command on to all the other
 | 
			
		||||
servers in the network that support this command (see section II.1 "Register
 | 
			
		||||
new server link", <serverflag> "M"), even if it doesn't support the given
 | 
			
		||||
<key> itself: unknown <key> names are ignored silently!
 | 
			
		||||
 | 
			
		||||
The following <key> names are defined:
 | 
			
		||||
 | 
			
		||||
 - "host": the hostname of a client (can't be empty)
 | 
			
		||||
 - "cloakhost": the cloaked hostname of a client
 | 
			
		||||
 - "info": info text ("real name") of a client
 | 
			
		||||
 - "user": the user name of a client (can't be empty)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
III. Numerics used by IRC+ Protocol
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
The IRC+ protocol uses numerics in the range 800-899 which aren't used by
 | 
			
		||||
RFC 2812 and hopefully don't clash with other implementations ...
 | 
			
		||||
 | 
			
		||||
Numerics 800-849 are used for status and success messages, and numerics
 | 
			
		||||
850-899 are failure and error messages.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
III.1 IRC+ status and success numerics
 | 
			
		||||
 | 
			
		||||
801 - RPL_IP_CHARCONV
 | 
			
		||||
	%1 :Client encoding set"
 | 
			
		||||
 | 
			
		||||
		%1	client character set
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
III.2 IRC+ failure and error numerics
 | 
			
		||||
 | 
			
		||||
851 - ERR_IP_CHARCONV
 | 
			
		||||
	:Can't initialize client encoding
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,10 @@
 | 
			
		||||
 | 
			
		||||
                    ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001-2010 Alexander Barton,
 | 
			
		||||
                   alex@barton.de, http://www.barton.de/
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
                           http://ngircd.barton.de/
 | 
			
		||||
 | 
			
		||||
               (c)2001-2012 Alexander Barton and Contributors.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                  terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                         -- README-Interix.txt --
 | 
			
		||||
 | 
			
		||||
@@ -20,10 +18,13 @@ Windows Server 2003. SUA is supported on Windows Server 2003 R2, Windows
 | 
			
		||||
Server 2008 & 2008 R2, Windows Vista, and Windows 7 -- so ngIRCd should be
 | 
			
		||||
able to run on all of these platforms.
 | 
			
		||||
 | 
			
		||||
But please note that the poll() API function is not fully implemented by
 | 
			
		||||
SFU/SUA and therefore can't be used by ngIRCd -- which normally would be
 | 
			
		||||
the default. Please see <http://www.suacommunity.com/faqs.aspx> section
 | 
			
		||||
4.25 for details:
 | 
			
		||||
But please note that two things:
 | 
			
		||||
 | 
			
		||||
1. Don't use the poll() IO API
 | 
			
		||||
 | 
			
		||||
The poll() API function is not fully implemented by SFU/SUA and therefore
 | 
			
		||||
can't be used by ngIRCd -- which normally would be the default. Please see
 | 
			
		||||
<http://www.suacommunity.com/faqs.aspx> section 4.25 for details:
 | 
			
		||||
 | 
			
		||||
  "If you do try to use the poll() API your program will block on the
 | 
			
		||||
  API call forever. You must direct your program to build using the
 | 
			
		||||
@@ -35,3 +36,9 @@ So when running the ./configure script, you HAVE TO DISABLE poll() support:
 | 
			
		||||
 | 
			
		||||
ngIRCd then defaults to using the select() API function which works fine.
 | 
			
		||||
 | 
			
		||||
2. Use GNU make(1)
 | 
			
		||||
 | 
			
		||||
Starting with ngIRCd 18, our build system doesn't work with the default
 | 
			
		||||
make(1) binary of Interix, you should use GNU make instead (tested with
 | 
			
		||||
version 3.82 built from source).
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -9,16 +9,20 @@
 | 
			
		||||
                              -- Services.txt --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
At the moment, ngIRCd doesn't implement a "special IRC services interface".
 | 
			
		||||
But services acting as a "regular server" are supported, either using the IRC
 | 
			
		||||
protocol defined in RFC 1459 or RFC 2812.
 | 
			
		||||
ngIRCd doesn't implement a "special IRC services interface", but services
 | 
			
		||||
acting as a "regular servers" ("pseudo servers") are supported, either
 | 
			
		||||
using the IRC protocol as defined in RFC 1459 or RFC 2812.
 | 
			
		||||
 | 
			
		||||
Support for Services has been tested using "IRC Services" version 5.x by
 | 
			
		||||
Andrew Church (<http://achurch.org/services/>), and a Anope 1.9 using a
 | 
			
		||||
preliminary protocol module for ngIRCd (<http://www.anope.org/>).
 | 
			
		||||
Support for Services has been tested using
 | 
			
		||||
 - Anope 1.9.8 or later (<http://www.anope.org/>; unreleased!)
 | 
			
		||||
 - Atheme 7.0.2 or later (<http://www.atheme.net>)
 | 
			
		||||
 - "IRC Services" 5.1.x by Andrew Church (<http://achurch.org/services/>)
 | 
			
		||||
 | 
			
		||||
This document describes setting up ngIRCd and these services.
 | 
			
		||||
 | 
			
		||||
Please let us know if you are successfully using other IRC service packages or
 | 
			
		||||
which problems you encounter -- thanks!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Setting up ngIRCd
 | 
			
		||||
~~~~~~~~~~~~~~~~~
 | 
			
		||||
@@ -40,13 +44,21 @@ Example:
 | 
			
		||||
Setting up Anope 1.9.x
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Anope 1.9.4 (and above) can be used with ngIRCd using a preliminary "ngircd"
 | 
			
		||||
protocol module contained in our contrib/Anope/ directory. Please see the
 | 
			
		||||
file contrib/Anope/README for installation instructions!
 | 
			
		||||
Anope 1.9.8 or later (<http://www.anope.org/>; unreleased as of 2012-11-10)
 | 
			
		||||
may be used with ngIRCd using the "ngircd" protocol module.
 | 
			
		||||
Until Anope 1.9.8 is released, you have to use the sources from the Anope
 | 
			
		||||
development GIT tree, see <http://sourceforge.net/projects/anope/develop/>!
 | 
			
		||||
 | 
			
		||||
After patching and installing Anope, at least the following configuration
 | 
			
		||||
variables have to be adjusted in data/services.conf, in addition to all the
 | 
			
		||||
settings marked as required:
 | 
			
		||||
At least the following settings have to be tweaked, in addition to all the
 | 
			
		||||
settings marked as required by Anope:
 | 
			
		||||
 | 
			
		||||
In conf/services.conf:
 | 
			
		||||
 | 
			
		||||
  define
 | 
			
		||||
  {
 | 
			
		||||
	name = "services.host"
 | 
			
		||||
	value = "services.irc.net"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  uplink
 | 
			
		||||
  {
 | 
			
		||||
@@ -55,12 +67,45 @@ settings marked as required:
 | 
			
		||||
	password = "123abc"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  serverinfo
 | 
			
		||||
  # Load ngIRCd protocol module
 | 
			
		||||
  module { name = "ngircd" }
 | 
			
		||||
 | 
			
		||||
  networkinfo
 | 
			
		||||
  {
 | 
			
		||||
	name = "services.irc.net"
 | 
			
		||||
	type = "ngircd"
 | 
			
		||||
	# Must be set to the "MaxNickLength" setting of ngIRCd!
 | 
			
		||||
	nicklen = 9
 | 
			
		||||
 | 
			
		||||
	chanlen = 50
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
In conf/nickserv.conf:
 | 
			
		||||
 | 
			
		||||
  nickserv
 | 
			
		||||
  {
 | 
			
		||||
	# not required if you are running ngIRCd with a higher nickname limit
 | 
			
		||||
	# ("MaxNickLength") than 11 characters, but REQUIRED by default!
 | 
			
		||||
	guestnickprefix = "G-"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Setting up Atheme 7.0.2 or later
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Atheme 7.0.2 or later (<http://www.atheme.net>) may be used with ngIRCd using
 | 
			
		||||
the "ngircd" protocol module.
 | 
			
		||||
 | 
			
		||||
The following settings need to be in atheme.conf:
 | 
			
		||||
 | 
			
		||||
  loadmodule "modules/protocol/ngircd";
 | 
			
		||||
 | 
			
		||||
  uplink "server.irc.net" {
 | 
			
		||||
	password = "123abc";
 | 
			
		||||
	port = 6667;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
The documentation of Atheme can be found in the doc/ directory of the
 | 
			
		||||
Atheme source distribution.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Setting up IRC Services 5.1.x
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
@@ -91,7 +136,3 @@ In modules.conf:
 | 
			
		||||
 | 
			
		||||
The documentation of IRC Services can be found here:
 | 
			
		||||
<http://www.ircservices.za.net/docs/>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Please let us know if you are successfully using other IRC service packages or
 | 
			
		||||
which problems you encounter, thanks!
 | 
			
		||||
 
 | 
			
		||||
@@ -95,11 +95,15 @@
 | 
			
		||||
	# 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).
 | 
			
		||||
	# Maximum length of an user nickname (Default: 9, as in RFC 2812).
 | 
			
		||||
	# Please note that all servers in an IRC network MUST use the same
 | 
			
		||||
	# maximum nick name length!
 | 
			
		||||
	# maximum nickname length!
 | 
			
		||||
	;MaxNickLength = 9
 | 
			
		||||
 | 
			
		||||
	# Maximum number of channels returned in response to a /list
 | 
			
		||||
	# command (0: unlimited):
 | 
			
		||||
	;MaxListSize = 100
 | 
			
		||||
 | 
			
		||||
	# After <PingTimeout> seconds of inactivity the server will send a
 | 
			
		||||
	# PING to the peer to test whether it is alive or not.
 | 
			
		||||
	;PingTimeout = 120
 | 
			
		||||
@@ -125,11 +129,19 @@
 | 
			
		||||
	;ChrootDir = /var/empty
 | 
			
		||||
 | 
			
		||||
	# Set this hostname for every client instead of the real one.
 | 
			
		||||
	# Please note: don't use the percentage sign ("%"), it is reserved for
 | 
			
		||||
	# future extensions!
 | 
			
		||||
	;CloakHost = irc.example.net
 | 
			
		||||
	# Use %x to add the hashed value of the original hostname.
 | 
			
		||||
	;CloakHost = cloaked.host
 | 
			
		||||
 | 
			
		||||
	# Set every clients' user name to their nick name
 | 
			
		||||
	# Use this hostname for hostname cloaking on clients that have the
 | 
			
		||||
	# user mode "+x" set, instead of the name of the server.
 | 
			
		||||
	# Use %x to add the hashed value of the original hostname.
 | 
			
		||||
	;CloakHostModeX = cloaked.user
 | 
			
		||||
 | 
			
		||||
	# The Salt for cloaked hostname hashing. When undefined a random
 | 
			
		||||
	# hash is generated after each server start.
 | 
			
		||||
	;CloakHostSalt = abcdefghijklmnopqrstuvwxyz
 | 
			
		||||
 | 
			
		||||
	# Set every clients' user name to their nickname
 | 
			
		||||
	;CloakUserToNick = yes
 | 
			
		||||
 | 
			
		||||
	# Try to connect to other IRC servers using IPv4 and IPv6, if possible.
 | 
			
		||||
@@ -140,6 +152,8 @@
 | 
			
		||||
	;DNS = yes
 | 
			
		||||
 | 
			
		||||
	# Do IDENT lookups if ngIRCd has been compiled with support for it.
 | 
			
		||||
	# Users identified using IDENT are registered without the "~" character
 | 
			
		||||
	# prepended to their user name.
 | 
			
		||||
	;Ident = yes
 | 
			
		||||
 | 
			
		||||
	# Enhance user privacy slightly (useful for IRC server on TOR or I2P)
 | 
			
		||||
@@ -155,12 +169,30 @@
 | 
			
		||||
	# they are not(!) channel-operators?
 | 
			
		||||
	;OperCanUseMode = no
 | 
			
		||||
 | 
			
		||||
	# Should IRC Operators get AutoOp (+o) in persistent (+P) channels?
 | 
			
		||||
	;OperChanPAutoOp = yes
 | 
			
		||||
 | 
			
		||||
	# Mask IRC Operator mode requests as if they were coming from the
 | 
			
		||||
	# server? (This is a compatibility hack for ircd-irc2 servers)
 | 
			
		||||
	;OperServerMode = no
 | 
			
		||||
 | 
			
		||||
	# Use PAM if ngIRCd has been compiled with support for it.
 | 
			
		||||
	;PAM = no
 | 
			
		||||
	# Users identified using PAM are registered without the "~" character
 | 
			
		||||
	# prepended to their user name.
 | 
			
		||||
	;PAM = yes
 | 
			
		||||
 | 
			
		||||
	# When PAM is enabled, all clients are required to be authenticated
 | 
			
		||||
	# using PAM; connecting to the server without successful PAM
 | 
			
		||||
	# authentication isn't possible.
 | 
			
		||||
	# If this option is set, clients not sending a password are still
 | 
			
		||||
	# allowed to connect: they won't become "identified" and keep the "~"
 | 
			
		||||
	# character prepended to their supplied user name.
 | 
			
		||||
	# Please note: To make some use of this behavior, it most probably
 | 
			
		||||
	# isn't useful to enable "Ident", "PAM" and "PAMIsOptional" at the
 | 
			
		||||
	# same time, because you wouldn't be able to distinguish between
 | 
			
		||||
	# Ident'ified and PAM-authenticated users: both don't have a "~"
 | 
			
		||||
	# character prepended to their respective user names!
 | 
			
		||||
	;PAMIsOptional = no
 | 
			
		||||
 | 
			
		||||
	# Allow Pre-Defined Channels only (see Section [Channels])
 | 
			
		||||
	;PredefChannelsOnly = no
 | 
			
		||||
@@ -209,7 +241,7 @@
 | 
			
		||||
	# [Operator] sections are used to define IRC Operators. There may be
 | 
			
		||||
	# more than one [Operator] block, one for each local operator.
 | 
			
		||||
 | 
			
		||||
	# ID of the operator (may be different of the nick name)
 | 
			
		||||
	# ID of the operator (may be different of the nickname)
 | 
			
		||||
	;Name = TheOper
 | 
			
		||||
 | 
			
		||||
	# Password of the IRC operator
 | 
			
		||||
@@ -272,15 +304,16 @@
 | 
			
		||||
	# Connect to the remote server using TLS/SSL (Default: false)
 | 
			
		||||
	;SSLConnect = yes
 | 
			
		||||
 | 
			
		||||
	# Define a (case insensitive) mask matching nick names that should be
 | 
			
		||||
	# treated as IRC services when introduced via this remote server.
 | 
			
		||||
	# Define a (case insensitive) list of masks matching nicknames that
 | 
			
		||||
	# should be treated as IRC services when introduced via this remote
 | 
			
		||||
	# server, separated by commas (",").
 | 
			
		||||
	# REGULAR SERVERS DON'T NEED this parameter, so leave it empty
 | 
			
		||||
	# (which is the default).
 | 
			
		||||
	# When you are connecting IRC services which mask as a IRC server
 | 
			
		||||
	# and which use "virtual users" to communicate with, for example
 | 
			
		||||
	# "NickServ" and "ChanServ", you should set this parameter to
 | 
			
		||||
	# something like "*Serv".
 | 
			
		||||
	;ServiceMask = *Serv
 | 
			
		||||
	# something like "*Serv" or "NickServ,ChanServ,XyzServ".
 | 
			
		||||
	;ServiceMask = *Serv,Global
 | 
			
		||||
 | 
			
		||||
[Server]
 | 
			
		||||
	# More [Server] sections, if you like ...
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ TEMPLATE_MANS = ngircd.conf.5.tmpl ngircd.8.tmpl
 | 
			
		||||
SUFFIXES = .tmpl .
 | 
			
		||||
 | 
			
		||||
.tmpl:
 | 
			
		||||
	sed \
 | 
			
		||||
	$(AM_V_GEN)sed \
 | 
			
		||||
	    -e s@:SBINDIR:@${sbindir}@ \
 | 
			
		||||
	    -e s@:BINDIR:@${bindir}@ \
 | 
			
		||||
	    -e s@:ETCDIR:@${sysconfdir}@ \
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +1,35 @@
 | 
			
		||||
.\"
 | 
			
		||||
.\" ngircd(8) manual page template
 | 
			
		||||
.\"
 | 
			
		||||
.TH ngircd 8 "Jul 2011" ngircd "ngIRCd Manual"
 | 
			
		||||
.TH ngircd 8 "Oct 2012" ngIRCd "ngIRCd Manual"
 | 
			
		||||
.SH NAME
 | 
			
		||||
ngIRCd \- the next generation IRC daemon
 | 
			
		||||
ngIRCd \- the "next generation" IRC daemon
 | 
			
		||||
.SH SYNOPSIS
 | 
			
		||||
.B ngircd [
 | 
			
		||||
.B ngircd
 | 
			
		||||
[
 | 
			
		||||
.I Options
 | 
			
		||||
.B ]
 | 
			
		||||
]
 | 
			
		||||
.SH DESCRIPTION
 | 
			
		||||
.BR ngIRCd
 | 
			
		||||
is a free open source daemon for the Internet Relay Chat (IRC),
 | 
			
		||||
developed under the GNU General Public License (GPL).
 | 
			
		||||
is a free, portable and lightweight Internet Relay Chat server for small
 | 
			
		||||
or private networks, developed under the GNU General Public License (GPL).
 | 
			
		||||
It is easy to configure, can cope with dynamic IP addresses, and supports
 | 
			
		||||
IPv6, SSL-protected connections as well as PAM for authentication.
 | 
			
		||||
It is written from scratch and not based on the original IRCd.
 | 
			
		||||
.PP
 | 
			
		||||
It's written from scratch and is not based upon the original IRCd like
 | 
			
		||||
many others. It is easy to configure, supports server links (even with
 | 
			
		||||
original ircd's) and runs on hosts with changing IP addresses (such as
 | 
			
		||||
dial-in networks).
 | 
			
		||||
The name ngIRCd means
 | 
			
		||||
.IR "next generation IRC daemon",
 | 
			
		||||
which is a little bit exaggerated:
 | 
			
		||||
.IR "lightweight Internet Relay Chat server"
 | 
			
		||||
most probably would have been a better name :-)
 | 
			
		||||
.PP
 | 
			
		||||
Currently supported platforms include AIX, A/UX, FreeBSD, HP-UX, IRIX,
 | 
			
		||||
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. By default, ngIRCd writes diagnostic and informational messages using
 | 
			
		||||
the syslog mechanism.
 | 
			
		||||
systems as well. By default, ngIRCd writes diagnostic and informational
 | 
			
		||||
messages using the syslog mechanism.
 | 
			
		||||
.SH OPTIONS
 | 
			
		||||
The default behavior of
 | 
			
		||||
.BR ngircd
 | 
			
		||||
@@ -78,7 +83,7 @@ It's wise to use "ngircd \-\-configtest" to validate the configuration file
 | 
			
		||||
after changing it.
 | 
			
		||||
.SH DEBUGGING
 | 
			
		||||
When ngIRCd is compiled with debug code, that is, its source code has
 | 
			
		||||
been ./configure'd with "--enable-debug" and/or "--enable-sniffer" (witch
 | 
			
		||||
been ./configure'd with "\-\-enable\-debug" and/or "\-\-enable\-sniffer" (witch
 | 
			
		||||
enables debug mode automatically as well), you can use two more command
 | 
			
		||||
line options and two more signals to debug problems with the daemon itself
 | 
			
		||||
or IRC clients:
 | 
			
		||||
@@ -91,7 +96,7 @@ Enable debug mode and log extra messages.
 | 
			
		||||
\fB\-s\fR, \fB\-\-sniffer\fR
 | 
			
		||||
Enable IRC protocol sniffer, which logs all sent and received IRC commands to
 | 
			
		||||
the console/syslog. This option requires that ngIRCd has been ./configure'd
 | 
			
		||||
with "--enable-sniffer" and enables debug mode automatically, too.
 | 
			
		||||
with "\-\-enable\-sniffer" and enables debug mode automatically, too.
 | 
			
		||||
.PP
 | 
			
		||||
\fBSignals:\fR
 | 
			
		||||
.TP
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
.\"
 | 
			
		||||
.\" ngircd.conf(5) manual page template
 | 
			
		||||
.\"
 | 
			
		||||
.TH ngircd.conf 5 "Jun 2011" ngircd "ngIRCd Manual"
 | 
			
		||||
.TH ngircd.conf 5 "Nov 2012" ngIRCd "ngIRCd Manual"
 | 
			
		||||
.SH NAME
 | 
			
		||||
ngircd.conf \- configuration file of ngIRCd
 | 
			
		||||
.SH SYNOPSIS
 | 
			
		||||
@@ -132,9 +132,8 @@ the pidfile resides in must be writable by the ngIRCd user and exist in the
 | 
			
		||||
chroot directory (if configured, see above).
 | 
			
		||||
.TP
 | 
			
		||||
\fBPorts\fR (list of numbers)
 | 
			
		||||
Ports on which the server should listen. There may be more than one port,
 | 
			
		||||
separated with commas (","). Default: 6667, unless \fBSSL_Ports\fR are also
 | 
			
		||||
specified.
 | 
			
		||||
Ports on which the server should listen for unencrypted connections. There
 | 
			
		||||
may be more than one port, separated with commas (","). Default: 6667.
 | 
			
		||||
.TP
 | 
			
		||||
\fBServerGID\fR (string or number)
 | 
			
		||||
Group ID under which the ngIRCd should run; you can use the name of the
 | 
			
		||||
@@ -179,10 +178,13 @@ Maximum number of channels a user can be member of (0: no limit).
 | 
			
		||||
Default: 10.
 | 
			
		||||
.TP
 | 
			
		||||
\fBMaxNickLength\fR (number)
 | 
			
		||||
Maximum length of an user nick name (Default: 9, as in RFC 2812). Please
 | 
			
		||||
note that all servers in an IRC network MUST use the same maximum nick name
 | 
			
		||||
Maximum length of an user nickname (Default: 9, as in RFC 2812). Please
 | 
			
		||||
note that all servers in an IRC network MUST use the same maximum nickname
 | 
			
		||||
length!
 | 
			
		||||
.TP
 | 
			
		||||
\fBMaxListSize\fR (number)
 | 
			
		||||
Maximum number of channels returned in response to a LIST command. Default: 100.
 | 
			
		||||
.TP
 | 
			
		||||
\fBPingTimeout\fR (number)
 | 
			
		||||
After <PingTimeout> seconds of inactivity the server will send a PING to
 | 
			
		||||
the peer to test whether it is alive or not. Default: 120.
 | 
			
		||||
@@ -213,16 +215,19 @@ For this to work the server must have been started with root privileges!
 | 
			
		||||
.TP
 | 
			
		||||
\fBCloakHost\fR (string)
 | 
			
		||||
Set this hostname for every client instead of the real one. Default: empty,
 | 
			
		||||
don't change.
 | 
			
		||||
.PP
 | 
			
		||||
.RS
 | 
			
		||||
.B Please note:
 | 
			
		||||
.br
 | 
			
		||||
Don't use the percentage sign ("%"), it is reserved for future extensions!
 | 
			
		||||
.RE
 | 
			
		||||
don't change. Use %x to add the hashed value of the original hostname.
 | 
			
		||||
.TP
 | 
			
		||||
\fBCloakHostModeX\fR (string)
 | 
			
		||||
Use this hostname for hostname cloaking on clients that have the user mode
 | 
			
		||||
"+x" set, instead of the name of the server. Default: empty, use the name
 | 
			
		||||
of the server. Use %x to add the hashed value of the original hostname
 | 
			
		||||
.TP
 | 
			
		||||
\fBCloakHostSalt\fR (string)
 | 
			
		||||
The Salt for cloaked hostname hashing. When undefined a random hash is
 | 
			
		||||
generated after each server start.
 | 
			
		||||
.TP
 | 
			
		||||
\fBCloakUserToNick\fR (boolean)
 | 
			
		||||
Set every clients' user name to their nick name and hide the one supplied
 | 
			
		||||
Set every clients' user name to their nickname and hide the one supplied
 | 
			
		||||
by the IRC client. Default: no.
 | 
			
		||||
.TP
 | 
			
		||||
\fBConnectIPv4\fR (boolean)
 | 
			
		||||
@@ -244,6 +249,8 @@ Default: yes.
 | 
			
		||||
\fBIdent\fR (boolean)
 | 
			
		||||
If ngIRCd is compiled with IDENT support this can be used to disable IDENT
 | 
			
		||||
lookups at run time.
 | 
			
		||||
Users identified using IDENT are registered without the "~" character
 | 
			
		||||
prepended to their user name.
 | 
			
		||||
Default: yes.
 | 
			
		||||
.TP
 | 
			
		||||
\fBMorePrivacy\fR (boolean)
 | 
			
		||||
@@ -264,6 +271,10 @@ while connecting. Default: no.
 | 
			
		||||
Should IRC Operators be allowed to use the MODE command even if they are
 | 
			
		||||
not(!) channel-operators? Default: no.
 | 
			
		||||
.TP
 | 
			
		||||
\fBOperChanPAutoOp\fR (boolean)
 | 
			
		||||
Should IRC Operators get AutoOp (+o) in persistent (+P) channels?
 | 
			
		||||
Default: yes.
 | 
			
		||||
.TP
 | 
			
		||||
\fBOperServerMode\fR (boolean)
 | 
			
		||||
If \fBOperCanUseMode\fR is enabled, this may lead the compatibility problems
 | 
			
		||||
with Servers that run the ircd-irc2 Software. This Option "masks" mode
 | 
			
		||||
@@ -274,8 +285,23 @@ only enable it if you have ircd-irc2 servers in your IRC network.
 | 
			
		||||
If ngIRCd is compiled with PAM support this can be used to disable all calls
 | 
			
		||||
to the PAM library at runtime; all users connecting without password are
 | 
			
		||||
allowed to connect, all passwords given will fail.
 | 
			
		||||
Users identified using PAM are registered without the "~" character
 | 
			
		||||
prepended to their user name.
 | 
			
		||||
Default: yes.
 | 
			
		||||
.TP
 | 
			
		||||
\fBPAMIsOptional\fR (boolean)
 | 
			
		||||
When PAM is enabled, all clients are required to be authenticated using PAM;
 | 
			
		||||
connecting to the server without successful PAM authentication isn't possible.
 | 
			
		||||
If this option is set, clients not sending a password are still allowed to
 | 
			
		||||
connect: they won't become "identified" and keep the "~" character prepended
 | 
			
		||||
to their supplied user name.
 | 
			
		||||
Please note:
 | 
			
		||||
To make some use of this behavior, it most probably isn't useful to enable
 | 
			
		||||
"Ident", "PAM" and "PAMIsOptional" at the same time, because you wouldn't be
 | 
			
		||||
able to distinguish between Ident'ified and PAM-authenticated users: both
 | 
			
		||||
don't have a "~" character prepended to their respective user names!
 | 
			
		||||
Default: no.
 | 
			
		||||
.TP
 | 
			
		||||
\fBPredefChannelsOnly\fR (boolean)
 | 
			
		||||
If enabled, no new channels can be created. Useful if you do not want to have
 | 
			
		||||
other channels than those defined in [Channel] sections in the configuration
 | 
			
		||||
@@ -343,7 +369,7 @@ sections are used to define IRC Operators. There may be more than one
 | 
			
		||||
block, one for each local operator.
 | 
			
		||||
.TP
 | 
			
		||||
\fBName\fR (string)
 | 
			
		||||
ID of the operator (may be different of the nick name).
 | 
			
		||||
ID of the operator (may be different of the nickname).
 | 
			
		||||
.TP
 | 
			
		||||
\fBPassword\fR (string)
 | 
			
		||||
Password of the IRC operator.
 | 
			
		||||
@@ -403,14 +429,16 @@ You can use the IRC Operator command CONNECT later on to create the link.
 | 
			
		||||
Connect to the remote server using TLS/SSL. Default: false.
 | 
			
		||||
.TP
 | 
			
		||||
\fBServiceMask\fR (string)
 | 
			
		||||
Define a (case insensitive) mask matching nick names that should be treated as
 | 
			
		||||
IRC services when introduced via this remote server. REGULAR SERVERS DON'T NEED
 | 
			
		||||
this parameter, so leave it empty (which is the default).
 | 
			
		||||
Define a (case insensitive) list of masks matching nicknames that should be
 | 
			
		||||
treated as IRC services when introduced via this remote server, separated
 | 
			
		||||
by commas (","). REGULAR SERVERS DON'T NEED this parameter, so leave it empty
 | 
			
		||||
(which is the default).
 | 
			
		||||
.PP
 | 
			
		||||
.RS
 | 
			
		||||
When you are connecting IRC services which mask as a IRC server and which use
 | 
			
		||||
"virtual users" to communicate with, for example "NickServ" and "ChanServ",
 | 
			
		||||
you should set this parameter to something like "*Serv".
 | 
			
		||||
you should set this parameter to something like "*Serv", "*Serv,OtherNick",
 | 
			
		||||
or "NickServ,ChanServ,XyzServ".
 | 
			
		||||
.SH [CHANNEL]
 | 
			
		||||
Pre-defined channels can be configured in
 | 
			
		||||
.I [Channel]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								src/ipaddr/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/ipaddr/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
Makefile.am
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
AUTOMAKE_OPTIONS = ansi2knr
 | 
			
		||||
 | 
			
		||||
INCLUDES = -I$(srcdir)/../portab
 | 
			
		||||
 | 
			
		||||
noinst_LIBRARIES = libngipaddr.a
 | 
			
		||||
 | 
			
		||||
libngipaddr_a_SOURCES = ng_ipaddr.c
 | 
			
		||||
 | 
			
		||||
noinst_HEADERS = ng_ipaddr.h
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
							
								
								
									
										21
									
								
								src/ipaddr/Makefile.ng
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/ipaddr/Makefile.ng
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
#
 | 
			
		||||
# ipaddr/Makefile.am
 | 
			
		||||
# (c) 2008 Florian Westphal <fw@strlen.de>, public domain.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
__ng_Makefile_am_template__
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = Makefile.ng
 | 
			
		||||
 | 
			
		||||
AM_CPPFLAGS = -I$(srcdir)/../portab
 | 
			
		||||
 | 
			
		||||
noinst_LIBRARIES = libngipaddr.a
 | 
			
		||||
 | 
			
		||||
libngipaddr_a_SOURCES = ng_ipaddr.c
 | 
			
		||||
 | 
			
		||||
noinst_HEADERS = ng_ipaddr.h
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in Makefile.am
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
@@ -32,7 +32,9 @@ ng_ipaddr_init(ng_ipaddr_t *addr, const char *ip_str, UINT16 port)
 | 
			
		||||
	assert(ip_str);
 | 
			
		||||
 | 
			
		||||
	memset(&hints, 0, sizeof(hints));
 | 
			
		||||
#ifdef AI_NUMERICHOST
 | 
			
		||||
	hints.ai_flags = AI_NUMERICHOST;
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef WANT_IPV6	/* do not convert ipv6 addresses */
 | 
			
		||||
	hints.ai_family = AF_INET;
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								src/ngircd/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/ngircd/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,4 @@
 | 
			
		||||
Makefile.am
 | 
			
		||||
check-help
 | 
			
		||||
check-version
 | 
			
		||||
ngircd
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 | 
			
		||||
# Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors
 | 
			
		||||
#
 | 
			
		||||
# This program is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -9,35 +9,107 @@
 | 
			
		||||
# Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
AUTOMAKE_OPTIONS = ../portab/ansi2knr
 | 
			
		||||
__ng_Makefile_am_template__
 | 
			
		||||
 | 
			
		||||
INCLUDES = -I$(srcdir)/../portab -I$(srcdir)/../tool -I$(srcdir)/../ipaddr
 | 
			
		||||
EXTRA_DIST = Makefile.ng
 | 
			
		||||
 | 
			
		||||
AM_CPPFLAGS = -I$(srcdir)/../portab -I$(srcdir)/../tool -I$(srcdir)/../ipaddr
 | 
			
		||||
 | 
			
		||||
LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN \
 | 
			
		||||
 -varuse -retvalother -emptyret -unrecog
 | 
			
		||||
 | 
			
		||||
sbin_PROGRAMS = ngircd
 | 
			
		||||
 | 
			
		||||
ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.c \
 | 
			
		||||
	conn-ssl.c conn-zip.c hash.c io.c irc.c irc-channel.c irc-info.c irc-login.c \
 | 
			
		||||
	irc-mode.c irc-op.c irc-oper.c irc-server.c irc-write.c lists.c log.c \
 | 
			
		||||
	match.c op.c numeric.c pam.c parse.c proc.c resolve.c sighandlers.c
 | 
			
		||||
ngircd_SOURCES = \
 | 
			
		||||
	ngircd.c \
 | 
			
		||||
	array.c \
 | 
			
		||||
	channel.c \
 | 
			
		||||
	class.c \
 | 
			
		||||
	client.c \
 | 
			
		||||
	client-cap.c \
 | 
			
		||||
	conf.c \
 | 
			
		||||
	conn.c \
 | 
			
		||||
	conn-encoding.c \
 | 
			
		||||
	conn-func.c \
 | 
			
		||||
	conn-ssl.c \
 | 
			
		||||
	conn-zip.c \
 | 
			
		||||
	hash.c \
 | 
			
		||||
	io.c \
 | 
			
		||||
	irc.c \
 | 
			
		||||
	irc-cap.c \
 | 
			
		||||
	irc-channel.c \
 | 
			
		||||
	irc-encoding.c \
 | 
			
		||||
	irc-info.c \
 | 
			
		||||
	irc-login.c \
 | 
			
		||||
	irc-metadata.c \
 | 
			
		||||
	irc-mode.c \
 | 
			
		||||
	irc-op.c \
 | 
			
		||||
	irc-oper.c \
 | 
			
		||||
	irc-server.c \
 | 
			
		||||
	irc-write.c \
 | 
			
		||||
	lists.c \
 | 
			
		||||
	log.c \
 | 
			
		||||
	login.c \
 | 
			
		||||
	match.c \
 | 
			
		||||
	numeric.c \
 | 
			
		||||
	op.c \
 | 
			
		||||
	pam.c \
 | 
			
		||||
	parse.c \
 | 
			
		||||
	proc.c \
 | 
			
		||||
	resolve.c \
 | 
			
		||||
	sighandlers.c
 | 
			
		||||
 | 
			
		||||
ngircd_LDFLAGS = -L../portab -L../tool -L../ipaddr
 | 
			
		||||
 | 
			
		||||
ngircd_LDADD = -lngportab -lngtool -lngipaddr
 | 
			
		||||
 | 
			
		||||
noinst_HEADERS = ngircd.h array.h channel.h client.h conf.h conf-ssl.h conn.h \
 | 
			
		||||
	conn-func.h conn-ssl.h conn-zip.h hash.h io.h irc.h irc-channel.h \
 | 
			
		||||
	irc-info.h irc-login.h irc-mode.h irc-op.h irc-oper.h irc-server.h \
 | 
			
		||||
	irc-write.h lists.h log.h match.h numeric.h op.h pam.h parse.h proc.h \
 | 
			
		||||
	resolve.h sighandlers.h defines.h messages.h
 | 
			
		||||
noinst_HEADERS = \
 | 
			
		||||
	ngircd.h \
 | 
			
		||||
	array.h \
 | 
			
		||||
	channel.h \
 | 
			
		||||
	class.h \
 | 
			
		||||
	client.h \
 | 
			
		||||
	client-cap.h \
 | 
			
		||||
	conf.h \
 | 
			
		||||
	conf-ssl.h \
 | 
			
		||||
	conn.h \
 | 
			
		||||
	conn-encoding.h \
 | 
			
		||||
	conn-func.h \
 | 
			
		||||
	conn-ssl.h \
 | 
			
		||||
	conn-zip.h \
 | 
			
		||||
	defines.h \
 | 
			
		||||
	hash.h \
 | 
			
		||||
	io.h \
 | 
			
		||||
	irc.h \
 | 
			
		||||
	irc-cap.h \
 | 
			
		||||
	irc-channel.h \
 | 
			
		||||
	irc-encoding.h \
 | 
			
		||||
	irc-info.h \
 | 
			
		||||
	irc-login.h \
 | 
			
		||||
	irc-metadata.h \
 | 
			
		||||
	irc-mode.h \
 | 
			
		||||
	irc-op.h \
 | 
			
		||||
	irc-oper.h \
 | 
			
		||||
	irc-server.h \
 | 
			
		||||
	irc-write.h \
 | 
			
		||||
	lists.h \
 | 
			
		||||
	log.h \
 | 
			
		||||
	login.h \
 | 
			
		||||
	match.h \
 | 
			
		||||
	messages.h \
 | 
			
		||||
	numeric.h \
 | 
			
		||||
	op.h \
 | 
			
		||||
	pam.h \
 | 
			
		||||
	parse.h \
 | 
			
		||||
	proc.h \
 | 
			
		||||
	resolve.h \
 | 
			
		||||
	sighandlers.h
 | 
			
		||||
 | 
			
		||||
clean-local:
 | 
			
		||||
	rm -f check-version check-help lint.out
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in
 | 
			
		||||
	rm -f Makefile Makefile.in Makefile.am
 | 
			
		||||
 | 
			
		||||
check-version: Makefile
 | 
			
		||||
	echo "#!/bin/sh" > check-version
 | 
			
		||||
@@ -56,7 +128,7 @@ lint:
 | 
			
		||||
	for f in *.c; do \
 | 
			
		||||
	 echo "checking $$f ..."; \
 | 
			
		||||
	 splint $$f $(LINTARGS) -I$(srcdir) -I$(srcdir)/.. \
 | 
			
		||||
	  $(INCLUDES) $(AM_CFLAGS) >lint.out 2>&1; \
 | 
			
		||||
	  $(AM_CPPFLAGS) $(AM_CFLAGS) >lint.out 2>&1; \
 | 
			
		||||
	 grep "no warnings" lint.out > /dev/null 2>&1; \
 | 
			
		||||
	 if [ $$? -ne 0 ]; then \
 | 
			
		||||
	  waswarning=1; \
 | 
			
		||||
@@ -84,7 +84,7 @@ extern void* array_get PARAMS((array* a, size_t membersize, size_t pos));
 | 
			
		||||
/* free the contents of this array. */
 | 
			
		||||
extern void array_free PARAMS((array* a));
 | 
			
		||||
 | 
			
		||||
/* overwrite array with zeroes before free */
 | 
			
		||||
/* overwrite array with zeros before free */
 | 
			
		||||
extern void array_free_wipe PARAMS((array* a));
 | 
			
		||||
 | 
			
		||||
/* return pointer to first element in this array */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -66,16 +66,8 @@ static void Set_KeyFile PARAMS((CHANNEL *Chan, const char *KeyFile));
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Channel_Init( void )
 | 
			
		||||
{
 | 
			
		||||
	CHANNEL *sc;
 | 
			
		||||
 | 
			
		||||
	My_Channels = NULL;
 | 
			
		||||
	My_Cl2Chan = NULL;
 | 
			
		||||
 | 
			
		||||
	sc = Channel_Create("&SERVER");
 | 
			
		||||
	if (sc) {
 | 
			
		||||
		Channel_SetModes(sc, "mnPt");
 | 
			
		||||
		Channel_SetTopic(sc, Client_ThisServer(), "Server Messages");
 | 
			
		||||
	}
 | 
			
		||||
} /* Channel_Init */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -87,6 +79,14 @@ Channel_GetListBans(CHANNEL *c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL struct list_head *
 | 
			
		||||
Channel_GetListExcepts(CHANNEL *c)
 | 
			
		||||
{
 | 
			
		||||
	assert(c != NULL);
 | 
			
		||||
	return &c->list_excepts;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL struct list_head *
 | 
			
		||||
Channel_GetListInvites(CHANNEL *c)
 | 
			
		||||
{
 | 
			
		||||
@@ -95,11 +95,12 @@ Channel_GetListInvites(CHANNEL *c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generate predefined persistent channels and &SERVER
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Channel_InitPredefined( void )
 | 
			
		||||
{
 | 
			
		||||
	/* Generate predefined persistent channels */
 | 
			
		||||
 | 
			
		||||
	CHANNEL *new_chan;
 | 
			
		||||
	const struct Conf_Channel *conf_chan;
 | 
			
		||||
	const char *c;
 | 
			
		||||
@@ -110,9 +111,12 @@ Channel_InitPredefined( void )
 | 
			
		||||
	assert(channel_count == 0 || conf_chan != NULL);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < channel_count; i++, conf_chan++) {
 | 
			
		||||
		if (!conf_chan->name[0] || !Channel_IsValidName(conf_chan->name)) {
 | 
			
		||||
			Log(LOG_ERR, "Can't create pre-defined channel: invalid name: \"%s\"",
 | 
			
		||||
									conf_chan->name);
 | 
			
		||||
		if (!conf_chan->name[0])
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!Channel_IsValidName(conf_chan->name)) {
 | 
			
		||||
			Log(LOG_ERR,
 | 
			
		||||
			    "Can't create pre-defined channel: invalid name: \"%s\"",
 | 
			
		||||
			    conf_chan->name);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -149,6 +153,18 @@ Channel_InitPredefined( void )
 | 
			
		||||
	}
 | 
			
		||||
	if (channel_count)
 | 
			
		||||
		array_free(&Conf_Channels);
 | 
			
		||||
 | 
			
		||||
	/* Make sure the local &SERVER channel exists */
 | 
			
		||||
	if (!Channel_Search("&SERVER")) {
 | 
			
		||||
		new_chan = Channel_Create("&SERVER");
 | 
			
		||||
		if (new_chan) {
 | 
			
		||||
			Channel_SetModes(new_chan, "mnPt");
 | 
			
		||||
			Channel_SetTopic(new_chan, Client_ThisServer(),
 | 
			
		||||
					 "Server Messages");
 | 
			
		||||
		} else
 | 
			
		||||
			Log(LOG_ERR, "Failed to create \"&SERVER\" channel!");
 | 
			
		||||
	} else
 | 
			
		||||
		LogDebug("Required channel \"&SERVER\" already exists, ok.");
 | 
			
		||||
} /* Channel_InitPredefined */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -158,6 +174,7 @@ Free_Channel(CHANNEL *chan)
 | 
			
		||||
	array_free(&chan->topic);
 | 
			
		||||
	array_free(&chan->keyfile);
 | 
			
		||||
	Lists_Free(&chan->list_bans);
 | 
			
		||||
	Lists_Free(&chan->list_excepts);
 | 
			
		||||
	Lists_Free(&chan->list_invites);
 | 
			
		||||
 | 
			
		||||
	free(chan);
 | 
			
		||||
@@ -282,6 +299,8 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
 | 
			
		||||
	     const char *Reason )
 | 
			
		||||
{
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	char *ptr, *target_modes;
 | 
			
		||||
	bool can_kick = false;
 | 
			
		||||
 | 
			
		||||
	assert(Peer != NULL);
 | 
			
		||||
	assert(Target != NULL);
 | 
			
		||||
@@ -302,14 +321,63 @@ Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
 | 
			
		||||
		/* Check that user is on the specified channel */
 | 
			
		||||
		if (!Channel_IsMemberOf(chan, Origin)) {
 | 
			
		||||
			IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG,
 | 
			
		||||
					   Client_ID(Origin), Name);
 | 
			
		||||
					    Client_ID(Origin), Name);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(Client_Type(Peer) == CLIENT_USER) {
 | 
			
		||||
		/* Channel mode 'Q' and user mode 'q' on target: nobody but
 | 
			
		||||
		 * IRC Operators and servers can kick the target user */
 | 
			
		||||
		if ((strchr(Channel_Modes(chan), 'Q')
 | 
			
		||||
		     || Client_HasMode(Target, 'q')
 | 
			
		||||
		     || Client_Type(Target) == CLIENT_SERVICE)
 | 
			
		||||
		    && !Client_HasMode(Origin, 'o')) {
 | 
			
		||||
			IRC_WriteStrClient(Origin, ERR_KICKDENY_MSG,
 | 
			
		||||
					   Client_ID(Origin), Name,
 | 
			
		||||
					   Client_ID(Target));
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Check if user has operator status */
 | 
			
		||||
		if (!strchr(Channel_UserModes(chan, Origin), 'o')) {
 | 
			
		||||
			IRC_WriteStrClient(Origin, ERR_CHANOPRIVSNEEDED_MSG,
 | 
			
		||||
					   Client_ID(Origin), Name);
 | 
			
		||||
		/* Check if client has the rights to kick target */
 | 
			
		||||
		ptr = Channel_UserModes(chan, Peer);
 | 
			
		||||
		target_modes = Channel_UserModes(chan, Target);
 | 
			
		||||
		while(*ptr) {
 | 
			
		||||
			/* Owner can kick everyone */
 | 
			
		||||
			if ( *ptr == 'q') {
 | 
			
		||||
				can_kick = true;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			/* Admin can't kick owner */
 | 
			
		||||
			if ( *ptr == 'a' ) {
 | 
			
		||||
				if (!strchr(target_modes, 'q')) {
 | 
			
		||||
					can_kick = true;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			/* Op can't kick owner | admin */
 | 
			
		||||
			if ( *ptr == 'o' ) {
 | 
			
		||||
				if (!strchr(target_modes, 'q') &&
 | 
			
		||||
				    !strchr(target_modes, 'a')) {
 | 
			
		||||
					can_kick = true;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			/* Half Op can't kick owner | admin | op */ 
 | 
			
		||||
			if ( *ptr == 'h' ) {
 | 
			
		||||
				if (!strchr(target_modes, 'q') &&
 | 
			
		||||
				    !strchr(target_modes, 'a') &&
 | 
			
		||||
				    !strchr(target_modes, 'o')) {
 | 
			
		||||
					can_kick = true;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			ptr++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if(!can_kick) {
 | 
			
		||||
			IRC_WriteStrClient(Origin, ERR_CHANOPPRIVTOOLOW_MSG,
 | 
			
		||||
				Client_ID(Origin), Name);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -349,20 +417,31 @@ Channel_Quit( CLIENT *Client, const char *Reason )
 | 
			
		||||
} /* Channel_Quit */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get number of channels this server knows and that are "visible" to
 | 
			
		||||
 * the given client. If no client is given, all channels will be counted.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client to check or NULL.
 | 
			
		||||
 * @return Number of channels visible to the client.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL unsigned long
 | 
			
		||||
Channel_Count( void )
 | 
			
		||||
Channel_CountVisible (CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	CHANNEL *c;
 | 
			
		||||
	unsigned long count = 0;
 | 
			
		||||
 | 
			
		||||
	c = My_Channels;
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		count++;
 | 
			
		||||
	while(c) {
 | 
			
		||||
		if (Client) {
 | 
			
		||||
			if (!strchr(Channel_Modes(c), 's')
 | 
			
		||||
			    || Channel_IsMemberOf(c, Client))
 | 
			
		||||
				count++;
 | 
			
		||||
		} else
 | 
			
		||||
			count++;
 | 
			
		||||
		c = c->next;
 | 
			
		||||
	}
 | 
			
		||||
	return count;
 | 
			
		||||
} /* Channel_Count */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL unsigned long
 | 
			
		||||
@@ -774,12 +853,19 @@ Channel_SetMaxUsers(CHANNEL *Chan, unsigned long Count)
 | 
			
		||||
} /* Channel_SetMaxUsers */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a client is allowed to send to a specific channel.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Chan The channel to check.
 | 
			
		||||
 * @param From The client that wants to send.
 | 
			
		||||
 * @return true if the client is allowed to send, false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
static bool
 | 
			
		||||
Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
 | 
			
		||||
{
 | 
			
		||||
	bool is_member, has_voice, is_op;
 | 
			
		||||
	bool is_member, has_voice, is_halfop, is_op, is_chanadmin, is_owner;
 | 
			
		||||
 | 
			
		||||
	is_member = has_voice = is_op = false;
 | 
			
		||||
	is_member = has_voice = is_halfop = is_op = is_chanadmin = is_owner = false;
 | 
			
		||||
 | 
			
		||||
	/* The server itself always can send messages :-) */
 | 
			
		||||
	if (Client_ThisServer() == From)
 | 
			
		||||
@@ -789,8 +875,14 @@ Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
 | 
			
		||||
		is_member = true;
 | 
			
		||||
		if (strchr(Channel_UserModes(Chan, From), 'v'))
 | 
			
		||||
			has_voice = true;
 | 
			
		||||
		if (strchr(Channel_UserModes(Chan, From), 'h'))
 | 
			
		||||
			is_halfop = true;
 | 
			
		||||
		if (strchr(Channel_UserModes(Chan, From), 'o'))
 | 
			
		||||
			is_op = true;
 | 
			
		||||
		if (strchr(Channel_UserModes(Chan, From), 'a'))
 | 
			
		||||
			is_chanadmin = true;
 | 
			
		||||
		if (strchr(Channel_UserModes(Chan, From), 'q'))
 | 
			
		||||
			is_owner = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
@@ -802,12 +894,19 @@ Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
 | 
			
		||||
	if (strchr(Channel_Modes(Chan), 'n') && !is_member)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	if (is_op || has_voice)
 | 
			
		||||
	if (strchr(Channel_Modes(Chan), 'M') && !Client_HasMode(From, 'R')
 | 
			
		||||
	    && !Client_HasMode(From, 'o'))
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	if (has_voice || is_halfop || is_op || is_chanadmin || is_owner)
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	if (strchr(Channel_Modes(Chan), 'm'))
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	if (Lists_Check(&Chan->list_excepts, From))
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	return !Lists_Check(&Chan->list_bans, From);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -819,7 +918,11 @@ Channel_Write(CHANNEL *Chan, CLIENT *From, CLIENT *Client, const char *Command,
 | 
			
		||||
	if (!Can_Send_To_Channel(Chan, From)) {
 | 
			
		||||
		if (! SendErrors)
 | 
			
		||||
			return CONNECTED;	/* no error, see RFC 2812 */
 | 
			
		||||
		return IRC_WriteStrClient(From, ERR_CANNOTSENDTOCHAN_MSG,
 | 
			
		||||
		if (strchr(Channel_Modes(Chan), 'M'))
 | 
			
		||||
			return IRC_WriteStrClient(From, ERR_NEEDREGGEDNICK_MSG,
 | 
			
		||||
						  Client_ID(From), Channel_Name(Chan));
 | 
			
		||||
		else
 | 
			
		||||
			return IRC_WriteStrClient(From, ERR_CANNOTSENDTOCHAN_MSG,
 | 
			
		||||
					  Client_ID(From), Channel_Name(Chan));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -999,8 +1102,17 @@ GLOBAL bool
 | 
			
		||||
Channel_AddBan(CHANNEL *c, const char *mask )
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *h = Channel_GetListBans(c);
 | 
			
		||||
	LogDebug("Adding \"%s\" to \"%s\" %s list", mask, Channel_Name(c), "ban");
 | 
			
		||||
	return Lists_Add(h, mask, false);
 | 
			
		||||
	LogDebug("Adding \"%s\" to \"%s\" ban list", mask, Channel_Name(c));
 | 
			
		||||
	return Lists_Add(h, mask, false, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Channel_AddExcept(CHANNEL *c, const char *mask )
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *h = Channel_GetListExcepts(c);
 | 
			
		||||
	LogDebug("Adding \"%s\" to \"%s\" exception list", mask, Channel_Name(c));
 | 
			
		||||
	return Lists_Add(h, mask, false, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1008,30 +1120,31 @@ GLOBAL bool
 | 
			
		||||
Channel_AddInvite(CHANNEL *c, const char *mask, bool onlyonce)
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *h = Channel_GetListInvites(c);
 | 
			
		||||
	LogDebug("Adding \"%s\" to \"%s\" %s list", mask, Channel_Name(c), "invite");
 | 
			
		||||
	return Lists_Add(h, mask, onlyonce);
 | 
			
		||||
	LogDebug("Adding \"%s\" to \"%s\" invite list", mask, Channel_Name(c));
 | 
			
		||||
	return Lists_Add(h, mask, onlyonce, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
ShowInvitesBans(struct list_head *head, CLIENT *Client, CHANNEL *Channel, bool invite)
 | 
			
		||||
ShowChannelList(struct list_head *head, CLIENT *Client, CHANNEL *Channel,
 | 
			
		||||
		char *msg, char *msg_end)
 | 
			
		||||
{
 | 
			
		||||
	struct list_elem *e;
 | 
			
		||||
	char *msg = invite ? RPL_INVITELIST_MSG : RPL_BANLIST_MSG;
 | 
			
		||||
	char *msg_end;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Channel != NULL );
 | 
			
		||||
	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;
 | 
			
		||||
		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 ));
 | 
			
		||||
	return IRC_WriteStrClient(Client, msg_end, Client_ID(Client),
 | 
			
		||||
				  Channel_Name(Channel));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1043,7 +1156,21 @@ Channel_ShowBans( CLIENT *Client, CHANNEL *Channel )
 | 
			
		||||
	assert( Channel != NULL );
 | 
			
		||||
 | 
			
		||||
	h = Channel_GetListBans(Channel);
 | 
			
		||||
	return ShowInvitesBans(h, Client, Channel, false);
 | 
			
		||||
	return ShowChannelList(h, Client, Channel, RPL_BANLIST_MSG,
 | 
			
		||||
			       RPL_ENDOFBANLIST_MSG);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Channel_ShowExcepts( CLIENT *Client, CHANNEL *Channel )
 | 
			
		||||
{
 | 
			
		||||
	struct list_head *h;
 | 
			
		||||
 | 
			
		||||
	assert( Channel != NULL );
 | 
			
		||||
 | 
			
		||||
	h = Channel_GetListExcepts(Channel);
 | 
			
		||||
	return ShowChannelList(h, Client, Channel, RPL_EXCEPTLIST_MSG,
 | 
			
		||||
			       RPL_ENDOFEXCEPTLIST_MSG);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1055,7 +1182,8 @@ Channel_ShowInvites( CLIENT *Client, CHANNEL *Channel )
 | 
			
		||||
	assert( Channel != NULL );
 | 
			
		||||
 | 
			
		||||
	h = Channel_GetListInvites(Channel);
 | 
			
		||||
	return ShowInvitesBans(h, Client, Channel, true);
 | 
			
		||||
	return ShowChannelList(h, Client, Channel, RPL_INVITELIST_MSG,
 | 
			
		||||
			       RPL_ENDOFINVITELIST_MSG);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1129,64 +1257,6 @@ Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const char *Key)
 | 
			
		||||
} /* Channel_CheckKey */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check wether a client is allowed to administer a channel or not.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Chan		The channel to test.
 | 
			
		||||
 * @param Client	The client from which the command has been received.
 | 
			
		||||
 * @param Origin	The originator of the command (or NULL).
 | 
			
		||||
 * @param OnChannel	Set to true if the originator is member of the channel.
 | 
			
		||||
 * @param AdminOk	Set to true if the client is allowed to do
 | 
			
		||||
 *			administrative tasks on this channel.
 | 
			
		||||
 * @param UseServerMode	Set to true if ngIRCd should emulate "server mode",
 | 
			
		||||
 *			that is send commands as if originating from a server
 | 
			
		||||
 *			and not the originator of the command.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Channel_CheckAdminRights(CHANNEL *Chan, CLIENT *Client, CLIENT *Origin,
 | 
			
		||||
			 bool *OnChannel, bool *AdminOk, bool *UseServerMode)
 | 
			
		||||
{
 | 
			
		||||
	assert (Chan != NULL);
 | 
			
		||||
	assert (Client != NULL);
 | 
			
		||||
	assert (OnChannel != NULL);
 | 
			
		||||
	assert (AdminOk != NULL);
 | 
			
		||||
	assert (UseServerMode != NULL);
 | 
			
		||||
 | 
			
		||||
	/* Use the client as origin, if no origin has been given (no prefix?) */
 | 
			
		||||
	if (!Origin)
 | 
			
		||||
		Origin = Client;
 | 
			
		||||
 | 
			
		||||
	*OnChannel = false;
 | 
			
		||||
	*AdminOk = false;
 | 
			
		||||
	*UseServerMode = false;
 | 
			
		||||
 | 
			
		||||
	if (Client_Type(Client) != CLIENT_USER
 | 
			
		||||
	    && Client_Type(Client) != CLIENT_SERVER
 | 
			
		||||
	    && Client_Type(Client) != CLIENT_SERVICE)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* Allow channel administration if the client is a server or service */
 | 
			
		||||
	if (Client_Type(Client) != CLIENT_USER) {
 | 
			
		||||
		*AdminOk = true;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*OnChannel = Channel_IsMemberOf(Chan, Origin);
 | 
			
		||||
 | 
			
		||||
	if (*OnChannel && strchr(Channel_UserModes(Chan, Origin), 'o')) {
 | 
			
		||||
		/* User is a channel operator */
 | 
			
		||||
		*AdminOk = true;
 | 
			
		||||
	} else if (Conf_OperCanMode) {
 | 
			
		||||
		/* IRC operators are allowed to administer channels as well */
 | 
			
		||||
		if (Client_OperByMe(Origin)) {
 | 
			
		||||
			*AdminOk = true;
 | 
			
		||||
			if (Conf_OperServerMode)
 | 
			
		||||
				*UseServerMode = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
} /* Channel_CheckAdminRights */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static CL2CHAN *
 | 
			
		||||
Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -38,6 +38,7 @@ typedef struct _CHANNEL
 | 
			
		||||
	char key[CLIENT_PASS_LEN];	/* Channel key ("password", mode "k" ) */
 | 
			
		||||
	unsigned long maxusers;		/* Maximum number of members (mode "l") */
 | 
			
		||||
	struct list_head list_bans;	/* list head of banned users */
 | 
			
		||||
	struct list_head list_excepts;	/* list head of (ban) exception list */
 | 
			
		||||
	struct list_head list_invites;	/* list head of invited users */
 | 
			
		||||
	array keyfile;			/* Name of the channel key file */
 | 
			
		||||
} CHANNEL;
 | 
			
		||||
@@ -58,6 +59,7 @@ typedef POINTER CL2CHAN;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
GLOBAL struct list_head *Channel_GetListBans PARAMS((CHANNEL *c));
 | 
			
		||||
GLOBAL struct list_head *Channel_GetListExcepts PARAMS((CHANNEL *c));
 | 
			
		||||
GLOBAL struct list_head *Channel_GetListInvites PARAMS((CHANNEL *c));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Channel_Init PARAMS(( void ));
 | 
			
		||||
@@ -72,7 +74,7 @@ GLOBAL void Channel_Quit PARAMS(( CLIENT *Client, const char *Reason ));
 | 
			
		||||
GLOBAL void Channel_Kick PARAMS((CLIENT *Peer, CLIENT *Target, CLIENT *Origin,
 | 
			
		||||
				 const char *Name, const char *Reason));
 | 
			
		||||
 | 
			
		||||
GLOBAL unsigned long Channel_Count PARAMS(( void ));
 | 
			
		||||
GLOBAL unsigned long Channel_CountVisible PARAMS((CLIENT *Client));
 | 
			
		||||
GLOBAL unsigned long Channel_MemberCount PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL int Channel_CountForUser PARAMS(( CLIENT *Client ));
 | 
			
		||||
 | 
			
		||||
@@ -123,10 +125,13 @@ GLOBAL char *Channel_TopicWho PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL unsigned int Channel_CreationTime PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Channel_AddInvite PARAMS((CHANNEL *c, const char *Mask, bool OnlyOnce ));
 | 
			
		||||
GLOBAL bool Channel_AddBan PARAMS((CHANNEL *c, const char *Mask ));
 | 
			
		||||
GLOBAL bool Channel_AddBan PARAMS((CHANNEL *c, const char *Mask));
 | 
			
		||||
GLOBAL bool Channel_AddExcept PARAMS((CHANNEL *c, const char *Mask));
 | 
			
		||||
GLOBAL bool Channel_AddInvite PARAMS((CHANNEL *c, const char *Mask,
 | 
			
		||||
				      bool OnlyOnce));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Channel_ShowBans PARAMS((CLIENT *client, CHANNEL *c));
 | 
			
		||||
GLOBAL bool Channel_ShowExcepts PARAMS((CLIENT *client, CHANNEL *c));
 | 
			
		||||
GLOBAL bool Channel_ShowInvites PARAMS((CLIENT *client, CHANNEL *c));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Channel_LogServer PARAMS((const char *msg));
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										143
									
								
								src/ngircd/class.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								src/ngircd/class.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,143 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * User class management.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "array.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "lists.h"
 | 
			
		||||
#include "match.h"
 | 
			
		||||
#include "stdio.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "class.h"
 | 
			
		||||
 | 
			
		||||
struct list_head My_Classes[CLASS_COUNT];
 | 
			
		||||
 | 
			
		||||
char Reject_Reason[COMMAND_LEN];
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Class_Init(void)
 | 
			
		||||
{
 | 
			
		||||
	memset(My_Classes, 0, sizeof(My_Classes));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Class_Exit(void)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < CLASS_COUNT; Lists_Free(&My_Classes[i++]));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLOBAL char *
 | 
			
		||||
Class_GetMemberReason(const int Class, CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	char *reason;
 | 
			
		||||
 | 
			
		||||
	assert(Class < CLASS_COUNT);
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
 | 
			
		||||
	reason = Lists_CheckReason(&My_Classes[Class], Client);
 | 
			
		||||
	if (!reason)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	if (!*reason)
 | 
			
		||||
		reason = "listed";
 | 
			
		||||
 | 
			
		||||
	switch(Class) {
 | 
			
		||||
		case CLASS_GLINE:
 | 
			
		||||
			snprintf(Reject_Reason, sizeof(Reject_Reason),
 | 
			
		||||
				 "\"%s\" (G-Line)", reason);
 | 
			
		||||
			return Reject_Reason;
 | 
			
		||||
		case CLASS_KLINE:
 | 
			
		||||
			snprintf(Reject_Reason, sizeof(Reject_Reason),
 | 
			
		||||
				 "\"%s\" (K-Line)", reason);
 | 
			
		||||
			return Reject_Reason;
 | 
			
		||||
	}
 | 
			
		||||
	return reason;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a client is banned from this server: GLINE, KLINE.
 | 
			
		||||
 *
 | 
			
		||||
 * If a client isn't allowed to connect, it will be disconnected again.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client to check.
 | 
			
		||||
 * @return CONNECTED if client is allowed to join, DISCONNECTED if not.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Class_HandleServerBans(CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	char *rejectptr;
 | 
			
		||||
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
 | 
			
		||||
	rejectptr = Class_GetMemberReason(CLASS_GLINE, Client);
 | 
			
		||||
	if (!rejectptr)
 | 
			
		||||
		rejectptr = Class_GetMemberReason(CLASS_KLINE, Client);
 | 
			
		||||
	if (rejectptr) {
 | 
			
		||||
		Client_Reject(Client, rejectptr, true);
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Class_AddMask(const int Class, const char *Mask, time_t ValidUntil,
 | 
			
		||||
	      const char *Reason)
 | 
			
		||||
{
 | 
			
		||||
	assert(Class < CLASS_COUNT);
 | 
			
		||||
	assert(Mask != NULL);
 | 
			
		||||
	assert(Reason != NULL);
 | 
			
		||||
 | 
			
		||||
	return Lists_Add(&My_Classes[Class], Lists_MakeMask(Mask),
 | 
			
		||||
			 ValidUntil, Reason);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Class_DeleteMask(const int Class, const char *Mask)
 | 
			
		||||
{
 | 
			
		||||
	assert(Class < CLASS_COUNT);
 | 
			
		||||
	assert(Mask != NULL);
 | 
			
		||||
 | 
			
		||||
	Lists_Del(&My_Classes[Class], Lists_MakeMask(Mask));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLOBAL struct list_head *
 | 
			
		||||
Class_GetList(const int Class)
 | 
			
		||||
{
 | 
			
		||||
	assert(Class < CLASS_COUNT);
 | 
			
		||||
 | 
			
		||||
	return &My_Classes[Class];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Class_Expire(void)
 | 
			
		||||
{
 | 
			
		||||
	Lists_Expire(&My_Classes[CLASS_GLINE], "G-Line");
 | 
			
		||||
	Lists_Expire(&My_Classes[CLASS_KLINE], "K-Line");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										41
									
								
								src/ngircd/class.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/ngircd/class.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __class_h__
 | 
			
		||||
#define __class_h__
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * User class management.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define CLASS_KLINE 0
 | 
			
		||||
#define CLASS_GLINE 1
 | 
			
		||||
 | 
			
		||||
#define CLASS_COUNT 2
 | 
			
		||||
 | 
			
		||||
GLOBAL void Class_Init PARAMS((void));
 | 
			
		||||
GLOBAL void Class_Exit PARAMS((void));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Class_AddMask PARAMS((const int Class, const char *Mask,
 | 
			
		||||
				  const time_t ValidUntil, const char *Reason));
 | 
			
		||||
GLOBAL void Class_DeleteMask PARAMS((const int Class, const char *Mask));
 | 
			
		||||
 | 
			
		||||
GLOBAL char *Class_GetMemberReason PARAMS((const int Class, CLIENT *Client));
 | 
			
		||||
GLOBAL bool Class_HandleServerBans PARAMS((CLIENT *Client));
 | 
			
		||||
 | 
			
		||||
GLOBAL struct list_head *Class_GetList PARAMS((const int Class));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Class_Expire PARAMS((void));
 | 
			
		||||
 | 
			
		||||
#endif /* __class_h__ */
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										73
									
								
								src/ngircd/client-cap.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/ngircd/client-cap.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define __client_cap_c__
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Functions to deal with IRC Capabilities
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "client-cap.h"
 | 
			
		||||
 | 
			
		||||
GLOBAL int
 | 
			
		||||
Client_Cap(CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	assert (Client != NULL);
 | 
			
		||||
 | 
			
		||||
	return Client->capabilities;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Client_CapSet(CLIENT *Client, int Cap)
 | 
			
		||||
{
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Cap >= 0);
 | 
			
		||||
 | 
			
		||||
	Client->capabilities = Cap;
 | 
			
		||||
	LogDebug("Set new capability of \"%s\" to %d.",
 | 
			
		||||
		 Client_ID(Client), Client->capabilities);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Client_CapAdd(CLIENT *Client, int Cap)
 | 
			
		||||
{
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Cap > 0);
 | 
			
		||||
 | 
			
		||||
	Client->capabilities |= Cap;
 | 
			
		||||
	LogDebug("Add capability %d, new capability of \"%s\" is %d.",
 | 
			
		||||
		 Cap, Client_ID(Client), Client->capabilities);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Client_CapDel(CLIENT *Client, int Cap)
 | 
			
		||||
{
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Cap > 0);
 | 
			
		||||
 | 
			
		||||
	Client->capabilities &= ~Cap;
 | 
			
		||||
	LogDebug("Delete capability %d, new capability of \"%s\" is %d.",
 | 
			
		||||
		 Cap, Client_ID(Client), Client->capabilities);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										31
									
								
								src/ngircd/client-cap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/ngircd/client-cap.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __client_cap_h__
 | 
			
		||||
#define __client_cap_h__
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Functions to deal with IRC Capabilities (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define CLIENT_CAP_PENDING 1		/* Capability negotiation pending */
 | 
			
		||||
#define CLIENT_CAP_SUPPORTED 2		/* Client supports IRC capabilities */
 | 
			
		||||
 | 
			
		||||
#define CLIENT_CAP_MULTI_PREFIX 4	/* multi-prefix */
 | 
			
		||||
 | 
			
		||||
GLOBAL int Client_Cap PARAMS((CLIENT *Client));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Client_CapSet PARAMS((CLIENT *Client, int Cap));
 | 
			
		||||
GLOBAL void Client_CapAdd PARAMS((CLIENT *Client, int Cap));
 | 
			
		||||
GLOBAL void Client_CapDel PARAMS((CLIENT *Client, int Cap));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -37,6 +37,7 @@
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "hash.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
@@ -69,6 +70,8 @@ static CLIENT *Init_New_Client PARAMS((CONN_ID Idx, CLIENT *Introducer,
 | 
			
		||||
static void Destroy_UserOrService PARAMS((CLIENT *Client,const char *Txt, const char *FwdMsg,
 | 
			
		||||
					bool SendQuit));
 | 
			
		||||
 | 
			
		||||
static void cb_introduceClient PARAMS((CLIENT *Client, CLIENT *Prefix,
 | 
			
		||||
				       void *i));
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Client_Init( void )
 | 
			
		||||
@@ -186,7 +189,6 @@ Init_New_Client(CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer,
 | 
			
		||||
 | 
			
		||||
	assert(Idx >= NONE);
 | 
			
		||||
	assert(Introducer != NULL);
 | 
			
		||||
	assert(Hostname != NULL);
 | 
			
		||||
 | 
			
		||||
	client = New_Client_Struct();
 | 
			
		||||
	if (!client)
 | 
			
		||||
@@ -313,16 +315,35 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen
 | 
			
		||||
} /* Client_Destroy */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set client hostname.
 | 
			
		||||
 *
 | 
			
		||||
 * If global hostname cloaking is in effect, don't set the real hostname
 | 
			
		||||
 * but the configured one.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client of which the hostname should be set.
 | 
			
		||||
 * @param Hostname The new hostname.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Client_SetHostname( CLIENT *Client, const char *Hostname )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Hostname != NULL );
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Hostname != NULL);
 | 
			
		||||
 | 
			
		||||
	if (strlen(Conf_CloakHost)) {
 | 
			
		||||
		strlcpy( Client->host, Conf_CloakHost, sizeof( Client->host ));
 | 
			
		||||
		char cloak[GETID_LEN];
 | 
			
		||||
 | 
			
		||||
		strlcpy(cloak, Hostname, GETID_LEN);
 | 
			
		||||
		strlcat(cloak, Conf_CloakHostSalt, GETID_LEN);
 | 
			
		||||
		snprintf(cloak, GETID_LEN, Conf_CloakHost, Hash(cloak));
 | 
			
		||||
 | 
			
		||||
		LogDebug("Updating hostname of \"%s\": \"%s\" -> \"%s\"",
 | 
			
		||||
			Client_ID(Client), Client->host, cloak);
 | 
			
		||||
		strlcpy(Client->host, cloak, sizeof(Client->host));
 | 
			
		||||
	} else {
 | 
			
		||||
		strlcpy( Client->host, Hostname, sizeof( Client->host ));
 | 
			
		||||
		LogDebug("Updating hostname of \"%s\": \"%s\" -> \"%s\"",
 | 
			
		||||
			 Client_ID(Client), Client->host, Hostname);
 | 
			
		||||
		strlcpy(Client->host, Hostname, sizeof(Client->host));
 | 
			
		||||
	}
 | 
			
		||||
} /* Client_SetHostname */
 | 
			
		||||
 | 
			
		||||
@@ -419,18 +440,6 @@ Client_SetFlags( CLIENT *Client, const char *Flags )
 | 
			
		||||
} /* Client_SetFlags */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Client_SetPassword( CLIENT *Client, const char *Pwd )
 | 
			
		||||
{
 | 
			
		||||
	/* set password sent by client */
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Pwd != NULL );
 | 
			
		||||
 | 
			
		||||
	strlcpy(Client->pwd, Pwd, sizeof(Client->pwd));
 | 
			
		||||
} /* Client_SetPassword */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Client_SetAway( CLIENT *Client, const char *Txt )
 | 
			
		||||
{
 | 
			
		||||
@@ -662,7 +671,6 @@ Client_OrigUser(CLIENT *Client) {
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return the hostname of a client.
 | 
			
		||||
 * @param Client Pointer to client structure
 | 
			
		||||
@@ -673,33 +681,88 @@ Client_Hostname(CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	assert (Client != NULL);
 | 
			
		||||
	return Client->host;
 | 
			
		||||
} /* Client_Hostname */
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get potentially cloaked hostname of a client.
 | 
			
		||||
 * If the client has not enabled cloaking, the real hostname is used.
 | 
			
		||||
 * @param Client Pointer to client structure
 | 
			
		||||
 * @return Pointer to client hostname
 | 
			
		||||
 * Return the cloaked hostname of a client, if set.
 | 
			
		||||
 * @param Client Pointer to the client structure.
 | 
			
		||||
 * @return Pointer to the cloaked hostname or NULL if not set.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL char *
 | 
			
		||||
Client_HostnameCloaked(CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	if (Client_HasMode(Client, 'x'))
 | 
			
		||||
		return Client_ID(Client->introducer);
 | 
			
		||||
	else
 | 
			
		||||
		return Client_Hostname(Client);
 | 
			
		||||
} /* Client_HostnameCloaked */
 | 
			
		||||
 | 
			
		||||
	return Client->cloaked;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get (potentially cloaked) hostname of a client to display it to other users.
 | 
			
		||||
 *
 | 
			
		||||
 * If the client has not enabled cloaking, the real hostname is used.
 | 
			
		||||
 * Please note that this function uses a global static buffer, so you can't
 | 
			
		||||
 * nest invocations without overwriting earlier results!
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client Pointer to client structure
 | 
			
		||||
 * @return Pointer to client hostname
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL char *
 | 
			
		||||
Client_Password( CLIENT *Client )
 | 
			
		||||
Client_HostnameDisplayed(CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Client->pwd;
 | 
			
		||||
} /* Client_Password */
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
 | 
			
		||||
	/* Client isn't cloaked at all, return real hostname: */
 | 
			
		||||
	if (!Client_HasMode(Client, 'x'))
 | 
			
		||||
		return Client_Hostname(Client);
 | 
			
		||||
 | 
			
		||||
	/* Use an already saved cloaked hostname, if there is one */
 | 
			
		||||
	if (Client->cloaked[0])
 | 
			
		||||
		return Client->cloaked;
 | 
			
		||||
 | 
			
		||||
	Client_UpdateCloakedHostname(Client, NULL, NULL);
 | 
			
		||||
	return Client->cloaked;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Update (and generate, if necessary) the cloaked hostname of a client.
 | 
			
		||||
 *
 | 
			
		||||
 * The newly set cloaked hostname is announced in the network using METADATA
 | 
			
		||||
 * commands to peers that support this feature.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client of which the cloaked hostname should be updated.
 | 
			
		||||
 * @param Origin The originator of the hostname change, or NULL if this server.
 | 
			
		||||
 * @param Hostname The new cloaked hostname, or NULL if it should be generated.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Client_UpdateCloakedHostname(CLIENT *Client, CLIENT *Origin,
 | 
			
		||||
			     const char *Hostname)
 | 
			
		||||
{
 | 
			
		||||
	static char Cloak_Buffer[CLIENT_HOST_LEN];
 | 
			
		||||
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	if (!Origin)
 | 
			
		||||
		Origin = Client_ThisServer();
 | 
			
		||||
 | 
			
		||||
	if (!Hostname) {
 | 
			
		||||
		/* Generate new cloaked hostname */
 | 
			
		||||
		if (*Conf_CloakHostModeX) {
 | 
			
		||||
			strlcpy(Cloak_Buffer, Client->host, CLIENT_HOST_LEN);
 | 
			
		||||
			strlcat(Cloak_Buffer, Conf_CloakHostSalt,
 | 
			
		||||
				CLIENT_HOST_LEN);
 | 
			
		||||
			snprintf(Client->cloaked, sizeof(Client->cloaked),
 | 
			
		||||
				 Conf_CloakHostModeX, Hash(Cloak_Buffer));
 | 
			
		||||
		} else
 | 
			
		||||
			strlcpy(Client->cloaked, Client_ID(Client->introducer),
 | 
			
		||||
				sizeof(Client->cloaked));
 | 
			
		||||
	} else
 | 
			
		||||
		strlcpy(Client->cloaked, Hostname, sizeof(Client->cloaked));
 | 
			
		||||
	LogDebug("Cloaked hostname of \"%s\" updated to \"%s\"",
 | 
			
		||||
		 Client_ID(Client), Client->cloaked);
 | 
			
		||||
 | 
			
		||||
	/* Inform other servers in the network */
 | 
			
		||||
	IRC_WriteStrServersPrefixFlag(Client_NextHop(Origin), Origin, 'M',
 | 
			
		||||
				      "METADATA %s cloakhost :%s",
 | 
			
		||||
				      Client_ID(Client), Client->cloaked);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GLOBAL char *
 | 
			
		||||
Client_Modes( CLIENT *Client )
 | 
			
		||||
@@ -768,7 +831,7 @@ Client_NextHop( CLIENT *Client )
 | 
			
		||||
 * Return ID of a client: "client!user@host"
 | 
			
		||||
 * This client ID is used for IRC prefixes, for example.
 | 
			
		||||
 * Please note that this function uses a global static buffer, so you can't
 | 
			
		||||
 * nest invocations without overwriting erlier results!
 | 
			
		||||
 * nest invocations without overwriting earlier results!
 | 
			
		||||
 * @param Client Pointer to client structure
 | 
			
		||||
 * @return Pointer to global buffer containing the client ID
 | 
			
		||||
 */
 | 
			
		||||
@@ -791,10 +854,12 @@ Client_Mask( CLIENT *Client )
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return ID of a client with cloaked hostname: "client!user@server-name"
 | 
			
		||||
 *
 | 
			
		||||
 * This client ID is used for IRC prefixes, for example.
 | 
			
		||||
 * Please note that this function uses a global static buffer, so you can't
 | 
			
		||||
 * nest invocations without overwriting erlier results!
 | 
			
		||||
 * nest invocations without overwriting earlier results!
 | 
			
		||||
 * If the client has not enabled cloaking, the real hostname is used.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client Pointer to client structure
 | 
			
		||||
 * @return Pointer to global buffer containing the client ID
 | 
			
		||||
 */
 | 
			
		||||
@@ -807,10 +872,11 @@ Client_MaskCloaked(CLIENT *Client)
 | 
			
		||||
 | 
			
		||||
	/* Is the client using cloaking at all? */
 | 
			
		||||
	if (!Client_HasMode(Client, 'x'))
 | 
			
		||||
	    return Client_Mask(Client);
 | 
			
		||||
		return Client_Mask(Client);
 | 
			
		||||
 | 
			
		||||
	snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user,
 | 
			
		||||
		 Client_HostnameDisplayed(Client));
 | 
			
		||||
 | 
			
		||||
	snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s",
 | 
			
		||||
		 Client->id, Client->user, Client_ID(Client->introducer));
 | 
			
		||||
	return Mask_Buffer;
 | 
			
		||||
} /* Client_MaskCloaked */
 | 
			
		||||
 | 
			
		||||
@@ -847,23 +913,47 @@ Client_Away( CLIENT *Client )
 | 
			
		||||
} /* Client_Away */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Make sure that a given nickname is valid.
 | 
			
		||||
 *
 | 
			
		||||
 * If the nickname is not valid for the given client, this function sends back
 | 
			
		||||
 * the appropriate error messages.
 | 
			
		||||
 *
 | 
			
		||||
 * @param	Client Client that wants to change the nickname.
 | 
			
		||||
 * @param	Nick New nickname.
 | 
			
		||||
 * @returns	true if nickname is valid, false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Client_CheckNick( CLIENT *Client, char *Nick )
 | 
			
		||||
Client_CheckNick(CLIENT *Client, char *Nick)
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Nick != NULL );
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Nick != NULL);
 | 
			
		||||
 | 
			
		||||
	if (! Client_IsValidNick( Nick ))
 | 
			
		||||
	{
 | 
			
		||||
		IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), Nick );
 | 
			
		||||
	if (!Client_IsValidNick(Nick)) {
 | 
			
		||||
		if (strlen(Nick ) >= Conf_MaxNickLength)
 | 
			
		||||
			IRC_WriteStrClient(Client, ERR_NICKNAMETOOLONG_MSG,
 | 
			
		||||
					   Client_ID(Client), Nick,
 | 
			
		||||
					   Conf_MaxNickLength - 1);
 | 
			
		||||
		else
 | 
			
		||||
			IRC_WriteStrClient(Client, ERR_ERRONEUSNICKNAME_MSG,
 | 
			
		||||
					   Client_ID(Client), Nick);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Nick bereits vergeben? */
 | 
			
		||||
	if( Client_Search( Nick ))
 | 
			
		||||
	{
 | 
			
		||||
		/* den Nick gibt es bereits */
 | 
			
		||||
		IRC_WriteStrClient( Client, ERR_NICKNAMEINUSE_MSG, Client_ID( Client ), Nick );
 | 
			
		||||
	if (Client_Type(Client) != CLIENT_SERVER
 | 
			
		||||
	    && Client_Type(Client) != CLIENT_SERVICE) {
 | 
			
		||||
		/* Make sure that this isn't a restricted/forbidden nickname */
 | 
			
		||||
		if (Conf_NickIsBlocked(Nick)) {
 | 
			
		||||
			IRC_WriteStrClient(Client, ERR_FORBIDDENNICKNAME_MSG,
 | 
			
		||||
					   Client_ID(Client), Nick);
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Nickname already registered? */
 | 
			
		||||
	if (Client_Search(Nick)) {
 | 
			
		||||
		IRC_WriteStrClient(Client, ERR_NICKNAMEINUSE_MSG,
 | 
			
		||||
			Client_ID(Client), Nick);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1019,23 +1109,31 @@ Client_MyMaxUserCount( void )
 | 
			
		||||
} /* Client_MyMaxUserCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check that a given nickname is valid.
 | 
			
		||||
 *
 | 
			
		||||
 * @param	Nick the nickname to check.
 | 
			
		||||
 * @returns	true if nickname is valid, false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Client_IsValidNick( const char *Nick )
 | 
			
		||||
Client_IsValidNick(const char *Nick)
 | 
			
		||||
{
 | 
			
		||||
	const char *ptr;
 | 
			
		||||
	static const char goodchars[] = ";0123456789-";
 | 
			
		||||
 | 
			
		||||
	assert( Nick != NULL );
 | 
			
		||||
	assert (Nick != NULL);
 | 
			
		||||
 | 
			
		||||
	if( Nick[0] == '#' ) return false;
 | 
			
		||||
	if( strchr( goodchars, Nick[0] )) return false;
 | 
			
		||||
	if( strlen( Nick ) >= Conf_MaxNickLength) return false;
 | 
			
		||||
	if (strchr(goodchars, Nick[0]))
 | 
			
		||||
		return false;
 | 
			
		||||
	if (strlen(Nick ) >= Conf_MaxNickLength)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	ptr = Nick;
 | 
			
		||||
	while( *ptr )
 | 
			
		||||
	{
 | 
			
		||||
		if (( *ptr < 'A' ) && ( ! strchr( goodchars, *ptr ))) return false;
 | 
			
		||||
		if ( *ptr > '}' ) return false;
 | 
			
		||||
	while (*ptr) {
 | 
			
		||||
		if (*ptr < 'A' && !strchr(goodchars, *ptr ))
 | 
			
		||||
			return false;
 | 
			
		||||
		if (*ptr > '}')
 | 
			
		||||
			return false;
 | 
			
		||||
		ptr++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -1075,6 +1173,79 @@ Client_StartTime(CLIENT *Client)
 | 
			
		||||
} /* Client_Uptime */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reject a client when logging in.
 | 
			
		||||
 *
 | 
			
		||||
 * This function is called when a client isn't allowed to connect to this
 | 
			
		||||
 * server. Possible reasons are bad server password, bad PAM password,
 | 
			
		||||
 * or that the client is G/K-Line'd.
 | 
			
		||||
 *
 | 
			
		||||
 * After calling this function, the client isn't connected any more.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client to reject.
 | 
			
		||||
 * @param Reason The reason why the client has been rejected.
 | 
			
		||||
 * @param InformClient If true, send the exact reason to the client.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Client_Reject(CLIENT *Client, const char *Reason, bool InformClient)
 | 
			
		||||
{
 | 
			
		||||
	char info[COMMAND_LEN];
 | 
			
		||||
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Reason != NULL);
 | 
			
		||||
 | 
			
		||||
	if (InformClient)
 | 
			
		||||
		snprintf(info, sizeof(info), "Access denied: %s", Reason);
 | 
			
		||||
	else
 | 
			
		||||
		strcpy(info, "Access denied: Bad password?");
 | 
			
		||||
 | 
			
		||||
	Log(LOG_ERR,
 | 
			
		||||
	    "User \"%s\" rejected (connection %d): %s!",
 | 
			
		||||
	    Client_Mask(Client), Client_Conn(Client), Reason);
 | 
			
		||||
	Conn_Close(Client_Conn(Client), Reason, info, true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Introduce a new user or service client in the network.
 | 
			
		||||
 *
 | 
			
		||||
 * @param From Remote server introducing the client or NULL (local).
 | 
			
		||||
 * @param Client New client.
 | 
			
		||||
 * @param Type Type of the client (CLIENT_USER or CLIENT_SERVICE).
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Client_Introduce(CLIENT *From, CLIENT *Client, int Type)
 | 
			
		||||
{
 | 
			
		||||
	/* Set client type (user or service) */
 | 
			
		||||
	Client_SetType(Client, Type);
 | 
			
		||||
 | 
			
		||||
	if (From) {
 | 
			
		||||
		if (Conf_NickIsService(Conf_GetServer(Client_Conn(From)),
 | 
			
		||||
				   Client_ID(Client)))
 | 
			
		||||
			Client_SetType(Client, CLIENT_SERVICE);
 | 
			
		||||
		LogDebug("%s \"%s\" (+%s) registered (via %s, on %s, %d hop%s).",
 | 
			
		||||
			 Client_TypeText(Client), Client_Mask(Client),
 | 
			
		||||
			 Client_Modes(Client), Client_ID(From),
 | 
			
		||||
			 Client_ID(Client_Introducer(Client)),
 | 
			
		||||
			 Client_Hops(Client), Client_Hops(Client) > 1 ? "s": "");
 | 
			
		||||
	} else {
 | 
			
		||||
		Log(LOG_NOTICE, "%s \"%s\" registered (connection %d).",
 | 
			
		||||
		    Client_TypeText(Client), Client_Mask(Client),
 | 
			
		||||
		    Client_Conn(Client));
 | 
			
		||||
		Log_ServerNotice('c', "Client connecting: %s (%s@%s) [%s] - %s",
 | 
			
		||||
			         Client_ID(Client), Client_User(Client),
 | 
			
		||||
				 Client_Hostname(Client),
 | 
			
		||||
				 Conn_IPA(Client_Conn(Client)),
 | 
			
		||||
				 Client_TypeText(Client));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Inform other servers */
 | 
			
		||||
	IRC_WriteStrServersPrefixFlag_CB(From,
 | 
			
		||||
				From != NULL ? From : Client_ThisServer(),
 | 
			
		||||
				'\0', cb_introduceClient, (void *)Client);
 | 
			
		||||
} /* Client_Introduce */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static unsigned long
 | 
			
		||||
Count( CLIENT_TYPE Type )
 | 
			
		||||
{
 | 
			
		||||
@@ -1213,7 +1384,7 @@ Client_RegisterWhowas( CLIENT *Client )
 | 
			
		||||
		 sizeof( My_Whowas[slot].id ));
 | 
			
		||||
	strlcpy( My_Whowas[slot].user, Client_User( Client ),
 | 
			
		||||
		 sizeof( My_Whowas[slot].user ));
 | 
			
		||||
	strlcpy( My_Whowas[slot].host, Client_HostnameCloaked( Client ),
 | 
			
		||||
	strlcpy( My_Whowas[slot].host, Client_HostnameDisplayed( Client ),
 | 
			
		||||
		 sizeof( My_Whowas[slot].host ));
 | 
			
		||||
	strlcpy( My_Whowas[slot].info, Client_Info( Client ),
 | 
			
		||||
		 sizeof( My_Whowas[slot].info ));
 | 
			
		||||
@@ -1294,6 +1465,59 @@ Destroy_UserOrService(CLIENT *Client, const char *Txt, const char *FwdMsg, bool
 | 
			
		||||
} /* Destroy_UserOrService */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Introduce a new user or service client to a remote server.
 | 
			
		||||
 *
 | 
			
		||||
 * This function differentiates between RFC1459 and RFC2813 server links and
 | 
			
		||||
 * generates the appropriate commands to register the new user or service.
 | 
			
		||||
 *
 | 
			
		||||
 * @param To		The remote server to inform.
 | 
			
		||||
 * @param Prefix	Prefix for the generated commands.
 | 
			
		||||
 * @param data		CLIENT structure of the new client.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
cb_introduceClient(CLIENT *To, CLIENT *Prefix, void *data)
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c = (CLIENT *)data;
 | 
			
		||||
	CONN_ID conn;
 | 
			
		||||
	char *modes, *user, *host;
 | 
			
		||||
 | 
			
		||||
	modes = Client_Modes(c);
 | 
			
		||||
	user = Client_User(c) ? Client_User(c) : "-";
 | 
			
		||||
	host = Client_Hostname(c) ? Client_Hostname(c) : "-";
 | 
			
		||||
 | 
			
		||||
	conn = Client_Conn(To);
 | 
			
		||||
	if (Conn_Options(conn) & CONN_RFC1459) {
 | 
			
		||||
		/* RFC 1459 mode: separate NICK and USER commands */
 | 
			
		||||
		Conn_WriteStr(conn, "NICK %s :%d", Client_ID(c),
 | 
			
		||||
			      Client_Hops(c) + 1);
 | 
			
		||||
		Conn_WriteStr(conn, ":%s USER %s %s %s :%s",
 | 
			
		||||
			      Client_ID(c), user, host,
 | 
			
		||||
			      Client_ID(Client_Introducer(c)), Client_Info(c));
 | 
			
		||||
		if (modes[0])
 | 
			
		||||
			Conn_WriteStr(conn, ":%s MODE %s +%s",
 | 
			
		||||
				      Client_ID(c), Client_ID(c), modes);
 | 
			
		||||
	} else {
 | 
			
		||||
		/* RFC 2813 mode: one combined NICK or SERVICE command */
 | 
			
		||||
		if (Client_Type(c) == CLIENT_SERVICE
 | 
			
		||||
		    && strchr(Client_Flags(To), 'S'))
 | 
			
		||||
			IRC_WriteStrClientPrefix(To, Prefix,
 | 
			
		||||
						 "SERVICE %s %d * +%s %d :%s",
 | 
			
		||||
						 Client_Mask(c),
 | 
			
		||||
						 Client_MyToken(Client_Introducer(c)),
 | 
			
		||||
						 Client_Modes(c), Client_Hops(c) + 1,
 | 
			
		||||
						 Client_Info(c));
 | 
			
		||||
		else
 | 
			
		||||
			IRC_WriteStrClientPrefix(To, Prefix,
 | 
			
		||||
						 "NICK %s %d %s %s %d +%s :%s",
 | 
			
		||||
						 Client_ID(c), Client_Hops(c) + 1,
 | 
			
		||||
						 user, host,
 | 
			
		||||
						 Client_MyToken(Client_Introducer(c)),
 | 
			
		||||
						 modes, Client_Info(c));
 | 
			
		||||
	}
 | 
			
		||||
} /* cb_introduceClient */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -29,12 +29,13 @@
 | 
			
		||||
#ifndef STRICT_RFC
 | 
			
		||||
# define CLIENT_WAITAUTHPING 512	/* waiting for AUTH PONG from client */
 | 
			
		||||
#endif
 | 
			
		||||
#define CLIENT_WAITCAPEND 1024		/* waiting for "CAP END" command */
 | 
			
		||||
 | 
			
		||||
#define CLIENT_TYPE int
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
 | 
			
		||||
#if defined(__client_c__) | defined(S_SPLINT_S)
 | 
			
		||||
#if defined(__client_c__) | defined(__client_cap_c__) | defined(S_SPLINT_S)
 | 
			
		||||
 | 
			
		||||
typedef struct _CLIENT
 | 
			
		||||
{
 | 
			
		||||
@@ -46,8 +47,8 @@ typedef struct _CLIENT
 | 
			
		||||
	CONN_ID conn_id;		/* ID of the connection (if local) or NONE (remote) */
 | 
			
		||||
	struct _CLIENT *introducer;	/* ID of the servers which the client is connected to */
 | 
			
		||||
	struct _CLIENT *topserver;	/* toplevel servers (only valid if client is a server) */
 | 
			
		||||
	char pwd[CLIENT_PASS_LEN];	/* password received of the client */
 | 
			
		||||
	char host[CLIENT_HOST_LEN];	/* hostname of the client */
 | 
			
		||||
	char cloaked[CLIENT_HOST_LEN];	/* cloaked hostname of the client */
 | 
			
		||||
	char user[CLIENT_USER_LEN];	/* user name ("login") */
 | 
			
		||||
#if defined(PAM) && defined(IDENTAUTH)
 | 
			
		||||
	char orig_user[CLIENT_USER_LEN];/* user name supplied by USER command */
 | 
			
		||||
@@ -58,6 +59,7 @@ typedef struct _CLIENT
 | 
			
		||||
	bool oper_by_me;		/* client is local IRC operator on this server? */
 | 
			
		||||
	char away[CLIENT_AWAY_LEN];	/* AWAY text (valid if mode 'a' is set) */
 | 
			
		||||
	char flags[CLIENT_FLAGS_LEN];	/* flags of the client */
 | 
			
		||||
	int capabilities;		/* enabled IRC capabilities */
 | 
			
		||||
} CLIENT;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
@@ -70,7 +72,7 @@ typedef POINTER CLIENT;
 | 
			
		||||
typedef struct _WHOWAS
 | 
			
		||||
{
 | 
			
		||||
	time_t time;			/* time stamp of entry or 0 if unused */
 | 
			
		||||
	char id[CLIENT_NICK_LEN];	/* client nick name */
 | 
			
		||||
	char id[CLIENT_NICK_LEN];	/* client nickname */
 | 
			
		||||
	char host[CLIENT_HOST_LEN];	/* hostname of the client */
 | 
			
		||||
	char user[CLIENT_USER_LEN];	/* user name ("login") */
 | 
			
		||||
	char info[CLIENT_INFO_LEN];	/* long user name */
 | 
			
		||||
@@ -106,8 +108,8 @@ GLOBAL char *Client_User PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL char *Client_OrigUser PARAMS(( CLIENT *Client ));
 | 
			
		||||
#endif
 | 
			
		||||
GLOBAL char *Client_Hostname PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL char *Client_HostnameCloaked PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL char *Client_Password PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL char *Client_HostnameCloaked PARAMS((CLIENT *Client));
 | 
			
		||||
GLOBAL char *Client_HostnameDisplayed PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL char *Client_Modes PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL char *Client_Flags PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CLIENT *Client_Introducer PARAMS(( CLIENT *Client ));
 | 
			
		||||
@@ -127,7 +129,6 @@ GLOBAL void Client_SetID PARAMS(( CLIENT *Client, const char *Nick ));
 | 
			
		||||
GLOBAL void Client_SetUser PARAMS(( CLIENT *Client, const char *User, bool Idented ));
 | 
			
		||||
GLOBAL void Client_SetOrigUser PARAMS(( CLIENT *Client, const char *User ));
 | 
			
		||||
GLOBAL void Client_SetInfo PARAMS(( CLIENT *Client, const char *Info ));
 | 
			
		||||
GLOBAL void Client_SetPassword PARAMS(( CLIENT *Client, const char *Pwd ));
 | 
			
		||||
GLOBAL void Client_SetType PARAMS(( CLIENT *Client, int Type ));
 | 
			
		||||
GLOBAL void Client_SetHops PARAMS(( CLIENT *Client, int Hops ));
 | 
			
		||||
GLOBAL void Client_SetToken PARAMS(( CLIENT *Client, int Token ));
 | 
			
		||||
@@ -163,6 +164,15 @@ GLOBAL void Client_RegisterWhowas PARAMS(( CLIENT *Client ));
 | 
			
		||||
 | 
			
		||||
GLOBAL const char *Client_TypeText PARAMS((CLIENT *Client));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Client_Reject PARAMS((CLIENT *Client, const char *Reason,
 | 
			
		||||
				  bool InformClient));
 | 
			
		||||
GLOBAL void Client_Introduce PARAMS((CLIENT *From, CLIENT *Client, int Type));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Client_UpdateCloakedHostname PARAMS((CLIENT *Client,
 | 
			
		||||
						 CLIENT *Originator,
 | 
			
		||||
						 const char *hostname));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
GLOBAL void Client_DebugDump PARAMS((void));
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -33,19 +33,15 @@ struct ConnSSL_State {
 | 
			
		||||
	SSL *ssl;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef HAVE_LIBGNUTLS
 | 
			
		||||
	gnutls_session gnutls_session;
 | 
			
		||||
	gnutls_session_t gnutls_session;
 | 
			
		||||
	void *cookie;		/* pointer to server configuration structure
 | 
			
		||||
				   (for outgoing connections), or NULL. */
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ConnSSL_InitLibrary(void);
 | 
			
		||||
#else
 | 
			
		||||
static inline bool
 | 
			
		||||
ConnSSL_InitLibrary(void)
 | 
			
		||||
{ return true; }
 | 
			
		||||
#endif /* SSL_SUPPORT */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
bool	ConnSSL_InitLibrary(void);
 | 
			
		||||
 | 
			
		||||
#endif /* conf_ssl_h */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -18,6 +18,7 @@
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
#	include <stdarg.h>
 | 
			
		||||
@@ -34,9 +35,6 @@
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_CTYPE_H
 | 
			
		||||
# include <ctype.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "array.h"
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
@@ -55,12 +53,10 @@ static bool Use_Log = true, Using_MotdFile = true;
 | 
			
		||||
static CONF_SERVER New_Server;
 | 
			
		||||
static int New_Server_Idx;
 | 
			
		||||
 | 
			
		||||
static size_t Conf_Oper_Count;
 | 
			
		||||
static size_t Conf_Channel_Count;
 | 
			
		||||
static char Conf_MotdFile[FNAME_LEN];
 | 
			
		||||
 | 
			
		||||
static void Set_Defaults PARAMS(( bool InitServers ));
 | 
			
		||||
static bool Read_Config PARAMS(( bool ngircd_starting ));
 | 
			
		||||
static bool Read_Config PARAMS(( bool TestOnly, bool IsStarting ));
 | 
			
		||||
static bool Validate_Config PARAMS(( bool TestOnly, bool Rehash ));
 | 
			
		||||
 | 
			
		||||
static void Handle_GLOBAL PARAMS(( int Line, char *Var, char *Arg ));
 | 
			
		||||
@@ -108,6 +104,8 @@ ConfSSL_Init(void)
 | 
			
		||||
	free(Conf_SSLOptions.DHFile);
 | 
			
		||||
	Conf_SSLOptions.DHFile = NULL;
 | 
			
		||||
	array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
 | 
			
		||||
 | 
			
		||||
	array_free(&Conf_SSLOptions.ListenPorts);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -208,7 +206,7 @@ ports_parse(array *a, int Line, char *Arg)
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conf_Init( void )
 | 
			
		||||
{
 | 
			
		||||
	Read_Config( true );
 | 
			
		||||
	Read_Config(false, true);
 | 
			
		||||
	Validate_Config(false, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -220,7 +218,7 @@ Conf_Init( void )
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Conf_Rehash( void )
 | 
			
		||||
{
 | 
			
		||||
	if (!Read_Config(false))
 | 
			
		||||
	if (!Read_Config(false, false))
 | 
			
		||||
		return false;
 | 
			
		||||
	Validate_Config(false, true);
 | 
			
		||||
 | 
			
		||||
@@ -265,18 +263,18 @@ static void
 | 
			
		||||
opers_puts(void)
 | 
			
		||||
{
 | 
			
		||||
	struct Conf_Oper *op;
 | 
			
		||||
	size_t len;
 | 
			
		||||
	size_t count, i;
 | 
			
		||||
 | 
			
		||||
	len = array_length(&Conf_Opers, sizeof(*op));
 | 
			
		||||
	count = array_length(&Conf_Opers, sizeof(*op));
 | 
			
		||||
	op = array_start(&Conf_Opers);
 | 
			
		||||
	while (len--) {
 | 
			
		||||
		assert(op->name[0]);
 | 
			
		||||
	for (i = 0; i < count; i++, op++) {
 | 
			
		||||
		if (!op->name[0])
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		puts("[OPERATOR]");
 | 
			
		||||
		printf("  Name = %s\n", op->name);
 | 
			
		||||
		printf("  Password = %s\n", op->pwd);
 | 
			
		||||
		printf("  Mask = %s\n\n", op->mask ? op->mask : "");
 | 
			
		||||
		op++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -301,7 +299,7 @@ Conf_Test( void )
 | 
			
		||||
 | 
			
		||||
	Use_Log = false;
 | 
			
		||||
 | 
			
		||||
	if (! Read_Config(true))
 | 
			
		||||
	if (!Read_Config(true, true))
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	config_valid = Validate_Config(true, false);
 | 
			
		||||
@@ -348,10 +346,11 @@ Conf_Test( void )
 | 
			
		||||
 | 
			
		||||
	puts("[LIMITS]");
 | 
			
		||||
	printf("  ConnectRetry = %d\n", Conf_ConnectRetry);
 | 
			
		||||
	printf("  MaxConnections = %ld\n", Conf_MaxConnections);
 | 
			
		||||
	printf("  MaxConnections = %d\n", Conf_MaxConnections);
 | 
			
		||||
	printf("  MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP);
 | 
			
		||||
	printf("  MaxJoins = %d\n", Conf_MaxJoins > 0 ? Conf_MaxJoins : -1);
 | 
			
		||||
	printf("  MaxNickLength = %u\n", Conf_MaxNickLength - 1);
 | 
			
		||||
	printf("  MaxListSize = %d\n", Conf_MaxListSize);
 | 
			
		||||
	printf("  PingTimeout = %d\n", Conf_PingTimeout);
 | 
			
		||||
	printf("  PongTimeout = %d\n", Conf_PongTimeout);
 | 
			
		||||
	puts("");
 | 
			
		||||
@@ -360,6 +359,8 @@ Conf_Test( void )
 | 
			
		||||
	printf("  AllowRemoteOper = %s\n", yesno_to_str(Conf_AllowRemoteOper));
 | 
			
		||||
	printf("  ChrootDir = %s\n", Conf_Chroot);
 | 
			
		||||
	printf("  CloakHost = %s\n", Conf_CloakHost);
 | 
			
		||||
	printf("  CloakHostModeX = %s\n", Conf_CloakHostModeX);
 | 
			
		||||
	printf("  CloakHostSalt = %s\n", Conf_CloakHostSalt);
 | 
			
		||||
	printf("  CloakUserToNick = %s\n", yesno_to_str(Conf_CloakUserToNick));
 | 
			
		||||
#ifdef WANT_IPV6
 | 
			
		||||
	printf("  ConnectIPv4 = %s\n", yesno_to_str(Conf_ConnectIPv6));
 | 
			
		||||
@@ -372,9 +373,11 @@ Conf_Test( void )
 | 
			
		||||
	printf("  MorePrivacy = %s\n", yesno_to_str(Conf_MorePrivacy));
 | 
			
		||||
	printf("  NoticeAuth = %s\n", yesno_to_str(Conf_NoticeAuth));
 | 
			
		||||
	printf("  OperCanUseMode = %s\n", yesno_to_str(Conf_OperCanMode));
 | 
			
		||||
	printf("  OperChanPAutoOp = %s\n", yesno_to_str(Conf_OperChanPAutoOp));
 | 
			
		||||
	printf("  OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode));
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
	printf("  PAM = %s\n", yesno_to_str(Conf_PAM));
 | 
			
		||||
	printf("  PAMIsOptional = %s\n", yesno_to_str(Conf_PAMIsOptional));
 | 
			
		||||
#endif
 | 
			
		||||
	printf("  PredefChannelsOnly = %s\n", yesno_to_str(Conf_PredefChannelsOnly));
 | 
			
		||||
#ifndef STRICT_RFC
 | 
			
		||||
@@ -478,8 +481,12 @@ Conf_UnsetServer( CONN_ID Idx )
 | 
			
		||||
				 * require the next attempt to be delayed. */
 | 
			
		||||
				Conf_Server[i].lasttry =
 | 
			
		||||
					t - Conf_ConnectRetry + RECONNECT_DELAY;
 | 
			
		||||
			} else
 | 
			
		||||
				Conf_Server[i].lasttry = t;
 | 
			
		||||
			} else {
 | 
			
		||||
				/* "Short" connection, enforce "ConnectRetry"
 | 
			
		||||
				 * but randomize it a little bit: 15 seconds. */
 | 
			
		||||
				Conf_Server[i].lasttry =
 | 
			
		||||
					t + rand() / (RAND_MAX / 15);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -487,13 +494,23 @@ Conf_UnsetServer( CONN_ID Idx )
 | 
			
		||||
/**
 | 
			
		||||
 * Set connection information for specified configured server.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Conf_SetServer( int ConfServer, CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	assert( ConfServer > NONE );
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
 | 
			
		||||
	if (Conf_Server[ConfServer].conn_id > NONE &&
 | 
			
		||||
	    Conf_Server[ConfServer].conn_id != Idx) {
 | 
			
		||||
		Log(LOG_ERR,
 | 
			
		||||
		    "Connection %d: Server configuration of \"%s\" already in use by connection %d!",
 | 
			
		||||
		    Idx, Conf_Server[ConfServer].name,
 | 
			
		||||
		    Conf_Server[ConfServer].conn_id);
 | 
			
		||||
		Conn_Close(Idx, NULL, "Server configuration already in use", true);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	Conf_Server[ConfServer].conn_id = Idx;
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -627,14 +644,41 @@ Conf_AddServer(const char *Name, UINT16 Port, const char *Host,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if the given nick name is an service.
 | 
			
		||||
 * Check if the given nickname is reserved for services on a particular server.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns true if the given nick name belongs to an "IRC service".
 | 
			
		||||
 * @param ConfServer The server index to check.
 | 
			
		||||
 * @param Nick The nickname to check.
 | 
			
		||||
 * @returns true if the given nickname belongs to an "IRC service".
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Conf_IsService(int ConfServer, const char *Nick)
 | 
			
		||||
Conf_NickIsService(int ConfServer, const char *Nick)
 | 
			
		||||
{
 | 
			
		||||
	return MatchCaseInsensitive(Conf_Server[ConfServer].svs_mask, Nick);
 | 
			
		||||
	assert (ConfServer >= 0);
 | 
			
		||||
	assert (ConfServer < MAX_SERVERS);
 | 
			
		||||
 | 
			
		||||
	return MatchCaseInsensitiveList(Conf_Server[ConfServer].svs_mask,
 | 
			
		||||
					Nick, ",");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if the given nickname is blocked for "normal client" use.
 | 
			
		||||
 *
 | 
			
		||||
 * @param ConfServer The server index or NONE to check all configured servers.
 | 
			
		||||
 * @param Nick The nickname to check.
 | 
			
		||||
 * @returns true if the given nickname belongs to an "IRC service".
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Conf_NickIsBlocked(const char *Nick)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for(i = 0; i < MAX_SERVERS; i++) {
 | 
			
		||||
		if (!Conf_Server[i].name[0])
 | 
			
		||||
			continue;
 | 
			
		||||
		if (Conf_NickIsService(i, Nick))
 | 
			
		||||
			return true;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -644,6 +688,7 @@ static void
 | 
			
		||||
Set_Defaults(bool InitServers)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	char random[RANDOM_SALT_LEN + 1];
 | 
			
		||||
 | 
			
		||||
	/* Global */
 | 
			
		||||
	strcpy(Conf_ServerName, "");
 | 
			
		||||
@@ -654,6 +699,7 @@ Set_Defaults(bool InitServers)
 | 
			
		||||
		 PACKAGE_NAME, PACKAGE_VERSION);
 | 
			
		||||
	free(Conf_ListenAddress);
 | 
			
		||||
	Conf_ListenAddress = NULL;
 | 
			
		||||
	array_free(&Conf_ListenPorts);
 | 
			
		||||
	array_free(&Conf_Motd);
 | 
			
		||||
	strlcpy(Conf_MotdFile, SYSCONFDIR, sizeof(Conf_MotdFile));
 | 
			
		||||
	strlcat(Conf_MotdFile, MOTD_FILE, sizeof(Conf_MotdFile));
 | 
			
		||||
@@ -667,6 +713,7 @@ Set_Defaults(bool InitServers)
 | 
			
		||||
	Conf_MaxConnectionsIP = 5;
 | 
			
		||||
	Conf_MaxJoins = 10;
 | 
			
		||||
	Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
 | 
			
		||||
	Conf_MaxListSize = 100;
 | 
			
		||||
	Conf_PingTimeout = 120;
 | 
			
		||||
	Conf_PongTimeout = 20;
 | 
			
		||||
 | 
			
		||||
@@ -677,6 +724,9 @@ Set_Defaults(bool InitServers)
 | 
			
		||||
#endif
 | 
			
		||||
	strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot));
 | 
			
		||||
	strcpy(Conf_CloakHost, "");
 | 
			
		||||
	strcpy(Conf_CloakHostModeX, "");
 | 
			
		||||
	strlcpy(Conf_CloakHostSalt, ngt_RandomStr(random, RANDOM_SALT_LEN),
 | 
			
		||||
		sizeof(Conf_CloakHostSalt));
 | 
			
		||||
	Conf_CloakUserToNick = false;
 | 
			
		||||
	Conf_ConnectIPv4 = true;
 | 
			
		||||
#ifdef WANT_IPV6
 | 
			
		||||
@@ -693,12 +743,14 @@ Set_Defaults(bool InitServers)
 | 
			
		||||
	Conf_MorePrivacy = false;
 | 
			
		||||
	Conf_NoticeAuth = false;
 | 
			
		||||
	Conf_OperCanMode = false;
 | 
			
		||||
	Conf_OperChanPAutoOp = true;
 | 
			
		||||
	Conf_OperServerMode = false;
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
	Conf_PAM = true;
 | 
			
		||||
#else
 | 
			
		||||
	Conf_PAM = false;
 | 
			
		||||
#endif
 | 
			
		||||
	Conf_PAMIsOptional = false;
 | 
			
		||||
	Conf_PredefChannelsOnly = false;
 | 
			
		||||
#ifdef SYSLOG
 | 
			
		||||
	Conf_ScrubCTCP = false;
 | 
			
		||||
@@ -709,10 +761,6 @@ Set_Defaults(bool InitServers)
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Initialize IRC operators and channels */
 | 
			
		||||
	Conf_Oper_Count = 0;
 | 
			
		||||
	Conf_Channel_Count = 0;
 | 
			
		||||
 | 
			
		||||
	/* Initialize server configuration structures */
 | 
			
		||||
	if (InitServers) {
 | 
			
		||||
		for (i = 0; i < MAX_SERVERS;
 | 
			
		||||
@@ -782,11 +830,12 @@ Read_Motd(const char *filename)
 | 
			
		||||
 *				successfully; false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
static bool
 | 
			
		||||
Read_Config( bool ngircd_starting )
 | 
			
		||||
Read_Config(bool TestOnly, bool IsStarting)
 | 
			
		||||
{
 | 
			
		||||
	char section[LINE_LEN], str[LINE_LEN], *var, *arg, *ptr;
 | 
			
		||||
	const UINT16 defaultport = 6667;
 | 
			
		||||
	int line, i, n;
 | 
			
		||||
	size_t count;
 | 
			
		||||
	FILE *fd;
 | 
			
		||||
 | 
			
		||||
	/* Open configuration file */
 | 
			
		||||
@@ -795,16 +844,19 @@ Read_Config( bool ngircd_starting )
 | 
			
		||||
		/* No configuration file found! */
 | 
			
		||||
		Config_Error( LOG_ALERT, "Can't read configuration \"%s\": %s",
 | 
			
		||||
					NGIRCd_ConfFile, strerror( errno ));
 | 
			
		||||
		if (!ngircd_starting)
 | 
			
		||||
		if (!IsStarting)
 | 
			
		||||
			return false;
 | 
			
		||||
		Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME );
 | 
			
		||||
		exit( 1 );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	opers_free();
 | 
			
		||||
	Set_Defaults( ngircd_starting );
 | 
			
		||||
	Set_Defaults(IsStarting);
 | 
			
		||||
 | 
			
		||||
	Config_Error( LOG_INFO, "Reading configuration from \"%s\" ...", NGIRCd_ConfFile );
 | 
			
		||||
	if (TestOnly)
 | 
			
		||||
		Config_Error(LOG_INFO,
 | 
			
		||||
			     "Reading configuration from \"%s\" ...",
 | 
			
		||||
			     NGIRCd_ConfFile );
 | 
			
		||||
 | 
			
		||||
	/* Clean up server configuration structure: mark all already
 | 
			
		||||
	 * configured servers as "once" so that they are deleted
 | 
			
		||||
@@ -857,10 +909,13 @@ Read_Config( bool ngircd_starting )
 | 
			
		||||
		/* Is this the beginning of a new section? */
 | 
			
		||||
		if(( str[0] == '[' ) && ( str[strlen( str ) - 1] == ']' )) {
 | 
			
		||||
			strlcpy( section, str, sizeof( section ));
 | 
			
		||||
			if (strcasecmp(section, "[GLOBAL]") == 0 ||
 | 
			
		||||
			    strcasecmp(section, "[LIMITS]") == 0 ||
 | 
			
		||||
			    strcasecmp(section, "[OPTIONS]") == 0 ||
 | 
			
		||||
			    strcasecmp(section, "[SSL]") == 0)
 | 
			
		||||
			if (strcasecmp(section, "[GLOBAL]") == 0
 | 
			
		||||
			    || strcasecmp(section, "[LIMITS]") == 0
 | 
			
		||||
			    || strcasecmp(section, "[OPTIONS]") == 0
 | 
			
		||||
#ifdef SSL_SUPPORT
 | 
			
		||||
			    || strcasecmp(section, "[SSL]") == 0
 | 
			
		||||
#endif
 | 
			
		||||
			    )
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			if( strcasecmp( section, "[SERVER]" ) == 0 ) {
 | 
			
		||||
@@ -887,12 +942,30 @@ Read_Config( bool ngircd_starting )
 | 
			
		||||
				else New_Server_Idx = i;
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (strcasecmp(section, "[CHANNEL]") == 0) {
 | 
			
		||||
				Conf_Channel_Count++;
 | 
			
		||||
				count = array_length(&Conf_Channels,
 | 
			
		||||
						     sizeof(struct Conf_Channel));
 | 
			
		||||
				if (!array_alloc(&Conf_Channels,
 | 
			
		||||
						 sizeof(struct Conf_Channel),
 | 
			
		||||
						 count)) {
 | 
			
		||||
					Config_Error(LOG_ERR,
 | 
			
		||||
						     "Could not allocate memory for new operator (line %d)",
 | 
			
		||||
						     line);
 | 
			
		||||
				}
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (strcasecmp(section, "[OPERATOR]") == 0) {
 | 
			
		||||
				Conf_Oper_Count++;
 | 
			
		||||
				count = array_length(&Conf_Opers,
 | 
			
		||||
						     sizeof(struct Conf_Oper));
 | 
			
		||||
				if (!array_alloc(&Conf_Opers,
 | 
			
		||||
						 sizeof(struct Conf_Oper),
 | 
			
		||||
						 count)) {
 | 
			
		||||
					Config_Error(LOG_ERR,
 | 
			
		||||
						     "Could not allocate memory for new channel (line &d)",
 | 
			
		||||
						     line);
 | 
			
		||||
				}
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@@ -978,17 +1051,21 @@ Read_Config( bool ngircd_starting )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check whether an string argument is true or false.
 | 
			
		||||
 * Check whether a string argument is "true" or "false".
 | 
			
		||||
 *
 | 
			
		||||
 * @param Arg	Input string.
 | 
			
		||||
 * @returns	true if string has been parsed as "yes"/"true"/"on".
 | 
			
		||||
 * @returns	true if the input string has been parsed as "yes", "true"
 | 
			
		||||
 *		(case insensitive) or a non-zero integer value.
 | 
			
		||||
 */
 | 
			
		||||
static bool
 | 
			
		||||
Check_ArgIsTrue( const char *Arg )
 | 
			
		||||
Check_ArgIsTrue(const char *Arg)
 | 
			
		||||
{
 | 
			
		||||
	if( strcasecmp( Arg, "yes" ) == 0 ) return true;
 | 
			
		||||
	if( strcasecmp( Arg, "true" ) == 0 ) return true;
 | 
			
		||||
	if( atoi( Arg ) != 0 ) return true;
 | 
			
		||||
	if (strcasecmp(Arg, "yes") == 0)
 | 
			
		||||
		return true;
 | 
			
		||||
	if (strcasecmp(Arg, "true") == 0)
 | 
			
		||||
		return true;
 | 
			
		||||
	if (atoi(Arg) != 0)
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
@@ -998,7 +1075,7 @@ Check_ArgIsTrue( const char *Arg )
 | 
			
		||||
 *
 | 
			
		||||
 * @param Line	Line number in configuration file.
 | 
			
		||||
 * @raram Arg	Input string.
 | 
			
		||||
 * @returns	New configured maximum nick name length.
 | 
			
		||||
 * @returns	New configured maximum nickname length.
 | 
			
		||||
 */
 | 
			
		||||
static unsigned int
 | 
			
		||||
Handle_MaxNickLength(int Line, const char *Arg)
 | 
			
		||||
@@ -1115,6 +1192,7 @@ CheckLegacyGlobalOption(int Line, char *Var, char *Arg)
 | 
			
		||||
	    || strcasecmp(Var, "ConnectIPv4") == 0
 | 
			
		||||
	    || strcasecmp(Var, "ConnectIPv6") == 0
 | 
			
		||||
	    || strcasecmp(Var, "OperCanUseMode") == 0
 | 
			
		||||
	    || strcasecmp(Var, "OperChanPAutoOp") == 0
 | 
			
		||||
	    || strcasecmp(Var, "OperServerMode") == 0
 | 
			
		||||
	    || strcasecmp(Var, "PredefChannelsOnly") == 0
 | 
			
		||||
	    || strcasecmp(Var, "SyslogFacility") == 0
 | 
			
		||||
@@ -1289,7 +1367,9 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 | 
			
		||||
		else {
 | 
			
		||||
			Conf_GID = (unsigned int)atoi(Arg);
 | 
			
		||||
			if (!Conf_GID && strcmp(Arg, "0"))
 | 
			
		||||
				Config_Error_NaN(Line, Var);
 | 
			
		||||
				Config_Error(LOG_WARNING,
 | 
			
		||||
					     "%s, line %d: Value of \"%s\" is not a valid group name or ID!",
 | 
			
		||||
					     NGIRCd_ConfFile, Line, Var);
 | 
			
		||||
		}
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
@@ -1300,7 +1380,9 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 | 
			
		||||
		else {
 | 
			
		||||
			Conf_UID = (unsigned int)atoi(Arg);
 | 
			
		||||
			if (!Conf_UID && strcmp(Arg, "0"))
 | 
			
		||||
				Config_Error_NaN(Line, Var);
 | 
			
		||||
				Config_Error(LOG_WARNING,
 | 
			
		||||
					     "%s, line %d: Value of \"%s\" is not a valid user name or ID!",
 | 
			
		||||
					     NGIRCd_ConfFile, Line, Var);
 | 
			
		||||
		}
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
@@ -1363,7 +1445,7 @@ Handle_LIMITS(int Line, char *Var, char *Arg)
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (strcasecmp(Var, "MaxConnections") == 0) {
 | 
			
		||||
		Conf_MaxConnections = atol(Arg);
 | 
			
		||||
		Conf_MaxConnections = atoi(Arg);
 | 
			
		||||
		if (!Conf_MaxConnections && strcmp(Arg, "0"))
 | 
			
		||||
			Config_Error_NaN(Line, Var);
 | 
			
		||||
		return;
 | 
			
		||||
@@ -1384,6 +1466,12 @@ Handle_LIMITS(int Line, char *Var, char *Arg)
 | 
			
		||||
		Conf_MaxNickLength = Handle_MaxNickLength(Line, Arg);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (strcasecmp(Var, "MaxListSize") == 0) {
 | 
			
		||||
		Conf_MaxListSize = atoi(Arg);
 | 
			
		||||
		if (!Conf_MaxListSize && strcmp(Arg, "0"))
 | 
			
		||||
			Config_Error_NaN(Line, Var);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (strcasecmp(Var, "PingTimeout") == 0) {
 | 
			
		||||
		Conf_PingTimeout = atoi(Arg);
 | 
			
		||||
		if (Conf_PingTimeout < 5) {
 | 
			
		||||
@@ -1440,6 +1528,18 @@ Handle_OPTIONS(int Line, char *Var, char *Arg)
 | 
			
		||||
			Config_Error_TooLong(Line, Var);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (strcasecmp(Var, "CloakHostModeX") == 0) {
 | 
			
		||||
		len = strlcpy(Conf_CloakHostModeX, Arg, sizeof(Conf_CloakHostModeX));
 | 
			
		||||
		if (len >= sizeof(Conf_CloakHostModeX))
 | 
			
		||||
			Config_Error_TooLong(Line, Var);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (strcasecmp(Var, "CloakHostSalt") == 0) {
 | 
			
		||||
		len = strlcpy(Conf_CloakHostSalt, Arg, sizeof(Conf_CloakHostSalt));
 | 
			
		||||
		if (len >= sizeof(Conf_CloakHostSalt))
 | 
			
		||||
			Config_Error_TooLong(Line, Var);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (strcasecmp(Var, "CloakUserToNick") == 0) {
 | 
			
		||||
		Conf_CloakUserToNick = Check_ArgIsTrue(Arg);
 | 
			
		||||
		return;
 | 
			
		||||
@@ -1474,6 +1574,10 @@ Handle_OPTIONS(int Line, char *Var, char *Arg)
 | 
			
		||||
		Conf_OperCanMode = Check_ArgIsTrue(Arg);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (strcasecmp(Var, "OperChanPAutoOp") == 0) {
 | 
			
		||||
		Conf_OperChanPAutoOp = Check_ArgIsTrue(Arg);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (strcasecmp(Var, "OperServerMode") == 0) {
 | 
			
		||||
		Conf_OperServerMode = Check_ArgIsTrue(Arg);
 | 
			
		||||
		return;
 | 
			
		||||
@@ -1483,6 +1587,10 @@ Handle_OPTIONS(int Line, char *Var, char *Arg)
 | 
			
		||||
		WarnPAM(Line);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (strcasecmp(Var, "PAMIsOptional") == 0 ) {
 | 
			
		||||
		Conf_PAMIsOptional = Check_ArgIsTrue(Arg);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	if (strcasecmp(Var, "PredefChannelsOnly") == 0) {
 | 
			
		||||
		Conf_PredefChannelsOnly = Check_ArgIsTrue(Arg);
 | 
			
		||||
		return;
 | 
			
		||||
@@ -1580,13 +1688,11 @@ Handle_OPERATOR( int Line, char *Var, char *Arg )
 | 
			
		||||
	assert( Line > 0 );
 | 
			
		||||
	assert( Var != NULL );
 | 
			
		||||
	assert( Arg != NULL );
 | 
			
		||||
	assert( Conf_Oper_Count > 0 );
 | 
			
		||||
 | 
			
		||||
	op = array_alloc(&Conf_Opers, sizeof(*op), Conf_Oper_Count - 1);
 | 
			
		||||
	if (!op) {
 | 
			
		||||
		Config_Error(LOG_ERR, "Could not allocate memory for operator (%d:%s = %s)", Line, Var, Arg);
 | 
			
		||||
	op = array_get(&Conf_Opers, sizeof(*op),
 | 
			
		||||
			 array_length(&Conf_Opers, sizeof(*op)) - 1);
 | 
			
		||||
	if (!op)
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (strcasecmp(Var, "Name") == 0) {
 | 
			
		||||
		/* Name of IRC operator */
 | 
			
		||||
@@ -1752,21 +1858,17 @@ static void
 | 
			
		||||
Handle_CHANNEL(int Line, char *Var, char *Arg)
 | 
			
		||||
{
 | 
			
		||||
	size_t len;
 | 
			
		||||
	size_t chancount;
 | 
			
		||||
	struct Conf_Channel *chan;
 | 
			
		||||
 | 
			
		||||
	assert( Line > 0 );
 | 
			
		||||
	assert( Var != NULL );
 | 
			
		||||
	assert( Arg != NULL );
 | 
			
		||||
	assert(Conf_Channel_Count > 0);
 | 
			
		||||
 | 
			
		||||
	chancount = Conf_Channel_Count - 1;
 | 
			
		||||
 | 
			
		||||
	chan = array_alloc(&Conf_Channels, sizeof(*chan), chancount);
 | 
			
		||||
	if (!chan) {
 | 
			
		||||
		Config_Error(LOG_ERR, "Could not allocate memory for predefined channel (%d:%s = %s)", Line, Var, Arg);
 | 
			
		||||
	chan = array_get(&Conf_Channels, sizeof(*chan),
 | 
			
		||||
			 array_length(&Conf_Channels, sizeof(*chan)) - 1);
 | 
			
		||||
	if (!chan)
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (strcasecmp(Var, "Name") == 0) {
 | 
			
		||||
		if (!Handle_Channelname(chan, Arg))
 | 
			
		||||
			Config_Error_TooLong(Line, Var);
 | 
			
		||||
@@ -1832,6 +1934,13 @@ Validate_Config(bool Configtest, bool Rehash)
 | 
			
		||||
	bool config_valid = true;
 | 
			
		||||
	char *ptr;
 | 
			
		||||
 | 
			
		||||
	/* Emit a warning when the config file is not a full path name */
 | 
			
		||||
	if (NGIRCd_ConfFile[0] && NGIRCd_ConfFile[0] != '/') {
 | 
			
		||||
		Config_Error(LOG_WARNING,
 | 
			
		||||
			"Not specifying a full path name to \"%s\" can cause problems when rehashing the server!",
 | 
			
		||||
			NGIRCd_ConfFile);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Validate configured server name, see RFC 2812 section 2.3.1 */
 | 
			
		||||
	ptr = Conf_ServerName;
 | 
			
		||||
	do {
 | 
			
		||||
@@ -1913,8 +2022,10 @@ Validate_Config(bool Configtest, bool Rehash)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	Log(LOG_DEBUG,
 | 
			
		||||
	    "Configuration: Operators=%d, Servers=%d[%d], Channels=%d",
 | 
			
		||||
	    Conf_Oper_Count, servers, servers_once, Conf_Channel_Count);
 | 
			
		||||
	    "Configuration: Operators=%ld, Servers=%d[%d], Channels=%ld",
 | 
			
		||||
	    array_length(&Conf_Opers, sizeof(struct Conf_Oper)),
 | 
			
		||||
	    servers, servers_once,
 | 
			
		||||
	    array_length(&Conf_Channels, sizeof(struct Conf_Channel)));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return config_valid;
 | 
			
		||||
@@ -2044,7 +2155,7 @@ Init_Server_Struct( CONF_SERVER *Server )
 | 
			
		||||
 | 
			
		||||
	Proc_InitStruct(&Server->res_stat);
 | 
			
		||||
	Server->conn_id = NONE;
 | 
			
		||||
	memset(&Server->bind_addr, 0, sizeof(&Server->bind_addr));
 | 
			
		||||
	memset(&Server->bind_addr, 0, sizeof(Server->bind_addr));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -62,7 +62,7 @@ typedef struct _Conf_Server
 | 
			
		||||
#ifdef SSL_SUPPORT
 | 
			
		||||
	bool SSLConnect;		/**< Establish connection using SSL? */
 | 
			
		||||
#endif
 | 
			
		||||
	char svs_mask[CLIENT_ID_LEN];	/**< Mask of nick names that should be
 | 
			
		||||
	char svs_mask[CLIENT_ID_LEN];	/**< Mask of nicknames that should be
 | 
			
		||||
					     treated and counted as services */
 | 
			
		||||
} CONF_SERVER;
 | 
			
		||||
 | 
			
		||||
@@ -151,10 +151,13 @@ GLOBAL bool Conf_PredefChannelsOnly;
 | 
			
		||||
/** Flag indicating if IRC operators are allowed to always use MODE (true) */
 | 
			
		||||
GLOBAL bool Conf_OperCanMode;
 | 
			
		||||
 | 
			
		||||
/** Flag indicating if IRC operators get AutoOp in persistent (+P) channels */
 | 
			
		||||
GLOBAL bool Conf_OperChanPAutoOp;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * If true, mask channel MODE commands of IRC operators to the server.
 | 
			
		||||
 * Background: ircd2 will ignore channel MODE commands if an IRC operator
 | 
			
		||||
 * gives chanel operator privileges to someone without being a channel operator
 | 
			
		||||
 * gives channel operator privileges to someone without being a channel operator
 | 
			
		||||
 * himself. This enables a workaround: it masks the MODE command as coming
 | 
			
		||||
 * from the IRC server and not the IRC operator.
 | 
			
		||||
 */
 | 
			
		||||
@@ -166,7 +169,13 @@ GLOBAL bool Conf_AllowRemoteOper;
 | 
			
		||||
/** Cloaked hostname of the clients */
 | 
			
		||||
GLOBAL char Conf_CloakHost[CLIENT_ID_LEN];
 | 
			
		||||
 | 
			
		||||
/** Use nick name as user name? */
 | 
			
		||||
/** Cloaked hostname for clients that did +x */
 | 
			
		||||
GLOBAL char Conf_CloakHostModeX[CLIENT_ID_LEN];
 | 
			
		||||
 | 
			
		||||
/** Salt for hostname hash for cloaked hostnames */
 | 
			
		||||
GLOBAL char Conf_CloakHostSalt[CLIENT_ID_LEN];
 | 
			
		||||
 | 
			
		||||
/** Use nickname as user name? */
 | 
			
		||||
GLOBAL bool Conf_CloakUserToNick;
 | 
			
		||||
 | 
			
		||||
/** Enable all DNS functions? */
 | 
			
		||||
@@ -184,6 +193,9 @@ GLOBAL bool Conf_NoticeAuth;
 | 
			
		||||
/** Enable all usage of PAM, even when compiled with support for it */
 | 
			
		||||
GLOBAL bool Conf_PAM;
 | 
			
		||||
 | 
			
		||||
/** Don't require all clients to send a password an to be PAM authenticated */
 | 
			
		||||
GLOBAL bool Conf_PAMIsOptional;
 | 
			
		||||
 | 
			
		||||
/** Disable all CTCP commands except for /me ? */
 | 
			
		||||
GLOBAL bool Conf_ScrubCTCP;
 | 
			
		||||
 | 
			
		||||
@@ -197,7 +209,7 @@ GLOBAL bool Conf_ConnectIPv6;
 | 
			
		||||
GLOBAL bool Conf_ConnectIPv4;
 | 
			
		||||
 | 
			
		||||
/** Maximum number of simultaneous connections to this server */
 | 
			
		||||
GLOBAL long Conf_MaxConnections;
 | 
			
		||||
GLOBAL int Conf_MaxConnections;
 | 
			
		||||
 | 
			
		||||
/** Maximum number of channels a user can join */
 | 
			
		||||
GLOBAL int Conf_MaxJoins;
 | 
			
		||||
@@ -205,9 +217,12 @@ GLOBAL int Conf_MaxJoins;
 | 
			
		||||
/** Maximum number of connections per IP address */
 | 
			
		||||
GLOBAL int Conf_MaxConnectionsIP;
 | 
			
		||||
 | 
			
		||||
/** Maximum length of a nick name */
 | 
			
		||||
/** Maximum length of a nickname */
 | 
			
		||||
GLOBAL unsigned int Conf_MaxNickLength;
 | 
			
		||||
 | 
			
		||||
/** Maximum number of channels returned to /list */
 | 
			
		||||
GLOBAL int Conf_MaxListSize;
 | 
			
		||||
 | 
			
		||||
#ifndef STRICT_RFC
 | 
			
		||||
 | 
			
		||||
/** Require "AUTH PING-PONG" on login */
 | 
			
		||||
@@ -227,7 +242,7 @@ GLOBAL bool Conf_Rehash PARAMS((void));
 | 
			
		||||
GLOBAL int Conf_Test PARAMS((void));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Conf_UnsetServer PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL void Conf_SetServer PARAMS(( int ConfServer, CONN_ID Idx ));
 | 
			
		||||
GLOBAL bool Conf_SetServer PARAMS(( int ConfServer, CONN_ID Idx ));
 | 
			
		||||
GLOBAL int Conf_GetServer PARAMS(( CONN_ID Idx ));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Conf_EnableServer PARAMS(( const char *Name, UINT16 Port ));
 | 
			
		||||
@@ -235,7 +250,8 @@ GLOBAL bool Conf_EnablePassiveServer PARAMS((const char *Name));
 | 
			
		||||
GLOBAL bool Conf_DisableServer PARAMS(( const char *Name ));
 | 
			
		||||
GLOBAL bool Conf_AddServer PARAMS(( const char *Name, UINT16 Port, const char *Host, const char *MyPwd, const char *PeerPwd ));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Conf_IsService PARAMS((int ConfServer, const char *Nick));
 | 
			
		||||
GLOBAL bool Conf_NickIsService PARAMS((int ConfServer, const char *Nick));
 | 
			
		||||
GLOBAL bool Conf_NickIsBlocked PARAMS((const char *Nick));
 | 
			
		||||
 | 
			
		||||
/* Password required by WEBIRC command */
 | 
			
		||||
GLOBAL char Conf_WebircPwd[CLIENT_PASS_LEN];
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										192
									
								
								src/ngircd/conn-encoding.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								src/ngircd/conn-encoding.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,192 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define __conn_encoding_c__
 | 
			
		||||
 | 
			
		||||
#define CONN_MODULE
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Functions to deal with character encodings and conversions
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "conn-encoding.h"
 | 
			
		||||
 | 
			
		||||
#ifdef ICONV
 | 
			
		||||
 | 
			
		||||
char Encoding_Buffer[COMMAND_LEN];
 | 
			
		||||
 | 
			
		||||
char *Convert_Message PARAMS((iconv_t Handle, char *Message));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set client character encoding on a connection.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Conn Connection identifier.
 | 
			
		||||
 * @param ClientEnc Client encoding (for example "ASCII", "MacRoman", ...).
 | 
			
		||||
 * @return true on success, false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Conn_SetEncoding(CONN_ID Conn, const char *ClientEnc)
 | 
			
		||||
{
 | 
			
		||||
	char client_enc[25], server_enc[25];
 | 
			
		||||
 | 
			
		||||
	assert(Conn > NONE);
 | 
			
		||||
	assert(ClientEnc != NULL);
 | 
			
		||||
 | 
			
		||||
	Conn_UnsetEncoding(Conn);
 | 
			
		||||
 | 
			
		||||
	/* Is the client character set identical to server character set? */
 | 
			
		||||
	if (strcasecmp(ClientEnc, "UTF-8") == 0)
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	snprintf(client_enc, sizeof(client_enc), "%s//TRANSLIT", ClientEnc);
 | 
			
		||||
	snprintf(server_enc, sizeof(server_enc), "%s//TRANSLIT", "UTF-8");
 | 
			
		||||
 | 
			
		||||
	My_Connections[Conn].iconv_from = iconv_open(server_enc, client_enc);
 | 
			
		||||
	if (My_Connections[Conn].iconv_from == (iconv_t)(-1)) {
 | 
			
		||||
		Conn_UnsetEncoding(Conn);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	My_Connections[Conn].iconv_to = iconv_open(client_enc, server_enc);
 | 
			
		||||
	if (My_Connections[Conn].iconv_to == (iconv_t)(-1)) {
 | 
			
		||||
		Conn_UnsetEncoding(Conn);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	LogDebug("Set client character set of connection \"%d\" to \"%s\".",
 | 
			
		||||
		 Conn, client_enc);
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Remove client character encoding conversion on a connection.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Conn Connection identifier.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_UnsetEncoding(CONN_ID Conn)
 | 
			
		||||
{
 | 
			
		||||
	assert(Conn > NONE);
 | 
			
		||||
 | 
			
		||||
	if (My_Connections[Conn].iconv_from != (iconv_t)(-1))
 | 
			
		||||
		iconv_close(My_Connections[Conn].iconv_from);
 | 
			
		||||
	if (My_Connections[Conn].iconv_to != (iconv_t)(-1))
 | 
			
		||||
		iconv_close(My_Connections[Conn].iconv_to);
 | 
			
		||||
 | 
			
		||||
	My_Connections[Conn].iconv_from = (iconv_t)(-1);
 | 
			
		||||
	My_Connections[Conn].iconv_to = (iconv_t)(-1);
 | 
			
		||||
 | 
			
		||||
	LogDebug("Unset character conversion of connection %d.", Conn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convert the encoding of a given message.
 | 
			
		||||
 *
 | 
			
		||||
 * This function uses a static buffer for the result of the encoding
 | 
			
		||||
 * conversion which is overwritten by subsequent calls to this function!
 | 
			
		||||
 *
 | 
			
		||||
 * @param Handle libiconv handle.
 | 
			
		||||
 * @param Message The message to convert.
 | 
			
		||||
 * @return Pointer to the result.
 | 
			
		||||
 */
 | 
			
		||||
char *
 | 
			
		||||
Convert_Message(iconv_t Handle, char *Message)
 | 
			
		||||
{
 | 
			
		||||
	size_t in_left, out_left;
 | 
			
		||||
	char *out = Encoding_Buffer;
 | 
			
		||||
 | 
			
		||||
	assert (Handle != (iconv_t)(-1));
 | 
			
		||||
	assert (Message != NULL);
 | 
			
		||||
 | 
			
		||||
	in_left = strlen(Message);
 | 
			
		||||
	out_left = sizeof(Encoding_Buffer) - 1;
 | 
			
		||||
 | 
			
		||||
	if (iconv(Handle, &Message, &in_left, &out, &out_left) == (size_t)(-1)) {
 | 
			
		||||
		/* An error occured! */
 | 
			
		||||
		LogDebug("Error converting message encoding!");
 | 
			
		||||
		strlcpy(Encoding_Buffer, Message, sizeof(Encoding_Buffer));
 | 
			
		||||
		iconv(Handle, NULL, NULL, NULL, NULL);
 | 
			
		||||
	} else
 | 
			
		||||
		*out = '\0';
 | 
			
		||||
 | 
			
		||||
	return Encoding_Buffer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convert encoding of a message received from a connection.
 | 
			
		||||
 *
 | 
			
		||||
 * Note 1: If no conversion is required, this function returns the original
 | 
			
		||||
 * pointer to the message.
 | 
			
		||||
 *
 | 
			
		||||
 * Note 2: This function uses Convert_Message(), so subsequent calls to this
 | 
			
		||||
 * function will overwrite the earlier results.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Conn Connection identifier.
 | 
			
		||||
 * @param Message The message to convert.
 | 
			
		||||
 * @return Pointer to the result.
 | 
			
		||||
 * @see Convert_Message
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL char *
 | 
			
		||||
Conn_EncodingFrom(UNUSED CONN_ID Conn, char *Message)
 | 
			
		||||
{
 | 
			
		||||
	assert(Conn > NONE);
 | 
			
		||||
	assert (Message != NULL);
 | 
			
		||||
 | 
			
		||||
#ifdef ICONV
 | 
			
		||||
	if (My_Connections[Conn].iconv_from != (iconv_t)(-1))
 | 
			
		||||
		return Convert_Message(My_Connections[Conn].iconv_from, Message);
 | 
			
		||||
#endif
 | 
			
		||||
	return Message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convert encoding of a message for sending on a connection.
 | 
			
		||||
 *
 | 
			
		||||
 * Note 1: If no conversion is required, this function returns the original
 | 
			
		||||
 * pointer to the message.
 | 
			
		||||
 *
 | 
			
		||||
 * Note 2: This function uses Convert_Message(), so subsequent calls to this
 | 
			
		||||
 * function will overwrite the earlier results.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Conn Connection identifier.
 | 
			
		||||
 * @param Message The message to convert.
 | 
			
		||||
 * @return Pointer to the result.
 | 
			
		||||
 * @see Convert_Message
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL char *
 | 
			
		||||
Conn_EncodingTo(UNUSED CONN_ID Conn, char *Message)
 | 
			
		||||
{
 | 
			
		||||
	assert(Conn > NONE);
 | 
			
		||||
	assert (Message != NULL);
 | 
			
		||||
 | 
			
		||||
#ifdef ICONV
 | 
			
		||||
	if (My_Connections[Conn].iconv_to != (iconv_t)(-1))
 | 
			
		||||
		return Convert_Message(My_Connections[Conn].iconv_to, Message);
 | 
			
		||||
#endif
 | 
			
		||||
	return Message;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										30
									
								
								src/ngircd/conn-encoding.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/ngircd/conn-encoding.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __conn_encoding_h__
 | 
			
		||||
#define __conn_encoding_h__
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Functions to deal with character encodings and conversions (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifdef ICONV
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Conn_SetEncoding PARAMS((CONN_ID Idx, const char *ClientEnc));
 | 
			
		||||
GLOBAL void Conn_UnsetEncoding PARAMS((CONN_ID Idx));
 | 
			
		||||
 | 
			
		||||
#endif /* ICONV */
 | 
			
		||||
 | 
			
		||||
GLOBAL char* Conn_EncodingFrom PARAMS((CONN_ID Idx, char *Message));
 | 
			
		||||
GLOBAL char* Conn_EncodingTo PARAMS((CONN_ID Idx, char *Message));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -30,13 +30,30 @@
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Update "idle timestamp", the time of the last visible user action
 | 
			
		||||
 * (e. g. like sending messages, joining or leaving channels).
 | 
			
		||||
 *
 | 
			
		||||
 * @param Idx Connection index.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_UpdateIdle( CONN_ID Idx )
 | 
			
		||||
Conn_UpdateIdle(CONN_ID Idx)
 | 
			
		||||
{
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	My_Connections[Idx].lastprivmsg = time( NULL );
 | 
			
		||||
	assert(Idx > NONE);
 | 
			
		||||
	My_Connections[Idx].lastprivmsg = time(NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Update "ping timestamp", the time of the last outgoing PING request.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Idx Connection index.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_UpdatePing(CONN_ID Idx)
 | 
			
		||||
{
 | 
			
		||||
	assert(Idx > NONE);
 | 
			
		||||
	My_Connections[Idx].lastping = time(NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Get signon time of a connection.
 | 
			
		||||
@@ -65,35 +82,56 @@ Conn_LastPing( CONN_ID Idx )
 | 
			
		||||
} /* Conn_LastPing */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Add "penalty time" for a connection.
 | 
			
		||||
 *
 | 
			
		||||
 * During the "penalty time" the socket is ignored completely, no new data
 | 
			
		||||
 * is read. This function only increases the penalty, it is not possible to
 | 
			
		||||
 * decrease the penalty time.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Idex Connection index.
 | 
			
		||||
 * @param Seconds Seconds to add.
 | 
			
		||||
 * @see Conn_ResetPenalty
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_SetPenalty( CONN_ID Idx, time_t Seconds )
 | 
			
		||||
Conn_SetPenalty(CONN_ID Idx, time_t Seconds)
 | 
			
		||||
{
 | 
			
		||||
	/* set Penalty-Delay for a socket.
 | 
			
		||||
	 * during the penalty, the socket is ignored completely, no new
 | 
			
		||||
	 * data is read. This function only increases the penalty, it is
 | 
			
		||||
	 * not possible to decrease the penalty time.
 | 
			
		||||
	 */
 | 
			
		||||
	time_t t;
 | 
			
		||||
	
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	assert( Seconds >= 0 );
 | 
			
		||||
 | 
			
		||||
	t = time( NULL ) + Seconds;
 | 
			
		||||
	if (t > My_Connections[Idx].delaytime)
 | 
			
		||||
	assert(Idx > NONE);
 | 
			
		||||
	assert(Seconds >= 0);
 | 
			
		||||
 | 
			
		||||
	t = time(NULL);
 | 
			
		||||
	if (My_Connections[Idx].delaytime < t)
 | 
			
		||||
		My_Connections[Idx].delaytime = t;
 | 
			
		||||
 | 
			
		||||
	My_Connections[Idx].delaytime += Seconds;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	Log(LOG_DEBUG, "Add penalty time on connection %d: %ld second(s).",
 | 
			
		||||
			Idx, (long)Seconds);
 | 
			
		||||
	Log(LOG_DEBUG,
 | 
			
		||||
	    "Add penalty time on connection %d: %ld second%s, total %ld second%s.",
 | 
			
		||||
	    Idx, (long)Seconds, Seconds != 1 ? "s" : "",
 | 
			
		||||
	    My_Connections[Idx].delaytime - t,
 | 
			
		||||
	    My_Connections[Idx].delaytime - t != 1 ? "s" : "");
 | 
			
		||||
#endif
 | 
			
		||||
} /* Conn_SetPenalty */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reset the "penalty time" for one connection.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Idx Connection index.
 | 
			
		||||
 * @see Conn_SetPenalty
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_ResetPenalty( CONN_ID Idx )
 | 
			
		||||
Conn_ResetPenalty(CONN_ID Idx)
 | 
			
		||||
{
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	assert(Idx > NONE);
 | 
			
		||||
 | 
			
		||||
	My_Connections[Idx].delaytime = 0;
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	Log(LOG_DEBUG, "Penalty time on connection %d has been reset.");
 | 
			
		||||
#endif
 | 
			
		||||
} /* Conn_ResetPenalty */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,9 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void Conn_UpdateIdle PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL void Conn_UpdateIdle PARAMS((CONN_ID Idx));
 | 
			
		||||
GLOBAL void Conn_UpdatePing 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 ));
 | 
			
		||||
 
 | 
			
		||||
@@ -156,7 +156,7 @@ Load_DH_params(void)
 | 
			
		||||
	bool ret = true;
 | 
			
		||||
 | 
			
		||||
	if (!Conf_SSLOptions.DHFile) {
 | 
			
		||||
		Log(LOG_NOTICE, "Configuration option \"SSLDHFile\" not set!");
 | 
			
		||||
		Log(LOG_NOTICE, "Configuration option \"DHFile\" not set!");
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	fp = fopen(Conf_SSLOptions.DHFile, "r");
 | 
			
		||||
@@ -201,7 +201,7 @@ Load_DH_params(void)
 | 
			
		||||
	}
 | 
			
		||||
	if (need_dhgenerate) {
 | 
			
		||||
		Log(LOG_WARNING,
 | 
			
		||||
		    "SSLDHFile not set, generating %u bit DH parameters. This may take a while ...",
 | 
			
		||||
		    "DHFile not set, generating %u bit DH parameters. This may take a while ...",
 | 
			
		||||
		    DH_BITS);
 | 
			
		||||
		err = gnutls_dh_params_generate2(tmp_dh_params, DH_BITS);
 | 
			
		||||
		if (err < 0) {
 | 
			
		||||
@@ -241,6 +241,9 @@ void ConnSSL_Free(CONNECTION *c)
 | 
			
		||||
bool
 | 
			
		||||
ConnSSL_InitLibrary( void )
 | 
			
		||||
{
 | 
			
		||||
	if (!array_bytes(&Conf_SSLOptions.ListenPorts))
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_LIBSSL
 | 
			
		||||
	SSL_CTX *newctx;
 | 
			
		||||
 | 
			
		||||
@@ -256,12 +259,14 @@ ConnSSL_InitLibrary( void )
 | 
			
		||||
		 * According to OpenSSL RAND_egd(3): "The automatic query of /var/run/egd-pool et al was added in OpenSSL 0.9.7";
 | 
			
		||||
		 * so it makes little sense to deal with PRNGD seeding ourselves.
 | 
			
		||||
		 */
 | 
			
		||||
		array_free(&Conf_SSLOptions.ListenPorts);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	newctx = SSL_CTX_new(SSLv23_method());
 | 
			
		||||
	if (!newctx) {
 | 
			
		||||
		LogOpenSSLError("SSL_CTX_new()", NULL);
 | 
			
		||||
		array_free(&Conf_SSLOptions.ListenPorts);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -276,6 +281,7 @@ ConnSSL_InitLibrary( void )
 | 
			
		||||
	return true;
 | 
			
		||||
out:
 | 
			
		||||
	SSL_CTX_free(newctx);
 | 
			
		||||
	array_free(&Conf_SSLOptions.ListenPorts);
 | 
			
		||||
	return false;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef HAVE_LIBGNUTLS
 | 
			
		||||
@@ -287,10 +293,13 @@ out:
 | 
			
		||||
	err = gnutls_global_init();
 | 
			
		||||
	if (err) {
 | 
			
		||||
		Log(LOG_ERR, "gnutls_global_init(): %s", gnutls_strerror(err));
 | 
			
		||||
		array_free(&Conf_SSLOptions.ListenPorts);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	if (!ConnSSL_LoadServerKey_gnutls())
 | 
			
		||||
	if (!ConnSSL_LoadServerKey_gnutls()) {
 | 
			
		||||
		array_free(&Conf_SSLOptions.ListenPorts);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	Log(LOG_INFO, "gnutls %s initialized.", gnutls_check_version(NULL));
 | 
			
		||||
	initialized = true;
 | 
			
		||||
	return true;
 | 
			
		||||
@@ -313,7 +322,7 @@ ConnSSL_LoadServerKey_gnutls(void)
 | 
			
		||||
 | 
			
		||||
	cert_file = Conf_SSLOptions.CertFile ? Conf_SSLOptions.CertFile:Conf_SSLOptions.KeyFile;
 | 
			
		||||
	if (!cert_file) {
 | 
			
		||||
		Log(LOG_NOTICE, "No SSL server key configured, SSL disabled.");
 | 
			
		||||
		Log(LOG_ERR, "No SSL server key configured!");
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -344,7 +353,7 @@ ConnSSL_LoadServerKey_openssl(SSL_CTX *ctx)
 | 
			
		||||
 | 
			
		||||
	assert(ctx);
 | 
			
		||||
	if (!Conf_SSLOptions.KeyFile) {
 | 
			
		||||
		Log(LOG_NOTICE, "No SSL server key configured, SSL disabled.");
 | 
			
		||||
		Log(LOG_ERR, "No SSL server key configured!");
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -549,17 +558,18 @@ ConnSSL_LogCertInfo( CONNECTION *c )
 | 
			
		||||
 | 
			
		||||
	assert(ssl);
 | 
			
		||||
 | 
			
		||||
	Log(LOG_INFO, "New %s connection using cipher %s on socket %d.",
 | 
			
		||||
		SSL_get_version(ssl), SSL_get_cipher(ssl), c->sock);
 | 
			
		||||
	Log(LOG_INFO, "Connection %d: initialized %s using cipher %s.",
 | 
			
		||||
		c->sock, SSL_get_version(ssl), SSL_get_cipher(ssl));
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef HAVE_LIBGNUTLS
 | 
			
		||||
	gnutls_session_t sess = c->ssl_state.gnutls_session;
 | 
			
		||||
	gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(sess);
 | 
			
		||||
 | 
			
		||||
	Log(LOG_INFO, "New %s connection using cipher %s-%s on socket %d.",
 | 
			
		||||
	Log(LOG_INFO, "Connection %d: initialized %s using cipher %s-%s.",
 | 
			
		||||
	    c->sock,
 | 
			
		||||
	    gnutls_protocol_get_name(gnutls_protocol_get_version(sess)),
 | 
			
		||||
	    gnutls_cipher_get_name(cipher),
 | 
			
		||||
	    gnutls_mac_get_name(gnutls_mac_get(sess)), c->sock);
 | 
			
		||||
	    gnutls_mac_get_name(gnutls_mac_get(sess)));
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -624,6 +634,8 @@ ConnectAccept( CONNECTION *c, bool connect)
 | 
			
		||||
#endif /* _GNUTLS */
 | 
			
		||||
	Conn_OPTION_DEL(c, (CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ|CONN_SSL_CONNECT));
 | 
			
		||||
	ConnSSL_LogCertInfo(c);
 | 
			
		||||
 | 
			
		||||
	Conn_StartLogin(CONNECTION2ID(c));
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -711,6 +723,13 @@ ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len)
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
ConnSSL_InitLibrary(void)
 | 
			
		||||
{
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* SSL_SUPPORT */
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -9,6 +9,8 @@
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#undef DEBUG_BUFFER
 | 
			
		||||
 | 
			
		||||
#define CONN_MODULE
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
@@ -45,10 +47,6 @@
 | 
			
		||||
# include <netinet/ip.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_STDINT_H
 | 
			
		||||
# include <stdint.h>			/* e.g. for Mac OS X */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef TCPWRAP
 | 
			
		||||
# include <tcpd.h>			/* for TCP Wrappers */
 | 
			
		||||
#endif
 | 
			
		||||
@@ -63,7 +61,9 @@
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "array.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "class.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "conn-encoding.h"
 | 
			
		||||
#include "conn-ssl.h"
 | 
			
		||||
#include "conn-zip.h"
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
@@ -79,13 +79,13 @@
 | 
			
		||||
#define SERVER_WAIT (NONE - 1)
 | 
			
		||||
 | 
			
		||||
#define MAX_COMMANDS 3
 | 
			
		||||
#define MAX_COMMANDS_SERVER 10
 | 
			
		||||
#define MAX_COMMANDS_SERVICE MAX_COMMANDS_SERVER
 | 
			
		||||
#define MAX_COMMANDS_SERVER_MIN 10
 | 
			
		||||
#define MAX_COMMANDS_SERVICE 10
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
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 int New_Connection PARAMS(( int Sock, bool IsSSL ));
 | 
			
		||||
static CONN_ID Socket2Index PARAMS(( int Sock ));
 | 
			
		||||
static void Read_Request PARAMS(( CONN_ID Idx ));
 | 
			
		||||
static unsigned int Handle_Buffer PARAMS(( CONN_ID Idx ));
 | 
			
		||||
@@ -131,7 +131,7 @@ static void
 | 
			
		||||
cb_listen(int sock, short irrelevant)
 | 
			
		||||
{
 | 
			
		||||
	(void) irrelevant;
 | 
			
		||||
	(void) New_Connection(sock);
 | 
			
		||||
	(void) New_Connection(sock, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -149,7 +149,7 @@ cb_listen_ssl(int sock, short irrelevant)
 | 
			
		||||
	int fd;
 | 
			
		||||
 | 
			
		||||
	(void) irrelevant;
 | 
			
		||||
	fd = New_Connection(sock);
 | 
			
		||||
	fd = New_Connection(sock, true);
 | 
			
		||||
	if (fd < 0)
 | 
			
		||||
		return;
 | 
			
		||||
	io_event_setcb(My_Connections[fd].sock, cb_clientserver_ssl);
 | 
			
		||||
@@ -367,7 +367,7 @@ cb_clientserver_ssl(int sock, short what)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialite connecion module.
 | 
			
		||||
 * Initialize connecion module.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_Init( void )
 | 
			
		||||
@@ -433,12 +433,13 @@ Conn_Exit( void )
 | 
			
		||||
 * they don't hold connections open that the main process wants to close.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_CloseAllSockets(void)
 | 
			
		||||
Conn_CloseAllSockets(int ExceptOf)
 | 
			
		||||
{
 | 
			
		||||
	CONN_ID idx;
 | 
			
		||||
 | 
			
		||||
	for(idx = 0; idx < Pool_Size; idx++) {
 | 
			
		||||
		if(My_Connections[idx].sock > NONE)
 | 
			
		||||
		if(My_Connections[idx].sock > NONE &&
 | 
			
		||||
		   My_Connections[idx].sock != ExceptOf)
 | 
			
		||||
			close(My_Connections[idx].sock);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -739,6 +740,9 @@ Conn_Handler(void)
 | 
			
		||||
		Check_Servers();
 | 
			
		||||
		Check_Connections();
 | 
			
		||||
 | 
			
		||||
		/* Expire outdated class/list items */
 | 
			
		||||
		Class_Expire();
 | 
			
		||||
 | 
			
		||||
		/* Look for non-empty read buffers ... */
 | 
			
		||||
		for (i = 0; i < Pool_Size; i++) {
 | 
			
		||||
			if ((My_Connections[i].sock > NONE)
 | 
			
		||||
@@ -858,6 +862,9 @@ va_dcl
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	char buffer[COMMAND_LEN];
 | 
			
		||||
#ifdef ICONV
 | 
			
		||||
	char *ptr, *message;
 | 
			
		||||
#endif
 | 
			
		||||
	size_t len;
 | 
			
		||||
	bool ok;
 | 
			
		||||
	va_list ap;
 | 
			
		||||
@@ -898,6 +905,16 @@ va_dcl
 | 
			
		||||
			CUT_TXTSUFFIX);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef ICONV
 | 
			
		||||
	ptr = strchr(buffer + 1, ':');
 | 
			
		||||
	if (ptr) {
 | 
			
		||||
		ptr++;
 | 
			
		||||
		message = Conn_EncodingTo(Idx, ptr);
 | 
			
		||||
		if (message != ptr)
 | 
			
		||||
			strlcpy(ptr, message, sizeof(buffer) - (ptr - buffer));
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef SNIFFER
 | 
			
		||||
	if (NGIRCd_Sniffer)
 | 
			
		||||
		Log(LOG_DEBUG, " -> connection %d: '%s'.", Idx, buffer);
 | 
			
		||||
@@ -911,6 +928,30 @@ va_dcl
 | 
			
		||||
	return ok;
 | 
			
		||||
} /* Conn_WriteStr */
 | 
			
		||||
 | 
			
		||||
GLOBAL char*
 | 
			
		||||
Conn_Password( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	if (My_Connections[Idx].pwd == NULL)
 | 
			
		||||
		return (char*)"\0";
 | 
			
		||||
	else
 | 
			
		||||
		return My_Connections[Idx].pwd;
 | 
			
		||||
} /* Conn_Password */
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_SetPassword( CONN_ID Idx, const char *Pwd )
 | 
			
		||||
{
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
 | 
			
		||||
	if (My_Connections[Idx].pwd)
 | 
			
		||||
		free(My_Connections[Idx].pwd);
 | 
			
		||||
 | 
			
		||||
	My_Connections[Idx].pwd = strdup(Pwd);
 | 
			
		||||
	if (My_Connections[Idx].pwd == NULL) {
 | 
			
		||||
		Log(LOG_EMERG, "Can't allocate memory! [Conn_SetPassword]");
 | 
			
		||||
		exit(1);
 | 
			
		||||
	}
 | 
			
		||||
} /* Conn_SetPassword */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Append Data to the outbound write buffer of a connection.
 | 
			
		||||
@@ -929,22 +970,25 @@ Conn_Write( CONN_ID Idx, char *Data, size_t Len )
 | 
			
		||||
	assert( Data != NULL );
 | 
			
		||||
	assert( Len > 0 );
 | 
			
		||||
 | 
			
		||||
	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 ) {
 | 
			
		||||
	if (My_Connections[Idx].sock <= NONE) {
 | 
			
		||||
		LogDebug("Skipped write on closed socket (connection %d).", Idx);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Make sure that there still exists a CLIENT structure associated
 | 
			
		||||
	 * with this connection and check if this is a server or not: */
 | 
			
		||||
	c = Conn_GetClient(Idx);
 | 
			
		||||
	if (c) {
 | 
			
		||||
		/* 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;
 | 
			
		||||
	} else
 | 
			
		||||
		LogDebug("Write on socket without client (connection %d)!?", Idx);
 | 
			
		||||
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
	if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_ZIP )) {
 | 
			
		||||
		/* Compressed link:
 | 
			
		||||
@@ -1007,7 +1051,7 @@ Conn_Write( CONN_ID Idx, char *Data, size_t Len )
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient )
 | 
			
		||||
{
 | 
			
		||||
	/* Close connection. Open pipes of asyncronous resolver
 | 
			
		||||
	/* Close connection. Open pipes of asynchronous resolver
 | 
			
		||||
	 * sub-processes are closed down. */
 | 
			
		||||
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
@@ -1136,6 +1180,8 @@ Conn_Close( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClie
 | 
			
		||||
 | 
			
		||||
	array_free(&My_Connections[Idx].rbuf);
 | 
			
		||||
	array_free(&My_Connections[Idx].wbuf);
 | 
			
		||||
	if (My_Connections[Idx].pwd != NULL)
 | 
			
		||||
		free(My_Connections[Idx].pwd);
 | 
			
		||||
 | 
			
		||||
	/* Clean up connection structure (=free it) */
 | 
			
		||||
	Init_Conn_Struct( Idx );
 | 
			
		||||
@@ -1216,6 +1262,20 @@ Conn_SyncServerStruct(void)
 | 
			
		||||
} /* SyncServerStruct */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get IP address string of a connection.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Idx Connection index.
 | 
			
		||||
 * @return Pointer to a global buffer containing the IP address as string.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL const char *
 | 
			
		||||
Conn_GetIPAInfo(CONN_ID Idx)
 | 
			
		||||
{
 | 
			
		||||
	assert(Idx > NONE);
 | 
			
		||||
	return ng_ipaddr_tostr(&My_Connections[Idx].addr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Send out data of write buffer; connect new sockets.
 | 
			
		||||
 *
 | 
			
		||||
@@ -1255,9 +1315,11 @@ Handle_Write( CONN_ID Idx )
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_BUFFER
 | 
			
		||||
	LogDebug
 | 
			
		||||
	    ("Handle_Write() called for connection %d, %ld bytes pending ...",
 | 
			
		||||
	     Idx, wdatalen);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef SSL_SUPPORT
 | 
			
		||||
	if ( Conn_OPTION_ISSET( &My_Connections[Idx], CONN_SSL )) {
 | 
			
		||||
@@ -1310,22 +1372,25 @@ Count_Connections(ng_ipaddr_t *a)
 | 
			
		||||
 * Initialize new client connection on a listening socket.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Sock	Listening socket descriptor.
 | 
			
		||||
 * @param IsSSL	true if this socket expects SSL-encrypted data.
 | 
			
		||||
 * @returns	Accepted socket descriptor or -1 on error.
 | 
			
		||||
 */
 | 
			
		||||
static int
 | 
			
		||||
New_Connection(int Sock)
 | 
			
		||||
New_Connection(int Sock, UNUSED bool IsSSL)
 | 
			
		||||
{
 | 
			
		||||
#ifdef TCPWRAP
 | 
			
		||||
	struct request_info req;
 | 
			
		||||
#endif
 | 
			
		||||
	ng_ipaddr_t new_addr;
 | 
			
		||||
	char ip_str[NG_INET_ADDRSTRLEN];
 | 
			
		||||
	int new_sock, new_sock_len, identsock;
 | 
			
		||||
	int new_sock, new_sock_len;
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	long cnt;
 | 
			
		||||
 | 
			
		||||
	assert(Sock > NONE);
 | 
			
		||||
 | 
			
		||||
	LogDebug("Accepting new connection on socket %d ...", Sock);
 | 
			
		||||
 | 
			
		||||
	new_sock_len = (int)sizeof(new_addr);
 | 
			
		||||
	new_sock = accept(Sock, (struct sockaddr *)&new_addr,
 | 
			
		||||
			  (socklen_t *)&new_sock_len);
 | 
			
		||||
@@ -1410,7 +1475,7 @@ New_Connection(int Sock)
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c = Client_NewLocal(new_sock, ip_str, CLIENT_UNKNOWN, false);
 | 
			
		||||
	c = Client_NewLocal(new_sock, NULL, CLIENT_UNKNOWN, false);
 | 
			
		||||
	if (!c) {
 | 
			
		||||
		Log(LOG_ALERT,
 | 
			
		||||
		    "Can't accept connection: can't create client structure!");
 | 
			
		||||
@@ -1438,32 +1503,58 @@ New_Connection(int Sock)
 | 
			
		||||
	Log(LOG_INFO, "Accepted connection %d from %s:%d on socket %d.",
 | 
			
		||||
	    new_sock, My_Connections[new_sock].host,
 | 
			
		||||
	    ng_ipaddr_getport(&new_addr), Sock);
 | 
			
		||||
 | 
			
		||||
	identsock = new_sock;
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
	if (!Conf_Ident)
 | 
			
		||||
		identsock = -1;
 | 
			
		||||
#endif
 | 
			
		||||
	if (Conf_DNS) {
 | 
			
		||||
		if (Conf_NoticeAuth) {
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
			if (Conf_Ident)
 | 
			
		||||
				(void)Conn_WriteStr(new_sock,
 | 
			
		||||
					"NOTICE AUTH :*** Looking up your hostname and checking ident");
 | 
			
		||||
			else
 | 
			
		||||
#endif
 | 
			
		||||
				(void)Conn_WriteStr(new_sock,
 | 
			
		||||
					"NOTICE AUTH :*** Looking up your hostname");
 | 
			
		||||
		}
 | 
			
		||||
		Resolve_Addr(&My_Connections[new_sock].proc_stat, &new_addr,
 | 
			
		||||
			     identsock, cb_Read_Resolver_Result);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Account_Connection();
 | 
			
		||||
 | 
			
		||||
#ifdef SSL_SUPPORT
 | 
			
		||||
	/* Delay connection initalization until SSL handshake is finished */
 | 
			
		||||
	if (!IsSSL)
 | 
			
		||||
#endif
 | 
			
		||||
		Conn_StartLogin(new_sock);
 | 
			
		||||
 | 
			
		||||
	return new_sock;
 | 
			
		||||
} /* New_Connection */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Finish connection initialization, start resolver subprocess.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Idx Connection index.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Conn_StartLogin(CONN_ID Idx)
 | 
			
		||||
{
 | 
			
		||||
	int ident_sock = -1;
 | 
			
		||||
 | 
			
		||||
	assert(Idx >= 0);
 | 
			
		||||
 | 
			
		||||
	/* Nothing to do if DNS (and resolver subprocess) is disabled */
 | 
			
		||||
	if (!Conf_DNS)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
	/* Should we make an IDENT request? */
 | 
			
		||||
	if (Conf_Ident)
 | 
			
		||||
		ident_sock = My_Connections[Idx].sock;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (Conf_NoticeAuth) {
 | 
			
		||||
		/* Send "NOTICE AUTH" messages to the client */
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
		if (Conf_Ident)
 | 
			
		||||
			(void)Conn_WriteStr(Idx,
 | 
			
		||||
				"NOTICE AUTH :*** Looking up your hostname and checking ident");
 | 
			
		||||
		else
 | 
			
		||||
#endif
 | 
			
		||||
			(void)Conn_WriteStr(Idx,
 | 
			
		||||
				"NOTICE AUTH :*** Looking up your hostname");
 | 
			
		||||
		(void)Handle_Write(Idx);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Resolve_Addr(&My_Connections[Idx].proc_stat, &My_Connections[Idx].addr,
 | 
			
		||||
		     ident_sock, cb_Read_Resolver_Result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Update global connection counters.
 | 
			
		||||
 */
 | 
			
		||||
@@ -1561,7 +1652,7 @@ Read_Request( CONN_ID Idx )
 | 
			
		||||
		if (!array_catb(&My_Connections[Idx].zip.rbuf, readbuf,
 | 
			
		||||
				(size_t) len)) {
 | 
			
		||||
			Log(LOG_ERR,
 | 
			
		||||
			    "Could not append recieved data to zip input buffer (connn %d): %d bytes!",
 | 
			
		||||
			    "Could not append received data to zip input buffer (connection %d): %d bytes!",
 | 
			
		||||
			    Idx, len);
 | 
			
		||||
			Conn_Close(Idx, "Receive buffer space exhausted", NULL,
 | 
			
		||||
				   false);
 | 
			
		||||
@@ -1571,7 +1662,9 @@ Read_Request( CONN_ID Idx )
 | 
			
		||||
#endif
 | 
			
		||||
	{
 | 
			
		||||
		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 );
 | 
			
		||||
			Log(LOG_ERR,
 | 
			
		||||
			    "Could not append received data to input buffer (connection %d): %d bytes!",
 | 
			
		||||
			    Idx, len);
 | 
			
		||||
			Conn_Close(Idx, "Receive buffer space exhausted", NULL, false );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -1644,16 +1737,15 @@ Handle_Buffer(CONN_ID Idx)
 | 
			
		||||
 | 
			
		||||
	assert(c != NULL);
 | 
			
		||||
 | 
			
		||||
	/* Servers do get special command limits, so they can process
 | 
			
		||||
	 * all the messages that are required while peering. */
 | 
			
		||||
	/* Servers get special command limits that depend on the user count */
 | 
			
		||||
	switch (Client_Type(c)) {
 | 
			
		||||
	    case CLIENT_SERVER:
 | 
			
		||||
		/* Allow servers to send more commands in the first 10 secods
 | 
			
		||||
		maxcmd = (int)(Client_UserCount() / 5)
 | 
			
		||||
		       + MAX_COMMANDS_SERVER_MIN;
 | 
			
		||||
		/* Allow servers to handle even more commands while peering
 | 
			
		||||
		 * to speed up server login and network synchronisation. */
 | 
			
		||||
		if (starttime - Client_StartTime(c) < 10)
 | 
			
		||||
			maxcmd = MAX_COMMANDS_SERVER * 5;
 | 
			
		||||
		else
 | 
			
		||||
			maxcmd = MAX_COMMANDS_SERVER;
 | 
			
		||||
		if (Conn_LastPing(Idx) == 0)
 | 
			
		||||
			maxcmd *= 5;
 | 
			
		||||
		break;
 | 
			
		||||
	    case CLIENT_SERVICE:
 | 
			
		||||
		maxcmd = MAX_COMMANDS_SERVICE; break;
 | 
			
		||||
@@ -1753,8 +1845,10 @@ Handle_Buffer(CONN_ID Idx)
 | 
			
		||||
			return 0; /* error -> connection has been closed */
 | 
			
		||||
 | 
			
		||||
		array_moveleft(&My_Connections[Idx].rbuf, 1, len);
 | 
			
		||||
#ifdef DEBUG_BUFFER
 | 
			
		||||
		LogDebug("Connection %d: %d bytes left in read buffer.",
 | 
			
		||||
			 Idx, array_bytes(&My_Connections[Idx].rbuf));
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
		if ((!old_z) && (My_Connections[Idx].options & CONN_ZIP) &&
 | 
			
		||||
		    (array_bytes(&My_Connections[Idx].rbuf) > 0)) {
 | 
			
		||||
@@ -1808,17 +1902,17 @@ Check_Connections(void)
 | 
			
		||||
				if (My_Connections[i].lastping <
 | 
			
		||||
				    time(NULL) - Conf_PongTimeout) {
 | 
			
		||||
					/* Timeout */
 | 
			
		||||
					LogDebug
 | 
			
		||||
					    ("Connection %d: Ping timeout: %d seconds.",
 | 
			
		||||
					     i, Conf_PongTimeout);
 | 
			
		||||
					snprintf(msg, sizeof(msg), "Ping timeout: %d seconds", Conf_PongTimeout);
 | 
			
		||||
					snprintf(msg, sizeof(msg),
 | 
			
		||||
						 "Ping timeout: %d seconds",
 | 
			
		||||
						 Conf_PongTimeout);
 | 
			
		||||
					LogDebug("Connection %d: %s.", i, msg);
 | 
			
		||||
					Conn_Close(i, NULL, msg, true);
 | 
			
		||||
				}
 | 
			
		||||
			} else if (My_Connections[i].lastdata <
 | 
			
		||||
				   time(NULL) - Conf_PingTimeout) {
 | 
			
		||||
				/* We need to send a PING ... */
 | 
			
		||||
				LogDebug("Connection %d: sending PING ...", i);
 | 
			
		||||
				My_Connections[i].lastping = time(NULL);
 | 
			
		||||
				Conn_UpdatePing(i);
 | 
			
		||||
				Conn_WriteStr(i, "PING :%s",
 | 
			
		||||
					      Client_ID(Client_ThisServer()));
 | 
			
		||||
			}
 | 
			
		||||
@@ -1904,6 +1998,14 @@ New_Server( int Server , ng_ipaddr_t *dest)
 | 
			
		||||
 | 
			
		||||
	assert( Server > NONE );
 | 
			
		||||
 | 
			
		||||
	/* Make sure that the remote server hasn't re-linked to this server
 | 
			
		||||
	 * asynchronously on its own */
 | 
			
		||||
	if (Conf_Server[Server].conn_id > NONE) {
 | 
			
		||||
		Log(LOG_INFO,
 | 
			
		||||
			"Connection to \"%s\" meanwhile re-established, aborting preparation.");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!ng_ipaddr_tostr_r(dest, ip_str)) {
 | 
			
		||||
		Log(LOG_WARNING, "New_Server: Could not convert IP to string");
 | 
			
		||||
		return;
 | 
			
		||||
@@ -1977,7 +2079,8 @@ New_Server( int Server , ng_ipaddr_t *dest)
 | 
			
		||||
	Client_SetToken( c, TOKEN_OUTBOUND );
 | 
			
		||||
 | 
			
		||||
	/* Register connection */
 | 
			
		||||
	Conf_Server[Server].conn_id = new_sock;
 | 
			
		||||
	if (!Conf_SetServer(Server, new_sock))
 | 
			
		||||
		return;
 | 
			
		||||
	My_Connections[new_sock].sock = new_sock;
 | 
			
		||||
	My_Connections[new_sock].addr = *dest;
 | 
			
		||||
	My_Connections[new_sock].client = c;
 | 
			
		||||
@@ -2017,6 +2120,11 @@ Init_Conn_Struct(CONN_ID Idx)
 | 
			
		||||
	My_Connections[Idx].lastdata = now;
 | 
			
		||||
	My_Connections[Idx].lastprivmsg = now;
 | 
			
		||||
	Proc_InitStruct(&My_Connections[Idx].proc_stat);
 | 
			
		||||
 | 
			
		||||
#ifdef ICONV
 | 
			
		||||
	My_Connections[Idx].iconv_from = (iconv_t)(-1);
 | 
			
		||||
	My_Connections[Idx].iconv_to = (iconv_t)(-1);
 | 
			
		||||
#endif
 | 
			
		||||
} /* Init_Conn_Struct */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -2051,13 +2159,14 @@ Init_Socket( int Sock )
 | 
			
		||||
	/* Set type of service (TOS) */
 | 
			
		||||
#if defined(IPPROTO_IP) && defined(IPTOS_LOWDELAY)
 | 
			
		||||
	value = IPTOS_LOWDELAY;
 | 
			
		||||
	LogDebug("Setting IP_TOS on socket %d to IPTOS_LOWDELAY.", Sock);
 | 
			
		||||
	if (setsockopt(Sock, IPPROTO_IP, IP_TOS, &value,
 | 
			
		||||
		       (socklen_t) sizeof(value))) {
 | 
			
		||||
		LogDebug("Can't set socket option IP_TOS: %s!",
 | 
			
		||||
			 strerror(errno));
 | 
			
		||||
		/* ignore this error */
 | 
			
		||||
	}
 | 
			
		||||
	} else
 | 
			
		||||
		LogDebug("IP_TOS on socket %d has been set to IPTOS_LOWDELAY.",
 | 
			
		||||
			 Sock);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
@@ -2098,6 +2207,7 @@ cb_Connect_to_Server(int fd, UNUSED short events)
 | 
			
		||||
 | 
			
		||||
	/* Read result from pipe */
 | 
			
		||||
	len = Proc_Read(&Conf_Server[i].res_stat, dest_addrs, sizeof(dest_addrs));
 | 
			
		||||
	Proc_Close(&Conf_Server[i].res_stat);
 | 
			
		||||
	if (len == 0) {
 | 
			
		||||
		/* Error resolving hostname: reset server structure */
 | 
			
		||||
		Conf_Server[i].conn_id = NONE;
 | 
			
		||||
@@ -2141,6 +2251,7 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 | 
			
		||||
	char *identptr;
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
	char readbuf[HOST_LEN + 2 + CLIENT_USER_LEN];
 | 
			
		||||
	char *ptr;
 | 
			
		||||
#else
 | 
			
		||||
	char readbuf[HOST_LEN + 1];
 | 
			
		||||
#endif
 | 
			
		||||
@@ -2157,6 +2268,7 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 | 
			
		||||
 | 
			
		||||
	/* Read result from pipe */
 | 
			
		||||
	len = Proc_Read(&My_Connections[i].proc_stat, readbuf, sizeof readbuf -1);
 | 
			
		||||
	Proc_Close(&My_Connections[i].proc_stat);
 | 
			
		||||
	if (len == 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
@@ -2188,15 +2300,37 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 | 
			
		||||
		Client_SetHostname(c, readbuf);
 | 
			
		||||
		if (Conf_NoticeAuth)
 | 
			
		||||
			(void)Conn_WriteStr(i,
 | 
			
		||||
					"NOTICE AUTH :*** Found your hostname");
 | 
			
		||||
					"NOTICE AUTH :*** Found your hostname: %s",
 | 
			
		||||
					My_Connections[i].host);
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
		++identptr;
 | 
			
		||||
		if (*identptr) {
 | 
			
		||||
			Log(LOG_INFO, "IDENT lookup for connection %d: \"%s\".", i, identptr);
 | 
			
		||||
			Client_SetUser(c, identptr, true);
 | 
			
		||||
			if (Conf_NoticeAuth)
 | 
			
		||||
			ptr = identptr;
 | 
			
		||||
			while (*ptr) {
 | 
			
		||||
				if ((*ptr < '0' || *ptr > '9') &&
 | 
			
		||||
				    (*ptr < 'A' || *ptr > 'Z') &&
 | 
			
		||||
				    (*ptr < 'a' || *ptr > 'z'))
 | 
			
		||||
					break;
 | 
			
		||||
				ptr++;
 | 
			
		||||
			}
 | 
			
		||||
			if (*ptr) {
 | 
			
		||||
				/* Erroneous IDENT reply */
 | 
			
		||||
				Log(LOG_NOTICE,
 | 
			
		||||
				    "Got invalid IDENT reply for connection %d! Ignored.",
 | 
			
		||||
				    i);
 | 
			
		||||
			} else {
 | 
			
		||||
				Log(LOG_INFO,
 | 
			
		||||
				    "IDENT lookup for connection %d: \"%s\".",
 | 
			
		||||
				    i, identptr);
 | 
			
		||||
				Client_SetUser(c, identptr, true);
 | 
			
		||||
			}
 | 
			
		||||
			if (Conf_NoticeAuth) {
 | 
			
		||||
				(void)Conn_WriteStr(i,
 | 
			
		||||
					"NOTICE AUTH :*** Got ident response");
 | 
			
		||||
					"NOTICE AUTH :*** Got %sident response%s%s",
 | 
			
		||||
					*ptr ? "invalid " : "",
 | 
			
		||||
					*ptr ? "" : ": ",
 | 
			
		||||
					*ptr ? "" : identptr);
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			Log(LOG_INFO, "IDENT lookup for connection %d: no result.", i);
 | 
			
		||||
			if (Conf_NoticeAuth && Conf_Ident)
 | 
			
		||||
@@ -2204,6 +2338,11 @@ cb_Read_Resolver_Result( int r_fd, UNUSED short events )
 | 
			
		||||
					"NOTICE AUTH :*** No ident response");
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		if (Conf_NoticeAuth)
 | 
			
		||||
			(void)Handle_Write(i);
 | 
			
		||||
 | 
			
		||||
		Class_HandleServerBans(c);
 | 
			
		||||
	}
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
		else Log( LOG_DEBUG, "Resolver: discarding result for already registered connection %d.", i );
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
 | 
			
		||||
 * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -42,7 +42,7 @@
 | 
			
		||||
#define CONN_SSL_WANT_READ	128	/* SSL/TLS library needs to read protocol data */
 | 
			
		||||
#define CONN_SSL_FLAGS_ALL	(CONN_SSL_CONNECT|CONN_SSL|CONN_SSL_WANT_WRITE|CONN_SSL_WANT_READ)
 | 
			
		||||
#endif
 | 
			
		||||
typedef long CONN_ID;
 | 
			
		||||
typedef int CONN_ID;
 | 
			
		||||
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "proc.h"
 | 
			
		||||
@@ -54,6 +54,10 @@ typedef long CONN_ID;
 | 
			
		||||
#include "tool.h"
 | 
			
		||||
#include "ng_ipaddr.h"
 | 
			
		||||
 | 
			
		||||
#ifdef ICONV
 | 
			
		||||
# include <iconv.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
#include <zlib.h>
 | 
			
		||||
typedef struct _ZipData
 | 
			
		||||
@@ -72,6 +76,7 @@ typedef struct _Connection
 | 
			
		||||
	ng_ipaddr_t addr;		/* Client address */
 | 
			
		||||
	PROC_STAT proc_stat;		/* Status of resolver process */
 | 
			
		||||
	char host[HOST_LEN];		/* Hostname */
 | 
			
		||||
	char *pwd;			/* password received of the client */
 | 
			
		||||
	array rbuf;			/* Read buffer */
 | 
			
		||||
	array wbuf;			/* Write buffer */
 | 
			
		||||
	time_t signon;			/* Signon ("connect") time */
 | 
			
		||||
@@ -94,27 +99,38 @@ typedef struct _Connection
 | 
			
		||||
#ifndef STRICT_RFC
 | 
			
		||||
	long auth_ping;			/** PING response expected on login */
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ICONV
 | 
			
		||||
	iconv_t iconv_from;		/** iconv: convert from client to server */
 | 
			
		||||
	iconv_t iconv_to;		/** iconv: convert from server to client */
 | 
			
		||||
#endif
 | 
			
		||||
} CONNECTION;
 | 
			
		||||
 | 
			
		||||
GLOBAL CONNECTION *My_Connections;
 | 
			
		||||
GLOBAL CONN_ID Pool_Size;
 | 
			
		||||
GLOBAL long WCounter;
 | 
			
		||||
 | 
			
		||||
#define CONNECTION2ID(x) (long)(x - My_Connections)
 | 
			
		||||
 | 
			
		||||
#endif /* CONN_MODULE */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void Conn_Init PARAMS((void ));
 | 
			
		||||
GLOBAL void Conn_Exit PARAMS(( void ));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Conn_CloseAllSockets PARAMS((void));
 | 
			
		||||
GLOBAL void Conn_CloseAllSockets PARAMS((int ExceptOf));
 | 
			
		||||
 | 
			
		||||
GLOBAL unsigned int Conn_InitListeners PARAMS(( void ));
 | 
			
		||||
GLOBAL void Conn_ExitListeners PARAMS(( void ));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Conn_StartLogin PARAMS((CONN_ID Idx));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Conn_Handler PARAMS(( void ));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Conn_WriteStr PARAMS(( CONN_ID Idx, const char *Format, ... ));
 | 
			
		||||
 | 
			
		||||
GLOBAL char* Conn_Password PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL void Conn_SetPassword PARAMS(( CONN_ID Idx, const char *Pwd ));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Conn_Close PARAMS(( CONN_ID Idx, const char *LogMsg, const char *FwdMsg, bool InformClient ));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
 | 
			
		||||
@@ -122,6 +138,7 @@ GLOBAL void Conn_SyncServerStruct PARAMS(( void ));
 | 
			
		||||
GLOBAL CONN_ID Conn_GetFromProc PARAMS((int fd));
 | 
			
		||||
GLOBAL CLIENT* Conn_GetClient PARAMS((CONN_ID i));
 | 
			
		||||
GLOBAL PROC_STAT* Conn_GetProcStat PARAMS((CONN_ID i));
 | 
			
		||||
 | 
			
		||||
#ifdef SSL_SUPPORT
 | 
			
		||||
GLOBAL bool Conn_GetCipherInfo PARAMS((CONN_ID Idx, char *buf, size_t len));
 | 
			
		||||
GLOBAL bool Conn_UsesSSL PARAMS((CONN_ID Idx));
 | 
			
		||||
@@ -131,6 +148,8 @@ Conn_UsesSSL(UNUSED CONN_ID Idx)
 | 
			
		||||
{ return false; }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
GLOBAL const char *Conn_GetIPAInfo PARAMS((CONN_ID Idx));
 | 
			
		||||
 | 
			
		||||
GLOBAL long Conn_Count PARAMS((void));
 | 
			
		||||
GLOBAL long Conn_CountMax PARAMS((void));
 | 
			
		||||
GLOBAL long Conn_CountAccepted PARAMS((void));
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -17,98 +17,188 @@
 | 
			
		||||
 * Global constants ("#defines") used by the ngIRCd.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Internal flags */
 | 
			
		||||
 | 
			
		||||
/** Flag: there is no connection. */
 | 
			
		||||
#define NONE -1
 | 
			
		||||
 | 
			
		||||
#define FNAME_LEN 256			/* Max. length of file name */
 | 
			
		||||
/** Flag: connection is (still) established. */
 | 
			
		||||
#define CONNECTED true
 | 
			
		||||
 | 
			
		||||
#define LINE_LEN 256			/* Max. length of a line in the
 | 
			
		||||
					   configuration file */
 | 
			
		||||
 | 
			
		||||
#define HOST_LEN 256			/* Max. lenght of fully qualified host
 | 
			
		||||
					   names (e. g. "abc.domain.tld") */
 | 
			
		||||
 | 
			
		||||
#define MAX_SERVERS 16			/* Max. count of configurable servers */
 | 
			
		||||
 | 
			
		||||
#define MAX_WHOWAS 64			/* Max. number of WHOWAS items */
 | 
			
		||||
#define DEFAULT_WHOWAS 5		/* default count for WHOWAS command */
 | 
			
		||||
 | 
			
		||||
#define CONNECTION_POOL 100		/* Size of default connection pool */
 | 
			
		||||
 | 
			
		||||
#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_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 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 */
 | 
			
		||||
 | 
			
		||||
#define CHANNEL_NAME_LEN 51		/* Max. length of a channel name, see
 | 
			
		||||
					   RFC 2812 section 1.3 */
 | 
			
		||||
#define CHANNEL_MODE_LEN 9		/* Max. length of channel modes */
 | 
			
		||||
 | 
			
		||||
#define COMMAND_LEN 513			/* Max. IRC command length, see. RFC
 | 
			
		||||
					   2812 section 3.2 */
 | 
			
		||||
 | 
			
		||||
#define READBUFFER_LEN 2048		/* Size of the read buffer of a
 | 
			
		||||
					   connection in bytes. */
 | 
			
		||||
#define WRITEBUFFER_FLUSH_LEN 4096	/* Size of a write buffer that triggers
 | 
			
		||||
					   buffer flushing if more space is
 | 
			
		||||
					   needed for storing data. */
 | 
			
		||||
#define WRITEBUFFER_MAX_LEN 32768	/* Maximum size of the write buffer of a
 | 
			
		||||
					   connection in bytes. */
 | 
			
		||||
#define WRITEBUFFER_SLINK_LEN 65536	/* Maximum 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. */
 | 
			
		||||
#define PROTOIRC "-IRC"			/* Protocol suffix, see RFC 2813
 | 
			
		||||
					   section 4.1.1 */
 | 
			
		||||
#define PROTOIRCPLUS "-IRC+"		/* Protocol suffix used by the IRC+
 | 
			
		||||
					   protocol, see doc/Protocol.txt */
 | 
			
		||||
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
# define IRCPLUSFLAGS "CHLS"		/* Standard IRC+ flags */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define STARTUP_DELAY 1			/* Delay outgoing connections n seconds
 | 
			
		||||
					   after startup. */
 | 
			
		||||
#define RECONNECT_DELAY 3		/* Time to delay re-connect attempts
 | 
			
		||||
					   in seconds. */
 | 
			
		||||
 | 
			
		||||
#define USERMODES "aciorswx"		/* Supported user modes. */
 | 
			
		||||
#define CHANMODES "biIklmnoOPstvz"	/* Supported channel modes. */
 | 
			
		||||
 | 
			
		||||
#define CONNECTED true			/* Internal status codes. */
 | 
			
		||||
/** Flag: connection isn't established (any more). */
 | 
			
		||||
#define DISCONNECTED false
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_AWAY_MSG "Away"		/* Away message for users connected to
 | 
			
		||||
					   linked servers. */
 | 
			
		||||
/** Tag for outbound server links. */
 | 
			
		||||
#define TOKEN_OUTBOUND -2
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_TOPIC_ID "-Server-"	/* Default ID for "topic owner". */
 | 
			
		||||
 | 
			
		||||
#define CONFIG_FILE "/ngircd.conf"	/* Configuration file name. */
 | 
			
		||||
#define MOTD_FILE "/ngircd.motd"	/* Name of the MOTD file. */
 | 
			
		||||
#define CHROOT_DIR ""			/* Default chroot() directory. */
 | 
			
		||||
#define PID_FILE ""			/* Default file for the process ID. */
 | 
			
		||||
/* Generic buffer sizes */
 | 
			
		||||
 | 
			
		||||
#define ERROR_DIR "/tmp"		/* Error directory used in debug mode */
 | 
			
		||||
/** Max. length of a line in the configuration file. */
 | 
			
		||||
#define LINE_LEN 256
 | 
			
		||||
 | 
			
		||||
#define MAX_LOG_MSG_LEN 256		/* Max. length of a log message. */
 | 
			
		||||
/** Max. length of a log message. */
 | 
			
		||||
#define MAX_LOG_MSG_LEN 256
 | 
			
		||||
 | 
			
		||||
#define TOKEN_OUTBOUND -2		/* Tag for outbound server links. */
 | 
			
		||||
/** Max. length of file name. */
 | 
			
		||||
#define FNAME_LEN 256
 | 
			
		||||
 | 
			
		||||
#define NOTICE_TXTPREFIX ""		/* Prefix for NOTICEs from the server
 | 
			
		||||
					   to users. Some servers use '*'. */
 | 
			
		||||
/** Max. length of fully qualified host names (e. g. "abc.domain.tld"). */
 | 
			
		||||
#define HOST_LEN 256
 | 
			
		||||
 | 
			
		||||
/** Max. length of random salt */
 | 
			
		||||
#define RANDOM_SALT_LEN 32
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Size of structures */
 | 
			
		||||
 | 
			
		||||
/** Max. count of configurable servers. */
 | 
			
		||||
#define MAX_SERVERS 16
 | 
			
		||||
 | 
			
		||||
/** Max. number of WHOWAS list items that can be stored. */
 | 
			
		||||
#define MAX_WHOWAS 64
 | 
			
		||||
 | 
			
		||||
/** Size of default connection pool. */
 | 
			
		||||
#define CONNECTION_POOL 100
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Hard-coded (default) options */
 | 
			
		||||
 | 
			
		||||
/** Delay after startup before outgoing connections are initiated in seconds. */
 | 
			
		||||
#define STARTUP_DELAY 1
 | 
			
		||||
 | 
			
		||||
/** Time to delay re-connect attempts in seconds. */
 | 
			
		||||
#define RECONNECT_DELAY 3
 | 
			
		||||
 | 
			
		||||
/** Configuration file name. */
 | 
			
		||||
#define CONFIG_FILE "/ngircd.conf"
 | 
			
		||||
 | 
			
		||||
/** Name of the MOTD file. */
 | 
			
		||||
#define MOTD_FILE "/ngircd.motd"
 | 
			
		||||
 | 
			
		||||
/** Default chroot() directory. */
 | 
			
		||||
#define CHROOT_DIR ""
 | 
			
		||||
 | 
			
		||||
/** Default file for the process ID. */
 | 
			
		||||
#define PID_FILE ""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Sizes of "IRC elements": nicks, users, ... */
 | 
			
		||||
 | 
			
		||||
/** Max. length of an IRC ID (incl. NULL); see RFC 2812 section 1.1 and 1.2.1. */
 | 
			
		||||
#define CLIENT_ID_LEN 64
 | 
			
		||||
 | 
			
		||||
/** Default nick length (including NULL), see. RFC 2812 section 1.2.1. */
 | 
			
		||||
#define CLIENT_NICK_LEN_DEFAULT 10
 | 
			
		||||
 | 
			
		||||
/** Maximum nickname length (including NULL). */
 | 
			
		||||
#define CLIENT_NICK_LEN 32
 | 
			
		||||
 | 
			
		||||
/** Max. password length (including NULL). */
 | 
			
		||||
#define CLIENT_PASS_LEN 21
 | 
			
		||||
 | 
			
		||||
/** Max. length of user name ("login"; incl. NULL), RFC 2812, section 1.2.1. */
 | 
			
		||||
#define CLIENT_USER_LEN 10
 | 
			
		||||
 | 
			
		||||
/** Max. length of "real names" (including NULL). */
 | 
			
		||||
#define CLIENT_NAME_LEN 32
 | 
			
		||||
 | 
			
		||||
/** Max. host name length (including NULL). */
 | 
			
		||||
#define CLIENT_HOST_LEN 64
 | 
			
		||||
 | 
			
		||||
/** Max. length of all client modes (including NULL). */
 | 
			
		||||
#define CLIENT_MODE_LEN 21
 | 
			
		||||
 | 
			
		||||
/** Max. length of server info texts (including NULL). */
 | 
			
		||||
#define CLIENT_INFO_LEN 64
 | 
			
		||||
 | 
			
		||||
/** Max. length of away messages (including NULL). */
 | 
			
		||||
#define CLIENT_AWAY_LEN 128
 | 
			
		||||
 | 
			
		||||
/** Max. length of client flags (including NULL). */
 | 
			
		||||
#define CLIENT_FLAGS_LEN 16
 | 
			
		||||
 | 
			
		||||
/** Max. length of a channel name (including NULL), see RFC 2812 section 1.3. */
 | 
			
		||||
#define CHANNEL_NAME_LEN 51
 | 
			
		||||
 | 
			
		||||
/** Max. length of channel modes (including NULL). */
 | 
			
		||||
#define CHANNEL_MODE_LEN 21
 | 
			
		||||
 | 
			
		||||
/** Max. IRC command length (including NULL), see. RFC 2812 section 3.2. */
 | 
			
		||||
#define COMMAND_LEN 513
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Read and write buffer sizes */
 | 
			
		||||
 | 
			
		||||
/** Size of the read buffer of a connection in bytes. */
 | 
			
		||||
#define READBUFFER_LEN 2048
 | 
			
		||||
 | 
			
		||||
/** Size that triggers write buffer flushing if more space is needed. */
 | 
			
		||||
#define WRITEBUFFER_FLUSH_LEN 4096
 | 
			
		||||
 | 
			
		||||
/** Maximum size of the write buffer of a connection in bytes. */
 | 
			
		||||
#define WRITEBUFFER_MAX_LEN 32768
 | 
			
		||||
 | 
			
		||||
/** Maximum size of the write buffer of a server link connection in bytes. */
 | 
			
		||||
#define WRITEBUFFER_SLINK_LEN 65536
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* IRC/IRC+ protocol */
 | 
			
		||||
 | 
			
		||||
/** Implemented IRC protocol version, see RFC 2813 section 4.1.1. */
 | 
			
		||||
#define PROTOVER "0210"
 | 
			
		||||
 | 
			
		||||
/** Protocol suffix, see RFC 2813 section 4.1.1. */
 | 
			
		||||
#define PROTOIRC "-IRC"
 | 
			
		||||
 | 
			
		||||
/** Protocol suffix used by the IRC+ protocol, see <doc/Protocol.txt>. */
 | 
			
		||||
#define PROTOIRCPLUS "-IRC+"
 | 
			
		||||
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
/** Standard IRC+ flags. */
 | 
			
		||||
# define IRCPLUSFLAGS "CHLMSX"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** Supported user modes. */
 | 
			
		||||
#define USERMODES "abBcCioqrRswx"
 | 
			
		||||
 | 
			
		||||
/** Supported channel modes. */
 | 
			
		||||
#define CHANMODES "abehiIklmMnoOPqQrRstvVz"
 | 
			
		||||
 | 
			
		||||
/** Away message for users connected to linked servers. */
 | 
			
		||||
#define DEFAULT_AWAY_MSG "Away"
 | 
			
		||||
 | 
			
		||||
/** Default ID for "topic owner". */
 | 
			
		||||
#define DEFAULT_TOPIC_ID "-Server-"
 | 
			
		||||
 | 
			
		||||
/** Prefix for NOTICEs from the server to users. Some servers use '*'. */
 | 
			
		||||
#define NOTICE_TXTPREFIX ""
 | 
			
		||||
 | 
			
		||||
/** Suffix for oversized messages that have been shortened and cut off. */
 | 
			
		||||
#define CUT_TXTSUFFIX "[CUT]"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Defaults and limits for IRC commands */
 | 
			
		||||
 | 
			
		||||
/** Max. number of elemets allowed in channel invite and ban lists. */
 | 
			
		||||
#define MAX_HNDL_CHANNEL_LISTS 50
 | 
			
		||||
 | 
			
		||||
/** Max. number of channel modes with arguments per MODE command. */
 | 
			
		||||
#define MAX_HNDL_MODES_ARG 5
 | 
			
		||||
 | 
			
		||||
/** Max. number of WHO replies. */
 | 
			
		||||
#define MAX_RPL_WHO 25
 | 
			
		||||
 | 
			
		||||
/** Max. number of WHOIS replies. */
 | 
			
		||||
#define MAX_RPL_WHOIS 10
 | 
			
		||||
 | 
			
		||||
/** Default count of WHOWAS command replies. */
 | 
			
		||||
#define DEF_RPL_WHOWAS 5
 | 
			
		||||
 | 
			
		||||
/** Max count of WHOWAS command replies. */
 | 
			
		||||
#define MAX_RPL_WHOWAS 25
 | 
			
		||||
 | 
			
		||||
#define CUT_TXTSUFFIX "[CUT]"		/* Suffix for oversized messages that
 | 
			
		||||
					   have been shortened and cut off. */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										171
									
								
								src/ngircd/io.c
									
									
									
									
									
								
							
							
						
						
									
										171
									
								
								src/ngircd/io.c
									
									
									
									
									
								
							@@ -41,6 +41,7 @@ typedef struct {
 | 
			
		||||
 | 
			
		||||
#define INIT_IOEVENT		{ NULL, -1, 0, NULL }
 | 
			
		||||
#define IO_ERROR		4
 | 
			
		||||
#define MAX_EVENTS		100
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_EPOLL_CREATE
 | 
			
		||||
#  define IO_USE_EPOLL		1
 | 
			
		||||
@@ -54,7 +55,7 @@ typedef struct {
 | 
			
		||||
#    ifdef HAVE_SYS_DEVPOLL_H
 | 
			
		||||
#      define IO_USE_DEVPOLL	1
 | 
			
		||||
#    else
 | 
			
		||||
#      ifdef HAVE_POLL
 | 
			
		||||
#      if defined(HAVE_POLL) && defined(HAVE_POLL_H)
 | 
			
		||||
#        define IO_USE_POLL	1
 | 
			
		||||
#      else
 | 
			
		||||
#        ifdef HAVE_SELECT
 | 
			
		||||
@@ -85,6 +86,20 @@ static int io_masterfd;
 | 
			
		||||
 | 
			
		||||
static int io_dispatch_kqueue(struct timeval *tv);
 | 
			
		||||
static bool io_event_change_kqueue(int, short, const int action);
 | 
			
		||||
 | 
			
		||||
#ifndef EV_SET
 | 
			
		||||
/* Taken from /usr/include/sys/event.h of FreeBSD 8.1 and required by all
 | 
			
		||||
 * platforms that have kqueue but lack EV_SET() -- for example FreeBSD 4. */
 | 
			
		||||
#define EV_SET(kevp, a, b, c, d, e, f) do {	\
 | 
			
		||||
	struct kevent *__kevp__ = (kevp);	\
 | 
			
		||||
	__kevp__->ident = (a);			\
 | 
			
		||||
	__kevp__->filter = (b);			\
 | 
			
		||||
	__kevp__->flags = (c);			\
 | 
			
		||||
	__kevp__->fflags = (d);			\
 | 
			
		||||
	__kevp__->data = (e);			\
 | 
			
		||||
	__kevp__->udata = (f);			\
 | 
			
		||||
} while(0)
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IO_USE_POLL
 | 
			
		||||
@@ -160,39 +175,34 @@ 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;
 | 
			
		||||
	int i, ret, timeout = tv->tv_usec + sec;
 | 
			
		||||
	short what;
 | 
			
		||||
	struct pollfd p[100];
 | 
			
		||||
	struct pollfd p[MAX_EVENTS];
 | 
			
		||||
 | 
			
		||||
	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;
 | 
			
		||||
	dvp.dp_timeout = timeout;
 | 
			
		||||
	dvp.dp_nfds = MAX_EVENTS;
 | 
			
		||||
	dvp.dp_fds = p;
 | 
			
		||||
	ret = ioctl(io_masterfd, DP_POLL, &dvp);
 | 
			
		||||
 | 
			
		||||
			if (p[i].revents & POLLOUT)
 | 
			
		||||
				what |= IO_WANTWRITE;
 | 
			
		||||
	for (i=0; i < ret ; i++) {
 | 
			
		||||
		what = 0;
 | 
			
		||||
		if (p[i].revents & (POLLIN|POLLPRI))
 | 
			
		||||
			what = IO_WANTREAD;
 | 
			
		||||
 | 
			
		||||
			if (p[i].revents && !what) {
 | 
			
		||||
				/* other flag is set, probably POLLERR */
 | 
			
		||||
				what = IO_ERROR;
 | 
			
		||||
			}
 | 
			
		||||
			io_docallback(p[i].fd, what);
 | 
			
		||||
		if (p[i].revents & POLLOUT)
 | 
			
		||||
			what |= IO_WANTWRITE;
 | 
			
		||||
 | 
			
		||||
		if (p[i].revents && !what) {
 | 
			
		||||
			/* other flag is set, probably POLLERR */
 | 
			
		||||
			what = IO_ERROR;
 | 
			
		||||
		}
 | 
			
		||||
	} while (ret == 100);
 | 
			
		||||
		io_docallback(p[i].fd, what);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return total;
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -462,37 +472,30 @@ static int
 | 
			
		||||
io_dispatch_epoll(struct timeval *tv)
 | 
			
		||||
{
 | 
			
		||||
	time_t sec = tv->tv_sec * 1000;
 | 
			
		||||
	int i, total = 0, ret, timeout = tv->tv_usec + sec;
 | 
			
		||||
	struct epoll_event epoll_ev[100];
 | 
			
		||||
	int i, ret, timeout = tv->tv_usec + sec;
 | 
			
		||||
	struct epoll_event epoll_ev[MAX_EVENTS];
 | 
			
		||||
	short type;
 | 
			
		||||
 | 
			
		||||
	if (timeout < 0)
 | 
			
		||||
		timeout = 1000;
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		ret = epoll_wait(io_masterfd, epoll_ev, 100, timeout);
 | 
			
		||||
		total += ret;
 | 
			
		||||
		if (ret <= 0)
 | 
			
		||||
			return total;
 | 
			
		||||
	ret = epoll_wait(io_masterfd, epoll_ev, MAX_EVENTS, timeout);
 | 
			
		||||
 | 
			
		||||
		for (i = 0; i < ret; i++) {
 | 
			
		||||
			type = 0;
 | 
			
		||||
			if (epoll_ev[i].events & (EPOLLERR | EPOLLHUP))
 | 
			
		||||
				type = IO_ERROR;
 | 
			
		||||
	for (i = 0; i < ret; i++) {
 | 
			
		||||
		type = 0;
 | 
			
		||||
		if (epoll_ev[i].events & (EPOLLERR | EPOLLHUP))
 | 
			
		||||
			type = IO_ERROR;
 | 
			
		||||
 | 
			
		||||
			if (epoll_ev[i].events & (EPOLLIN | EPOLLPRI))
 | 
			
		||||
				type |= IO_WANTREAD;
 | 
			
		||||
		if (epoll_ev[i].events & (EPOLLIN | EPOLLPRI))
 | 
			
		||||
			type |= IO_WANTREAD;
 | 
			
		||||
 | 
			
		||||
			if (epoll_ev[i].events & EPOLLOUT)
 | 
			
		||||
				type |= IO_WANTWRITE;
 | 
			
		||||
		if (epoll_ev[i].events & EPOLLOUT)
 | 
			
		||||
			type |= IO_WANTWRITE;
 | 
			
		||||
 | 
			
		||||
			io_docallback(epoll_ev[i].data.fd, type);
 | 
			
		||||
		}
 | 
			
		||||
		io_docallback(epoll_ev[i].data.fd, type);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		timeout = 0;
 | 
			
		||||
	} while (ret == 100);
 | 
			
		||||
 | 
			
		||||
	return total;
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
@@ -576,58 +579,50 @@ io_event_change_kqueue(int fd, short what, const int action)
 | 
			
		||||
static int
 | 
			
		||||
io_dispatch_kqueue(struct timeval *tv)
 | 
			
		||||
{
 | 
			
		||||
	int i, total = 0, ret;
 | 
			
		||||
	struct kevent kev[100];
 | 
			
		||||
	int i, ret;
 | 
			
		||||
	struct kevent kev[MAX_EVENTS];
 | 
			
		||||
	struct kevent *newevents;
 | 
			
		||||
	struct timespec ts;
 | 
			
		||||
	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);
 | 
			
		||||
	newevents_len = (int) array_length(&io_evcache, sizeof (struct kevent));
 | 
			
		||||
	newevents = (newevents_len > 0) ? array_start(&io_evcache) : NULL;
 | 
			
		||||
	assert(newevents_len >= 0);
 | 
			
		||||
 | 
			
		||||
		ret = kevent(io_masterfd, newevents, newevents_len, kev, 100, &ts);
 | 
			
		||||
		if (newevents && ret != -1)
 | 
			
		||||
			array_trunc(&io_evcache);
 | 
			
		||||
	ret = kevent(io_masterfd, newevents, newevents_len, kev, MAX_EVENTS, &ts);
 | 
			
		||||
	if (newevents && ret != -1)
 | 
			
		||||
		array_trunc(&io_evcache);
 | 
			
		||||
 | 
			
		||||
		total += ret;
 | 
			
		||||
		if (ret <= 0)
 | 
			
		||||
			return total;
 | 
			
		||||
 | 
			
		||||
		for (i = 0; i < ret; i++) {
 | 
			
		||||
			io_debug("dispatch_kqueue: fd, kev.flags", (int)kev[i].ident, kev[i].flags);
 | 
			
		||||
			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:
 | 
			
		||||
				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;
 | 
			
		||||
			}
 | 
			
		||||
	for (i = 0; i < ret; i++) {
 | 
			
		||||
		io_debug("dispatch_kqueue: fd, kev.flags", (int)kev[i].ident, kev[i].flags);
 | 
			
		||||
		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;
 | 
			
		||||
		}
 | 
			
		||||
		ts.tv_sec = 0;
 | 
			
		||||
		ts.tv_nsec = 0;
 | 
			
		||||
	} while (ret == 100);
 | 
			
		||||
 | 
			
		||||
	return total;
 | 
			
		||||
		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:
 | 
			
		||||
			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;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										291
									
								
								src/ngircd/irc-cap.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										291
									
								
								src/ngircd/irc-cap.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,291 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Handler for IRC capability ("CAP") commands
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "client-cap.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "login.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "irc-cap.h"
 | 
			
		||||
 | 
			
		||||
bool Handle_CAP_LS PARAMS((CLIENT *Client, char *Arg));
 | 
			
		||||
bool Handle_CAP_LIST PARAMS((CLIENT *Client, char *Arg));
 | 
			
		||||
bool Handle_CAP_REQ PARAMS((CLIENT *Client, char *Arg));
 | 
			
		||||
bool Handle_CAP_ACK PARAMS((CLIENT *Client, char *Arg));
 | 
			
		||||
bool Handle_CAP_CLEAR PARAMS((CLIENT *Client));
 | 
			
		||||
bool Handle_CAP_END PARAMS((CLIENT *Client));
 | 
			
		||||
 | 
			
		||||
void Set_CAP_Negotiation PARAMS((CLIENT *Client));
 | 
			
		||||
 | 
			
		||||
int Parse_CAP PARAMS((int Capabilities, char *Args));
 | 
			
		||||
char *Get_CAP_String PARAMS((int Capabilities));
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the IRCv3 "CAP" command.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Req Request structure with prefix and all parameters.
 | 
			
		||||
 * @returns CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_CAP(CLIENT *Client, REQUEST *Req)
 | 
			
		||||
{
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Req != NULL);
 | 
			
		||||
 | 
			
		||||
	/* Bad number of prameters? */
 | 
			
		||||
	if (Req->argc < 1 || Req->argc > 2)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
	LogDebug("Got \"%s %s\" command from \"%s\" ...",
 | 
			
		||||
		 Req->command, Req->argv[0], Client_ID(Client));
 | 
			
		||||
 | 
			
		||||
	if (Req->argc == 1) {
 | 
			
		||||
		if (strcasecmp(Req->argv[0], "CLEAR") == 0)
 | 
			
		||||
			return Handle_CAP_CLEAR(Client);
 | 
			
		||||
		if (strcasecmp(Req->argv[0], "END") == 0)
 | 
			
		||||
			return Handle_CAP_END(Client);
 | 
			
		||||
	}
 | 
			
		||||
	if (Req->argc >= 1 && Req->argc <= 2) {
 | 
			
		||||
		if (strcasecmp(Req->argv[0], "LS") == 0)
 | 
			
		||||
			return Handle_CAP_LS(Client, Req->argv[1]);
 | 
			
		||||
		if (strcasecmp(Req->argv[0], "LIST") == 0)
 | 
			
		||||
			return Handle_CAP_LIST(Client, Req->argv[1]);
 | 
			
		||||
	}
 | 
			
		||||
	if (Req->argc == 2) {
 | 
			
		||||
		if (strcasecmp(Req->argv[0], "REQ") == 0)
 | 
			
		||||
			return Handle_CAP_REQ(Client, Req->argv[1]);
 | 
			
		||||
		if (strcasecmp(Req->argv[0], "ACK") == 0)
 | 
			
		||||
			return Handle_CAP_ACK(Client, Req->argv[1]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return IRC_WriteStrClient(Client, ERR_INVALIDCAP_MSG,
 | 
			
		||||
				  Client_ID(Client), Req->argv[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the "CAP LS" command.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Arg Command argument or NULL.
 | 
			
		||||
 * @returns CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
bool
 | 
			
		||||
Handle_CAP_LS(CLIENT *Client, UNUSED char *Arg)
 | 
			
		||||
{
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
 | 
			
		||||
	Set_CAP_Negotiation(Client);
 | 
			
		||||
 | 
			
		||||
	return IRC_WriteStrClient(Client,
 | 
			
		||||
				  "CAP %s LS :multi-prefix",
 | 
			
		||||
				  Client_ID(Client));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the "CAP LIST" command.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Arg Command argument or NULL.
 | 
			
		||||
 * @returns CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
bool
 | 
			
		||||
Handle_CAP_LIST(CLIENT *Client, UNUSED char *Arg)
 | 
			
		||||
{
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
 | 
			
		||||
	return IRC_WriteStrClient(Client, "CAP %s LIST :%s", Client_ID(Client),
 | 
			
		||||
				  Get_CAP_String(Client_Cap(Client)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the "CAP REQ" command.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Arg Command argument.
 | 
			
		||||
 * @returns CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
bool
 | 
			
		||||
Handle_CAP_REQ(CLIENT *Client, char *Arg)
 | 
			
		||||
{
 | 
			
		||||
	int new_cap;
 | 
			
		||||
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Arg != NULL);
 | 
			
		||||
 | 
			
		||||
	Set_CAP_Negotiation(Client);
 | 
			
		||||
 | 
			
		||||
	new_cap = Parse_CAP(Client_Cap(Client), Arg);
 | 
			
		||||
 | 
			
		||||
	if (new_cap < 0)
 | 
			
		||||
		return IRC_WriteStrClient(Client, "CAP %s NAK :%s",
 | 
			
		||||
					  Client_ID(Client), Arg);
 | 
			
		||||
 | 
			
		||||
	Client_CapSet(Client, new_cap);
 | 
			
		||||
	return IRC_WriteStrClient(Client, "CAP %s ACK :%s",
 | 
			
		||||
				  Client_ID(Client), Arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the "CAP ACK" command.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Arg Command argument.
 | 
			
		||||
 * @returns CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
bool
 | 
			
		||||
Handle_CAP_ACK(UNUSED CLIENT *Client, UNUSED char *Arg)
 | 
			
		||||
{
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Arg != NULL);
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the "CAP CLEAR" command.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @returns CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
bool
 | 
			
		||||
Handle_CAP_CLEAR(CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	int cap_old;
 | 
			
		||||
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
 | 
			
		||||
	cap_old = Client_Cap(Client);
 | 
			
		||||
	if (cap_old & CLIENT_CAP_MULTI_PREFIX)
 | 
			
		||||
		Client_CapDel(Client, CLIENT_CAP_MULTI_PREFIX);
 | 
			
		||||
 | 
			
		||||
	return IRC_WriteStrClient(Client, "CAP %s ACK :%s", Client_ID(Client),
 | 
			
		||||
				  Get_CAP_String(cap_old));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the "CAP END" command.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @returns CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
bool
 | 
			
		||||
Handle_CAP_END(CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
 | 
			
		||||
	if (Client_Type(Client) != CLIENT_USER) {
 | 
			
		||||
		/* User is still logging in ... */
 | 
			
		||||
		Client_CapDel(Client, CLIENT_CAP_PENDING);
 | 
			
		||||
 | 
			
		||||
		if (Client_Type(Client) == CLIENT_WAITCAPEND) {
 | 
			
		||||
			/* Only "CAP END" was missing: log in! */
 | 
			
		||||
			return Login_User(Client);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set CAP negotiation status and mark client as "supports capabilities".
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client to handle.
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
Set_CAP_Negotiation(CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
 | 
			
		||||
	if (Client_Type(Client) != CLIENT_USER)
 | 
			
		||||
		Client_CapAdd(Client, CLIENT_CAP_PENDING);
 | 
			
		||||
	Client_CapAdd(Client, CLIENT_CAP_SUPPORTED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Parse capability string and return numeric flag value.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Args The string containing space-separated capability names.
 | 
			
		||||
 * @return Changed capability flags or 0 on error.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
Parse_CAP(int Capabilities, char *Args)
 | 
			
		||||
{
 | 
			
		||||
	static char tmp[COMMAND_LEN];
 | 
			
		||||
	char *ptr;
 | 
			
		||||
 | 
			
		||||
	assert(Args != NULL);
 | 
			
		||||
 | 
			
		||||
	strlcpy(tmp, Args, sizeof(tmp));
 | 
			
		||||
 | 
			
		||||
	ptr = strtok(tmp, " ");
 | 
			
		||||
	while (ptr) {
 | 
			
		||||
		if (*ptr == '-') {
 | 
			
		||||
			/* drop capabilities */
 | 
			
		||||
			ptr++;
 | 
			
		||||
			if (strcmp(ptr, "multi-prefix") == 0)
 | 
			
		||||
				Capabilities &= ~CLIENT_CAP_MULTI_PREFIX;
 | 
			
		||||
			else
 | 
			
		||||
				return -1;
 | 
			
		||||
		} else {
 | 
			
		||||
			/* request capabilities */
 | 
			
		||||
			if (strcmp(ptr, "multi-prefix") == 0)
 | 
			
		||||
				Capabilities |= CLIENT_CAP_MULTI_PREFIX;
 | 
			
		||||
			else
 | 
			
		||||
				return -1;
 | 
			
		||||
		}
 | 
			
		||||
		ptr = strtok(NULL, " ");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return Capabilities;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return textual representation of capability flags.
 | 
			
		||||
 *
 | 
			
		||||
 * Please note: this function returns a pointer to a global buffer and
 | 
			
		||||
 * therefore isn't thread safe!
 | 
			
		||||
 *
 | 
			
		||||
 * @param Capabilities Capability flags (bitmask).
 | 
			
		||||
 * @return Pointer to textual representation.
 | 
			
		||||
 */
 | 
			
		||||
char *
 | 
			
		||||
Get_CAP_String(int Capabilities)
 | 
			
		||||
{
 | 
			
		||||
	static char txt[COMMAND_LEN];
 | 
			
		||||
 | 
			
		||||
	txt[0] = '\0';
 | 
			
		||||
 | 
			
		||||
	if (Capabilities & CLIENT_CAP_MULTI_PREFIX)
 | 
			
		||||
		strlcat(txt, "multi-prefix ", sizeof(txt));
 | 
			
		||||
 | 
			
		||||
	return txt;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										24
									
								
								src/ngircd/irc-cap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/ngircd/irc-cap.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2010 Alexander Barton (alex@barton.de).
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __irc_cap_h__
 | 
			
		||||
#define __irc_cap_h__
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Handler for IRC capability ("CAP") commands (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
GLOBAL bool IRC_CAP PARAMS((CLIENT *Client, REQUEST *Req));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
@@ -31,6 +31,7 @@
 | 
			
		||||
#include "match.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "irc.h"
 | 
			
		||||
#include "irc-info.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
@@ -81,7 +82,7 @@ static bool
 | 
			
		||||
join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
 | 
			
		||||
	     const char *key)
 | 
			
		||||
{
 | 
			
		||||
	bool is_invited, is_banned;
 | 
			
		||||
	bool is_invited, is_banned, is_exception;
 | 
			
		||||
	const char *channel_modes;
 | 
			
		||||
 | 
			
		||||
	/* Allow IRC operators to overwrite channel limits */
 | 
			
		||||
@@ -89,9 +90,10 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	is_banned = Lists_Check(Channel_GetListBans(chan), Client);
 | 
			
		||||
	is_exception = Lists_Check(Channel_GetListExcepts(chan), Client);
 | 
			
		||||
	is_invited = Lists_Check(Channel_GetListInvites(chan), Client);
 | 
			
		||||
 | 
			
		||||
	if (is_banned && !is_invited) {
 | 
			
		||||
	if (is_banned && !is_invited && !is_exception) {
 | 
			
		||||
		/* Client is banned from channel (and not on invite list) */
 | 
			
		||||
		IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG,
 | 
			
		||||
				   Client_ID(Client), channame);
 | 
			
		||||
@@ -137,6 +139,13 @@ join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (strchr(channel_modes, 'R') && !strchr(Client_Modes(Client), 'R')) {
 | 
			
		||||
		/* Only registered users are allowed! */
 | 
			
		||||
		IRC_WriteStrClient(Client, ERR_REGONLYCHANNEL_MSG,
 | 
			
		||||
				   Client_ID(Client), channame);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
} /* join_allowed */
 | 
			
		||||
 | 
			
		||||
@@ -158,8 +167,10 @@ join_set_channelmodes(CHANNEL *chan, CLIENT *target, const char *flags)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* If channel persistent and client is ircop: make client chanop */
 | 
			
		||||
	if (strchr(Channel_Modes(chan), 'P') && strchr(Client_Modes(target), 'o'))
 | 
			
		||||
	/* If the channel is persistent (+P) and client is an IRC op:
 | 
			
		||||
	 * make client chanop, if not disabled in configuration. */
 | 
			
		||||
	if (strchr(Channel_Modes(chan), 'P') && Conf_OperChanPAutoOp
 | 
			
		||||
	    && strchr(Client_Modes(target), 'o'))
 | 
			
		||||
		Channel_UserModeAdd(chan, target, 'o');
 | 
			
		||||
} /* join_set_channelmodes */
 | 
			
		||||
 | 
			
		||||
@@ -237,7 +248,7 @@ join_forward(CLIENT *Client, CLIENT *target, CHANNEL *chan,
 | 
			
		||||
	IRC_WriteStrChannelPrefix(Client, chan, target, false,
 | 
			
		||||
				  "JOIN :%s",  channame);
 | 
			
		||||
 | 
			
		||||
	/* syncronize channel modes */
 | 
			
		||||
	/* synchronize channel modes */
 | 
			
		||||
	if (modes[1]) {
 | 
			
		||||
		IRC_WriteStrChannelPrefix(Client, chan, target, false,
 | 
			
		||||
					  "MODE %s +%s %s", channame,
 | 
			
		||||
@@ -294,9 +305,9 @@ join_send_topic(CLIENT *Client, CLIENT *target, CHANNEL *chan,
 | 
			
		||||
 *
 | 
			
		||||
 * See RFC 2812, 3.2.1 "Join message"; RFC 2813, 4.2.1 "Join message".
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client	The client from which this command has been received
 | 
			
		||||
 * @param Req		Request structure with prefix and all parameters
 | 
			
		||||
 * @returns		CONNECTED or DISCONNECTED
 | 
			
		||||
 * @param Client The client from which this command has been received
 | 
			
		||||
 * @param Req Request structure with prefix and all parameters
 | 
			
		||||
 * @returns CONNECTED or DISCONNECTED
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
@@ -305,8 +316,8 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	CLIENT *target;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
	assert (Client != NULL);
 | 
			
		||||
	assert (Req != NULL);
 | 
			
		||||
 | 
			
		||||
	/* Bad number of arguments? */
 | 
			
		||||
	if (Req->argc < 1 || Req->argc > 2)
 | 
			
		||||
@@ -320,7 +331,8 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		target = Client;
 | 
			
		||||
 | 
			
		||||
	if (!target)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix);
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->prefix);
 | 
			
		||||
 | 
			
		||||
	/* Is argument "0"? */
 | 
			
		||||
	if (Req->argc == 1 && !strncmp("0", Req->argv[0], 2))
 | 
			
		||||
@@ -352,24 +364,35 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
 | 
			
		||||
		chan = Channel_Search(channame);
 | 
			
		||||
		if (!chan && Conf_PredefChannelsOnly) {
 | 
			
		||||
			 /* channel must be created, but server does not allow this */
 | 
			
		||||
			IRC_WriteStrClient(Client, ERR_BANNEDFROMCHAN_MSG, Client_ID(Client), channame);
 | 
			
		||||
			break;
 | 
			
		||||
			 /* channel must be created, but forbidden by config */
 | 
			
		||||
			IRC_WriteStrClient(Client, ERR_NOSUCHCHANNEL_MSG,
 | 
			
		||||
					   Client_ID(Client), channame);
 | 
			
		||||
			goto join_next;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Local client? */
 | 
			
		||||
		if (Client_Type(Client) == CLIENT_USER) {
 | 
			
		||||
			if (chan) {
 | 
			
		||||
				/* Already existing channel: already member? */
 | 
			
		||||
				if (Channel_IsMemberOf(chan, Client))
 | 
			
		||||
				    goto join_next;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* Test if the user has reached the channel limit */
 | 
			
		||||
			if ((Conf_MaxJoins > 0) &&
 | 
			
		||||
			    (Channel_CountForUser(Client) >= Conf_MaxJoins))
 | 
			
		||||
				return IRC_WriteStrClient(Client,
 | 
			
		||||
			    (Channel_CountForUser(Client) >= Conf_MaxJoins)) {
 | 
			
		||||
				if (!IRC_WriteStrClient(Client,
 | 
			
		||||
						ERR_TOOMANYCHANNELS_MSG,
 | 
			
		||||
						Client_ID(Client), channame);
 | 
			
		||||
						Client_ID(Client), channame))
 | 
			
		||||
					return DISCONNECTED;
 | 
			
		||||
				goto join_next;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (chan) {
 | 
			
		||||
				/* Already existing channel: check if the
 | 
			
		||||
				 * client is allowed to join */
 | 
			
		||||
				if (!join_allowed(Client, chan, channame, key))
 | 
			
		||||
					break;
 | 
			
		||||
					goto join_next;
 | 
			
		||||
			} else {
 | 
			
		||||
				/* New channel: first user will become channel
 | 
			
		||||
				 * operator unless this is a modeless channel */
 | 
			
		||||
@@ -392,7 +415,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
 | 
			
		||||
		/* Join channel (and create channel if it doesn't exist) */
 | 
			
		||||
		if (!Channel_Join(target, channame))
 | 
			
		||||
			break;
 | 
			
		||||
			goto join_next;
 | 
			
		||||
 | 
			
		||||
		if (!chan) { /* channel is new; it has been created above */
 | 
			
		||||
			chan = Channel_Search(channame);
 | 
			
		||||
@@ -411,6 +434,7 @@ IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		if (!join_send_topic(Client, target, chan, channame))
 | 
			
		||||
			break; /* write error */
 | 
			
		||||
 | 
			
		||||
	join_next:
 | 
			
		||||
		/* next channel? */
 | 
			
		||||
		channame = strtok_r(NULL, ",", &lastchan);
 | 
			
		||||
		if (channame && key)
 | 
			
		||||
@@ -488,7 +512,7 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	CLIENT *from;
 | 
			
		||||
	char *topic;
 | 
			
		||||
	bool onchannel, topicok, use_servermode, r;
 | 
			
		||||
	bool r, topic_power;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
@@ -511,12 +535,17 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		return IRC_WriteStrClient(from, ERR_NOSUCHCHANNEL_MSG,
 | 
			
		||||
					  Client_ID(from), Req->argv[0]);
 | 
			
		||||
 | 
			
		||||
	Channel_CheckAdminRights(chan, Client, from,
 | 
			
		||||
				 &onchannel, &topicok, &use_servermode);
 | 
			
		||||
 | 
			
		||||
	if (!onchannel && !topicok)
 | 
			
		||||
		return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG,
 | 
			
		||||
					  Client_ID(from), Req->argv[0]);
 | 
			
		||||
	/* Only remote servers and channel members are allowed to change the
 | 
			
		||||
	 * channel topic, and IRC opreators when the Conf_OperCanMode option
 | 
			
		||||
	 * is set in the server configuration. */
 | 
			
		||||
	if (Client_Type(Client) != CLIENT_SERVER) {
 | 
			
		||||
		topic_power = Client_HasMode(from, 'o');
 | 
			
		||||
		if (!Channel_IsMemberOf(chan, from)
 | 
			
		||||
		    && !(Conf_OperCanMode && topic_power))
 | 
			
		||||
			return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG,
 | 
			
		||||
						  Client_ID(from), Req->argv[0]);
 | 
			
		||||
	} else
 | 
			
		||||
		topic_power = true;
 | 
			
		||||
 | 
			
		||||
	if (Req->argc == 1) {
 | 
			
		||||
		/* Request actual topic */
 | 
			
		||||
@@ -543,8 +572,12 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (strchr(Channel_Modes(chan), 't')) {
 | 
			
		||||
		/* Topic Lock. Is the user a channel or IRC operator? */
 | 
			
		||||
		if (!topicok)
 | 
			
		||||
		/* Topic Lock. Is the user a channel op or IRC operator? */
 | 
			
		||||
		if(!topic_power &&
 | 
			
		||||
		   !strchr(Channel_UserModes(chan, from), 'h') &&
 | 
			
		||||
		   !strchr(Channel_UserModes(chan, from), 'o') &&
 | 
			
		||||
		   !strchr(Channel_UserModes(chan, from), 'a') &&
 | 
			
		||||
		   !strchr(Channel_UserModes(chan, from), 'q'))
 | 
			
		||||
			return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
 | 
			
		||||
						  Client_ID(from),
 | 
			
		||||
						  Channel_Name(chan));
 | 
			
		||||
@@ -556,7 +589,7 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		 Client_TypeText(from), Client_Mask(from), Channel_Name(chan),
 | 
			
		||||
		 Req->argv[1][0] ? Req->argv[1] : "<none>");
 | 
			
		||||
 | 
			
		||||
	if (use_servermode)
 | 
			
		||||
	if (Conf_OperServerMode)
 | 
			
		||||
		from = Client_ThisServer();
 | 
			
		||||
 | 
			
		||||
	/* Update channel and forward new topic to other servers */
 | 
			
		||||
@@ -582,9 +615,9 @@ IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
 * This implementation handles the local case as well as the forwarding of the
 | 
			
		||||
 * LIST command to other servers in the IRC network.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client	The client from which this command has been received
 | 
			
		||||
 * @param Req		Request structure with prefix and all parameters
 | 
			
		||||
 * @returns		CONNECTED or DISCONNECTED
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Req Request structure with prefix and all parameters.
 | 
			
		||||
 * @return CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_LIST( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
@@ -592,79 +625,86 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	char *pattern;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	CLIENT *from, *target;
 | 
			
		||||
	int count = 0;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Req != NULL);
 | 
			
		||||
 | 
			
		||||
	/* Bad number of prameters? */
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
	if( Req->argc > 0 )
 | 
			
		||||
		pattern = strtok( Req->argv[0], "," );
 | 
			
		||||
	if (Req->argc > 0)
 | 
			
		||||
		pattern = strtok(Req->argv[0], ",");
 | 
			
		||||
	else
 | 
			
		||||
		pattern = "*";
 | 
			
		||||
 | 
			
		||||
	/* Get sender from prefix, if any */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER )
 | 
			
		||||
		from = Client_Search( Req->prefix );
 | 
			
		||||
	if (Client_Type(Client) == CLIENT_SERVER)
 | 
			
		||||
		from = Client_Search(Req->prefix);
 | 
			
		||||
	else
 | 
			
		||||
		from = Client;
 | 
			
		||||
 | 
			
		||||
	if( ! from )
 | 
			
		||||
		return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG,
 | 
			
		||||
				Client_ID( Client ), Req->prefix );
 | 
			
		||||
	if (!from)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->prefix);
 | 
			
		||||
 | 
			
		||||
	if( Req->argc == 2 )
 | 
			
		||||
	{
 | 
			
		||||
	if (Req->argc == 2) {
 | 
			
		||||
		/* Forward to other server? */
 | 
			
		||||
		target = Client_Search( Req->argv[1] );
 | 
			
		||||
		if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER ))
 | 
			
		||||
			return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG,
 | 
			
		||||
					Client_ID( Client ), Req->argv[1] );
 | 
			
		||||
		target = Client_Search(Req->argv[1]);
 | 
			
		||||
		if (! target || Client_Type(target) != CLIENT_SERVER)
 | 
			
		||||
			return IRC_WriteStrClient(from, ERR_NOSUCHSERVER_MSG,
 | 
			
		||||
						  Client_ID(Client),
 | 
			
		||||
						  Req->argv[1]);
 | 
			
		||||
 | 
			
		||||
		if( target != Client_ThisServer( ))
 | 
			
		||||
		{
 | 
			
		||||
		if (target != Client_ThisServer()) {
 | 
			
		||||
			/* Target is indeed an other server, forward it! */
 | 
			
		||||
			return IRC_WriteStrClientPrefix( target, from,
 | 
			
		||||
					"LIST %s :%s", Client_ID( from ),
 | 
			
		||||
					Req->argv[1] );
 | 
			
		||||
			return IRC_WriteStrClientPrefix(target, from,
 | 
			
		||||
							"LIST %s :%s",
 | 
			
		||||
							Req->argv[0],
 | 
			
		||||
							Req->argv[1]);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while( pattern )
 | 
			
		||||
	{
 | 
			
		||||
	while (pattern) {
 | 
			
		||||
		/* Loop through all the channels */
 | 
			
		||||
		chan = Channel_First( );
 | 
			
		||||
		while( chan )
 | 
			
		||||
		{
 | 
			
		||||
		if (Req->argc > 0)
 | 
			
		||||
			ngt_LowerStr(pattern);
 | 
			
		||||
		chan = Channel_First();
 | 
			
		||||
		while (chan) {
 | 
			
		||||
			/* Check search pattern */
 | 
			
		||||
			if( Match( pattern, Channel_Name( chan )))
 | 
			
		||||
			{
 | 
			
		||||
			if (MatchCaseInsensitive(pattern, Channel_Name(chan))) {
 | 
			
		||||
				/* Gotcha! */
 | 
			
		||||
				if( ! strchr( Channel_Modes( chan ), 's' ) ||
 | 
			
		||||
				    Channel_IsMemberOf( chan, from ))
 | 
			
		||||
				{
 | 
			
		||||
					if( ! IRC_WriteStrClient( from,
 | 
			
		||||
					    RPL_LIST_MSG, Client_ID( from ),
 | 
			
		||||
					    Channel_Name( chan ),
 | 
			
		||||
					    Channel_MemberCount( chan ),
 | 
			
		||||
					    Channel_Topic( chan )))
 | 
			
		||||
				if (!strchr(Channel_Modes(chan), 's')
 | 
			
		||||
				    || Channel_IsMemberOf(chan, from)
 | 
			
		||||
				    || (!Conf_MorePrivacy && Client_OperByMe(Client))) {
 | 
			
		||||
					if ((Conf_MaxListSize > 0)
 | 
			
		||||
					    && IRC_CheckListTooBig(from, count,
 | 
			
		||||
								   Conf_MaxListSize,
 | 
			
		||||
								   "LIST"))
 | 
			
		||||
						break;
 | 
			
		||||
					if (!IRC_WriteStrClient(from,
 | 
			
		||||
					     RPL_LIST_MSG, Client_ID(from),
 | 
			
		||||
					     Channel_Name(chan),
 | 
			
		||||
					     Channel_MemberCount(chan),
 | 
			
		||||
					     Channel_Topic( chan )))
 | 
			
		||||
						return DISCONNECTED;
 | 
			
		||||
					count++;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			chan = Channel_Next( chan );
 | 
			
		||||
			chan = Channel_Next(chan);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Get next name ... */
 | 
			
		||||
		if( Req->argc > 0 )
 | 
			
		||||
			pattern = strtok( NULL, "," );
 | 
			
		||||
		if(Req->argc > 0)
 | 
			
		||||
			pattern = strtok(NULL, ",");
 | 
			
		||||
		else
 | 
			
		||||
			pattern = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return IRC_WriteStrClient( from, RPL_LISTEND_MSG, Client_ID( from ));
 | 
			
		||||
	IRC_SetPenalty(from, 2);
 | 
			
		||||
	return IRC_WriteStrClient(from, RPL_LISTEND_MSG, Client_ID(from));
 | 
			
		||||
} /* IRC_LIST */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										68
									
								
								src/ngircd/irc-encoding.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/ngircd/irc-encoding.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * IRC encoding commands
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "conn-encoding.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "tool.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "irc-encoding.h"
 | 
			
		||||
 | 
			
		||||
#ifdef ICONV
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the IRC+ "CHARCONV" command.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Req Request structure with prefix and all parameters.
 | 
			
		||||
 * @returns CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_CHARCONV(CLIENT *Client, REQUEST *Req)
 | 
			
		||||
{
 | 
			
		||||
	char encoding[20];
 | 
			
		||||
 | 
			
		||||
	assert (Client != NULL);
 | 
			
		||||
	assert (Req != NULL);
 | 
			
		||||
 | 
			
		||||
	if (Req->argc != 1)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
	strlcpy(encoding, Req->argv[0], sizeof(encoding));
 | 
			
		||||
	ngt_UpperStr(encoding);
 | 
			
		||||
 | 
			
		||||
	if (!Conn_SetEncoding(Client_Conn(Client), encoding))
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_IP_CHARCONV_MSG,
 | 
			
		||||
					  Client_ID(Client), encoding);
 | 
			
		||||
 | 
			
		||||
	return IRC_WriteStrClient(Client, RPL_IP_CHARCONV_MSG,
 | 
			
		||||
				  Client_ID(Client), encoding);
 | 
			
		||||
} /* IRC_CHARCONV */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										24
									
								
								src/ngircd/irc-encoding.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/ngircd/irc-encoding.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __irc_encoding_h__
 | 
			
		||||
#define __irc_encoding_h__
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * IRC encoding commands (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
GLOBAL bool IRC_CHARCONV PARAMS((CLIENT *Client, REQUEST *Req));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -18,21 +18,18 @@
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "class.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "login.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "pam.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "irc.h"
 | 
			
		||||
#include "irc-info.h"
 | 
			
		||||
@@ -41,19 +38,10 @@
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "irc-login.h"
 | 
			
		||||
 | 
			
		||||
static void Kill_Nick PARAMS((char *Nick, char *Reason));
 | 
			
		||||
static void Change_Nick PARAMS((CLIENT * Origin, CLIENT * Target, char *NewNick,
 | 
			
		||||
				bool InformClient));
 | 
			
		||||
 | 
			
		||||
static bool Hello_User PARAMS(( CLIENT *Client ));
 | 
			
		||||
static bool Hello_User_PostAuth PARAMS(( CLIENT *Client ));
 | 
			
		||||
static void Kill_Nick PARAMS(( char *Nick, char *Reason ));
 | 
			
		||||
static void Introduce_Client PARAMS((CLIENT *To, CLIENT *Client, int Type));
 | 
			
		||||
static void Reject_Client PARAMS((CLIENT *Client));
 | 
			
		||||
 | 
			
		||||
static void cb_introduceClient PARAMS((CLIENT *Client, CLIENT *Prefix,
 | 
			
		||||
				       void *i));
 | 
			
		||||
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
static void cb_Read_Auth_Result PARAMS((int r_fd, UNUSED short events));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the IRC "PASS" command.
 | 
			
		||||
@@ -103,7 +91,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
					  Client_ID(Client));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Client_SetPassword(Client, Req->argv[0]);
 | 
			
		||||
	Conn_SetPassword(Client_Conn(Client), Req->argv[0]);
 | 
			
		||||
 | 
			
		||||
	/* Protocol version */
 | 
			
		||||
	if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) {
 | 
			
		||||
@@ -285,45 +273,14 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
			/* If we received a valid USER command already then
 | 
			
		||||
			 * register the new client! */
 | 
			
		||||
			if( Client_Type( Client ) == CLIENT_GOTUSER )
 | 
			
		||||
				return Hello_User( Client );
 | 
			
		||||
				return Login_User( Client );
 | 
			
		||||
			else
 | 
			
		||||
				Client_SetType( Client, CLIENT_GOTNICK );
 | 
			
		||||
		} else {
 | 
			
		||||
			/* Nickname change */
 | 
			
		||||
			if (Client_Conn(target) > NONE) {
 | 
			
		||||
				/* Local client */
 | 
			
		||||
				Log(LOG_INFO,
 | 
			
		||||
				    "%s \"%s\" changed nick (connection %d): \"%s\" -> \"%s\".",
 | 
			
		||||
				    Client_TypeText(target), Client_Mask(target),
 | 
			
		||||
				    Client_Conn(target), Client_ID(target),
 | 
			
		||||
				    Req->argv[0]);
 | 
			
		||||
				Conn_UpdateIdle(Client_Conn(target));
 | 
			
		||||
			} else {
 | 
			
		||||
				/* Remote client */
 | 
			
		||||
				LogDebug("%s \"%s\" changed nick: \"%s\" -> \"%s\".",
 | 
			
		||||
					 Client_TypeText(target),
 | 
			
		||||
					 Client_Mask(target), Client_ID(target),
 | 
			
		||||
					 Req->argv[0]);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* Inform all users and servers (which have to know)
 | 
			
		||||
			 * of this nickname change */
 | 
			
		||||
			if( Client_Type( Client ) == CLIENT_USER )
 | 
			
		||||
				IRC_WriteStrClientPrefix( Client, Client,
 | 
			
		||||
							  "NICK :%s",
 | 
			
		||||
							  Req->argv[0] );
 | 
			
		||||
			IRC_WriteStrServersPrefix( Client, target,
 | 
			
		||||
						   "NICK :%s", Req->argv[0] );
 | 
			
		||||
			IRC_WriteStrRelatedPrefix( target, target, false,
 | 
			
		||||
						   "NICK :%s", Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
			/* Register old nickname for WHOWAS queries */
 | 
			
		||||
			Client_RegisterWhowas( target );
 | 
			
		||||
 | 
			
		||||
			/* Save new nickname */
 | 
			
		||||
			Client_SetID( target, Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
			IRC_SetPenalty( target, 2 );
 | 
			
		||||
			Change_Nick(Client, target, Req->argv[0],
 | 
			
		||||
				    Client_Type(Client) == CLIENT_USER ? true : false);
 | 
			
		||||
			IRC_SetPenalty(target, 2);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
@@ -395,7 +352,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
				 Client_Mask(c));
 | 
			
		||||
			Client_SetType(c, CLIENT_GOTNICK);
 | 
			
		||||
		} else
 | 
			
		||||
			Introduce_Client(Client, c, CLIENT_USER);
 | 
			
		||||
			Client_Introduce(Client, c, CLIENT_USER);
 | 
			
		||||
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
@@ -403,6 +360,54 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
} /* IRC_NICK */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the IRC "SVSNICK" command.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Req Request structure with prefix and all parameters.
 | 
			
		||||
 * @return CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_SVSNICK(CLIENT *Client, REQUEST *Req)
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *from, *target;
 | 
			
		||||
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Req != NULL);
 | 
			
		||||
 | 
			
		||||
	if (Req->argc != 2)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
	/* Search the originator */
 | 
			
		||||
	from = Client_Search(Req->prefix);
 | 
			
		||||
	if (!from)
 | 
			
		||||
		from = Client;
 | 
			
		||||
 | 
			
		||||
	/* Search the target */
 | 
			
		||||
	target = Client_Search(Req->argv[0]);
 | 
			
		||||
	if (!target || Client_Type(target) != CLIENT_USER) {
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->argv[0]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (Client_Conn(target) <= NONE) {
 | 
			
		||||
		/* We have to forward the message to the server handling
 | 
			
		||||
		 * this user; this is required to make sure all servers
 | 
			
		||||
		 * in the network do follow the nick name change! */
 | 
			
		||||
		return IRC_WriteStrClientPrefix(Client_NextHop(target), from,
 | 
			
		||||
						"SVSNICK %s %s",
 | 
			
		||||
						Req->argv[0], Req->argv[1]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Make sure that the new nickname is valid */
 | 
			
		||||
	if (!Client_CheckNick(from, Req->argv[1]))
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
 | 
			
		||||
	Change_Nick(from, target, Req->argv[1], true);
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the IRC "USER" command.
 | 
			
		||||
 *
 | 
			
		||||
@@ -416,9 +421,7 @@ GLOBAL bool
 | 
			
		||||
IRC_USER(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
	char *ptr;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Req != NULL);
 | 
			
		||||
@@ -436,7 +439,20 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
						  Client_ID(Client),
 | 
			
		||||
						  Req->command);
 | 
			
		||||
 | 
			
		||||
		/* User name */
 | 
			
		||||
		/* User name: only alphanumeric characters and limited
 | 
			
		||||
		   punctuation is allowed.*/
 | 
			
		||||
		ptr = Req->argv[0];
 | 
			
		||||
		while (*ptr) {
 | 
			
		||||
			if (!isalnum((int)*ptr) &&
 | 
			
		||||
			    *ptr != '+' && *ptr != '-' &&
 | 
			
		||||
			    *ptr != '.' && *ptr != '_') {
 | 
			
		||||
				Conn_Close(Client_Conn(Client), NULL,
 | 
			
		||||
					   "Invalid user name", true);
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
			ptr++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
		ptr = Client_User(Client);
 | 
			
		||||
		if (!ptr || !*ptr || *ptr == '~')
 | 
			
		||||
@@ -457,7 +473,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
		LogDebug("Connection %d: got valid USER command ...",
 | 
			
		||||
		    Client_Conn(Client));
 | 
			
		||||
		if (Client_Type(Client) == CLIENT_GOTNICK)
 | 
			
		||||
			return Hello_User(Client);
 | 
			
		||||
			return Login_User(Client);
 | 
			
		||||
		else
 | 
			
		||||
			Client_SetType(Client, CLIENT_GOTUSER);
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
@@ -487,7 +503,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
		/* RFC 1459 style user registration?
 | 
			
		||||
		 * Introduce client to network: */
 | 
			
		||||
		if (Client_Type(c) == CLIENT_GOTNICK)
 | 
			
		||||
			Introduce_Client(Client, c, CLIENT_USER);
 | 
			
		||||
			Client_Introduce(Client, c, CLIENT_USER);
 | 
			
		||||
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	} else if (Client_Type(Client) == CLIENT_USER) {
 | 
			
		||||
@@ -550,10 +566,10 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req)
 | 
			
		||||
	hops = atoi(Req->argv[4]);
 | 
			
		||||
	info = Req->argv[5];
 | 
			
		||||
 | 
			
		||||
	/* Validate service name ("nick name") */
 | 
			
		||||
	/* Validate service name ("nickname") */
 | 
			
		||||
	c = Client_Search(nick);
 | 
			
		||||
	if(c) {
 | 
			
		||||
		/* Nick name collission: disconnect (KILL) both clients! */
 | 
			
		||||
		/* Nickname collission: disconnect (KILL) both clients! */
 | 
			
		||||
		Log(LOG_ERR, "Server %s introduces already registered service \"%s\"!",
 | 
			
		||||
		    Client_ID(Client), nick);
 | 
			
		||||
		Kill_Nick(nick, "Nick collision");
 | 
			
		||||
@@ -601,7 +617,7 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req)
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Introduce_Client(Client, c, CLIENT_SERVICE);
 | 
			
		||||
	Client_Introduce(Client, c, CLIENT_SERVICE);
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_SERVICE */
 | 
			
		||||
 | 
			
		||||
@@ -653,32 +669,37 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	CLIENT *target;
 | 
			
		||||
	char quitmsg[LINE_LEN];
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Req != NULL);
 | 
			
		||||
 | 
			
		||||
	/* Wrong number of arguments? */
 | 
			
		||||
	if( Req->argc > 1 )
 | 
			
		||||
		return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
	if (Req->argc > 1)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
	if (Req->argc == 1)
 | 
			
		||||
		strlcpy(quitmsg, Req->argv[0], sizeof quitmsg);
 | 
			
		||||
 | 
			
		||||
	if ( Client_Type( Client ) == CLIENT_SERVER )
 | 
			
		||||
	{
 | 
			
		||||
	if (Client_Type(Client) == CLIENT_SERVER) {
 | 
			
		||||
		/* Server */
 | 
			
		||||
		target = Client_Search( Req->prefix );
 | 
			
		||||
		if( ! target )
 | 
			
		||||
		{
 | 
			
		||||
			Log( LOG_WARNING, "Got QUIT from %s for unknown client!?", Client_ID( Client ));
 | 
			
		||||
		target = Client_Search(Req->prefix);
 | 
			
		||||
		if (!target) {
 | 
			
		||||
			Log(LOG_WARNING,
 | 
			
		||||
			    "Got QUIT from %s for unknown client!?",
 | 
			
		||||
			    Client_ID(Client));
 | 
			
		||||
			return CONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Client_Destroy( target, "Got QUIT command.", Req->argc == 1 ? quitmsg : NULL, true);
 | 
			
		||||
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if (target != Client) {
 | 
			
		||||
			Client_Destroy(target, "Got QUIT command.",
 | 
			
		||||
				       Req->argc == 1 ? quitmsg : NULL, true);
 | 
			
		||||
			return CONNECTED;
 | 
			
		||||
		} else {
 | 
			
		||||
			Conn_Close(Client_Conn(Client), "Got QUIT command.",
 | 
			
		||||
				   Req->argc == 1 ? quitmsg : NULL, true);
 | 
			
		||||
			return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		if (Req->argc == 1 && quitmsg[0] != '\"') {
 | 
			
		||||
			/* " " to avoid confusion */
 | 
			
		||||
			strlcpy(quitmsg, "\"", sizeof quitmsg);
 | 
			
		||||
@@ -687,7 +708,8 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* User, Service, or not yet registered */
 | 
			
		||||
		Conn_Close( Client_Conn( Client ), "Got QUIT command.", Req->argc == 1 ? quitmsg : NULL, true);
 | 
			
		||||
		Conn_Close(Client_Conn(Client), "Got QUIT command.",
 | 
			
		||||
			   Req->argc == 1 ? quitmsg : NULL, true);
 | 
			
		||||
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
@@ -874,7 +896,7 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
 | 
			
		||||
		if (auth_ping == atoi(Req->argv[0])) {
 | 
			
		||||
			Conn_SetAuthPing(conn, 0);
 | 
			
		||||
			if (Client_Type(Client) == CLIENT_WAITAUTHPING)
 | 
			
		||||
				Hello_User(Client);
 | 
			
		||||
				Login_User(Client);
 | 
			
		||||
		} else
 | 
			
		||||
			if (!IRC_WriteStrClient(Client,
 | 
			
		||||
					"To connect, type /QUOTE PONG %ld",
 | 
			
		||||
@@ -883,327 +905,84 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	if (conn > NONE)
 | 
			
		||||
		Log(LOG_DEBUG,
 | 
			
		||||
			"Connection %d: received PONG. Lag: %ld seconds.", conn,
 | 
			
		||||
			time(NULL) - Conn_LastPing(Client_Conn(Client)));
 | 
			
		||||
	else
 | 
			
		||||
		 Log(LOG_DEBUG,
 | 
			
		||||
			"Connection %d: received PONG.", conn);
 | 
			
		||||
#endif
 | 
			
		||||
	if (Client_Type(Client) == CLIENT_SERVER && Conn_LastPing(conn) == 0) {
 | 
			
		||||
		Log(LOG_INFO,
 | 
			
		||||
		    "Synchronization with \"%s\" done (connection %d): %ld seconds [%ld users, %ld channels]",
 | 
			
		||||
		    Client_ID(Client), conn, time(NULL) - Conn_GetSignon(conn),
 | 
			
		||||
		    Client_UserCount(), Channel_CountVisible(NULL));
 | 
			
		||||
		Conn_UpdatePing(conn);
 | 
			
		||||
	} else
 | 
			
		||||
		LogDebug("Connection %d: received PONG. Lag: %ld seconds.",
 | 
			
		||||
			 conn, time(NULL) - Conn_LastPing(conn));
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_PONG */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initiate client registration.
 | 
			
		||||
 * Kill all users with a specific nickname in the network.
 | 
			
		||||
 *
 | 
			
		||||
 * This function is called after the daemon received the required NICK and
 | 
			
		||||
 * USER commands of a new client. If the daemon is compiled with support for
 | 
			
		||||
 * PAM, the authentication sub-processs is forked; otherwise the global server
 | 
			
		||||
 * password is checked.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client	The client logging in.
 | 
			
		||||
 * @returns		CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
static bool
 | 
			
		||||
Hello_User(CLIENT * Client)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
	int pipefd[2], result;
 | 
			
		||||
	pid_t pid;
 | 
			
		||||
#endif
 | 
			
		||||
	CONN_ID conn;
 | 
			
		||||
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	conn = Client_Conn(Client);
 | 
			
		||||
 | 
			
		||||
#ifndef STRICT_RFC
 | 
			
		||||
	if (Conf_AuthPing) {
 | 
			
		||||
		/* Did we receive the "auth PONG" already? */
 | 
			
		||||
		if (Conn_GetAuthPing(conn)) {
 | 
			
		||||
			Client_SetType(Client, CLIENT_WAITAUTHPING);
 | 
			
		||||
			LogDebug("Connection %d: Waiting for AUTH PONG ...", conn);
 | 
			
		||||
			return CONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
	if (!Conf_PAM) {
 | 
			
		||||
		/* Don't do any PAM authentication at all, instead emulate
 | 
			
		||||
		 * the beahiour of the daemon compiled without PAM support:
 | 
			
		||||
		 * because there can't be any "server password", all
 | 
			
		||||
		 * passwords supplied are classified as "wrong". */
 | 
			
		||||
		if(Client_Password(Client)[0] == '\0')
 | 
			
		||||
			return Hello_User_PostAuth(Client);
 | 
			
		||||
		Reject_Client(Client);
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Fork child process for PAM authentication; and make sure that the
 | 
			
		||||
	 * process timeout is set higher than the login timeout! */
 | 
			
		||||
	pid = Proc_Fork(Conn_GetProcStat(conn), pipefd,
 | 
			
		||||
			cb_Read_Auth_Result, Conf_PongTimeout + 1);
 | 
			
		||||
	if (pid > 0) {
 | 
			
		||||
		LogDebug("Authenticator for connection %d created (PID %d).",
 | 
			
		||||
			 conn, pid);
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	} else {
 | 
			
		||||
		/* Sub process */
 | 
			
		||||
		Log_Init_Subprocess("Auth");
 | 
			
		||||
		result = PAM_Authenticate(Client);
 | 
			
		||||
		if (write(pipefd[1], &result, sizeof(result)) != sizeof(result))
 | 
			
		||||
			Log_Subprocess(LOG_ERR,
 | 
			
		||||
				       "Failed to pipe result to parent!");
 | 
			
		||||
		Log_Exit_Subprocess("Auth");
 | 
			
		||||
		exit(0);
 | 
			
		||||
	}
 | 
			
		||||
#else
 | 
			
		||||
	/* Check global server password ... */
 | 
			
		||||
	if (strcmp(Client_Password(Client), Conf_ServerPwd) != 0) {
 | 
			
		||||
		/* Bad password! */
 | 
			
		||||
		Reject_Client(Client);
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	return Hello_User_PostAuth(Client);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Read result of the authenticatior sub-process from pipe
 | 
			
		||||
 *
 | 
			
		||||
 * @param r_fd		File descriptor of the pipe.
 | 
			
		||||
 * @param events	(ignored IO specification)
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
cb_Read_Auth_Result(int r_fd, UNUSED short events)
 | 
			
		||||
{
 | 
			
		||||
	CONN_ID conn;
 | 
			
		||||
	CLIENT *client;
 | 
			
		||||
	int result;
 | 
			
		||||
	size_t len;
 | 
			
		||||
	PROC_STAT *proc;
 | 
			
		||||
 | 
			
		||||
	LogDebug("Auth: Got callback on fd %d, events %d", r_fd, events);
 | 
			
		||||
	conn = Conn_GetFromProc(r_fd);
 | 
			
		||||
	if (conn == NONE) {
 | 
			
		||||
		/* Ops, none found? Probably the connection has already
 | 
			
		||||
		 * been closed!? We'll ignore that ... */
 | 
			
		||||
		io_close(r_fd);
 | 
			
		||||
		LogDebug("Auth: Got callback for unknown connection!?");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	proc = Conn_GetProcStat(conn);
 | 
			
		||||
	client = Conn_GetClient(conn);
 | 
			
		||||
 | 
			
		||||
	/* Read result from pipe */
 | 
			
		||||
	len = Proc_Read(proc, &result, sizeof(result));
 | 
			
		||||
	if (len == 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (len != sizeof(result)) {
 | 
			
		||||
		Log(LOG_CRIT, "Auth: Got malformed result!");
 | 
			
		||||
		Reject_Client(client);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (result == true) {
 | 
			
		||||
		Client_SetUser(client, Client_OrigUser(client), true);
 | 
			
		||||
		(void)Hello_User_PostAuth(client);
 | 
			
		||||
	} else
 | 
			
		||||
		Reject_Client(client);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reject a client because of wrong password.
 | 
			
		||||
 *
 | 
			
		||||
 * This function is called either when the global server password or a password
 | 
			
		||||
 * checked using PAM has been wrong.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client	The client to reject.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
Reject_Client(CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	Log(LOG_ERR,
 | 
			
		||||
	    "User \"%s\" rejected (connection %d): Access denied!",
 | 
			
		||||
	    Client_Mask(Client), Client_Conn(Client));
 | 
			
		||||
	Conn_Close(Client_Conn(Client), NULL,
 | 
			
		||||
		   "Access denied! Bad password?", true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Finish client registration.
 | 
			
		||||
 *
 | 
			
		||||
 * Introduce the new client to the network and send all "hello messages"
 | 
			
		||||
 * to it after authentication has been succeeded.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client	The client logging in.
 | 
			
		||||
 * @returns		CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
static bool
 | 
			
		||||
Hello_User_PostAuth(CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	Introduce_Client(NULL, Client, CLIENT_USER);
 | 
			
		||||
 | 
			
		||||
	if (!IRC_WriteStrClient
 | 
			
		||||
	    (Client, RPL_WELCOME_MSG, Client_ID(Client), Client_Mask(Client)))
 | 
			
		||||
		return false;
 | 
			
		||||
	if (!IRC_WriteStrClient
 | 
			
		||||
	    (Client, RPL_YOURHOST_MSG, Client_ID(Client),
 | 
			
		||||
	     Client_ID(Client_ThisServer()), PACKAGE_VERSION, TARGET_CPU,
 | 
			
		||||
	     TARGET_VENDOR, TARGET_OS))
 | 
			
		||||
		return false;
 | 
			
		||||
	if (!IRC_WriteStrClient
 | 
			
		||||
	    (Client, RPL_CREATED_MSG, Client_ID(Client), NGIRCd_StartStr))
 | 
			
		||||
		return false;
 | 
			
		||||
	if (!IRC_WriteStrClient
 | 
			
		||||
	    (Client, RPL_MYINFO_MSG, Client_ID(Client),
 | 
			
		||||
	     Client_ID(Client_ThisServer()), PACKAGE_VERSION, USERMODES,
 | 
			
		||||
	     CHANMODES))
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	/* 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;
 | 
			
		||||
 | 
			
		||||
	if (!IRC_Send_LUSERS(Client))
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
	if (!IRC_Show_MOTD(Client))
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	/* Suspend the client for a second ... */
 | 
			
		||||
	IRC_SetPenalty(Client, 1);
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Kill all users with a specific nick name in the network.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Nick		Nick name.
 | 
			
		||||
 * @param Nick		Nickname.
 | 
			
		||||
 * @param Reason	Reason for the KILL.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
Kill_Nick( char *Nick, char *Reason )
 | 
			
		||||
Kill_Nick(char *Nick, char *Reason)
 | 
			
		||||
{
 | 
			
		||||
	REQUEST r;
 | 
			
		||||
 | 
			
		||||
	assert( Nick != NULL );
 | 
			
		||||
	assert( Reason != NULL );
 | 
			
		||||
	assert (Nick != NULL);
 | 
			
		||||
	assert (Reason != NULL);
 | 
			
		||||
 | 
			
		||||
	r.prefix = (char *)Client_ThisServer( );
 | 
			
		||||
	r.prefix = NULL;
 | 
			
		||||
	r.argv[0] = Nick;
 | 
			
		||||
	r.argv[1] = Reason;
 | 
			
		||||
	r.argc = 2;
 | 
			
		||||
 | 
			
		||||
	Log( LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s", Nick, Reason );
 | 
			
		||||
	IRC_KILL( Client_ThisServer( ), &r );
 | 
			
		||||
	Log(LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s",
 | 
			
		||||
	    Nick, Reason);
 | 
			
		||||
 | 
			
		||||
	IRC_KILL(Client_ThisServer(), &r);
 | 
			
		||||
} /* Kill_Nick */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Introduce a new user or service client in the network.
 | 
			
		||||
 * Change the nickname of a client.
 | 
			
		||||
 *
 | 
			
		||||
 * @param From		Remote server introducing the client or NULL (local).
 | 
			
		||||
 * @param Client	New client.
 | 
			
		||||
 * @param Type		Type of the client (CLIENT_USER or CLIENT_SERVICE).
 | 
			
		||||
 * @param Origin The client which caused the nickname change.
 | 
			
		||||
 * @param Target The client of which the nickname should be changed.
 | 
			
		||||
 * @param NewNick The new nickname.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
Introduce_Client(CLIENT *From, CLIENT *Client, int Type)
 | 
			
		||||
Change_Nick(CLIENT *Origin, CLIENT *Target, char *NewNick, bool InformClient)
 | 
			
		||||
{
 | 
			
		||||
	/* Set client type (user or service) */
 | 
			
		||||
	Client_SetType(Client, Type);
 | 
			
		||||
 | 
			
		||||
	if (From) {
 | 
			
		||||
		if (Conf_IsService(Conf_GetServer(Client_Conn(From)),
 | 
			
		||||
				   Client_ID(Client)))
 | 
			
		||||
			Client_SetType(Client, CLIENT_SERVICE);
 | 
			
		||||
		LogDebug("%s \"%s\" (+%s) registered (via %s, on %s, %d hop%s).",
 | 
			
		||||
			 Client_TypeText(Client), Client_Mask(Client),
 | 
			
		||||
			 Client_Modes(Client), Client_ID(From),
 | 
			
		||||
			 Client_ID(Client_Introducer(Client)),
 | 
			
		||||
			 Client_Hops(Client), Client_Hops(Client) > 1 ? "s": "");
 | 
			
		||||
	if (Client_Conn(Target) > NONE) {
 | 
			
		||||
		/* Local client */
 | 
			
		||||
		Log(LOG_INFO,
 | 
			
		||||
		    "%s \"%s\" changed nick (connection %d): \"%s\" -> \"%s\".",
 | 
			
		||||
		    Client_TypeText(Target), Client_Mask(Target),
 | 
			
		||||
		    Client_Conn(Target), Client_ID(Target), NewNick);
 | 
			
		||||
		Conn_UpdateIdle(Client_Conn(Target));
 | 
			
		||||
	} else {
 | 
			
		||||
		Log(LOG_NOTICE, "%s \"%s\" registered (connection %d).",
 | 
			
		||||
		    Client_TypeText(Client), Client_Mask(Client),
 | 
			
		||||
		    Client_Conn(Client));
 | 
			
		||||
		Log_ServerNotice('c', "Client connecting: %s (%s@%s) [%s] - %s",
 | 
			
		||||
			         Client_ID(Client), Client_User(Client),
 | 
			
		||||
				 Client_Hostname(Client),
 | 
			
		||||
				 Conn_IPA(Client_Conn(Client)),
 | 
			
		||||
				 Client_TypeText(Client));
 | 
			
		||||
		/* Remote client */
 | 
			
		||||
		LogDebug("%s \"%s\" changed nick: \"%s\" -> \"%s\".",
 | 
			
		||||
			 Client_TypeText(Target),
 | 
			
		||||
			 Client_Mask(Target), Client_ID(Target), NewNick);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Inform other servers */
 | 
			
		||||
	IRC_WriteStrServersPrefixFlag_CB(From,
 | 
			
		||||
				From != NULL ? From : Client_ThisServer(),
 | 
			
		||||
				'\0', cb_introduceClient, (void *)Client);
 | 
			
		||||
} /* Introduce_Client */
 | 
			
		||||
	/* Inform all servers and users (which have to know) of the new name */
 | 
			
		||||
	if (InformClient) {
 | 
			
		||||
		IRC_WriteStrClientPrefix(Target, Target, "NICK :%s", NewNick);
 | 
			
		||||
		IRC_WriteStrServersPrefix(NULL, Target, "NICK :%s", NewNick);
 | 
			
		||||
	} else
 | 
			
		||||
		IRC_WriteStrServersPrefix(Origin, Target, "NICK :%s", NewNick);
 | 
			
		||||
	IRC_WriteStrRelatedPrefix(Target, Target, false, "NICK :%s", NewNick);
 | 
			
		||||
 | 
			
		||||
	/* Register old nickname for WHOWAS queries */
 | 
			
		||||
	Client_RegisterWhowas(Target);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Introduce a new user or service client to a remote server.
 | 
			
		||||
 *
 | 
			
		||||
 * This function differentiates between RFC1459 and RFC2813 server links and
 | 
			
		||||
 * generates the appropriate commands to register the new user or service.
 | 
			
		||||
 *
 | 
			
		||||
 * @param To		The remote server to inform.
 | 
			
		||||
 * @param Prefix	Prefix for the generated commands.
 | 
			
		||||
 * @param data		CLIENT structure of the new client.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
cb_introduceClient(CLIENT *To, CLIENT *Prefix, void *data)
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c = (CLIENT *)data;
 | 
			
		||||
	CONN_ID conn;
 | 
			
		||||
	char *modes, *user, *host;
 | 
			
		||||
 | 
			
		||||
	modes = Client_Modes(c);
 | 
			
		||||
	user = Client_User(c) ? Client_User(c) : "-";
 | 
			
		||||
	host = Client_Hostname(c) ? Client_Hostname(c) : "-";
 | 
			
		||||
 | 
			
		||||
	conn = Client_Conn(To);
 | 
			
		||||
	if (Conn_Options(conn) & CONN_RFC1459) {
 | 
			
		||||
		/* RFC 1459 mode: separate NICK and USER commands */
 | 
			
		||||
		Conn_WriteStr(conn, "NICK %s :%d", Client_ID(c),
 | 
			
		||||
			      Client_Hops(c) + 1);
 | 
			
		||||
		Conn_WriteStr(conn, ":%s USER %s %s %s :%s",
 | 
			
		||||
			      Client_ID(c), user, host,
 | 
			
		||||
			      Client_ID(Client_Introducer(c)), Client_Info(c));
 | 
			
		||||
		if (modes[0])
 | 
			
		||||
			Conn_WriteStr(conn, ":%s MODE %s +%s",
 | 
			
		||||
				      Client_ID(c), Client_ID(c), modes);
 | 
			
		||||
	} else {
 | 
			
		||||
		/* RFC 2813 mode: one combined NICK or SERVICE command */
 | 
			
		||||
		if (Client_Type(c) == CLIENT_SERVICE
 | 
			
		||||
		    && strchr(Client_Flags(To), 'S'))
 | 
			
		||||
			IRC_WriteStrClientPrefix(To, Prefix,
 | 
			
		||||
					 "SERVICE %s %d * +%s %d :%s",
 | 
			
		||||
					 Client_Mask(c),
 | 
			
		||||
					 Client_MyToken(Client_Introducer(c)),
 | 
			
		||||
					 Client_Modes(c), Client_Hops(c) + 1,
 | 
			
		||||
					 Client_Info(c));
 | 
			
		||||
		else
 | 
			
		||||
			IRC_WriteStrClientPrefix(To, Prefix,
 | 
			
		||||
					 "NICK %s %d %s %s %d +%s :%s",
 | 
			
		||||
					 Client_ID(c), Client_Hops(c) + 1,
 | 
			
		||||
					 user, host,
 | 
			
		||||
					 Client_MyToken(Client_Introducer(c)),
 | 
			
		||||
					 modes, Client_Info(c));
 | 
			
		||||
	}
 | 
			
		||||
} /* cb_introduceClient */
 | 
			
		||||
	/* Save new nickname */
 | 
			
		||||
	Client_SetID(Target, NewNick);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -26,6 +26,7 @@ GLOBAL bool IRC_PING PARAMS((CLIENT *Client, REQUEST *Req));
 | 
			
		||||
GLOBAL bool IRC_PONG PARAMS((CLIENT *Client, REQUEST *Req));
 | 
			
		||||
GLOBAL bool IRC_QUIT PARAMS((CLIENT *Client, REQUEST *Req));
 | 
			
		||||
GLOBAL bool IRC_QUIT_HTTP PARAMS((CLIENT *Client, REQUEST *Req));
 | 
			
		||||
GLOBAL bool IRC_SVSNICK PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										109
									
								
								src/ngircd/irc-metadata.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								src/ngircd/irc-metadata.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define __irc_metadata_c__
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * IRC metadata commands
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "conn-encoding.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "tool.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "irc-metadata.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the IRC+ "METADATA" command.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Req Request structure with prefix and all parameters.
 | 
			
		||||
 * @returns CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_METADATA(CLIENT *Client, REQUEST *Req)
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *prefix, *target;
 | 
			
		||||
	char new_flags[COMMAND_LEN];
 | 
			
		||||
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Req != NULL);
 | 
			
		||||
 | 
			
		||||
	if (Req->argc != 3)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
	prefix = Client_Search(Req->prefix);
 | 
			
		||||
	if (!prefix)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->prefix);
 | 
			
		||||
 | 
			
		||||
	target = Client_Search(Req->argv[0]);
 | 
			
		||||
	if (!target)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->argv[0]);
 | 
			
		||||
 | 
			
		||||
	LogDebug("Got \"METADATA\" command from \"%s\" for client \"%s\": \"%s=%s\".",
 | 
			
		||||
		 Client_ID(prefix), Client_ID(target),
 | 
			
		||||
		 Req->argv[1], Req->argv[2]);
 | 
			
		||||
 | 
			
		||||
	/* Mark client: it has receiveda a METADATA command */
 | 
			
		||||
	if (!strchr(Client_Flags(target), 'M')) {
 | 
			
		||||
		snprintf(new_flags, sizeof new_flags, "%sM",
 | 
			
		||||
			 Client_Flags(target));
 | 
			
		||||
		Client_SetFlags(target, new_flags);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (strcasecmp(Req->argv[1], "cloakhost") == 0) {
 | 
			
		||||
		Client_UpdateCloakedHostname(target, prefix, Req->argv[2]);
 | 
			
		||||
		if (Client_Conn(target) > NONE && Client_HasMode(target, 'x'))
 | 
			
		||||
			IRC_WriteStrClientPrefix(target, prefix,
 | 
			
		||||
					RPL_HOSTHIDDEN_MSG, Client_ID(target),
 | 
			
		||||
					Client_HostnameDisplayed(target));
 | 
			
		||||
		/* The Client_UpdateCloakedHostname() function already
 | 
			
		||||
		 * forwarded the METADATA command, don't do it twice: */
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	else if (*Req->argv[2] && strcasecmp(Req->argv[1], "host") == 0) {
 | 
			
		||||
		Client_SetHostname(target, Req->argv[2]);
 | 
			
		||||
		if (Client_Conn(target) > NONE && !Client_HasMode(target, 'x'))
 | 
			
		||||
			IRC_WriteStrClientPrefix(target, prefix,
 | 
			
		||||
						 RPL_HOSTHIDDEN_MSG, Client_ID(target),
 | 
			
		||||
						 Client_HostnameDisplayed(target));
 | 
			
		||||
	} else if (strcasecmp(Req->argv[1], "info") == 0)
 | 
			
		||||
		Client_SetInfo(target, Req->argv[2]);
 | 
			
		||||
	else if (*Req->argv[2] && strcasecmp(Req->argv[1], "user") == 0)
 | 
			
		||||
		Client_SetUser(target, Req->argv[2], true);
 | 
			
		||||
	else
 | 
			
		||||
		Log(LOG_WARNING,
 | 
			
		||||
		    "Ignored metadata update from \"%s\" for client \"%s\": \"%s=%s\" - unknown key!",
 | 
			
		||||
		    Client_ID(Client), Client_ID(target),
 | 
			
		||||
		    Req->argv[1], Req->argv[2]);
 | 
			
		||||
 | 
			
		||||
	/* Forward the METADATA command to peers that support it: */
 | 
			
		||||
	IRC_WriteStrServersPrefixFlag(Client, prefix, 'M', "METADATA %s %s :%s",
 | 
			
		||||
				Client_ID(target), Req->argv[1], Req->argv[2]);
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								src/ngircd/irc-metadata.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/ngircd/irc-metadata.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __irc_metadata_h__
 | 
			
		||||
#define __irc_metadata_h__
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * IRC metadata commands (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
GLOBAL bool IRC_METADATA PARAMS((CLIENT *Client, REQUEST *Req));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -164,10 +164,18 @@ IRC_INVITE(CLIENT *Client, REQUEST *Req)
 | 
			
		||||
		if (!Channel_IsMemberOf(chan, from))
 | 
			
		||||
			return IRC_WriteStrClient(from, ERR_NOTONCHANNEL_MSG, Client_ID(Client), Req->argv[1]);
 | 
			
		||||
 | 
			
		||||
		/* Is the channel "invite-disallow"? */
 | 
			
		||||
		if (strchr(Channel_Modes(chan), 'V'))
 | 
			
		||||
			return IRC_WriteStrClient(from, ERR_NOINVITE_MSG,
 | 
			
		||||
				Client_ID(from), Channel_Name(chan));
 | 
			
		||||
 | 
			
		||||
		/* Is the channel "invite-only"? */
 | 
			
		||||
		if (strchr(Channel_Modes(chan), 'i')) {
 | 
			
		||||
			/* Yes. The user must be channel operator! */
 | 
			
		||||
			if (!strchr(Channel_UserModes(chan, from), 'o'))
 | 
			
		||||
			/* Yes. The user must be channel owner/admin/operator/halfop! */
 | 
			
		||||
			if (!strchr(Channel_UserModes(chan, from), 'q') &&
 | 
			
		||||
			    !strchr(Channel_UserModes(chan, from), 'a') &&
 | 
			
		||||
			    !strchr(Channel_UserModes(chan, from), 'o') &&
 | 
			
		||||
			    !strchr(Channel_UserModes(chan, from), 'h'))
 | 
			
		||||
				return IRC_WriteStrClient(from, ERR_CHANOPRIVSNEEDED_MSG,
 | 
			
		||||
						Client_ID(from), Channel_Name(chan));
 | 
			
		||||
			remember = true;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -27,6 +27,7 @@
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "class.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "match.h"
 | 
			
		||||
@@ -37,7 +38,6 @@
 | 
			
		||||
#include <exp.h>
 | 
			
		||||
#include "irc-oper.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle invalid received OPER command.
 | 
			
		||||
 * Log OPER attempt and send error message to client.
 | 
			
		||||
@@ -52,7 +52,15 @@ Bad_OperPass(CLIENT *Client, char *errtoken, char *errmsg)
 | 
			
		||||
				  Client_ID(Client));
 | 
			
		||||
} /* Bad_OperPass */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the IRC "OPER" command.
 | 
			
		||||
 *
 | 
			
		||||
 * See RFC 2812, 3.1.4 "Oper message".
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Req Request structure with prefix and all parameters.
 | 
			
		||||
 * @return CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_OPER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
@@ -62,7 +70,9 @@ IRC_OPER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
	len = array_length(&Conf_Opers, sizeof(*op));
 | 
			
		||||
	op = array_start(&Conf_Opers);
 | 
			
		||||
@@ -77,20 +87,33 @@ IRC_OPER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	if (op[i].mask && (!Match(op[i].mask, Client_Mask(Client))))
 | 
			
		||||
		return Bad_OperPass(Client, op[i].mask, "hostmask check failed");
 | 
			
		||||
 | 
			
		||||
	if( ! Client_HasMode( Client, 'o' ))
 | 
			
		||||
	{
 | 
			
		||||
		Client_ModeAdd( Client, 'o' );
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, "MODE %s :+o", Client_ID( Client ))) return DISCONNECTED;
 | 
			
		||||
		IRC_WriteStrServersPrefix( NULL, Client, "MODE %s :+o", Client_ID( Client ));
 | 
			
		||||
	if (!Client_HasMode(Client, 'o')) {
 | 
			
		||||
		Client_ModeAdd(Client, 'o');
 | 
			
		||||
		if (!IRC_WriteStrClient(Client, "MODE %s :+o",
 | 
			
		||||
					Client_ID(Client)))
 | 
			
		||||
			return DISCONNECTED;
 | 
			
		||||
		IRC_WriteStrServersPrefix(NULL, Client, "MODE %s :+o",
 | 
			
		||||
					  Client_ID(Client));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( ! Client_OperByMe( Client )) Log( LOG_NOTICE|LOG_snotice, "Got valid OPER from \"%s\", user is an IRC operator now.", Client_Mask( Client ));
 | 
			
		||||
	if (!Client_OperByMe(Client))
 | 
			
		||||
		Log(LOG_NOTICE|LOG_snotice,
 | 
			
		||||
		    "Got valid OPER from \"%s\", user is an IRC operator now.",
 | 
			
		||||
		    Client_Mask(Client));
 | 
			
		||||
 | 
			
		||||
	Client_SetOperByMe( Client, true);
 | 
			
		||||
	return IRC_WriteStrClient( Client, RPL_YOUREOPER_MSG, Client_ID( Client ));
 | 
			
		||||
	Client_SetOperByMe(Client, true);
 | 
			
		||||
	return IRC_WriteStrClient(Client, RPL_YOUREOPER_MSG, Client_ID(Client));
 | 
			
		||||
} /* IRC_OPER */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the IRC "DIE" command.
 | 
			
		||||
 *
 | 
			
		||||
 * See RFC 2812, 4.3 "Die message".
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Req Request structure with prefix and all parameters.
 | 
			
		||||
 * @return CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_DIE(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
{
 | 
			
		||||
@@ -133,7 +156,15 @@ IRC_DIE(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_DIE */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the IRC "REHASH" command.
 | 
			
		||||
 *
 | 
			
		||||
 * See RFC 2812, 4.2 "Rehash message".
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Req Request structure with prefix and all parameters.
 | 
			
		||||
 * @return CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_REHASH( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
@@ -146,15 +177,28 @@ IRC_REHASH( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		return Op_NoPrivileges(Client, Req);
 | 
			
		||||
 | 
			
		||||
	/* Bad number of parameters? */
 | 
			
		||||
	if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
	if (Req->argc != 0)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command );
 | 
			
		||||
 | 
			
		||||
	Log(LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...",
 | 
			
		||||
	    Client_Mask(Client));
 | 
			
		||||
	IRC_WriteStrClient(Client, RPL_REHASHING_MSG, Client_ID(Client));
 | 
			
		||||
 | 
			
		||||
	Log( LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...", Client_Mask( Client ));
 | 
			
		||||
	raise(SIGHUP);
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_REHASH */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the IRC "RESTART" command.
 | 
			
		||||
 *
 | 
			
		||||
 * See RFC 2812, 4.4 "Restart message".
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Req Request structure with prefix and all parameters.
 | 
			
		||||
 * @return CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_RESTART( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
@@ -167,16 +211,25 @@ IRC_RESTART( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		return Op_NoPrivileges(Client, Req);
 | 
			
		||||
 | 
			
		||||
	/* Bad number of parameters? */
 | 
			
		||||
	if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
	if (Req->argc != 0)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
	Log( LOG_NOTICE|LOG_snotice, "Got RESTART command from \"%s\" ...", Client_Mask( Client ));
 | 
			
		||||
	Log(LOG_NOTICE|LOG_snotice, "Got RESTART command from \"%s\" ...",
 | 
			
		||||
	    Client_Mask(Client));
 | 
			
		||||
	NGIRCd_SignalRestart = true;
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_RESTART */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Connect configured or new server.
 | 
			
		||||
 * Handler for the IRC "CONNECT" command.
 | 
			
		||||
 *
 | 
			
		||||
 * See RFC 2812, 3.4.7 "Connect message".
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Req Request structure with prefix and all parameters.
 | 
			
		||||
 * @return CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_CONNECT(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
@@ -272,9 +325,15 @@ IRC_CONNECT(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_CONNECT */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Disconnect (and disable) configured server.
 | 
			
		||||
 * Handler for the IRC "DISCONNECT" command.
 | 
			
		||||
 *
 | 
			
		||||
 * This command is not specified in the IRC RFCs, it is an extension
 | 
			
		||||
 * of ngIRCd: it shuts down and disables a configured server connection.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Req Request structure with prefix and all parameters.
 | 
			
		||||
 * @return CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_DISCONNECT(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
@@ -315,7 +374,15 @@ IRC_DISCONNECT(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
} /* IRC_DISCONNECT */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handler for the IRC "WALLOPS" command.
 | 
			
		||||
 *
 | 
			
		||||
 * See RFC 2812, 4.7 "Operwall message".
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Req Request structure with prefix and all parameters.
 | 
			
		||||
 * @return CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
@@ -325,12 +392,14 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if (Req->argc != 1)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command);
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
	switch (Client_Type(Client)) {
 | 
			
		||||
	case CLIENT_USER:
 | 
			
		||||
		if (!Client_OperByMe(Client))
 | 
			
		||||
			return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG, Client_ID(Client));
 | 
			
		||||
			return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
 | 
			
		||||
						  Client_ID(Client));
 | 
			
		||||
		from = Client;
 | 
			
		||||
		break;
 | 
			
		||||
	case CLIENT_SERVER:
 | 
			
		||||
@@ -341,11 +410,87 @@ IRC_WALLOPS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!from)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix);
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->prefix);
 | 
			
		||||
 | 
			
		||||
	IRC_SendWallops(Client, from, "%s", Req->argv[0]);
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_WALLOPS */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Handle <?>LINE commands (GLINE, KLINE).
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client from which this command has been received.
 | 
			
		||||
 * @param Req Request structure with prefix and all parameters.
 | 
			
		||||
 * @return CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_xLINE(CLIENT *Client, REQUEST *Req)
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *from;
 | 
			
		||||
	int class;
 | 
			
		||||
	char class_c;
 | 
			
		||||
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Req != NULL);
 | 
			
		||||
 | 
			
		||||
	from = Op_Check(Client, Req);
 | 
			
		||||
	if (!from)
 | 
			
		||||
		return Op_NoPrivileges(Client, Req);
 | 
			
		||||
 | 
			
		||||
	/* Bad number of parameters? */
 | 
			
		||||
	if (Req->argc != 1 && Req->argc != 3)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->command);
 | 
			
		||||
 | 
			
		||||
	switch(Req->command[0]) {
 | 
			
		||||
		case 'g':
 | 
			
		||||
		case 'G':
 | 
			
		||||
			class = CLASS_GLINE; class_c = 'G';
 | 
			
		||||
			break;
 | 
			
		||||
		case 'k':
 | 
			
		||||
		case 'K':
 | 
			
		||||
			class = CLASS_KLINE; class_c = 'K';
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			Log(LOG_CRIT,
 | 
			
		||||
			    "IRC_xLINE() called for unknown line: %c!? Ignored.",
 | 
			
		||||
			    Req->command[0]);
 | 
			
		||||
			return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (Req->argc == 1) {
 | 
			
		||||
		/* Delete mask from list */
 | 
			
		||||
		Class_DeleteMask(class, Req->argv[0]);
 | 
			
		||||
		Log(LOG_NOTICE|LOG_snotice,
 | 
			
		||||
		    "\"%s\" deleted \"%s\" from %c-Line list.",
 | 
			
		||||
		    Client_Mask(from), Req->argv[0], class_c);
 | 
			
		||||
		if (class == CLASS_GLINE) {
 | 
			
		||||
			/* Inform other servers */
 | 
			
		||||
			IRC_WriteStrServersPrefix(Client, from, "%s %s",
 | 
			
		||||
						  Req->command, Req->argv[0]);
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		/* Add new mask to list */
 | 
			
		||||
		if (Class_AddMask(class, Req->argv[0],
 | 
			
		||||
				  time(NULL) + atol(Req->argv[1]),
 | 
			
		||||
				  Req->argv[2])) {
 | 
			
		||||
			Log(LOG_NOTICE|LOG_snotice,
 | 
			
		||||
			    "\"%s\" added \"%s\" to %c-Line list: \"%s\" (%ld seconds).",
 | 
			
		||||
			    Client_Mask(from), Req->argv[0], class_c,
 | 
			
		||||
			    Req->argv[2], atol(Req->argv[1]));
 | 
			
		||||
			if (class == CLASS_GLINE) {
 | 
			
		||||
				/* Inform other servers */
 | 
			
		||||
				IRC_WriteStrServersPrefix(Client, from,
 | 
			
		||||
						"%s %s %s :%s", Req->command,
 | 
			
		||||
						Req->argv[0], Req->argv[1],
 | 
			
		||||
						Req->argv[2]);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -25,6 +25,8 @@ 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 ));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool IRC_xLINE PARAMS((CLIENT *Client, REQUEST *Req));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -53,8 +53,7 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	char str[LINE_LEN];
 | 
			
		||||
	CLIENT *from, *c;
 | 
			
		||||
	int i;
 | 
			
		||||
	CONN_ID con;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
@@ -70,26 +69,44 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		LogDebug("Connection %d: got SERVER command (new server link) ...",
 | 
			
		||||
			Client_Conn(Client));
 | 
			
		||||
 | 
			
		||||
		if(( Req->argc != 2 ) && ( Req->argc != 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
		if (Req->argc != 2 && Req->argc != 3)
 | 
			
		||||
			return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
 | 
			
		||||
						  Client_ID(Client),
 | 
			
		||||
						  Req->command);
 | 
			
		||||
 | 
			
		||||
		/* Ist this server configured on out side? */
 | 
			
		||||
		for( i = 0; i < MAX_SERVERS; i++ ) if( strcasecmp( Req->argv[0], Conf_Server[i].name ) == 0 ) break;
 | 
			
		||||
		if( i >= MAX_SERVERS )
 | 
			
		||||
		{
 | 
			
		||||
			Log( LOG_ERR, "Connection %d: Server \"%s\" not configured here!", Client_Conn( Client ), Req->argv[0] );
 | 
			
		||||
			Conn_Close( Client_Conn( Client ), NULL, "Server not configured here", true);
 | 
			
		||||
		/* Get configuration index of new remote server ... */
 | 
			
		||||
		for (i = 0; i < MAX_SERVERS; i++)
 | 
			
		||||
			if (strcasecmp(Req->argv[0], Conf_Server[i].name) == 0)
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
		/* Makre sure the remote server is configured here */
 | 
			
		||||
		if (i >= MAX_SERVERS) {
 | 
			
		||||
			Log(LOG_ERR,
 | 
			
		||||
			    "Connection %d: Server \"%s\" not configured here!",
 | 
			
		||||
			    Client_Conn(Client), Req->argv[0]);
 | 
			
		||||
			Conn_Close(Client_Conn(Client), NULL,
 | 
			
		||||
				   "Server not configured here", true);
 | 
			
		||||
			return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
		if( strcmp( Client_Password( Client ), Conf_Server[i].pwd_in ) != 0 )
 | 
			
		||||
		{
 | 
			
		||||
			/* wrong password */
 | 
			
		||||
			Log( LOG_ERR, "Connection %d: Got bad password from server \"%s\"!", Client_Conn( Client ), Req->argv[0] );
 | 
			
		||||
			Conn_Close( Client_Conn( Client ), NULL, "Bad password", true);
 | 
			
		||||
 | 
			
		||||
		/* Check server password */
 | 
			
		||||
		if (strcmp(Conn_Password(Client_Conn(Client)),
 | 
			
		||||
		    Conf_Server[i].pwd_in) != 0) {
 | 
			
		||||
			Log(LOG_ERR,
 | 
			
		||||
			    "Connection %d: Got bad password from server \"%s\"!",
 | 
			
		||||
			    Client_Conn(Client), Req->argv[0]);
 | 
			
		||||
			Conn_Close(Client_Conn(Client), NULL,
 | 
			
		||||
				   "Bad password", true);
 | 
			
		||||
			return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		/* Is there a registered server with this ID? */
 | 
			
		||||
		if( ! Client_CheckID( Client, Req->argv[0] )) return DISCONNECTED;
 | 
			
		||||
		if (!Client_CheckID(Client, Req->argv[0]))
 | 
			
		||||
			return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
		/* Mark this connection as belonging to an configured server */
 | 
			
		||||
		if (!Conf_SetServer(i, Client_Conn(Client)))
 | 
			
		||||
			return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
		Client_SetID( Client, Req->argv[0] );
 | 
			
		||||
		Client_SetHops( Client, 1 );
 | 
			
		||||
@@ -97,7 +114,6 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
 | 
			
		||||
		/* Is this server registering on our side, or are we connecting to
 | 
			
		||||
		 * a remote server? */
 | 
			
		||||
		con = Client_Conn(Client);
 | 
			
		||||
		if (Client_Token(Client) != TOKEN_OUTBOUND) {
 | 
			
		||||
			/* Incoming connection, send user/pass */
 | 
			
		||||
			if (!IRC_WriteStrClient(Client, "PASS %s %s",
 | 
			
		||||
@@ -106,7 +122,8 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
			    || !IRC_WriteStrClient(Client, "SERVER %s 1 :%s",
 | 
			
		||||
						   Conf_ServerName,
 | 
			
		||||
						   Conf_ServerInfo)) {
 | 
			
		||||
				    Conn_Close(con, "Unexpected server behavior!",
 | 
			
		||||
				    Conn_Close(Client_Conn(Client),
 | 
			
		||||
					       "Unexpected server behavior!",
 | 
			
		||||
					       NULL, false);
 | 
			
		||||
				    return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
@@ -118,25 +135,25 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
			Client_SetToken(Client, atoi(Req->argv[1]));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Mark this connection as belonging to an configured server */
 | 
			
		||||
		Conf_SetServer(i, con);
 | 
			
		||||
 | 
			
		||||
		/* Check protocol level */
 | 
			
		||||
		if (Client_Type(Client) == CLIENT_GOTPASS) {
 | 
			
		||||
			/* We got a "simple" PASS command, so the peer is
 | 
			
		||||
			 * using the protocol as defined in RFC 1459. */
 | 
			
		||||
			if (! (Conn_Options(con) & CONN_RFC1459))
 | 
			
		||||
			if (! (Conn_Options(Client_Conn(Client)) & CONN_RFC1459))
 | 
			
		||||
				Log(LOG_INFO,
 | 
			
		||||
				    "Switching connection %d (\"%s\") to RFC 1459 compatibility mode.",
 | 
			
		||||
				    con, Client_ID(Client));
 | 
			
		||||
			Conn_SetOption(con, CONN_RFC1459);
 | 
			
		||||
				    Client_Conn(Client), Client_ID(Client));
 | 
			
		||||
			Conn_SetOption(Client_Conn(Client), CONN_RFC1459);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Client_SetType(Client, CLIENT_UNKNOWNSERVER);
 | 
			
		||||
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
		if (strchr(Client_Flags(Client), 'Z') && !Zip_InitConn(con)) {
 | 
			
		||||
			Conn_Close( con, "Can't inizialize compression (zlib)!", NULL, false );
 | 
			
		||||
		if (strchr(Client_Flags(Client), 'Z')
 | 
			
		||||
		    && !Zip_InitConn(Client_Conn(Client))) {
 | 
			
		||||
			Conn_Close(Client_Conn(Client),
 | 
			
		||||
				   "Can't inizialize compression (zlib)!",
 | 
			
		||||
				   NULL, false );
 | 
			
		||||
			return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
@@ -202,10 +219,10 @@ GLOBAL bool
 | 
			
		||||
IRC_NJOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	char nick_in[COMMAND_LEN], nick_out[COMMAND_LEN], *channame, *ptr, modes[8];
 | 
			
		||||
	bool is_op, is_voiced;
 | 
			
		||||
	bool is_owner, is_chanadmin, is_op, is_halfop, is_voiced;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
@@ -218,12 +235,16 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	ptr = strtok( nick_in, "," );
 | 
			
		||||
	while( ptr )
 | 
			
		||||
	{
 | 
			
		||||
		is_op = is_voiced = false;
 | 
			
		||||
		
 | 
			
		||||
		is_owner = is_chanadmin = is_op = is_halfop = is_voiced = false;
 | 
			
		||||
 | 
			
		||||
		/* cut off prefixes */
 | 
			
		||||
		while(( *ptr == '@' ) || ( *ptr == '+' ))
 | 
			
		||||
		while(( *ptr == '~') || ( *ptr == '&' ) || ( *ptr == '@' ) ||
 | 
			
		||||
			( *ptr == '%') || ( *ptr == '+' ))
 | 
			
		||||
		{
 | 
			
		||||
			if( *ptr == '~' ) is_owner = true;
 | 
			
		||||
			if( *ptr == '&' ) is_chanadmin = true;
 | 
			
		||||
			if( *ptr == '@' ) is_op = true;
 | 
			
		||||
			if( *ptr == 'h' ) is_halfop = true;
 | 
			
		||||
			if( *ptr == '+' ) is_voiced = true;
 | 
			
		||||
			ptr++;
 | 
			
		||||
		}
 | 
			
		||||
@@ -234,8 +255,11 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
			Channel_Join( c, channame );
 | 
			
		||||
			chan = Channel_Search( channame );
 | 
			
		||||
			assert( chan != NULL );
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			if( is_owner ) Channel_UserModeAdd( chan, c, 'q' );
 | 
			
		||||
			if( is_chanadmin ) Channel_UserModeAdd( chan, c, 'a' );
 | 
			
		||||
			if( is_op ) Channel_UserModeAdd( chan, c, 'o' );
 | 
			
		||||
			if( is_halfop ) Channel_UserModeAdd( chan, c, 'h' );
 | 
			
		||||
			if( is_voiced ) Channel_UserModeAdd( chan, c, 'v' );
 | 
			
		||||
 | 
			
		||||
			/* announce to channel... */
 | 
			
		||||
@@ -250,12 +274,15 @@ IRC_NJOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if( nick_out[0] != '\0' ) strlcat( nick_out, ",", sizeof( nick_out ));
 | 
			
		||||
			if( is_owner ) strlcat( nick_out, "~", sizeof( nick_out ));
 | 
			
		||||
			if( is_chanadmin ) strlcat( nick_out, "&", sizeof( nick_out ));
 | 
			
		||||
			if( is_op ) strlcat( nick_out, "@", sizeof( nick_out ));
 | 
			
		||||
			if( is_halfop ) strlcat( nick_out, "%", sizeof( nick_out ));
 | 
			
		||||
			if( is_voiced ) strlcat( nick_out, "+", sizeof( nick_out ));
 | 
			
		||||
			strlcat( nick_out, ptr, sizeof( nick_out ));
 | 
			
		||||
		}
 | 
			
		||||
		else Log( LOG_ERR, "Got NJOIN for unknown nick \"%s\" for channel \"%s\"!", ptr, channame );
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		/* search for next Nick */
 | 
			
		||||
		ptr = strtok( NULL, "," );
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										196
									
								
								src/ngircd/irc.c
									
									
									
									
									
								
							
							
						
						
									
										196
									
								
								src/ngircd/irc.c
									
									
									
									
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2004 Alexander Barton <alex@barton.de>
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -25,6 +25,7 @@
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "conn-encoding.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
@@ -45,6 +46,35 @@ static bool Send_Message_Mask PARAMS((CLIENT *from, char *command,
 | 
			
		||||
				      bool SendErrors));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a list limit is reached and inform client accordingly.
 | 
			
		||||
 *
 | 
			
		||||
 * @param From The client.
 | 
			
		||||
 * @param Count Reply item count.
 | 
			
		||||
 * @param Limit Reply limit.
 | 
			
		||||
 * @param Name Name of the list.
 | 
			
		||||
 * @return true if list limit has been reached; false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_CheckListTooBig(CLIENT *From, const int Count, const int Limit,
 | 
			
		||||
		    const char *Name)
 | 
			
		||||
{
 | 
			
		||||
	assert(From != NULL);
 | 
			
		||||
	assert(Count >= 0);
 | 
			
		||||
	assert(Limit > 0);
 | 
			
		||||
	assert(Name != NULL);
 | 
			
		||||
 | 
			
		||||
	if (Count < Limit)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	(void)IRC_WriteStrClient(From,
 | 
			
		||||
				 "NOTICE %s :%s list limit (%d) reached!",
 | 
			
		||||
				 Client_ID(From), Name, Limit);
 | 
			
		||||
	IRC_SetPenalty(From, 2);
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_ERROR( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
@@ -63,13 +93,21 @@ IRC_ERROR( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Kill client on request.
 | 
			
		||||
 * Handler for the IRC "KILL" command.
 | 
			
		||||
 *
 | 
			
		||||
 * This function implements the IRC command "KILL" wich is used to selectively
 | 
			
		||||
 * disconnect clients. It can be used by IRC operators and servers, for example
 | 
			
		||||
 * to "solve" nick collisions after netsplits.
 | 
			
		||||
 * to "solve" nick collisions after netsplits. See RFC 2812 section 3.7.1.
 | 
			
		||||
 *
 | 
			
		||||
 * Please note that this function is also called internally, without a real
 | 
			
		||||
 * KILL command being received over the network! Client is Client_ThisServer()
 | 
			
		||||
 * in this case. */
 | 
			
		||||
 * in this case, and the prefix in Req is NULL.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client	The client from which this command has been received
 | 
			
		||||
 *			or Client_ThisServer() when generated interanlly.
 | 
			
		||||
 * @param Req		Request structure with prefix and all parameters.
 | 
			
		||||
 * @returns		CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
IRC_KILL( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
@@ -77,55 +115,47 @@ IRC_KILL( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	char reason[COMMAND_LEN], *msg;
 | 
			
		||||
	CONN_ID my_conn, conn;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
	assert (Client != NULL);
 | 
			
		||||
	assert (Req != NULL);
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Client ) != CLIENT_SERVER ) &&
 | 
			
		||||
	   ( ! Client_OperByMe( Client )))
 | 
			
		||||
	{
 | 
			
		||||
		/* The originator of the KILL is neither an IRC operator of
 | 
			
		||||
		 * this server nor a server. */
 | 
			
		||||
		return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG,
 | 
			
		||||
					   Client_ID( Client ));
 | 
			
		||||
	}
 | 
			
		||||
	if (Client_Type(Client) != CLIENT_SERVER && !Client_OperByMe(Client))
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
 | 
			
		||||
					  Client_ID(Client));
 | 
			
		||||
 | 
			
		||||
	if( Req->argc != 2 )
 | 
			
		||||
	{
 | 
			
		||||
		/* This command requires exactly 2 parameters! */
 | 
			
		||||
		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);
 | 
			
		||||
 | 
			
		||||
	if( Req->prefix ) prefix = Client_Search( Req->prefix );
 | 
			
		||||
	else prefix = Client;
 | 
			
		||||
	if( ! prefix )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_WARNING, "Got KILL with invalid prefix: \"%s\"!",
 | 
			
		||||
		     Req->prefix );
 | 
			
		||||
		prefix = Client_ThisServer( );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( Client != Client_ThisServer( ))
 | 
			
		||||
	{
 | 
			
		||||
		/* This is a "real" KILL received from the network. */
 | 
			
		||||
		Log( LOG_NOTICE|LOG_snotice, "Got KILL command from \"%s\" for \"%s\": %s",
 | 
			
		||||
		     Client_Mask( prefix ), Req->argv[0], Req->argv[1] );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Build reason string */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_USER )
 | 
			
		||||
	{
 | 
			
		||||
		/* Prefix the "reason" if the originator is a regular user,
 | 
			
		||||
		 * so users can't spoof KILLs of servers. */
 | 
			
		||||
		snprintf( reason, sizeof( reason ), "KILLed by %s: %s",
 | 
			
		||||
			  Client_ID( Client ), Req->argv[1] );
 | 
			
		||||
	}
 | 
			
		||||
	/* Get prefix (origin); use the client if no prefix is given. */
 | 
			
		||||
	if (Req->prefix)
 | 
			
		||||
		prefix = Client_Search(Req->prefix);
 | 
			
		||||
	else
 | 
			
		||||
		strlcpy( reason, Req->argv[1], sizeof( reason ));
 | 
			
		||||
		prefix = Client;
 | 
			
		||||
 | 
			
		||||
	/* Log a warning message and use this server as origin when the
 | 
			
		||||
	 * prefix (origin) is invalid. */
 | 
			
		||||
	if (!prefix) {
 | 
			
		||||
		Log(LOG_WARNING, "Got KILL with invalid prefix: \"%s\"!",
 | 
			
		||||
		    Req->prefix );
 | 
			
		||||
		prefix = Client_ThisServer();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (Client != Client_ThisServer())
 | 
			
		||||
		Log(LOG_NOTICE|LOG_snotice,
 | 
			
		||||
		    "Got KILL command from \"%s\" for \"%s\": %s",
 | 
			
		||||
		    Client_Mask(prefix), Req->argv[0], Req->argv[1]);
 | 
			
		||||
 | 
			
		||||
	/* Build reason string: Prefix the "reason" if the originator is a
 | 
			
		||||
	 * regular user, so users can't spoof KILLs of servers. */
 | 
			
		||||
	if (Client_Type(Client) == CLIENT_USER)
 | 
			
		||||
		snprintf(reason, sizeof(reason), "KILLed by %s: %s",
 | 
			
		||||
			 Client_ID(Client), Req->argv[1]);
 | 
			
		||||
	else
 | 
			
		||||
		strlcpy(reason, Req->argv[1], sizeof(reason));
 | 
			
		||||
 | 
			
		||||
	/* Inform other servers */
 | 
			
		||||
	IRC_WriteStrServersPrefix( Client, prefix, "KILL %s :%s",
 | 
			
		||||
				   Req->argv[0], reason );
 | 
			
		||||
	IRC_WriteStrServersPrefix(Client, prefix, "KILL %s :%s",
 | 
			
		||||
				  Req->argv[0], reason);
 | 
			
		||||
 | 
			
		||||
	/* Save ID of this connection */
 | 
			
		||||
	my_conn = Client_Conn( Client );
 | 
			
		||||
@@ -298,12 +328,18 @@ IRC_HELP( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
Option_String( CONN_ID Idx )
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
Option_String(CONN_ID Idx)
 | 
			
		||||
#else
 | 
			
		||||
Option_String(UNUSED CONN_ID Idx)
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	static char option_txt[8];
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
	UINT16 options;
 | 
			
		||||
 | 
			
		||||
	options = Conn_Options(Idx);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	strcpy(option_txt, "F");	/* No idea what this means, but the
 | 
			
		||||
					 * original ircd sends it ... */
 | 
			
		||||
@@ -320,9 +356,11 @@ static bool
 | 
			
		||||
Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *cl, *from;
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	char *currentTarget = Req->argv[0];
 | 
			
		||||
	char *lastCurrentTarget = NULL;
 | 
			
		||||
	char *message = NULL;
 | 
			
		||||
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	assert(Req != NULL);
 | 
			
		||||
@@ -354,6 +392,13 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 | 
			
		||||
		return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
 | 
			
		||||
					  Client_ID(Client), Req->prefix);
 | 
			
		||||
 | 
			
		||||
#ifdef ICONV
 | 
			
		||||
	if (Client_Conn(Client) > NONE)
 | 
			
		||||
		message = Conn_EncodingFrom(Client_Conn(Client), Req->argv[1]);
 | 
			
		||||
	else
 | 
			
		||||
#endif
 | 
			
		||||
		message = Req->argv[1];
 | 
			
		||||
 | 
			
		||||
	/* handle msgtarget = msgto *("," msgto) */
 | 
			
		||||
	currentTarget = strtok_r(currentTarget, ",", &lastCurrentTarget);
 | 
			
		||||
	ngt_UpperStr(Req->command);
 | 
			
		||||
@@ -410,9 +455,9 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 | 
			
		||||
				    Client_Type(cl) != CLIENT_SERVICE)
 | 
			
		||||
					continue;
 | 
			
		||||
				if (nick != NULL && host != NULL) {
 | 
			
		||||
					if (strcmp(nick, Client_ID(cl)) == 0 &&
 | 
			
		||||
					    strcmp(user, Client_User(cl)) == 0 &&
 | 
			
		||||
					    strcasecmp(host, Client_HostnameCloaked(cl)) == 0)
 | 
			
		||||
					if (strcasecmp(nick, Client_ID(cl)) == 0 &&
 | 
			
		||||
					    strcasecmp(user, Client_User(cl)) == 0 &&
 | 
			
		||||
					    strcasecmp(host, Client_HostnameDisplayed(cl)) == 0)
 | 
			
		||||
						break;
 | 
			
		||||
					else
 | 
			
		||||
						continue;
 | 
			
		||||
@@ -420,7 +465,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 | 
			
		||||
				if (strcasecmp(user, Client_User(cl)) != 0)
 | 
			
		||||
					continue;
 | 
			
		||||
				if (host != NULL && strcasecmp(host,
 | 
			
		||||
						Client_HostnameCloaked(cl)) != 0)
 | 
			
		||||
						Client_HostnameDisplayed(cl)) != 0)
 | 
			
		||||
					continue;
 | 
			
		||||
				if (server != NULL && strcasecmp(server,
 | 
			
		||||
						Client_ID(Client_Introducer(cl))) != 0)
 | 
			
		||||
@@ -439,11 +484,11 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 | 
			
		||||
#else
 | 
			
		||||
			if (Client_Type(cl) != ForceType) {
 | 
			
		||||
#endif
 | 
			
		||||
				if (!SendErrors)
 | 
			
		||||
					return CONNECTED;
 | 
			
		||||
				return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
 | 
			
		||||
							  Client_ID(from),
 | 
			
		||||
							  currentTarget);
 | 
			
		||||
				if (SendErrors && !IRC_WriteStrClient(
 | 
			
		||||
				    from, ERR_NOSUCHNICK_MSG,Client_ID(from),
 | 
			
		||||
				    currentTarget))
 | 
			
		||||
					return DISCONNECTED;
 | 
			
		||||
				goto send_next_target;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
#ifndef STRICT_RFC
 | 
			
		||||
@@ -455,6 +500,34 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 | 
			
		||||
				Req->command = "PRIVMSG";
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
			if (Client_HasMode(cl, 'b') &&
 | 
			
		||||
			    !Client_HasMode(from, 'R') &&
 | 
			
		||||
			    !Client_HasMode(from, 'o') &&
 | 
			
		||||
			    !(Client_Type(from) == CLIENT_SERVER) &&
 | 
			
		||||
			    !(Client_Type(from) == CLIENT_SERVICE)) {
 | 
			
		||||
				if (SendErrors && !IRC_WriteStrClient(from,
 | 
			
		||||
						ERR_NONONREG_MSG,
 | 
			
		||||
						Client_ID(from), Client_ID(cl)))
 | 
			
		||||
					return DISCONNECTED;
 | 
			
		||||
				goto send_next_target;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (Client_HasMode(cl, 'C')) {
 | 
			
		||||
				cl2chan = Channel_FirstChannelOf(cl);
 | 
			
		||||
				while (cl2chan) {
 | 
			
		||||
					chan = Channel_GetChannel(cl2chan);
 | 
			
		||||
					if (Channel_IsMemberOf(chan, from))
 | 
			
		||||
						break;
 | 
			
		||||
					cl2chan = Channel_NextChannelOf(cl, cl2chan);
 | 
			
		||||
				}
 | 
			
		||||
				if (!cl2chan) {
 | 
			
		||||
					if (SendErrors && !IRC_WriteStrClient(
 | 
			
		||||
					    from, ERR_NOTONSAMECHANNEL_MSG,
 | 
			
		||||
					    Client_ID(from), Client_ID(cl)))
 | 
			
		||||
						return DISCONNECTED;
 | 
			
		||||
					goto send_next_target;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (SendErrors && (Client_Type(Client) != CLIENT_SERVER)
 | 
			
		||||
			    && strchr(Client_Modes(cl), 'a')) {
 | 
			
		||||
@@ -470,12 +543,12 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 | 
			
		||||
			}
 | 
			
		||||
			if (!IRC_WriteStrClientPrefix(cl, from, "%s %s :%s",
 | 
			
		||||
						      Req->command, Client_ID(cl),
 | 
			
		||||
						      Req->argv[1]))
 | 
			
		||||
						      message))
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
		} else if (ForceType != CLIENT_SERVICE
 | 
			
		||||
			   && (chan = Channel_Search(currentTarget))) {
 | 
			
		||||
			if (!Channel_Write(chan, from, Client, Req->command,
 | 
			
		||||
					   SendErrors, Req->argv[1]))
 | 
			
		||||
					   SendErrors, message))
 | 
			
		||||
					return DISCONNECTED;
 | 
			
		||||
		} else if (ForceType != CLIENT_SERVICE
 | 
			
		||||
			/* $#: server/target mask, RFC 2812, sec. 3.3.1 */
 | 
			
		||||
@@ -483,7 +556,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 | 
			
		||||
			   && strchr(currentTarget, '.')) {
 | 
			
		||||
			/* targetmask */
 | 
			
		||||
			if (!Send_Message_Mask(from, Req->command, currentTarget,
 | 
			
		||||
					       Req->argv[1], SendErrors))
 | 
			
		||||
					       message, SendErrors))
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
		} else {
 | 
			
		||||
			if (!SendErrors)
 | 
			
		||||
@@ -493,7 +566,10 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	send_next_target:
 | 
			
		||||
		currentTarget = strtok_r(NULL, ",", &lastCurrentTarget);
 | 
			
		||||
		if (currentTarget)
 | 
			
		||||
			Conn_SetPenalty(Client_Conn(Client), 1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2008 Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -17,6 +17,9 @@
 | 
			
		||||
 * IRC commands (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
GLOBAL bool IRC_CheckListTooBig PARAMS((CLIENT *From, const int Count,
 | 
			
		||||
					const int Limit, const char *Name));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool IRC_ERROR PARAMS((CLIENT *Client, REQUEST *Req));
 | 
			
		||||
GLOBAL bool IRC_KILL PARAMS((CLIENT *Client, REQUEST *Req));
 | 
			
		||||
GLOBAL bool IRC_NOTICE PARAMS((CLIENT *Client, REQUEST *Req));
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2005 Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -37,89 +37,176 @@
 | 
			
		||||
#define MASK_LEN	(2*CLIENT_HOST_LEN)
 | 
			
		||||
 | 
			
		||||
struct list_elem {
 | 
			
		||||
	struct list_elem *next;
 | 
			
		||||
	char mask[MASK_LEN];
 | 
			
		||||
	bool onlyonce;
 | 
			
		||||
	struct list_elem *next;	/** pointer to next list element */
 | 
			
		||||
	char mask[MASK_LEN];	/** IRC mask */
 | 
			
		||||
	char *reason;		/** Optional "reason" text */
 | 
			
		||||
	time_t valid_until;	/** 0: unlimited; 1: once; t(>1): until t */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get IRC mask stored in list element.
 | 
			
		||||
 *
 | 
			
		||||
 * @param list_elem List element.
 | 
			
		||||
 * @return Pointer to IRC mask
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL const char *
 | 
			
		||||
Lists_GetMask(const struct list_elem *e)
 | 
			
		||||
{
 | 
			
		||||
	assert(e != NULL);
 | 
			
		||||
	return e->mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get optional "reason" text stored in list element.
 | 
			
		||||
 *
 | 
			
		||||
 * @param list_elem List element.
 | 
			
		||||
 * @return Pointer to "reason" text or empty string ("").
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL const char *
 | 
			
		||||
Lists_GetReason(const struct list_elem *e)
 | 
			
		||||
{
 | 
			
		||||
	assert(e != NULL);
 | 
			
		||||
	return e->reason ? e->reason : "";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get "validity" value stored in list element.
 | 
			
		||||
 *
 | 
			
		||||
 * @param list_elem List element.
 | 
			
		||||
 * @return Validity: 0=unlimited, 1=once, >1 until this time stamp.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL time_t
 | 
			
		||||
Lists_GetValidity(const struct list_elem *e)
 | 
			
		||||
{
 | 
			
		||||
	assert(e != NULL);
 | 
			
		||||
	return e->valid_until;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get first list element of a list.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h List head.
 | 
			
		||||
 * @return Pointer to first list element.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL struct list_elem*
 | 
			
		||||
Lists_GetFirst(const struct list_head *h)
 | 
			
		||||
{
 | 
			
		||||
	assert(h != NULL);
 | 
			
		||||
	return h->first;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get next list element of a list.
 | 
			
		||||
 *
 | 
			
		||||
 * @param e Current list element.
 | 
			
		||||
 * @return Pointer to next list element.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL struct list_elem*
 | 
			
		||||
Lists_GetNext(const struct list_elem *e)
 | 
			
		||||
{
 | 
			
		||||
	assert(e != NULL);
 | 
			
		||||
	return e->next;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Add a new mask to a list.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h List head.
 | 
			
		||||
 * @param Mask The IRC mask to add to the list.
 | 
			
		||||
 * @param ValidUntil 0: unlimited, 1: only once, t>1: until given time_t.
 | 
			
		||||
 * @param Reason Reason string or NULL, if no reason should be saved.
 | 
			
		||||
 * @return true on success, false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
bool
 | 
			
		||||
Lists_Add(struct list_head *header, const char *Mask, bool OnlyOnce )
 | 
			
		||||
Lists_Add(struct list_head *h, const char *Mask, time_t ValidUntil,
 | 
			
		||||
	  const char *Reason)
 | 
			
		||||
{
 | 
			
		||||
	struct list_elem *e, *newelem;
 | 
			
		||||
 | 
			
		||||
	assert( header != NULL );
 | 
			
		||||
	assert( Mask != NULL );
 | 
			
		||||
	assert(h != NULL);
 | 
			
		||||
	assert(Mask != NULL);
 | 
			
		||||
 | 
			
		||||
	if (Lists_CheckDupeMask(header, Mask )) return true;
 | 
			
		||||
	e = Lists_CheckDupeMask(h, Mask);
 | 
			
		||||
	if (e) {
 | 
			
		||||
		e->valid_until = ValidUntil;
 | 
			
		||||
		if (Reason) {
 | 
			
		||||
			free(e->reason);
 | 
			
		||||
			e->reason = strdup(Reason);
 | 
			
		||||
		}
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	e = Lists_GetFirst(header);
 | 
			
		||||
	e = Lists_GetFirst(h);
 | 
			
		||||
 | 
			
		||||
	newelem = malloc(sizeof(struct list_elem));
 | 
			
		||||
	if( ! newelem ) {
 | 
			
		||||
		Log( LOG_EMERG, "Can't allocate memory for new Ban/Invite entry!" );
 | 
			
		||||
	if (!newelem) {
 | 
			
		||||
		Log(LOG_EMERG,
 | 
			
		||||
		    "Can't allocate memory for new list entry!");
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	strlcpy( newelem->mask, Mask, sizeof( newelem->mask ));
 | 
			
		||||
	newelem->onlyonce = OnlyOnce;
 | 
			
		||||
	strlcpy(newelem->mask, Mask, sizeof(newelem->mask));
 | 
			
		||||
	if (Reason) {
 | 
			
		||||
		newelem->reason = strdup(Reason);
 | 
			
		||||
		if (!newelem->reason)
 | 
			
		||||
			Log(LOG_EMERG,
 | 
			
		||||
			    "Can't allocate memory for new list reason text!");
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		newelem->reason = NULL;
 | 
			
		||||
	newelem->valid_until = ValidUntil;
 | 
			
		||||
	newelem->next = e;
 | 
			
		||||
	header->first = newelem;
 | 
			
		||||
	h->first = newelem;
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Delete a list element from a list.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h List head.
 | 
			
		||||
 * @param p Pointer to previous list element or NULL, if there is none.
 | 
			
		||||
 * @param victim List element to delete.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
Lists_Unlink(struct list_head *header, struct list_elem *p, struct list_elem *victim)
 | 
			
		||||
Lists_Unlink(struct list_head *h, struct list_elem *p, struct list_elem *victim)
 | 
			
		||||
{
 | 
			
		||||
	assert(victim != NULL);
 | 
			
		||||
	assert(header != NULL);
 | 
			
		||||
	assert(h != NULL);
 | 
			
		||||
 | 
			
		||||
	if (p) p->next = victim->next;
 | 
			
		||||
	else header->first = victim->next;
 | 
			
		||||
	if (p)
 | 
			
		||||
		p->next = victim->next;
 | 
			
		||||
	else
 | 
			
		||||
		h->first = victim->next;
 | 
			
		||||
 | 
			
		||||
	if (victim->reason)
 | 
			
		||||
		free(victim->reason);
 | 
			
		||||
 | 
			
		||||
	free(victim);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Delete a given IRC mask from a list.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h List head.
 | 
			
		||||
 * @param Mask IRC mask to delete from the list.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Lists_Del(struct list_head *header, const char *Mask)
 | 
			
		||||
Lists_Del(struct list_head *h, const char *Mask)
 | 
			
		||||
{
 | 
			
		||||
	struct list_elem *e, *last, *victim;
 | 
			
		||||
 | 
			
		||||
	assert( header != NULL );
 | 
			
		||||
	assert( Mask != NULL );
 | 
			
		||||
	assert(h != NULL);
 | 
			
		||||
	assert(Mask != NULL);
 | 
			
		||||
 | 
			
		||||
	last = NULL;
 | 
			
		||||
	e = Lists_GetFirst(header);
 | 
			
		||||
	while( e ) {
 | 
			
		||||
		if(strcasecmp( e->mask, Mask ) == 0 ) {
 | 
			
		||||
	e = Lists_GetFirst(h);
 | 
			
		||||
	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);
 | 
			
		||||
			Lists_Unlink(h, last, victim);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		last = e;
 | 
			
		||||
@@ -127,7 +214,11 @@ Lists_Del(struct list_head *header, const char *Mask)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Free a complete list.
 | 
			
		||||
 *
 | 
			
		||||
 * @param head List head.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Lists_Free(struct list_head *head)
 | 
			
		||||
{
 | 
			
		||||
@@ -138,101 +229,193 @@ Lists_Free(struct list_head *head)
 | 
			
		||||
	e = head->first;
 | 
			
		||||
	head->first = NULL;
 | 
			
		||||
	while (e) {
 | 
			
		||||
		LogDebug("Deleted \"%s\" from invite list" , e->mask);
 | 
			
		||||
		LogDebug("Deleted \"%s\" from list" , e->mask);
 | 
			
		||||
		victim = e;
 | 
			
		||||
		e = e->next;
 | 
			
		||||
		free( victim );
 | 
			
		||||
		if (victim->reason)
 | 
			
		||||
			free(victim->reason);
 | 
			
		||||
		free(victim);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
/**
 | 
			
		||||
 * Check if an IRC mask is already contained in a list.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h List head.
 | 
			
		||||
 * @param Mask IRC mask to test.
 | 
			
		||||
 * @return true if mask is already stored in the list, false otherwise.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL struct list_elem *
 | 
			
		||||
Lists_CheckDupeMask(const struct list_head *h, const char *Mask )
 | 
			
		||||
{
 | 
			
		||||
	struct list_elem *e;
 | 
			
		||||
	e = h->first;
 | 
			
		||||
	while (e) {
 | 
			
		||||
		if (strcasecmp( e->mask, Mask ) == 0 )
 | 
			
		||||
			return true;
 | 
			
		||||
		if (strcasecmp(e->mask, Mask) == 0)
 | 
			
		||||
			return e;
 | 
			
		||||
		e = e->next;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Generate a valid IRC mask from "any" string given.
 | 
			
		||||
 *
 | 
			
		||||
 * Attention: This mask is only valid until the next call to Lists_MakeMask(),
 | 
			
		||||
 * because a single global buffer ist used! You have to copy the generated
 | 
			
		||||
 * mask to some sane location yourself!
 | 
			
		||||
 *
 | 
			
		||||
 * @param Pattern Source string to generate an IRC mask for.
 | 
			
		||||
 * @return Pointer to global result buffer.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL const char *
 | 
			
		||||
Lists_MakeMask(const char *Pattern)
 | 
			
		||||
{
 | 
			
		||||
	/* This function generats a valid IRC mask of "any" string. This
 | 
			
		||||
	 * mask is only valid until the next call to Lists_MakeMask(),
 | 
			
		||||
	 * because a single global buffer is used. You have to copy the
 | 
			
		||||
	 * generated mask to some sane location yourself! */
 | 
			
		||||
 | 
			
		||||
	static char TheMask[MASK_LEN];
 | 
			
		||||
	char *excl, *at;
 | 
			
		||||
 | 
			
		||||
	assert( Pattern != NULL );
 | 
			
		||||
	assert(Pattern != NULL);
 | 
			
		||||
 | 
			
		||||
	excl = strchr( Pattern, '!' );
 | 
			
		||||
	at = strchr( Pattern, '@' );
 | 
			
		||||
	excl = strchr(Pattern, '!');
 | 
			
		||||
	at = strchr(Pattern, '@');
 | 
			
		||||
 | 
			
		||||
	if(( at ) && ( at < excl )) excl = NULL;
 | 
			
		||||
	if (at && at < excl)
 | 
			
		||||
		excl = NULL;
 | 
			
		||||
 | 
			
		||||
	if(( ! at ) && ( ! excl ))
 | 
			
		||||
	{
 | 
			
		||||
		/* Neither "!" nor "@" found: use string as nick name */
 | 
			
		||||
		strlcpy( TheMask, Pattern, sizeof( TheMask ) - 5 );
 | 
			
		||||
		strlcat( TheMask, "!*@*", sizeof( TheMask ));
 | 
			
		||||
	if (!at && !excl) {
 | 
			
		||||
		/* Neither "!" nor "@" found: use string as nickname */
 | 
			
		||||
		strlcpy(TheMask, Pattern, sizeof(TheMask) - 5);
 | 
			
		||||
		strlcat(TheMask, "!*@*", sizeof(TheMask));
 | 
			
		||||
		return TheMask;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(( ! at ) && ( excl ))
 | 
			
		||||
	{
 | 
			
		||||
	if (!at && excl) {
 | 
			
		||||
		/* Domain part is missing */
 | 
			
		||||
		strlcpy( TheMask, Pattern, sizeof( TheMask ) - 3 );
 | 
			
		||||
		strlcat( TheMask, "@*", sizeof( TheMask ));
 | 
			
		||||
		strlcpy(TheMask, Pattern, sizeof(TheMask) - 3);
 | 
			
		||||
		strlcat(TheMask, "@*", sizeof(TheMask));
 | 
			
		||||
		return TheMask;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(( at ) && ( ! excl ))
 | 
			
		||||
	{
 | 
			
		||||
	if (at && !excl) {
 | 
			
		||||
		/* User name is missing */
 | 
			
		||||
		*at = '\0'; at++;
 | 
			
		||||
		strlcpy( TheMask, Pattern, sizeof( TheMask ) - 5 );
 | 
			
		||||
		strlcat( TheMask, "!*@", sizeof( TheMask ));
 | 
			
		||||
		strlcat( TheMask, at, sizeof( TheMask ));
 | 
			
		||||
		strlcpy(TheMask, Pattern, sizeof(TheMask) - 5);
 | 
			
		||||
		strlcat(TheMask, "!*@", sizeof(TheMask));
 | 
			
		||||
		strlcat(TheMask, at, sizeof(TheMask));
 | 
			
		||||
		return TheMask;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* All parts (nick, user and domain name) are given */
 | 
			
		||||
	strlcpy( TheMask, Pattern, sizeof( TheMask ));
 | 
			
		||||
	strlcpy(TheMask, Pattern, sizeof(TheMask));
 | 
			
		||||
	return TheMask;
 | 
			
		||||
} /* Lists_MakeMask */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a client is listed in a list.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h List head.
 | 
			
		||||
 * @param Client Client to check.
 | 
			
		||||
 * @return true if client is listed, false if not.
 | 
			
		||||
 */
 | 
			
		||||
bool
 | 
			
		||||
Lists_Check( struct list_head *header, CLIENT *Client)
 | 
			
		||||
Lists_Check(struct list_head *h, CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	struct list_elem *e, *last;
 | 
			
		||||
	return Lists_CheckReason(h, Client) != NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	assert( header != NULL );
 | 
			
		||||
/**
 | 
			
		||||
 * Check if a client is listed in a list and return the "reason".
 | 
			
		||||
 *
 | 
			
		||||
 * @param h List head.
 | 
			
		||||
 * @param Client Client to check.
 | 
			
		||||
 * @return true if client is listed, false if not.
 | 
			
		||||
 */
 | 
			
		||||
char *
 | 
			
		||||
Lists_CheckReason(struct list_head *h, CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	struct list_elem *e, *last, *next;
 | 
			
		||||
 | 
			
		||||
	e = header->first;
 | 
			
		||||
	assert(h != NULL);
 | 
			
		||||
 | 
			
		||||
	e = h->first;
 | 
			
		||||
	last = NULL;
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
	while (e) {
 | 
			
		||||
		next = e->next;
 | 
			
		||||
		if (Match(e->mask, Client_Mask(Client))) {
 | 
			
		||||
			if (e->valid_until == 1) {
 | 
			
		||||
				/* Entry is valid only once, delete it */
 | 
			
		||||
				LogDebug("Deleted \"%s\" from list (used).",
 | 
			
		||||
					 e->mask);
 | 
			
		||||
				Lists_Unlink(h, last, e);
 | 
			
		||||
			}
 | 
			
		||||
			return true;
 | 
			
		||||
			return e->reason ? e->reason : "";
 | 
			
		||||
		}
 | 
			
		||||
		last = e;
 | 
			
		||||
		e = e->next;
 | 
			
		||||
		e = next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false;
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check list and purge expired entries.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h List head.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Lists_Expire(struct list_head *h, const char *ListName)
 | 
			
		||||
{
 | 
			
		||||
	struct list_elem *e, *last, *next;
 | 
			
		||||
	time_t now;
 | 
			
		||||
 | 
			
		||||
	assert(h != NULL);
 | 
			
		||||
 | 
			
		||||
	e = h->first;
 | 
			
		||||
	last = NULL;
 | 
			
		||||
	now = time(NULL);
 | 
			
		||||
 | 
			
		||||
	while (e) {
 | 
			
		||||
		next = e->next;
 | 
			
		||||
		if (e->valid_until > 1 && e->valid_until < now) {
 | 
			
		||||
			/* Entry is expired, delete it */
 | 
			
		||||
			if (e->reason)
 | 
			
		||||
				Log(LOG_INFO,
 | 
			
		||||
				    "Deleted \"%s\" (\"%s\") from %s list (expired).",
 | 
			
		||||
				    e->mask, e->reason, ListName);
 | 
			
		||||
			else
 | 
			
		||||
				Log(LOG_INFO,
 | 
			
		||||
				    "Deleted \"%s\" from %s list (expired).",
 | 
			
		||||
				    e->mask, ListName);
 | 
			
		||||
			Lists_Unlink(h, last, e);
 | 
			
		||||
			e = next;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		last = e;
 | 
			
		||||
		e = next;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Return the number of entries of a list.
 | 
			
		||||
 *
 | 
			
		||||
 * @param h List head.
 | 
			
		||||
 * @return Number of items.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL unsigned long
 | 
			
		||||
Lists_Count(struct list_head *h)
 | 
			
		||||
{
 | 
			
		||||
	struct list_elem *e;
 | 
			
		||||
	unsigned long count = 0;
 | 
			
		||||
 | 
			
		||||
	assert(h != NULL);
 | 
			
		||||
 | 
			
		||||
	e = h->first;
 | 
			
		||||
	while (e) {
 | 
			
		||||
		count++;
 | 
			
		||||
		e = e->next;
 | 
			
		||||
	}
 | 
			
		||||
	return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -29,18 +29,24 @@ struct list_head {
 | 
			
		||||
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_Check PARAMS((struct list_head *head, CLIENT *client ));
 | 
			
		||||
GLOBAL bool Lists_CheckDupeMask PARAMS((const struct list_head *head, const char *mask ));
 | 
			
		||||
GLOBAL bool Lists_Check PARAMS((struct list_head *head, CLIENT *client));
 | 
			
		||||
GLOBAL char *Lists_CheckReason PARAMS((struct list_head *head, CLIENT *client));
 | 
			
		||||
GLOBAL struct list_elem *Lists_CheckDupeMask PARAMS((const struct list_head *head,
 | 
			
		||||
					const char *mask));
 | 
			
		||||
 | 
			
		||||
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 bool Lists_Add PARAMS((struct list_head *h, const char *Mask,
 | 
			
		||||
			      time_t ValidUntil, const char *Reason));
 | 
			
		||||
GLOBAL void Lists_Del PARAMS((struct list_head *head, const char *Mask));
 | 
			
		||||
GLOBAL unsigned long Lists_Count PARAMS((struct list_head *h));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Lists_AlreadyRegistered PARAMS(( const struct list_head *head, const char *Mask));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Lists_Free PARAMS(( struct list_head *head ));
 | 
			
		||||
GLOBAL void Lists_Free PARAMS((struct list_head *head));
 | 
			
		||||
 | 
			
		||||
GLOBAL const char *Lists_MakeMask PARAMS((const char *Pattern));
 | 
			
		||||
GLOBAL const char *Lists_GetMask PARAMS(( const struct list_elem *e ));
 | 
			
		||||
GLOBAL const char *Lists_GetMask PARAMS((const struct list_elem *e));
 | 
			
		||||
GLOBAL const char *Lists_GetReason PARAMS((const struct list_elem *e));
 | 
			
		||||
GLOBAL time_t Lists_GetValidity PARAMS((const struct list_elem *e));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Lists_Expire PARAMS((struct list_head *h, const char *ListName));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -44,7 +44,6 @@
 | 
			
		||||
#include "log.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static char Init_Txt[127];
 | 
			
		||||
static bool Is_Daemon;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -65,49 +64,48 @@ Log_Message(int Level, const char *msg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialitze logging.
 | 
			
		||||
 * This function is called before the configuration file is read in.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Daemon_Mode Set to true if ngIRCd is running as daemon.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Log_Init( bool Daemon_Mode )
 | 
			
		||||
Log_Init(bool Daemon_Mode)
 | 
			
		||||
{
 | 
			
		||||
	Is_Daemon = Daemon_Mode;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
#ifdef SYSLOG
 | 
			
		||||
#ifndef LOG_CONS     /* Kludge: mips-dec-ultrix4.5 has no LOG_CONS */
 | 
			
		||||
#define LOG_CONS 0
 | 
			
		||||
#endif
 | 
			
		||||
	openlog(PACKAGE_NAME, LOG_CONS|LOG_PID, Conf_SyslogFacility);
 | 
			
		||||
#ifdef LOG_DAEMON
 | 
			
		||||
	openlog(PACKAGE, LOG_CONS|LOG_PID, LOG_DAEMON);
 | 
			
		||||
#else
 | 
			
		||||
	openlog(PACKAGE, LOG_CONS|LOG_PID, 0);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	Log( LOG_NOTICE, "%s started.", NGIRCd_Version );
 | 
			
		||||
	  
 | 
			
		||||
	/* Information about "Operation Mode" */
 | 
			
		||||
	Init_Txt[0] = '\0';
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	if( NGIRCd_Debug )
 | 
			
		||||
	{
 | 
			
		||||
		strlcpy( Init_Txt, "debug-mode", sizeof Init_Txt );
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	if( ! Is_Daemon )
 | 
			
		||||
	{
 | 
			
		||||
		if( Init_Txt[0] ) strlcat( Init_Txt, ", ", sizeof Init_Txt );
 | 
			
		||||
		strlcat( Init_Txt, "no-daemon-mode", sizeof Init_Txt );
 | 
			
		||||
	}
 | 
			
		||||
	if( NGIRCd_Passive )
 | 
			
		||||
	{
 | 
			
		||||
		if( Init_Txt[0] ) strlcat( Init_Txt, ", ", sizeof Init_Txt );
 | 
			
		||||
		strlcat( Init_Txt, "passive-mode", sizeof Init_Txt );
 | 
			
		||||
	}
 | 
			
		||||
#ifdef SNIFFER
 | 
			
		||||
	if( NGIRCd_Sniffer )
 | 
			
		||||
	{
 | 
			
		||||
		if( Init_Txt[0] ) strlcat( Init_Txt, ", ", sizeof Init_Txt );
 | 
			
		||||
		strlcat( Init_Txt, "network sniffer", sizeof Init_Txt );
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	if( Init_Txt[0] ) Log( LOG_INFO, "Activating: %s.", Init_Txt );
 | 
			
		||||
} /* Log_Init */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Re-init logging after reading the configuration file.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Log_ReInit(void)
 | 
			
		||||
{
 | 
			
		||||
#ifdef SYSLOG
 | 
			
		||||
#ifndef LOG_CONS     /* Kludge: mips-dec-ultrix4.5 has no LOG_CONS */
 | 
			
		||||
#define LOG_CONS 0
 | 
			
		||||
#endif
 | 
			
		||||
	closelog();
 | 
			
		||||
	openlog(PACKAGE, LOG_CONS|LOG_PID, Conf_SyslogFacility);
 | 
			
		||||
#endif
 | 
			
		||||
	Log(LOG_NOTICE, "%s started.", NGIRCd_Version);
 | 
			
		||||
	Log(LOG_INFO, "Using configuration file \"%s\" ...", NGIRCd_ConfFile);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL void
 | 
			
		||||
Log_Exit( void )
 | 
			
		||||
{
 | 
			
		||||
@@ -220,7 +218,7 @@ GLOBAL void
 | 
			
		||||
Log_Init_Subprocess(char UNUSED *Name)
 | 
			
		||||
{
 | 
			
		||||
#ifdef SYSLOG
 | 
			
		||||
	openlog(PACKAGE_NAME, LOG_CONS|LOG_PID, Conf_SyslogFacility);
 | 
			
		||||
	openlog(PACKAGE, LOG_CONS|LOG_PID, Conf_SyslogFacility);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	Log_Subprocess(LOG_DEBUG, "%s sub-process starting, PID %ld.",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -36,6 +36,7 @@ GLOBAL void Log_Init PARAMS(( bool Daemon_Mode ));
 | 
			
		||||
GLOBAL void Log_Exit PARAMS(( void ));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Log PARAMS(( int Level, const char *Format, ... ));
 | 
			
		||||
GLOBAL void Log_ReInit PARAMS((void));
 | 
			
		||||
 | 
			
		||||
GLOBAL void Log_ServerNotice PARAMS((char UserMode, const char *Format, ...));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										244
									
								
								src/ngircd/login.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								src/ngircd/login.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,244 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Functions to deal with client logins
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "class.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "client-cap.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "io.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "pam.h"
 | 
			
		||||
#include "irc-info.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "login.h"
 | 
			
		||||
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
static void cb_Read_Auth_Result PARAMS((int r_fd, UNUSED short events));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initiate client login.
 | 
			
		||||
 *
 | 
			
		||||
 * This function is called after the daemon received the required NICK and
 | 
			
		||||
 * USER commands of a new client. If the daemon is compiled with support for
 | 
			
		||||
 * PAM, the authentication sub-processs is forked; otherwise the global server
 | 
			
		||||
 * password is checked.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client logging in.
 | 
			
		||||
 * @returns CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Login_User(CLIENT * Client)
 | 
			
		||||
{
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
	int pipefd[2], result;
 | 
			
		||||
	pid_t pid;
 | 
			
		||||
#endif
 | 
			
		||||
	CONN_ID conn;
 | 
			
		||||
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
	conn = Client_Conn(Client);
 | 
			
		||||
 | 
			
		||||
#ifndef STRICT_RFC
 | 
			
		||||
	if (Conf_AuthPing) {
 | 
			
		||||
		/* Did we receive the "auth PONG" already? */
 | 
			
		||||
		if (Conn_GetAuthPing(conn)) {
 | 
			
		||||
			Client_SetType(Client, CLIENT_WAITAUTHPING);
 | 
			
		||||
			LogDebug("Connection %d: Waiting for AUTH PONG ...", conn);
 | 
			
		||||
			return CONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Still waiting for "CAP END" command? */
 | 
			
		||||
	if (Client_Cap(Client) & CLIENT_CAP_PENDING) {
 | 
			
		||||
		Client_SetType(Client, CLIENT_WAITCAPEND);
 | 
			
		||||
		LogDebug("Connection %d: Waiting for CAP END ...", conn);
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
	if (!Conf_PAM) {
 | 
			
		||||
		/* Don't do any PAM authentication at all, instead emulate
 | 
			
		||||
		 * the beahiour of the daemon compiled without PAM support:
 | 
			
		||||
		 * because there can't be any "server password", all
 | 
			
		||||
		 * passwords supplied are classified as "wrong". */
 | 
			
		||||
		if(Conn_Password(conn)[0] == '\0')
 | 
			
		||||
			return Login_User_PostAuth(Client);
 | 
			
		||||
		Client_Reject(Client, "Non-empty password", false);
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (Conf_PAMIsOptional &&
 | 
			
		||||
	    strcmp(Conn_Password(conn), "") == 0) {
 | 
			
		||||
		/* Clients are not required to send a password and to be PAM-
 | 
			
		||||
		 * authenticated at all. If not, they won't become "identified"
 | 
			
		||||
		 * and keep the "~" in their supplied user name.
 | 
			
		||||
		 * Therefore it is sensible to either set Conf_PAMisOptional or
 | 
			
		||||
		 * to enable IDENT lookups -- not both. */
 | 
			
		||||
		return Login_User_PostAuth(Client);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Fork child process for PAM authentication; and make sure that the
 | 
			
		||||
	 * process timeout is set higher than the login timeout! */
 | 
			
		||||
	pid = Proc_Fork(Conn_GetProcStat(conn), pipefd,
 | 
			
		||||
			cb_Read_Auth_Result, Conf_PongTimeout + 1);
 | 
			
		||||
	if (pid > 0) {
 | 
			
		||||
		LogDebug("Authenticator for connection %d created (PID %d).",
 | 
			
		||||
			 conn, pid);
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	} else {
 | 
			
		||||
		/* Sub process */
 | 
			
		||||
		Log_Init_Subprocess("Auth");
 | 
			
		||||
		Conn_CloseAllSockets(NONE);
 | 
			
		||||
		result = PAM_Authenticate(Client);
 | 
			
		||||
		if (write(pipefd[1], &result, sizeof(result)) != sizeof(result))
 | 
			
		||||
			Log_Subprocess(LOG_ERR,
 | 
			
		||||
				       "Failed to pipe result to parent!");
 | 
			
		||||
		Log_Exit_Subprocess("Auth");
 | 
			
		||||
		exit(0);
 | 
			
		||||
	}
 | 
			
		||||
#else
 | 
			
		||||
	/* Check global server password ... */
 | 
			
		||||
	if (strcmp(Conn_Password(conn), Conf_ServerPwd) != 0) {
 | 
			
		||||
		/* Bad password! */
 | 
			
		||||
		Client_Reject(Client, "Bad server password", false);
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	return Login_User_PostAuth(Client);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Finish client registration.
 | 
			
		||||
 *
 | 
			
		||||
 * Introduce the new client to the network and send all "hello messages"
 | 
			
		||||
 * to it after authentication has been succeeded.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client The client logging in.
 | 
			
		||||
 * @return CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Login_User_PostAuth(CLIENT *Client)
 | 
			
		||||
{
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
 | 
			
		||||
	if (Class_HandleServerBans(Client) != CONNECTED)
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	Client_Introduce(NULL, Client, CLIENT_USER);
 | 
			
		||||
 | 
			
		||||
	if (!IRC_WriteStrClient
 | 
			
		||||
	    (Client, RPL_WELCOME_MSG, Client_ID(Client), Client_Mask(Client)))
 | 
			
		||||
		return false;
 | 
			
		||||
	if (!IRC_WriteStrClient
 | 
			
		||||
	    (Client, RPL_YOURHOST_MSG, Client_ID(Client),
 | 
			
		||||
	     Client_ID(Client_ThisServer()), PACKAGE_VERSION, HOST_CPU,
 | 
			
		||||
	     HOST_VENDOR, HOST_OS))
 | 
			
		||||
		return false;
 | 
			
		||||
	if (!IRC_WriteStrClient
 | 
			
		||||
	    (Client, RPL_CREATED_MSG, Client_ID(Client), NGIRCd_StartStr))
 | 
			
		||||
		return false;
 | 
			
		||||
	if (!IRC_WriteStrClient
 | 
			
		||||
	    (Client, RPL_MYINFO_MSG, Client_ID(Client),
 | 
			
		||||
	     Client_ID(Client_ThisServer()), PACKAGE_VERSION, USERMODES,
 | 
			
		||||
	     CHANMODES))
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	/* 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;
 | 
			
		||||
 | 
			
		||||
	if (!IRC_Send_LUSERS(Client))
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
	if (!IRC_Show_MOTD(Client))
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	/* Suspend the client for a second ... */
 | 
			
		||||
	IRC_SetPenalty(Client, 1);
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Read result of the authenticatior sub-process from pipe
 | 
			
		||||
 *
 | 
			
		||||
 * @param r_fd		File descriptor of the pipe.
 | 
			
		||||
 * @param events	(ignored IO specification)
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
cb_Read_Auth_Result(int r_fd, UNUSED short events)
 | 
			
		||||
{
 | 
			
		||||
	CONN_ID conn;
 | 
			
		||||
	CLIENT *client;
 | 
			
		||||
	int result;
 | 
			
		||||
	size_t len;
 | 
			
		||||
	PROC_STAT *proc;
 | 
			
		||||
 | 
			
		||||
	LogDebug("Auth: Got callback on fd %d, events %d", r_fd, events);
 | 
			
		||||
	conn = Conn_GetFromProc(r_fd);
 | 
			
		||||
	if (conn == NONE) {
 | 
			
		||||
		/* Ops, none found? Probably the connection has already
 | 
			
		||||
		 * been closed!? We'll ignore that ... */
 | 
			
		||||
		io_close(r_fd);
 | 
			
		||||
		LogDebug("Auth: Got callback for unknown connection!?");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	proc = Conn_GetProcStat(conn);
 | 
			
		||||
	client = Conn_GetClient(conn);
 | 
			
		||||
 | 
			
		||||
	/* Read result from pipe */
 | 
			
		||||
	len = Proc_Read(proc, &result, sizeof(result));
 | 
			
		||||
	Proc_Close(proc);
 | 
			
		||||
	if (len == 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (len != sizeof(result)) {
 | 
			
		||||
		Log(LOG_CRIT, "Auth: Got malformed result!");
 | 
			
		||||
		Client_Reject(client, "Internal error", false);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (result == true) {
 | 
			
		||||
		Client_SetUser(client, Client_OrigUser(client), true);
 | 
			
		||||
		(void)Login_User_PostAuth(client);
 | 
			
		||||
	} else
 | 
			
		||||
		Client_Reject(client, "Bad password", false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										25
									
								
								src/ngircd/login.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/ngircd/login.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __login_h__
 | 
			
		||||
#define __login_h__
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Functions to deal with client logins (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Login_User PARAMS((CLIENT * Client));
 | 
			
		||||
GLOBAL bool Login_User_PostAuth PARAMS((CLIENT *Client));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -48,9 +48,9 @@ static int Matche_After_Star PARAMS(( const char *p, const char *t ));
 | 
			
		||||
/**
 | 
			
		||||
 * Match string with pattern.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Pattern	Pattern to match with
 | 
			
		||||
 * @param String	Input string
 | 
			
		||||
 * @return		true if pattern matches
 | 
			
		||||
 * @param Pattern Pattern to match with
 | 
			
		||||
 * @param String Input string
 | 
			
		||||
 * @return true if pattern matches
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
Match( const char *Pattern, const char *String )
 | 
			
		||||
@@ -64,17 +64,46 @@ Match( const char *Pattern, const char *String )
 | 
			
		||||
/**
 | 
			
		||||
 * Match string with pattern case-insensitive.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pattern	Pattern to match with
 | 
			
		||||
 * @param searchme	Input string, at most COMMAND_LEN-1 characters long
 | 
			
		||||
 * @return		true if pattern matches
 | 
			
		||||
 * @param Pattern Pattern to match with
 | 
			
		||||
 * @param String Input string, at most COMMAND_LEN-1 characters long
 | 
			
		||||
 * @return true if pattern matches
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
MatchCaseInsensitive(const char *pattern, const char *searchme)
 | 
			
		||||
MatchCaseInsensitive(const char *Pattern, const char *String)
 | 
			
		||||
{
 | 
			
		||||
	char haystack[COMMAND_LEN];
 | 
			
		||||
 | 
			
		||||
	strlcpy(haystack, searchme, sizeof(haystack));
 | 
			
		||||
	return Match(pattern, ngt_LowerStr(haystack));
 | 
			
		||||
	strlcpy(haystack, String, sizeof(haystack));
 | 
			
		||||
	return Match(Pattern, ngt_LowerStr(haystack));
 | 
			
		||||
} /* MatchCaseInsensitive */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Match string with pattern case-insensitive.
 | 
			
		||||
 *
 | 
			
		||||
 * @param pattern Pattern to match with
 | 
			
		||||
 * @param String Input string, at most COMMAND_LEN-1 characters long
 | 
			
		||||
 * @param Separator Character separating the individual patterns in the list
 | 
			
		||||
 * @return true if pattern matches
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
MatchCaseInsensitiveList(const char *Pattern, const char *String,
 | 
			
		||||
		     const char *Separator)
 | 
			
		||||
{
 | 
			
		||||
	char tmp_pattern[COMMAND_LEN], haystack[COMMAND_LEN], *ptr;
 | 
			
		||||
 | 
			
		||||
	strlcpy(tmp_pattern, Pattern, sizeof(tmp_pattern));
 | 
			
		||||
	strlcpy(haystack, String, sizeof(haystack));
 | 
			
		||||
	ngt_LowerStr(haystack);
 | 
			
		||||
 | 
			
		||||
	ptr = strtok(tmp_pattern, Separator);
 | 
			
		||||
	while (ptr) {
 | 
			
		||||
		ngt_TrimStr(ptr);
 | 
			
		||||
		if (Match(ptr, haystack))
 | 
			
		||||
			return true;
 | 
			
		||||
		ptr = strtok(NULL, Separator);
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
} /* MatchCaseInsensitive */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -17,8 +17,14 @@
 | 
			
		||||
 * Wildcard pattern matching (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Match PARAMS(( const char *Pattern, const char *String ));
 | 
			
		||||
GLOBAL bool MatchCaseInsensitive PARAMS(( const char *Pattern, const char *searchme ));
 | 
			
		||||
GLOBAL bool Match PARAMS((const char *Pattern, const char *String));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool MatchCaseInsensitive PARAMS((const char *Pattern,
 | 
			
		||||
					 const char *String));
 | 
			
		||||
 | 
			
		||||
GLOBAL bool MatchCaseInsensitiveList PARAMS((const char *Pattern,
 | 
			
		||||
					     const char *String,
 | 
			
		||||
					     const char *Separator));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2010 Alexander Barton <alex@barton.de>
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -21,19 +21,19 @@
 | 
			
		||||
#define RPL_YOURHOST_MSG		"002 %s :Your host is %s, running version ngircd-%s (%s/%s/%s)"
 | 
			
		||||
#define RPL_CREATED_MSG			"003 %s :This server has been started %s"
 | 
			
		||||
#define RPL_MYINFO_MSG			"004 %s %s ngircd-%s %s %s"
 | 
			
		||||
#define RPL_ISUPPORT1_MSG		"005 %s RFC2812 IRCD=ngIRCd CASEMAPPING=ascii PREFIX=(ov)@+ CHANTYPES=#&+ CHANMODES=bI,k,l,imnPst CHANLIMIT=#&+:%d :are supported on this server"
 | 
			
		||||
#define RPL_ISUPPORT2_MSG		"005 %s CHANNELLEN=%d NICKLEN=%d TOPICLEN=%d AWAYLEN=%d KICKLEN=%d PENALTY :are supported on this server"
 | 
			
		||||
#define RPL_ISUPPORT1_MSG		"005 %s RFC2812 IRCD=ngIRCd CHARSET=UTF-8 CASEMAPPING=ascii PREFIX=(qaohv)~&@%%+ CHANTYPES=#&+ CHANMODES=beI,k,l,imMnOPQRstVz CHANLIMIT=#&+:%d :are supported on this server"
 | 
			
		||||
#define RPL_ISUPPORT2_MSG		"005 %s CHANNELLEN=%d NICKLEN=%d TOPICLEN=%d AWAYLEN=%d KICKLEN=%d MODES=%d MAXLIST=beI:%d EXCEPTS=e INVEX=I 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"
 | 
			
		||||
#define RPL_TRACESERVER_MSG		"206 %s Serv 1 0S 0C %s[%s@%s] *!*@%s :V%s"
 | 
			
		||||
#define RPL_STATSLINKINFO_MSG		"211 %s %s %d %ld %ld %ld %ld :%ld"
 | 
			
		||||
#define RPL_STATSCOMMANDS_MSG		"212 %s %s %ld %ld %ld"
 | 
			
		||||
#define RPL_STATSXLINE_MSG		"216 %s %c %s %ld :%s"
 | 
			
		||||
#define RPL_ENDOFSTATS_MSG		"219 %s %c :End of STATS report"
 | 
			
		||||
#define RPL_UMODEIS_MSG			"221 %s +%s"
 | 
			
		||||
#define RPL_SERVLIST_MSG		"234 %s %s %s %s %d %d :%s"
 | 
			
		||||
#define RPL_SERVLISTEND_MSG		"235 %s %s %s :End of service listing"
 | 
			
		||||
 | 
			
		||||
#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 %lu :operator(s) online"
 | 
			
		||||
@@ -55,6 +55,7 @@
 | 
			
		||||
#define RPL_ISON_MSG			"303 %s :"
 | 
			
		||||
#define RPL_UNAWAY_MSG			"305 %s :You are no longer marked as being away"
 | 
			
		||||
#define RPL_NOWAWAY_MSG			"306 %s :You have been marked as being away"
 | 
			
		||||
#define RPL_WHOISREGNICK_MSG		"307 %s %s :is a registered nick"
 | 
			
		||||
#define RPL_WHOISUSER_MSG		"311 %s %s %s %s * :%s"
 | 
			
		||||
#define RPL_WHOISSERVER_MSG		"312 %s %s %s :%s"
 | 
			
		||||
#define RPL_WHOISOPERATOR_MSG		"313 %s %s :is an IRC operator"
 | 
			
		||||
@@ -70,9 +71,12 @@
 | 
			
		||||
#define RPL_NOTOPIC_MSG			"331 %s %s :No topic is set"
 | 
			
		||||
#define RPL_TOPIC_MSG			"332 %s %s :%s"
 | 
			
		||||
#define RPL_TOPICSETBY_MSG		"333 %s %s %s %u"
 | 
			
		||||
#define RPL_WHOISBOT_MSG		"335 %s %s :is a IRC Bot"
 | 
			
		||||
#define RPL_INVITING_MSG		"341 %s %s %s%s"
 | 
			
		||||
#define RPL_INVITELIST_MSG		"346 %s %s %s"
 | 
			
		||||
#define RPL_ENDOFINVITELIST_MSG		"347 %s %s :End of channel invite list"
 | 
			
		||||
#define RPL_EXCEPTLIST_MSG		"348 %s %s %s"
 | 
			
		||||
#define RPL_ENDOFEXCEPTLIST_MSG		"349 %s %s :End of channel exception list"
 | 
			
		||||
#define RPL_VERSION_MSG			"351 %s %s-%s.%s %s :%s"
 | 
			
		||||
#define RPL_WHOREPLY_MSG		"352 %s %s %s %s %s %s %s :%d %s"
 | 
			
		||||
#define RPL_NAMREPLY_MSG		"353 %s %s %s :"
 | 
			
		||||
@@ -87,9 +91,13 @@
 | 
			
		||||
#define RPL_MOTD_MSG			"372 %s :- %s"
 | 
			
		||||
#define RPL_MOTDSTART_MSG		"375 %s :- %s message of the day"
 | 
			
		||||
#define RPL_ENDOFMOTD_MSG		"376 %s :End of MOTD command"
 | 
			
		||||
#define RPL_WHOISHOST_MSG		"378 %s %s :is connecting from *@%s %s"
 | 
			
		||||
#define RPL_WHOISMODES_MSG		"379 %s %s :is using modes +%s"
 | 
			
		||||
#define RPL_YOUREOPER_MSG		"381 %s :You are now an IRC Operator"
 | 
			
		||||
#define RPL_REHASHING_MSG		"382 %s :Rehashing"
 | 
			
		||||
#define RPL_YOURESERVICE_MSG		"383 %s :You are service %s"
 | 
			
		||||
#define RPL_TIME_MSG			"391 %s %s :%s"
 | 
			
		||||
#define RPL_HOSTHIDDEN_MSG		"396 %s %s :is your displayed hostname now"
 | 
			
		||||
 | 
			
		||||
#define ERR_NOSUCHNICK_MSG		"401 %s %s :No such nick or channel name"
 | 
			
		||||
#define ERR_NOSUCHSERVER_MSG		"402 %s %s :No such server"
 | 
			
		||||
@@ -98,6 +106,7 @@
 | 
			
		||||
#define ERR_TOOMANYCHANNELS_MSG		"405 %s %s :You have joined too many channels"
 | 
			
		||||
#define ERR_WASNOSUCHNICK_MSG		"406 %s %s :There was no such nickname"
 | 
			
		||||
#define ERR_NOORIGIN_MSG		"409 %s :No origin specified"
 | 
			
		||||
#define ERR_INVALIDCAP_MSG		"410 %s %s :Invalid CAP subcommand"
 | 
			
		||||
#define ERR_NORECIPIENT_MSG		"411 %s :No recipient given (%s)"
 | 
			
		||||
#define ERR_NOTEXTTOSEND_MSG		"412 %s :No text to send"
 | 
			
		||||
#define ERR_WILDTOPLEVEL		"414 %s :Wildcard in toplevel domain"
 | 
			
		||||
@@ -105,39 +114,58 @@
 | 
			
		||||
#define ERR_NOMOTD_MSG			"422 %s :MOTD file is missing"
 | 
			
		||||
#define ERR_NONICKNAMEGIVEN_MSG		"431 %s :No nickname given"
 | 
			
		||||
#define ERR_ERRONEUSNICKNAME_MSG	"432 %s %s :Erroneous nickname"
 | 
			
		||||
#define ERR_NICKNAMETOOLONG_MSG		"432 %s %s :Nickname too long, max. %u characters"
 | 
			
		||||
#define ERR_FORBIDDENNICKNAME_MSG	"432 %s %s :Nickname is forbidden/blocked"
 | 
			
		||||
#define ERR_NICKNAMEINUSE_MSG		"433 %s %s :Nickname already in use"
 | 
			
		||||
#define ERR_USERNOTINCHANNEL_MSG	"441 %s %s %s :They aren't on that channel"
 | 
			
		||||
#define ERR_NOTONCHANNEL_MSG		"442 %s %s :You are not on that channel"
 | 
			
		||||
#define ERR_USERONCHANNEL_MSG		"443 %s %s %s :is already on channel"
 | 
			
		||||
#define ERR_SUMMONDISABLED_MSG		"445 %s %s :SUMMON has been disabled"
 | 
			
		||||
#define ERR_USERSDISABLED_MSG		"446 %s %s :USERS has been disabled"
 | 
			
		||||
#define ERR_SUMMONDISABLED_MSG		"445 %s :SUMMON has been disabled"
 | 
			
		||||
#define ERR_USERSDISABLED_MSG		"446 %s :USERS has been disabled"
 | 
			
		||||
#define ERR_NOTREGISTERED_MSG		"451 %s :Connection not registered"
 | 
			
		||||
#define ERR_NOTREGISTEREDSERVER_MSG	"451 %s :Connection not registered as server link"
 | 
			
		||||
#define ERR_NEEDMOREPARAMS_MSG		"461 %s %s :Syntax error"
 | 
			
		||||
#define ERR_ALREADYREGISTRED_MSG	"462 %s :Connection already registered"
 | 
			
		||||
#define ERR_PASSWDMISMATCH_MSG		"464 %s :Invalid password"
 | 
			
		||||
#define ERR_CHANNELISFULL_MSG		"471 %s %s :Cannot join channel (+l)"
 | 
			
		||||
#define ERR_SECURECHANNEL_MSG		"471 %s %s :Cannot join channel (+z)"
 | 
			
		||||
#define ERR_OPONLYCHANNEL_MSG		"471 %s %s :Cannot join channel (+O)"
 | 
			
		||||
#define ERR_UNKNOWNMODE_MSG		"472 %s: %c :is unknown mode char for %s"
 | 
			
		||||
#define ERR_INVITEONLYCHAN_MSG		"473 %s %s :Cannot join channel (+i)"
 | 
			
		||||
#define ERR_BANNEDFROMCHAN_MSG		"474 %s %s :Cannot join channel (+b)"
 | 
			
		||||
#define ERR_BADCHANNELKEY_MSG		"475 %s %s :Cannot join channel (+k)"
 | 
			
		||||
#define ERR_CHANNELISFULL_MSG		"471 %s %s :Cannot join channel (+l) -- Channel is full, try later"
 | 
			
		||||
#define ERR_SECURECHANNEL_MSG		"471 %s %s :Cannot join channel (+z) -- SSL connections only"
 | 
			
		||||
#define ERR_OPONLYCHANNEL_MSG		"471 %s %s :Cannot join channel (+O) -- IRC opers only"
 | 
			
		||||
#define ERR_REGONLYCHANNEL_MSG		"471 %s %s :Cannot join channel (+R) -- Registered users only"
 | 
			
		||||
#define ERR_UNKNOWNMODE_MSG		"472 %s %c :is unknown mode char for %s"
 | 
			
		||||
#define ERR_INVITEONLYCHAN_MSG		"473 %s %s :Cannot join channel (+i) -- Invited users only"
 | 
			
		||||
#define ERR_BANNEDFROMCHAN_MSG		"474 %s %s :Cannot join channel (+b) -- You are banned"
 | 
			
		||||
#define ERR_BADCHANNELKEY_MSG		"475 %s %s :Cannot join channel (+k) -- Wrong channel key"
 | 
			
		||||
#define ERR_NOCHANMODES_MSG		"477 %s %s :Channel doesn't support modes"
 | 
			
		||||
#define ERR_NEEDREGGEDNICK_MSG		"477 %s %s :Cannot send to channel (+M) -- You need to be identified to a registered account to message this channel"
 | 
			
		||||
#define ERR_LISTFULL_MSG		"478 %s %s %s: Channel list is full (%d)"
 | 
			
		||||
#define ERR_NOPRIVILEGES_MSG		"481 %s :Permission denied"
 | 
			
		||||
#define ERR_CHANOPRIVSNEEDED_MSG	"482 %s %s :You are not channel operator"
 | 
			
		||||
#define ERR_CHANOPPRIVTOOLOW_MSG	"482 %s %s :Your privileges are too low"
 | 
			
		||||
#define ERR_KICKDENY_MSG		"482 %s %s :Cannot kick, %s is protected"
 | 
			
		||||
#define ERR_CANTKILLSERVER_MSG		"483 %s :You can't kill a server!"
 | 
			
		||||
#define ERR_RESTRICTED_MSG		"484 %s :Your connection is restricted"
 | 
			
		||||
#define ERR_NICKREGISTER_MSG		"484 %s :Cannot modify user mode (+R) -- Use IRC services"
 | 
			
		||||
#define ERR_NONONREG_MSG		"486 %s :Cannot send to user (+b) -- You must identify to a registered nick to private message %s"
 | 
			
		||||
#define ERR_NOOPERHOST_MSG		"491 %s :Not configured for your host"
 | 
			
		||||
#define ERR_NOTONSAMECHANNEL_MSG	"493 %s :You must share a common channel with %s"
 | 
			
		||||
 | 
			
		||||
#define ERR_UMODEUNKNOWNFLAG_MSG	"501 %s :Unknown mode"
 | 
			
		||||
#define ERR_UMODEUNKNOWNFLAG2_MSG	"501 %s :Unknown mode \"%c%c\""
 | 
			
		||||
#define ERR_USERSDONTMATCH_MSG		"502 %s :Can't set/get mode for other users"
 | 
			
		||||
#define ERR_NOINVITE_MSG		"518 %s :Cannot invite to %s (+V)"
 | 
			
		||||
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
#define RPL_STATSLINKINFOZIP_MSG	"211 %s %s %d %ld %ld/%ld %ld %ld/%ld :%ld"
 | 
			
		||||
# define RPL_STATSLINKINFOZIP_MSG	"211 %s %s %d %ld %ld/%ld %ld %ld/%ld :%ld"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
 | 
			
		||||
# define RPL_IP_CHARCONV_MSG		"801 %s %s :Client encoding set"
 | 
			
		||||
 | 
			
		||||
# define ERR_IP_CHARCONV_MSG		"851 %s :Can't initialize client encoding"
 | 
			
		||||
 | 
			
		||||
#endif /* IRCPLUS */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -38,6 +38,7 @@
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "class.h"
 | 
			
		||||
#include "conf-ssl.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
@@ -73,12 +74,12 @@ static bool NGIRCd_Init PARAMS(( bool ));
 | 
			
		||||
 * Here all starts: this function is called by the operating system loader,
 | 
			
		||||
 * it is the first portion of code executed of ngIRCd.
 | 
			
		||||
 *
 | 
			
		||||
 * @param argc	The number of arguments passed to ngIRCd on the command line.
 | 
			
		||||
 * @param argv	An array containing all the arguments passed to ngIRCd.
 | 
			
		||||
 * @return	Global exit code of ngIRCd, zero on success.
 | 
			
		||||
 * @param argc The number of arguments passed to ngIRCd on the command line.
 | 
			
		||||
 * @param argv An array containing all the arguments passed to ngIRCd.
 | 
			
		||||
 * @return Global exit code of ngIRCd, zero on success.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL int
 | 
			
		||||
main( int argc, const char *argv[] )
 | 
			
		||||
main(int argc, const char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	bool ok, configtest = false;
 | 
			
		||||
	bool NGIRCd_NoDaemon = false;
 | 
			
		||||
@@ -91,7 +92,7 @@ main( int argc, const char *argv[] )
 | 
			
		||||
	mtrace();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	umask( 0077 );
 | 
			
		||||
	umask(0077);
 | 
			
		||||
 | 
			
		||||
	NGIRCd_SignalQuit = NGIRCd_SignalRestart = false;
 | 
			
		||||
	NGIRCd_Passive = false;
 | 
			
		||||
@@ -101,75 +102,62 @@ main( int argc, const char *argv[] )
 | 
			
		||||
#ifdef SNIFFER
 | 
			
		||||
	NGIRCd_Sniffer = false;
 | 
			
		||||
#endif
 | 
			
		||||
	strlcpy( NGIRCd_ConfFile, SYSCONFDIR, sizeof( NGIRCd_ConfFile ));
 | 
			
		||||
	strlcat( NGIRCd_ConfFile, CONFIG_FILE, sizeof( NGIRCd_ConfFile ));
 | 
			
		||||
	strlcpy(NGIRCd_ConfFile, SYSCONFDIR, sizeof(NGIRCd_ConfFile));
 | 
			
		||||
	strlcat(NGIRCd_ConfFile, CONFIG_FILE, sizeof(NGIRCd_ConfFile));
 | 
			
		||||
 | 
			
		||||
	Fill_Version( );
 | 
			
		||||
	Fill_Version();
 | 
			
		||||
 | 
			
		||||
	/* parse conmmand line */
 | 
			
		||||
	for( i = 1; i < argc; i++ )
 | 
			
		||||
	{
 | 
			
		||||
	for (i = 1; i < argc; i++) {
 | 
			
		||||
		ok = false;
 | 
			
		||||
		if(( argv[i][0] == '-' ) && ( argv[i][1] == '-' ))
 | 
			
		||||
		{
 | 
			
		||||
		if (argv[i][0] == '-' && argv[i][1] == '-') {
 | 
			
		||||
			/* long option */
 | 
			
		||||
			if( strcmp( argv[i], "--config" ) == 0 )
 | 
			
		||||
			{
 | 
			
		||||
				if( i + 1 < argc )
 | 
			
		||||
				{
 | 
			
		||||
			if (strcmp(argv[i], "--config") == 0) {
 | 
			
		||||
				if (i + 1 < argc) {
 | 
			
		||||
					/* Ok, there's an parameter left */
 | 
			
		||||
					strlcpy( NGIRCd_ConfFile, argv[i + 1], sizeof( NGIRCd_ConfFile ));
 | 
			
		||||
 | 
			
		||||
					strlcpy(NGIRCd_ConfFile, argv[i+1],
 | 
			
		||||
						sizeof(NGIRCd_ConfFile));
 | 
			
		||||
					/* next parameter */
 | 
			
		||||
					i++; ok = true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if( strcmp( argv[i], "--configtest" ) == 0 )
 | 
			
		||||
			{
 | 
			
		||||
			if (strcmp(argv[i], "--configtest") == 0) {
 | 
			
		||||
				configtest = true;
 | 
			
		||||
				ok = true;
 | 
			
		||||
			}
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
			if( strcmp( argv[i], "--debug" ) == 0 )
 | 
			
		||||
			{
 | 
			
		||||
			if (strcmp(argv[i], "--debug") == 0) {
 | 
			
		||||
				NGIRCd_Debug = true;
 | 
			
		||||
				ok = true;
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
			if( strcmp( argv[i], "--help" ) == 0 )
 | 
			
		||||
			{
 | 
			
		||||
				Show_Version( );
 | 
			
		||||
				puts( "" ); Show_Help( ); puts( "" );
 | 
			
		||||
				exit( 1 );
 | 
			
		||||
			if (strcmp(argv[i], "--help") == 0) {
 | 
			
		||||
				Show_Version();
 | 
			
		||||
				puts(""); Show_Help( ); puts( "" );
 | 
			
		||||
				exit(1);
 | 
			
		||||
			}
 | 
			
		||||
			if( strcmp( argv[i], "--nodaemon" ) == 0 )
 | 
			
		||||
			{
 | 
			
		||||
			if (strcmp(argv[i], "--nodaemon") == 0) {
 | 
			
		||||
				NGIRCd_NoDaemon = true;
 | 
			
		||||
				ok = true;
 | 
			
		||||
			}
 | 
			
		||||
			if( strcmp( argv[i], "--passive" ) == 0 )
 | 
			
		||||
			{
 | 
			
		||||
			if (strcmp(argv[i], "--passive") == 0) {
 | 
			
		||||
				NGIRCd_Passive = true;
 | 
			
		||||
				ok = true;
 | 
			
		||||
			}
 | 
			
		||||
#ifdef SNIFFER
 | 
			
		||||
			if( strcmp( argv[i], "--sniffer" ) == 0 )
 | 
			
		||||
			{
 | 
			
		||||
			if (strcmp(argv[i], "--sniffer") == 0) {
 | 
			
		||||
				NGIRCd_Sniffer = true;
 | 
			
		||||
				ok = true;
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
			if( strcmp( argv[i], "--version" ) == 0 )
 | 
			
		||||
			{
 | 
			
		||||
				Show_Version( );
 | 
			
		||||
				exit( 1 );
 | 
			
		||||
			if (strcmp(argv[i], "--version") == 0) {
 | 
			
		||||
				Show_Version();
 | 
			
		||||
				exit(1);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if(( argv[i][0] == '-' ) && ( argv[i][1] != '-' ))
 | 
			
		||||
		{
 | 
			
		||||
		else if(argv[i][0] == '-' && argv[i][1] != '-') {
 | 
			
		||||
			/* short option */
 | 
			
		||||
			for( n = 1; n < strlen( argv[i] ); n++ )
 | 
			
		||||
			{
 | 
			
		||||
			for (n = 1; n < strlen(argv[i]); n++) {
 | 
			
		||||
				ok = false;
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
				if (argv[i][n] == 'd') {
 | 
			
		||||
@@ -178,14 +166,14 @@ main( int argc, const char *argv[] )
 | 
			
		||||
				}
 | 
			
		||||
#endif
 | 
			
		||||
				if (argv[i][n] == 'f') {
 | 
			
		||||
					if(( ! argv[i][n + 1] ) && ( i + 1 < argc ))
 | 
			
		||||
					{
 | 
			
		||||
					if (!argv[i][n+1] && i+1 < argc) {
 | 
			
		||||
						/* Ok, next character is a blank */
 | 
			
		||||
						strlcpy( NGIRCd_ConfFile, argv[i + 1], sizeof( NGIRCd_ConfFile ));
 | 
			
		||||
						strlcpy(NGIRCd_ConfFile, argv[i+1],
 | 
			
		||||
							sizeof(NGIRCd_ConfFile));
 | 
			
		||||
 | 
			
		||||
						/* go to the following parameter */
 | 
			
		||||
						i++;
 | 
			
		||||
						n = strlen( argv[i] );
 | 
			
		||||
						n = strlen(argv[i]);
 | 
			
		||||
						ok = true;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
@@ -220,55 +208,58 @@ main( int argc, const char *argv[] )
 | 
			
		||||
					exit(1);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (! ok) {
 | 
			
		||||
					printf( "%s: invalid option \"-%c\"!\n", PACKAGE_NAME, argv[i][n] );
 | 
			
		||||
					printf( "Try \"%s --help\" for more information.\n", PACKAGE_NAME );
 | 
			
		||||
					exit( 1 );
 | 
			
		||||
				if (!ok) {
 | 
			
		||||
					printf("%s: invalid option \"-%c\"!\n",
 | 
			
		||||
					       PACKAGE_NAME, argv[i][n]);
 | 
			
		||||
					printf("Try \"%s --help\" for more information.\n",
 | 
			
		||||
					       PACKAGE_NAME);
 | 
			
		||||
					exit(1);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		if( ! ok )
 | 
			
		||||
		{
 | 
			
		||||
			printf( "%s: invalid option \"%s\"!\n", PACKAGE_NAME, argv[i] );
 | 
			
		||||
			printf( "Try \"%s --help\" for more information.\n", PACKAGE_NAME );
 | 
			
		||||
			exit( 1 );
 | 
			
		||||
		if (!ok) {
 | 
			
		||||
			printf("%s: invalid option \"%s\"!\n",
 | 
			
		||||
			       PACKAGE_NAME, argv[i]);
 | 
			
		||||
			printf("Try \"%s --help\" for more information.\n",
 | 
			
		||||
			       PACKAGE_NAME);
 | 
			
		||||
			exit(1);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Debug level for "VERSION" command */
 | 
			
		||||
	NGIRCd_DebugLevel[0] = '\0';
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	if( NGIRCd_Debug ) strcpy( NGIRCd_DebugLevel, "1" );
 | 
			
		||||
	if (NGIRCd_Debug)
 | 
			
		||||
		strcpy(NGIRCd_DebugLevel, "1");
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SNIFFER
 | 
			
		||||
	if( NGIRCd_Sniffer )
 | 
			
		||||
	{
 | 
			
		||||
	if (NGIRCd_Sniffer) {
 | 
			
		||||
		NGIRCd_Debug = true;
 | 
			
		||||
		strcpy( NGIRCd_DebugLevel, "2" );
 | 
			
		||||
		strcpy(NGIRCd_DebugLevel, "2");
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if( configtest )
 | 
			
		||||
	{
 | 
			
		||||
		Show_Version( ); puts( "" );
 | 
			
		||||
		exit( Conf_Test( ));
 | 
			
		||||
	if (configtest) {
 | 
			
		||||
		Show_Version(); puts("");
 | 
			
		||||
		exit(Conf_Test());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	while( ! NGIRCd_SignalQuit )
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
	while (!NGIRCd_SignalQuit) {
 | 
			
		||||
		/* Initialize global variables */
 | 
			
		||||
		NGIRCd_Start = time( NULL );
 | 
			
		||||
		(void)strftime( NGIRCd_StartStr, 64, "%a %b %d %Y at %H:%M:%S (%Z)", localtime( &NGIRCd_Start ));
 | 
			
		||||
		NGIRCd_Start = time(NULL);
 | 
			
		||||
		(void)strftime(NGIRCd_StartStr, 64,
 | 
			
		||||
			       "%a %b %d %Y at %H:%M:%S (%Z)",
 | 
			
		||||
			       localtime(&NGIRCd_Start));
 | 
			
		||||
 | 
			
		||||
		NGIRCd_SignalRestart = false;
 | 
			
		||||
		NGIRCd_SignalQuit = false;
 | 
			
		||||
 | 
			
		||||
		Random_Init();
 | 
			
		||||
 | 
			
		||||
		/* Initialize modules, part I */
 | 
			
		||||
		Log_Init( ! NGIRCd_NoDaemon );
 | 
			
		||||
		Conf_Init( );
 | 
			
		||||
		Log_Init(!NGIRCd_NoDaemon);
 | 
			
		||||
		Random_Init();
 | 
			
		||||
		Conf_Init();
 | 
			
		||||
		Log_ReInit();
 | 
			
		||||
 | 
			
		||||
		/* Initialize the "main program": chroot environment, user and
 | 
			
		||||
		 * group ID, ... */
 | 
			
		||||
@@ -279,17 +270,22 @@ main( int argc, const char *argv[] )
 | 
			
		||||
 | 
			
		||||
		/* Initialize modules, part II: these functions are eventually
 | 
			
		||||
		 * called with already dropped privileges ... */
 | 
			
		||||
		Channel_Init( );
 | 
			
		||||
		Client_Init( );
 | 
			
		||||
		Conn_Init( );
 | 
			
		||||
		Channel_Init();
 | 
			
		||||
		Client_Init();
 | 
			
		||||
		Conn_Init();
 | 
			
		||||
		Class_Init();
 | 
			
		||||
 | 
			
		||||
		if (!io_library_init(CONNECTION_POOL)) {
 | 
			
		||||
			Log(LOG_ALERT, "Fatal: Cannot initialize IO routines: %s", strerror(errno));
 | 
			
		||||
			Log(LOG_ALERT,
 | 
			
		||||
			    "Fatal: Could not initialize IO routines: %s",
 | 
			
		||||
			    strerror(errno));
 | 
			
		||||
			exit(1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!Signals_Init()) {
 | 
			
		||||
			Log(LOG_ALERT, "Fatal: Could not set up signal handlers: %s", strerror(errno));
 | 
			
		||||
			Log(LOG_ALERT,
 | 
			
		||||
			    "Fatal: Could not set up signal handlers: %s",
 | 
			
		||||
			    strerror(errno));
 | 
			
		||||
			exit(1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@@ -297,39 +293,46 @@ main( int argc, const char *argv[] )
 | 
			
		||||
		 * used by ngIRCd in PASS commands and the known "extended
 | 
			
		||||
		 * flags" are described in doc/Protocol.txt. */
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
		snprintf( NGIRCd_ProtoID, sizeof NGIRCd_ProtoID, "%s%s %s|%s:%s", PROTOVER, PROTOIRCPLUS, PACKAGE_NAME, PACKAGE_VERSION, IRCPLUSFLAGS );
 | 
			
		||||
		snprintf(NGIRCd_ProtoID, sizeof NGIRCd_ProtoID, "%s%s %s|%s:%s",
 | 
			
		||||
			 PROTOVER, PROTOIRCPLUS, PACKAGE_NAME, PACKAGE_VERSION,
 | 
			
		||||
			 IRCPLUSFLAGS);
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
		strcat( NGIRCd_ProtoID, "Z" );
 | 
			
		||||
		strcat(NGIRCd_ProtoID, "Z");
 | 
			
		||||
#endif
 | 
			
		||||
		if( Conf_OperCanMode ) strcat( NGIRCd_ProtoID, "o" );
 | 
			
		||||
#else
 | 
			
		||||
		snprintf( NGIRCd_ProtoID, sizeof NGIRCd_ProtoID, "%s%s %s|%s", PROTOVER, PROTOIRC, PACKAGE_NAME, PACKAGE_VERSION );
 | 
			
		||||
#endif
 | 
			
		||||
		strlcat( NGIRCd_ProtoID, " P", sizeof NGIRCd_ProtoID );
 | 
			
		||||
		if (Conf_OperCanMode)
 | 
			
		||||
			strcat(NGIRCd_ProtoID, "o");
 | 
			
		||||
#else /* IRCPLUS */
 | 
			
		||||
		snprintf(NGIRCd_ProtoID, sizeof NGIRCd_ProtoID, "%s%s %s|%s",
 | 
			
		||||
			 PROTOVER, PROTOIRC, PACKAGE_NAME, PACKAGE_VERSION);
 | 
			
		||||
#endif /* IRCPLUS */
 | 
			
		||||
		strlcat(NGIRCd_ProtoID, " P", sizeof NGIRCd_ProtoID);
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
		strlcat( NGIRCd_ProtoID, "Z", sizeof NGIRCd_ProtoID );
 | 
			
		||||
		strlcat(NGIRCd_ProtoID, "Z", sizeof NGIRCd_ProtoID);
 | 
			
		||||
#endif
 | 
			
		||||
		LogDebug("Protocol and server ID is \"%s\".", NGIRCd_ProtoID);
 | 
			
		||||
 | 
			
		||||
		Channel_InitPredefined( );
 | 
			
		||||
		Channel_InitPredefined();
 | 
			
		||||
 | 
			
		||||
		if( Conn_InitListeners( ) < 1 )
 | 
			
		||||
		{
 | 
			
		||||
			Log( LOG_ALERT, "Server isn't listening on a single port!" );
 | 
			
		||||
			Log( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME );
 | 
			
		||||
			Pidfile_Delete( );
 | 
			
		||||
			exit( 1 );
 | 
			
		||||
		if (Conn_InitListeners() < 1) {
 | 
			
		||||
			Log(LOG_ALERT,
 | 
			
		||||
			    "Server isn't listening on a single port!" );
 | 
			
		||||
			Log(LOG_ALERT,
 | 
			
		||||
			    "%s exiting due to fatal errors!", PACKAGE_NAME);
 | 
			
		||||
			Pidfile_Delete();
 | 
			
		||||
			exit(1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Main Run Loop */
 | 
			
		||||
		Conn_Handler( );
 | 
			
		||||
		Conn_Handler();
 | 
			
		||||
 | 
			
		||||
		Conn_Exit( );
 | 
			
		||||
		Client_Exit( );
 | 
			
		||||
		Channel_Exit( );
 | 
			
		||||
		Log_Exit( );
 | 
			
		||||
		Conn_Exit();
 | 
			
		||||
		Client_Exit();
 | 
			
		||||
		Channel_Exit();
 | 
			
		||||
		Class_Exit();
 | 
			
		||||
		Log_Exit();
 | 
			
		||||
		Signals_Exit();
 | 
			
		||||
	}
 | 
			
		||||
	Pidfile_Delete( );
 | 
			
		||||
	Pidfile_Delete();
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
} /* main */
 | 
			
		||||
@@ -344,70 +347,106 @@ main( int argc, const char *argv[] )
 | 
			
		||||
 * line switch.
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
Fill_Version( void )
 | 
			
		||||
Fill_Version(void)
 | 
			
		||||
{
 | 
			
		||||
	NGIRCd_VersionAddition[0] = '\0';
 | 
			
		||||
 | 
			
		||||
#ifdef SYSLOG
 | 
			
		||||
	strlcpy( NGIRCd_VersionAddition, "SYSLOG", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
	if( NGIRCd_VersionAddition[0] )
 | 
			
		||||
		strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
	strlcat( NGIRCd_VersionAddition, "ZLIB", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SSL_SUPPORT
 | 
			
		||||
	if ( NGIRCd_VersionAddition[0] ) strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
	strlcat( NGIRCd_VersionAddition, "SSL", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef TCPWRAP
 | 
			
		||||
	if( NGIRCd_VersionAddition[0] )
 | 
			
		||||
			strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
	strlcat( NGIRCd_VersionAddition, "TCPWRAP", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
	if( NGIRCd_VersionAddition[0] )
 | 
			
		||||
		strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
	strlcat( NGIRCd_VersionAddition, "IDENT", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
#ifdef ICONV
 | 
			
		||||
	if (NGIRCd_VersionAddition[0])
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition);
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "PAM", sizeof NGIRCd_VersionAddition);
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "+",
 | 
			
		||||
			sizeof NGIRCd_VersionAddition);
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "CHARCONV",
 | 
			
		||||
		sizeof NGIRCd_VersionAddition);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	if( NGIRCd_VersionAddition[0] )
 | 
			
		||||
		strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
	strlcat( NGIRCd_VersionAddition, "DEBUG", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
	if (NGIRCd_VersionAddition[0])
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "+",
 | 
			
		||||
			sizeof NGIRCd_VersionAddition);
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "DEBUG",
 | 
			
		||||
		sizeof NGIRCd_VersionAddition);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SNIFFER
 | 
			
		||||
	if( NGIRCd_VersionAddition[0] )
 | 
			
		||||
		strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
	strlcat( NGIRCd_VersionAddition, "SNIFFER", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef STRICT_RFC
 | 
			
		||||
	if( NGIRCd_VersionAddition[0] )
 | 
			
		||||
		strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
	strlcat( NGIRCd_VersionAddition, "RFC", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
	if( NGIRCd_VersionAddition[0] )
 | 
			
		||||
		strlcat( NGIRCd_VersionAddition, "+", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
	strlcat( NGIRCd_VersionAddition, "IRCPLUS", sizeof NGIRCd_VersionAddition );
 | 
			
		||||
#ifdef IDENTAUTH
 | 
			
		||||
	if (NGIRCd_VersionAddition[0])
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "+",
 | 
			
		||||
			sizeof NGIRCd_VersionAddition);
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "IDENT",
 | 
			
		||||
		sizeof NGIRCd_VersionAddition);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef WANT_IPV6
 | 
			
		||||
	if (NGIRCd_VersionAddition[0])
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "+", sizeof(NGIRCd_VersionAddition));
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "IPv6", sizeof(NGIRCd_VersionAddition));
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "+",
 | 
			
		||||
			sizeof(NGIRCd_VersionAddition));
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "IPv6",
 | 
			
		||||
		sizeof(NGIRCd_VersionAddition));
 | 
			
		||||
#endif
 | 
			
		||||
	if( NGIRCd_VersionAddition[0] )
 | 
			
		||||
		strlcat( NGIRCd_VersionAddition, "-", sizeof( NGIRCd_VersionAddition ));
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
	if (NGIRCd_VersionAddition[0])
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "+",
 | 
			
		||||
			sizeof NGIRCd_VersionAddition);
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "IRCPLUS",
 | 
			
		||||
		sizeof NGIRCd_VersionAddition);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef PAM
 | 
			
		||||
	if (NGIRCd_VersionAddition[0])
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "+",
 | 
			
		||||
			sizeof NGIRCd_VersionAddition);
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "PAM",
 | 
			
		||||
		sizeof NGIRCd_VersionAddition);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef STRICT_RFC
 | 
			
		||||
	if (NGIRCd_VersionAddition[0])
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "+",
 | 
			
		||||
			sizeof NGIRCd_VersionAddition);
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "RFC",
 | 
			
		||||
		sizeof NGIRCd_VersionAddition);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SNIFFER
 | 
			
		||||
	if (NGIRCd_VersionAddition[0])
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "+",
 | 
			
		||||
			sizeof NGIRCd_VersionAddition);
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "SNIFFER",
 | 
			
		||||
		sizeof NGIRCd_VersionAddition);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SSL_SUPPORT
 | 
			
		||||
	if (NGIRCd_VersionAddition[0])
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "+",
 | 
			
		||||
			sizeof NGIRCd_VersionAddition);
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "SSL",
 | 
			
		||||
		sizeof NGIRCd_VersionAddition);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SYSLOG
 | 
			
		||||
	if (NGIRCd_VersionAddition[0])
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "+",
 | 
			
		||||
			sizeof NGIRCd_VersionAddition);
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "SYSLOG",
 | 
			
		||||
		sizeof NGIRCd_VersionAddition);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef TCPWRAP
 | 
			
		||||
	if (NGIRCd_VersionAddition[0])
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "+",
 | 
			
		||||
			sizeof NGIRCd_VersionAddition);
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "TCPWRAP",
 | 
			
		||||
		sizeof NGIRCd_VersionAddition);
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ZLIB
 | 
			
		||||
	if (NGIRCd_VersionAddition[0])
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "+",
 | 
			
		||||
			sizeof NGIRCd_VersionAddition);
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "ZLIB",
 | 
			
		||||
		sizeof NGIRCd_VersionAddition);
 | 
			
		||||
#endif
 | 
			
		||||
	if (NGIRCd_VersionAddition[0])
 | 
			
		||||
		strlcat(NGIRCd_VersionAddition, "-",
 | 
			
		||||
			sizeof(NGIRCd_VersionAddition));
 | 
			
		||||
 | 
			
		||||
	strlcat( NGIRCd_VersionAddition, TARGET_CPU, sizeof( NGIRCd_VersionAddition ));
 | 
			
		||||
	strlcat( NGIRCd_VersionAddition, "/", sizeof( NGIRCd_VersionAddition ));
 | 
			
		||||
	strlcat( NGIRCd_VersionAddition, TARGET_VENDOR, sizeof( NGIRCd_VersionAddition ));
 | 
			
		||||
	strlcat( NGIRCd_VersionAddition, "/", sizeof( NGIRCd_VersionAddition ));
 | 
			
		||||
	strlcat( NGIRCd_VersionAddition, TARGET_OS, sizeof( NGIRCd_VersionAddition ));
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, HOST_CPU,
 | 
			
		||||
		sizeof(NGIRCd_VersionAddition));
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "/", sizeof(NGIRCd_VersionAddition));
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, HOST_VENDOR,
 | 
			
		||||
		sizeof(NGIRCd_VersionAddition));
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, "/", sizeof(NGIRCd_VersionAddition));
 | 
			
		||||
	strlcat(NGIRCd_VersionAddition, HOST_OS,
 | 
			
		||||
		sizeof(NGIRCd_VersionAddition));
 | 
			
		||||
 | 
			
		||||
	snprintf(NGIRCd_Version, sizeof NGIRCd_Version, "%s %s-%s",
 | 
			
		||||
		 PACKAGE_NAME, PACKAGE_VERSION, NGIRCd_VersionAddition);
 | 
			
		||||
@@ -421,7 +460,7 @@ static void
 | 
			
		||||
Show_Version( void )
 | 
			
		||||
{
 | 
			
		||||
	puts( NGIRCd_Version );
 | 
			
		||||
	puts( "Copyright (c)2001-2011 Alexander Barton (<alex@barton.de>) and Contributors." );
 | 
			
		||||
	puts( "Copyright (c)2001-2012 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." );
 | 
			
		||||
@@ -496,7 +535,8 @@ Pidfile_Create(pid_t pid)
 | 
			
		||||
 | 
			
		||||
	len = snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid);
 | 
			
		||||
	if (len < 0 || len >= (int)sizeof pidbuf) {
 | 
			
		||||
		Log( LOG_ERR, "Error converting pid");
 | 
			
		||||
		Log(LOG_ERR, "Error converting pid");
 | 
			
		||||
		close(pidfd);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
@@ -527,6 +567,8 @@ Setup_FDStreams(int fd)
 | 
			
		||||
} /* Setup_FDStreams */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if !defined(SINGLE_USER_OS)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Get user and group ID of unprivileged "nobody" user.
 | 
			
		||||
 *
 | 
			
		||||
@@ -553,9 +595,10 @@ NGIRCd_getNobodyID(uid_t *uid, gid_t *gid )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	pwd = getpwnam("nobody");
 | 
			
		||||
	if (!pwd) return false;
 | 
			
		||||
	if (!pwd)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	if ( !pwd->pw_uid || !pwd->pw_gid)
 | 
			
		||||
	if (!pwd->pw_uid || !pwd->pw_gid)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	*uid = pwd->pw_uid;
 | 
			
		||||
@@ -565,6 +608,8 @@ NGIRCd_getNobodyID(uid_t *uid, gid_t *gid )
 | 
			
		||||
	return true;
 | 
			
		||||
} /* NGIRCd_getNobodyID */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
Random_Init_Kern(const char *file)
 | 
			
		||||
@@ -593,19 +638,19 @@ Random_Init(void)
 | 
			
		||||
		return;
 | 
			
		||||
	if (Random_Init_Kern("/dev/arandom"))
 | 
			
		||||
		return;
 | 
			
		||||
	srand(rand() ^ getpid() ^ time(NULL));
 | 
			
		||||
	srand(rand() ^ (unsigned)getpid() ^ (unsigned)time(NULL));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialize ngIRCd daemon.
 | 
			
		||||
 *
 | 
			
		||||
 * @param NGIRCd_NoDaemon	Set to true if ngIRCd should run in the
 | 
			
		||||
 *				foreground and not as a daemon.
 | 
			
		||||
 * @return			true on success.
 | 
			
		||||
 * @param NGIRCd_NoDaemon Set to true if ngIRCd should run in the
 | 
			
		||||
 *		foreground (and not as a daemon).
 | 
			
		||||
 * @return true on success.
 | 
			
		||||
 */
 | 
			
		||||
static bool
 | 
			
		||||
NGIRCd_Init( bool NGIRCd_NoDaemon ) 
 | 
			
		||||
NGIRCd_Init(bool NGIRCd_NoDaemon)
 | 
			
		||||
{
 | 
			
		||||
	static bool initialized;
 | 
			
		||||
	bool chrooted = false;
 | 
			
		||||
@@ -621,57 +666,74 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
 | 
			
		||||
		/* open /dev/null before chroot() */
 | 
			
		||||
		fd = open( "/dev/null", O_RDWR);
 | 
			
		||||
		if (fd < 0)
 | 
			
		||||
			Log(LOG_WARNING, "Could not open /dev/null: %s", strerror(errno));
 | 
			
		||||
			Log(LOG_WARNING, "Could not open /dev/null: %s",
 | 
			
		||||
			    strerror(errno));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* SSL initialization */
 | 
			
		||||
	if (!ConnSSL_InitLibrary())
 | 
			
		||||
		Log(LOG_WARNING,
 | 
			
		||||
		    "Warning: Error during SSL initialization, continuing ...");
 | 
			
		||||
		    "Error during SSL initialization, continuing without SSL ...");
 | 
			
		||||
 | 
			
		||||
	if( Conf_Chroot[0] ) {
 | 
			
		||||
		if( chdir( Conf_Chroot ) != 0 ) {
 | 
			
		||||
			Log( LOG_ERR, "Can't chdir() in ChrootDir (%s): %s", Conf_Chroot, strerror( errno ));
 | 
			
		||||
	/* Change root */
 | 
			
		||||
	if (Conf_Chroot[0]) {
 | 
			
		||||
		if (chdir(Conf_Chroot) != 0) {
 | 
			
		||||
			Log(LOG_ERR, "Can't chdir() in ChrootDir (%s): %s",
 | 
			
		||||
			    Conf_Chroot, strerror(errno));
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if( chroot( Conf_Chroot ) != 0 ) {
 | 
			
		||||
			if (errno != EPERM) {
 | 
			
		||||
				Log( LOG_ERR, "Can't change root directory to \"%s\": %s",
 | 
			
		||||
								Conf_Chroot, strerror( errno ));
 | 
			
		||||
				goto out;
 | 
			
		||||
			}
 | 
			
		||||
		if (chroot(Conf_Chroot) != 0) {
 | 
			
		||||
			Log(LOG_ERR,
 | 
			
		||||
			    "Can't change root directory to \"%s\": %s",
 | 
			
		||||
			    Conf_Chroot, strerror(errno));
 | 
			
		||||
			goto out;
 | 
			
		||||
		} else {
 | 
			
		||||
			chrooted = true;
 | 
			
		||||
			Log( LOG_INFO, "Changed root and working directory to \"%s\".", Conf_Chroot );
 | 
			
		||||
			Log(LOG_INFO,
 | 
			
		||||
			    "Changed root and working directory to \"%s\".",
 | 
			
		||||
			    Conf_Chroot);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#if !defined(SINGLE_USER_OS)
 | 
			
		||||
	/* Check user ID */
 | 
			
		||||
	if (Conf_UID == 0) {
 | 
			
		||||
		Log(LOG_INFO, "ServerUID must not be 0, using \"nobody\" instead.", Conf_UID);
 | 
			
		||||
 | 
			
		||||
  		if (! NGIRCd_getNobodyID(&Conf_UID, &Conf_GID)) {
 | 
			
		||||
			Log(LOG_WARNING, "Could not get user/group ID of user \"nobody\": %s",
 | 
			
		||||
					errno ? strerror(errno) : "not found" );
 | 
			
		||||
		pwd = getpwuid(0);
 | 
			
		||||
		Log(LOG_INFO,
 | 
			
		||||
		    "ServerUID must not be %s(0), using \"nobody\" instead.",
 | 
			
		||||
		    pwd ? pwd->pw_name : "?");
 | 
			
		||||
		if (!NGIRCd_getNobodyID(&Conf_UID, &Conf_GID)) {
 | 
			
		||||
			Log(LOG_WARNING,
 | 
			
		||||
			    "Could not get user/group ID of user \"nobody\": %s",
 | 
			
		||||
			    errno ? strerror(errno) : "not found" );
 | 
			
		||||
			goto out;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Change group ID */
 | 
			
		||||
	if (getgid() != Conf_GID) {
 | 
			
		||||
		/* Change group ID */
 | 
			
		||||
		if (setgid(Conf_GID) != 0) {
 | 
			
		||||
			real_errno = errno;
 | 
			
		||||
			Log( LOG_ERR, "Can't change group ID to %u: %s", Conf_GID, strerror( errno ));
 | 
			
		||||
			grp = getgrgid(Conf_GID);
 | 
			
		||||
			Log(LOG_ERR, "Can't change group ID to %s(%u): %s",
 | 
			
		||||
			    grp ? grp->gr_name : "?", Conf_GID,
 | 
			
		||||
			    strerror(errno));
 | 
			
		||||
			if (real_errno != EPERM) 
 | 
			
		||||
				goto out;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Change user ID */
 | 
			
		||||
	if (getuid() != Conf_UID) {
 | 
			
		||||
		/* Change user ID */
 | 
			
		||||
		if (setuid(Conf_UID) != 0) {
 | 
			
		||||
			real_errno = errno;
 | 
			
		||||
			Log(LOG_ERR, "Can't change user ID to %u: %s", Conf_UID, strerror(errno));
 | 
			
		||||
			if (real_errno != EPERM) 
 | 
			
		||||
			pwd = getpwuid(Conf_UID);
 | 
			
		||||
			Log(LOG_ERR, "Can't change user ID to %s(%u): %s",
 | 
			
		||||
			    pwd ? pwd->pw_name : "?", Conf_UID,
 | 
			
		||||
			    strerror(errno));
 | 
			
		||||
			if (real_errno != EPERM)
 | 
			
		||||
				goto out;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -681,26 +743,27 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
 | 
			
		||||
	/* Normally a child process is forked which isn't any longer
 | 
			
		||||
	 * connected to ther controlling terminal. Use "--nodaemon"
 | 
			
		||||
	 * to disable this "daemon mode" (useful for debugging). */
 | 
			
		||||
	if ( ! NGIRCd_NoDaemon ) {
 | 
			
		||||
		pid = fork( );
 | 
			
		||||
		if( pid > 0 ) {
 | 
			
		||||
	if (!NGIRCd_NoDaemon) {
 | 
			
		||||
		pid = fork();
 | 
			
		||||
		if (pid > 0) {
 | 
			
		||||
			/* "Old" process: exit. */
 | 
			
		||||
			exit( 0 );
 | 
			
		||||
			exit(0);
 | 
			
		||||
		}
 | 
			
		||||
		if( pid < 0 ) {
 | 
			
		||||
		if (pid < 0) {
 | 
			
		||||
			/* Error!? */
 | 
			
		||||
			fprintf( stderr, "%s: Can't fork: %s!\nFatal error, exiting now ...\n",
 | 
			
		||||
								PACKAGE_NAME, strerror( errno ));
 | 
			
		||||
			exit( 1 );
 | 
			
		||||
			fprintf(stderr,
 | 
			
		||||
				"%s: Can't fork: %s!\nFatal error, exiting now ...\n",
 | 
			
		||||
				PACKAGE_NAME, strerror(errno));
 | 
			
		||||
			exit(1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* New child process */
 | 
			
		||||
#ifndef NeXT
 | 
			
		||||
		(void)setsid( );
 | 
			
		||||
#ifdef HAVE_SETSID
 | 
			
		||||
		(void)setsid();
 | 
			
		||||
#else
 | 
			
		||||
		setpgrp(0, getpid());
 | 
			
		||||
#endif
 | 
			
		||||
		if (chdir( "/" ) != 0)
 | 
			
		||||
		if (chdir("/") != 0)
 | 
			
		||||
			Log(LOG_ERR, "Can't change directory to '/': %s",
 | 
			
		||||
				     strerror(errno));
 | 
			
		||||
 | 
			
		||||
@@ -711,19 +774,19 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
 | 
			
		||||
	}
 | 
			
		||||
	pid = getpid();
 | 
			
		||||
 | 
			
		||||
	Pidfile_Create( pid );
 | 
			
		||||
	Pidfile_Create(pid);
 | 
			
		||||
 | 
			
		||||
	/* Check UID/GID we are running as, can be different from values
 | 
			
		||||
	 * configured (e. g. if we were already started with a UID>0. */
 | 
			
		||||
	Conf_UID = getuid();
 | 
			
		||||
	Conf_GID = getgid();
 | 
			
		||||
 | 
			
		||||
	pwd = getpwuid( Conf_UID );
 | 
			
		||||
	grp = getgrgid( Conf_GID );
 | 
			
		||||
	pwd = getpwuid(Conf_UID);
 | 
			
		||||
	grp = getgrgid(Conf_GID);
 | 
			
		||||
 | 
			
		||||
	Log(LOG_INFO, "Running as user %s(%ld), group %s(%ld), with PID %ld.",
 | 
			
		||||
				pwd ? pwd->pw_name : "unknown", (long)Conf_UID,
 | 
			
		||||
				grp ? grp->gr_name : "unknown", (long)Conf_GID, (long)pid);
 | 
			
		||||
	    pwd ? pwd->pw_name : "unknown", (long)Conf_UID,
 | 
			
		||||
	    grp ? grp->gr_name : "unknown", (long)Conf_GID, (long)pid);
 | 
			
		||||
 | 
			
		||||
	if (chrooted) {
 | 
			
		||||
		Log(LOG_INFO, "Running with root directory \"%s\".",
 | 
			
		||||
@@ -732,20 +795,23 @@ NGIRCd_Init( bool NGIRCd_NoDaemon )
 | 
			
		||||
	} else
 | 
			
		||||
		Log(LOG_INFO, "Not running with changed root directory.");
 | 
			
		||||
 | 
			
		||||
	/* Change working directory to home directory of the user
 | 
			
		||||
	 * we are running as (only when running in daemon mode and not in chroot) */
 | 
			
		||||
	/* Change working directory to home directory of the user we are
 | 
			
		||||
	 * running as (only when running in daemon mode and not in chroot) */
 | 
			
		||||
 | 
			
		||||
	if (NGIRCd_NoDaemon)
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	if (pwd) {
 | 
			
		||||
		if (!NGIRCd_NoDaemon ) {
 | 
			
		||||
			if( chdir( pwd->pw_dir ) == 0 ) 
 | 
			
		||||
				Log( LOG_DEBUG, "Changed working directory to \"%s\" ...", pwd->pw_dir );
 | 
			
		||||
			else 
 | 
			
		||||
				Log( LOG_INFO, "Notice: Can't change working directory to \"%s\": %s",
 | 
			
		||||
								pwd->pw_dir, strerror( errno ));
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		Log( LOG_ERR, "Can't get user informaton for UID %d!?", Conf_UID );
 | 
			
		||||
	}
 | 
			
		||||
		if (chdir(pwd->pw_dir) == 0)
 | 
			
		||||
			Log(LOG_DEBUG,
 | 
			
		||||
			    "Changed working directory to \"%s\" ...",
 | 
			
		||||
			    pwd->pw_dir);
 | 
			
		||||
		else
 | 
			
		||||
			Log(LOG_INFO,
 | 
			
		||||
			    "Notice: Can't change working directory to \"%s\": %s",
 | 
			
		||||
			    pwd->pw_dir, strerror(errno));
 | 
			
		||||
	} else
 | 
			
		||||
		Log(LOG_ERR, "Can't get user informaton for UID %d!?", Conf_UID);
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
 out:
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,7 @@
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "class.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "lists.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
@@ -47,12 +48,11 @@ Announce_Channel(CLIENT *Client, CHANNEL *Chan)
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	CLIENT *cl;
 | 
			
		||||
	char str[LINE_LEN], *ptr;
 | 
			
		||||
	bool njoin;
 | 
			
		||||
	bool njoin, xop;
 | 
			
		||||
 | 
			
		||||
	if (Conn_Options(Client_Conn(Client)) & CONN_RFC1459)
 | 
			
		||||
		njoin = false;
 | 
			
		||||
	else
 | 
			
		||||
		njoin = true;
 | 
			
		||||
	/* Check features of remote server */
 | 
			
		||||
	njoin = Conn_Options(Client_Conn(Client)) & CONN_RFC1459 ? false : true;
 | 
			
		||||
	xop = strchr(Client_Flags(Client), 'X') ? true : false;
 | 
			
		||||
 | 
			
		||||
	/* Get all the members of this channel */
 | 
			
		||||
	cl2chan = Channel_FirstMember(Chan);
 | 
			
		||||
@@ -62,14 +62,23 @@ Announce_Channel(CLIENT *Client, CHANNEL *Chan)
 | 
			
		||||
		assert(cl != NULL);
 | 
			
		||||
 | 
			
		||||
		if (njoin) {
 | 
			
		||||
			/* RFC 2813: send NJOIN with nick names and modes
 | 
			
		||||
			/* RFC 2813: send NJOIN with nicknames and modes
 | 
			
		||||
			 * (if user is channel operator or has voice) */
 | 
			
		||||
			if (str[strlen(str) - 1] != ':')
 | 
			
		||||
				strlcat(str, ",", sizeof(str));
 | 
			
		||||
			if (strchr(Channel_UserModes(Chan, cl), 'v'))
 | 
			
		||||
				strlcat(str, "+", sizeof(str));
 | 
			
		||||
 | 
			
		||||
			/* Prepare user prefix (ChanOp, voiced, ...) */
 | 
			
		||||
			if (xop && strchr(Channel_UserModes(Chan, cl), 'q'))
 | 
			
		||||
				strlcat(str, "~", sizeof(str));
 | 
			
		||||
			if (xop && strchr(Channel_UserModes(Chan, cl), 'a'))
 | 
			
		||||
				strlcat(str, "&", sizeof(str));
 | 
			
		||||
			if (strchr(Channel_UserModes(Chan, cl), 'o'))
 | 
			
		||||
				strlcat(str, "@", sizeof(str));
 | 
			
		||||
			if (xop && strchr(Channel_UserModes(Chan, cl), 'h'))
 | 
			
		||||
				strlcat(str, "%", sizeof(str));
 | 
			
		||||
			if (strchr(Channel_UserModes(Chan, cl), 'v'))
 | 
			
		||||
				strlcat(str, "+", sizeof(str));
 | 
			
		||||
 | 
			
		||||
			strlcat(str, Client_ID(cl), sizeof(str));
 | 
			
		||||
 | 
			
		||||
			/* Send the data if the buffer is "full" */
 | 
			
		||||
@@ -170,32 +179,50 @@ Announce_User(CLIENT * Client, CLIENT * User)
 | 
			
		||||
				     Client_ID(User), Client_ID(User),
 | 
			
		||||
				     modes);
 | 
			
		||||
		}
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	} else {
 | 
			
		||||
		/* RFC 2813 mode: one combined NICK or SERVICE command */
 | 
			
		||||
		if (Client_Type(User) == CLIENT_SERVICE
 | 
			
		||||
		    && strchr(Client_Flags(Client), 'S'))
 | 
			
		||||
			return IRC_WriteStrClient(Client,
 | 
			
		||||
				"SERVICE %s %d * +%s %d :%s", Client_Mask(User),
 | 
			
		||||
				Client_MyToken(Client_Introducer(User)),
 | 
			
		||||
				Client_Modes(User), Client_Hops(User) + 1,
 | 
			
		||||
				Client_Info(User));
 | 
			
		||||
		else
 | 
			
		||||
			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));
 | 
			
		||||
		    && strchr(Client_Flags(Client), 'S')) {
 | 
			
		||||
			if (!IRC_WriteStrClient(Client,
 | 
			
		||||
					"SERVICE %s %d * +%s %d :%s",
 | 
			
		||||
					Client_Mask(User),
 | 
			
		||||
					Client_MyToken(Client_Introducer(User)),
 | 
			
		||||
					Client_Modes(User), Client_Hops(User) + 1,
 | 
			
		||||
					Client_Info(User)))
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
		} else {
 | 
			
		||||
			if (!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)))
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (strchr(Client_Flags(Client), 'M')) {
 | 
			
		||||
		/* Synchronize metadata */
 | 
			
		||||
		if (Client_HostnameCloaked(User)) {
 | 
			
		||||
			if (!IRC_WriteStrClient(Client,
 | 
			
		||||
						"METADATA %s cloakhost :%s",
 | 
			
		||||
						Client_ID(User),
 | 
			
		||||
						Client_HostnameCloaked(User)))
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* Announce_User */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Synchronize invite and ban lists between servers
 | 
			
		||||
 * @param Client New server
 | 
			
		||||
 * Synchronize invite, ban, G- and K-Line lists between servers.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Client New server.
 | 
			
		||||
 * @return CONNECTED or DISCONNECTED.
 | 
			
		||||
 */
 | 
			
		||||
static bool
 | 
			
		||||
Synchronize_Lists(CLIENT * Client)
 | 
			
		||||
@@ -206,6 +233,18 @@ Synchronize_Lists(CLIENT * Client)
 | 
			
		||||
 | 
			
		||||
	assert(Client != NULL);
 | 
			
		||||
 | 
			
		||||
	/* g-lines */
 | 
			
		||||
	head = Class_GetList(CLASS_GLINE);
 | 
			
		||||
	elem = Lists_GetFirst(head);
 | 
			
		||||
	while (elem) {
 | 
			
		||||
		if (!IRC_WriteStrClient(Client, "GLINE %s %ld :%s",
 | 
			
		||||
					Lists_GetMask(elem),
 | 
			
		||||
					Lists_GetValidity(elem) - time(NULL),
 | 
			
		||||
					Lists_GetReason(elem)))
 | 
			
		||||
			return DISCONNECTED;
 | 
			
		||||
		elem = Lists_GetNext(elem);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c = Channel_First();
 | 
			
		||||
	while (c) {
 | 
			
		||||
		/* ban list */
 | 
			
		||||
@@ -369,6 +408,10 @@ IRC_Num_ENDOFMOTD(CLIENT * Client, UNUSED REQUEST * Req)
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (!IRC_WriteStrClient(Client, "PING :%s",
 | 
			
		||||
	    Client_ID(Client_ThisServer())))
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_Num_ENDOFMOTD */
 | 
			
		||||
 | 
			
		||||
@@ -394,12 +437,12 @@ IRC_Num_ISUPPORT(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
			if ((unsigned int)atol(value) == Conf_MaxNickLength - 1)
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			/* Nick name length settings are different! */
 | 
			
		||||
			/* Nickname length settings are different! */
 | 
			
		||||
			Log(LOG_ERR,
 | 
			
		||||
			    "Peer uses incompatible nick name length (%d/%d)! Disconnecting ...",
 | 
			
		||||
			    "Peer uses incompatible nickname length (%d/%d)! Disconnecting ...",
 | 
			
		||||
			    Conf_MaxNickLength - 1, atoi(value));
 | 
			
		||||
			Conn_Close(Client_Conn(Client),
 | 
			
		||||
				   "Incompatible nick name length",
 | 
			
		||||
				   "Incompatible nickname length",
 | 
			
		||||
				   NULL, false);
 | 
			
		||||
			return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -58,9 +58,15 @@ Op_NoPrivileges(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Check that the client is an IRC operator allowed to administer this server.
 | 
			
		||||
 * Check that the originator of a request is an IRC operator and allowed
 | 
			
		||||
 * to administer this server.
 | 
			
		||||
 *
 | 
			
		||||
 * @param CLient Client from which the command has been received.
 | 
			
		||||
 * @param Req Request structure.
 | 
			
		||||
 * @return CLIENT structure of the client that initiated the command or
 | 
			
		||||
 *	   NULL if client is not allowed to execute operator commands.
 | 
			
		||||
 */
 | 
			
		||||
GLOBAL bool
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Op_Check(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
@@ -72,15 +78,20 @@ Op_Check(CLIENT * Client, REQUEST * Req)
 | 
			
		||||
		c = Client_Search(Req->prefix);
 | 
			
		||||
	else
 | 
			
		||||
		c = Client;
 | 
			
		||||
 | 
			
		||||
	if (!c)
 | 
			
		||||
		return false;
 | 
			
		||||
		return NULL;
 | 
			
		||||
	if (Client_Type(Client) == CLIENT_SERVER
 | 
			
		||||
	    && Client_Type(c) == CLIENT_SERVER)
 | 
			
		||||
		return c;
 | 
			
		||||
	if (!Client_HasMode(c, 'o'))
 | 
			
		||||
		return false;
 | 
			
		||||
		return NULL;
 | 
			
		||||
	if (!Client_OperByMe(c) && !Conf_AllowRemoteOper)
 | 
			
		||||
		return false;
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	/* The client is an local IRC operator, or this server is configured
 | 
			
		||||
	 * to trust remote operators. */
 | 
			
		||||
	return true;
 | 
			
		||||
	return c;
 | 
			
		||||
} /* Op_Check */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2009 Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
@@ -18,7 +18,7 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
GLOBAL bool Op_NoPrivileges PARAMS((CLIENT * Client, REQUEST * Req));
 | 
			
		||||
GLOBAL bool Op_Check PARAMS((CLIENT * Client, REQUEST * Req));
 | 
			
		||||
GLOBAL CLIENT *Op_Check PARAMS((CLIENT * Client, REQUEST * Req));
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user