mirror of
				https://github.com/osmarks/ngircd.git
				synced 2025-11-03 23:43:00 +00:00 
			
		
		
		
	Compare commits
	
		
			687 Commits
		
	
	
		
			branch-0-4
			...
			rel-0-7-5
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					29d430edd5 | ||
| 
						 | 
					2b8052b03a | ||
| 
						 | 
					d155ed17c8 | ||
| 
						 | 
					0b114e814b | ||
| 
						 | 
					d72811c9af | ||
| 
						 | 
					4aa0fa7119 | ||
| 
						 | 
					ad22b3087f | ||
| 
						 | 
					c3c4f32145 | ||
| 
						 | 
					d72b14b9c8 | ||
| 
						 | 
					6d7de626c8 | ||
| 
						 | 
					73fc65a35f | ||
| 
						 | 
					01929c161d | ||
| 
						 | 
					b0ea5b7d04 | ||
| 
						 | 
					f0653cdf24 | ||
| 
						 | 
					0b95570a80 | ||
| 
						 | 
					ef907632b8 | ||
| 
						 | 
					810127e2a8 | ||
| 
						 | 
					3045ce06ef | ||
| 
						 | 
					3b17c66068 | ||
| 
						 | 
					25a947f0dd | ||
| 
						 | 
					e765124c25 | ||
| 
						 | 
					8186e930aa | ||
| 
						 | 
					ae683b294f | ||
| 
						 | 
					9295fce7cf | ||
| 
						 | 
					9dfe74ffe2 | ||
| 
						 | 
					10577f8e36 | ||
| 
						 | 
					fbead4a15c | ||
| 
						 | 
					322d3ebaec | ||
| 
						 | 
					bbfeaa953b | ||
| 
						 | 
					26790e960f | ||
| 
						 | 
					4b1711a614 | ||
| 
						 | 
					3630e840e5 | ||
| 
						 | 
					bcd6db9016 | ||
| 
						 | 
					0e7970cfe6 | ||
| 
						 | 
					9a9b4617aa | ||
| 
						 | 
					434a6887f0 | ||
| 
						 | 
					a9a605ddb9 | ||
| 
						 | 
					99ab8607c9 | ||
| 
						 | 
					14b1ae7aea | ||
| 
						 | 
					2517c2cb99 | ||
| 
						 | 
					75fb85d029 | ||
| 
						 | 
					1e599eb535 | ||
| 
						 | 
					36bd5d3ad6 | ||
| 
						 | 
					0be9053c17 | ||
| 
						 | 
					cd7d28d743 | ||
| 
						 | 
					f04a2ce2b4 | ||
| 
						 | 
					4d7a5df0e2 | ||
| 
						 | 
					7ba1bde408 | ||
| 
						 | 
					a7d00cd7b1 | ||
| 
						 | 
					3585e2bc50 | ||
| 
						 | 
					bd52d4e49c | ||
| 
						 | 
					e0345e5e0a | ||
| 
						 | 
					c1dd86d702 | ||
| 
						 | 
					b25faf3c2a | ||
| 
						 | 
					384d6b894a | ||
| 
						 | 
					a061668b1a | ||
| 
						 | 
					489d8c5cd0 | ||
| 
						 | 
					daa996f177 | ||
| 
						 | 
					7deacbaa11 | ||
| 
						 | 
					c3dfd63bf3 | ||
| 
						 | 
					f5b91cd03d | ||
| 
						 | 
					8e43b16d22 | ||
| 
						 | 
					4ef6dae1cd | ||
| 
						 | 
					0b91df05e0 | ||
| 
						 | 
					feafb6cb2e | ||
| 
						 | 
					0391d35a67 | ||
| 
						 | 
					a93b4d9789 | ||
| 
						 | 
					eefa1b1c64 | ||
| 
						 | 
					016e547daa | ||
| 
						 | 
					b588eaed02 | ||
| 
						 | 
					36e0345ce6 | ||
| 
						 | 
					62796722f1 | ||
| 
						 | 
					935ffd0dc0 | ||
| 
						 | 
					fa54e6e2a4 | ||
| 
						 | 
					179e760cf1 | ||
| 
						 | 
					47faa8595a | ||
| 
						 | 
					9ab97b29ae | ||
| 
						 | 
					24df40eca7 | ||
| 
						 | 
					02a22611be | ||
| 
						 | 
					59a0fb8cd9 | ||
| 
						 | 
					d383703b78 | ||
| 
						 | 
					8291e10b96 | ||
| 
						 | 
					312e4aeb86 | ||
| 
						 | 
					ac4f25e3a7 | ||
| 
						 | 
					7646739431 | ||
| 
						 | 
					5f19a9418e | ||
| 
						 | 
					3858e28e07 | ||
| 
						 | 
					f53455977d | ||
| 
						 | 
					9ca1f6a988 | ||
| 
						 | 
					1a1ff404a8 | ||
| 
						 | 
					c755b82dd9 | ||
| 
						 | 
					8fc69bb6fb | ||
| 
						 | 
					10edb7c741 | ||
| 
						 | 
					ff019dd76f | ||
| 
						 | 
					a004f34447 | ||
| 
						 | 
					10bb43c66e | ||
| 
						 | 
					b6999f10c0 | ||
| 
						 | 
					516064dc06 | ||
| 
						 | 
					a84b9d99a1 | ||
| 
						 | 
					5170ecf045 | ||
| 
						 | 
					23a28fa336 | ||
| 
						 | 
					15b5e1a6eb | ||
| 
						 | 
					ade2fdc9aa | ||
| 
						 | 
					e744936d19 | ||
| 
						 | 
					4a5b3f34a5 | ||
| 
						 | 
					7640aa5190 | ||
| 
						 | 
					35771fa776 | ||
| 
						 | 
					439c945d56 | ||
| 
						 | 
					93146b5718 | ||
| 
						 | 
					fd4a6b5dd5 | ||
| 
						 | 
					b896f8acda | ||
| 
						 | 
					29bd35bc4f | ||
| 
						 | 
					f179070113 | ||
| 
						 | 
					f813833ba1 | ||
| 
						 | 
					f349b18949 | ||
| 
						 | 
					aa15257936 | ||
| 
						 | 
					6e0c5698e4 | ||
| 
						 | 
					cf4ad8d6f7 | ||
| 
						 | 
					2a3f8cc57d | ||
| 
						 | 
					560c79615c | ||
| 
						 | 
					d1b2a1c4f9 | ||
| 
						 | 
					9d8f425a9a | ||
| 
						 | 
					fbec1f1070 | ||
| 
						 | 
					d978d8ddbb | ||
| 
						 | 
					e07542a1ff | ||
| 
						 | 
					155f26eee2 | ||
| 
						 | 
					9eee0c883b | ||
| 
						 | 
					939767d502 | ||
| 
						 | 
					dccb297678 | ||
| 
						 | 
					2152e37722 | ||
| 
						 | 
					28cd2c1191 | ||
| 
						 | 
					947c512435 | ||
| 
						 | 
					42c4e6c7b1 | ||
| 
						 | 
					f9cb4a42a0 | ||
| 
						 | 
					0f3e84f415 | ||
| 
						 | 
					6a0bd57ec4 | ||
| 
						 | 
					fc1118cb5a | ||
| 
						 | 
					070976e443 | ||
| 
						 | 
					0bcaed3564 | ||
| 
						 | 
					df00b38a0b | ||
| 
						 | 
					aca6310dac | ||
| 
						 | 
					ff98833136 | ||
| 
						 | 
					1443bc381c | ||
| 
						 | 
					9d82635b15 | ||
| 
						 | 
					fa80012e71 | ||
| 
						 | 
					43d9a62473 | ||
| 
						 | 
					51e1a2e04a | ||
| 
						 | 
					b8a3178a1b | ||
| 
						 | 
					bb94d18115 | ||
| 
						 | 
					3b79965e38 | ||
| 
						 | 
					e82e3c3fdc | ||
| 
						 | 
					f39d628512 | ||
| 
						 | 
					5b33308528 | ||
| 
						 | 
					444fdcf905 | ||
| 
						 | 
					1bf0426aaf | ||
| 
						 | 
					8139505829 | ||
| 
						 | 
					c9540015c8 | ||
| 
						 | 
					2070cfe107 | ||
| 
						 | 
					91f4aeec20 | ||
| 
						 | 
					8c1df9ef8d | ||
| 
						 | 
					c428ac7563 | ||
| 
						 | 
					e12179aa92 | ||
| 
						 | 
					cd9650c07e | ||
| 
						 | 
					5e3e3ad445 | ||
| 
						 | 
					e6a352dcfe | ||
| 
						 | 
					e17976a172 | ||
| 
						 | 
					ae6a7e7c0b | ||
| 
						 | 
					717a26e37d | ||
| 
						 | 
					8dadb17f83 | ||
| 
						 | 
					281f7583f5 | ||
| 
						 | 
					a7956f334e | ||
| 
						 | 
					3e026ded6f | ||
| 
						 | 
					4e485443d3 | ||
| 
						 | 
					01b58a0582 | ||
| 
						 | 
					f83ea4b124 | ||
| 
						 | 
					b8d7dcec77 | ||
| 
						 | 
					b77dae3499 | ||
| 
						 | 
					0b04bfa7c0 | ||
| 
						 | 
					4953c15bdf | ||
| 
						 | 
					437f2c335f | ||
| 
						 | 
					e68cdf304f | ||
| 
						 | 
					a2544e496c | ||
| 
						 | 
					e5b824388d | ||
| 
						 | 
					214842853c | ||
| 
						 | 
					cf6b9e3ec1 | ||
| 
						 | 
					50d354bc21 | ||
| 
						 | 
					3c9da65652 | ||
| 
						 | 
					8340e4267c | ||
| 
						 | 
					c9ee3ae4f0 | ||
| 
						 | 
					e21b9d842c | ||
| 
						 | 
					15e4f67402 | ||
| 
						 | 
					01bec0daa2 | ||
| 
						 | 
					d19813cc4b | ||
| 
						 | 
					cf7660c975 | ||
| 
						 | 
					9c5c0c7c84 | ||
| 
						 | 
					4d2f279d2d | ||
| 
						 | 
					371fc25967 | ||
| 
						 | 
					b316c380ad | ||
| 
						 | 
					695631b298 | ||
| 
						 | 
					6626395c88 | ||
| 
						 | 
					0ced4181b0 | ||
| 
						 | 
					4f6f84e7e1 | ||
| 
						 | 
					b8456d1ba6 | ||
| 
						 | 
					fbdf85b553 | ||
| 
						 | 
					e13cb291dd | ||
| 
						 | 
					8193bf2070 | ||
| 
						 | 
					5efd0987f3 | ||
| 
						 | 
					60cf07c875 | ||
| 
						 | 
					3c738ed46d | ||
| 
						 | 
					9353a4a9cb | ||
| 
						 | 
					18dfd96635 | ||
| 
						 | 
					77751e0fbf | ||
| 
						 | 
					d9a13b317e | ||
| 
						 | 
					d449496aa4 | ||
| 
						 | 
					2f90341225 | ||
| 
						 | 
					ab44e1c6cc | ||
| 
						 | 
					a3f59f1a5b | ||
| 
						 | 
					212d36a33c | ||
| 
						 | 
					d0304b19a2 | ||
| 
						 | 
					c69b208bd4 | ||
| 
						 | 
					397c5e2e02 | ||
| 
						 | 
					77c4c015e3 | ||
| 
						 | 
					43a4bc5b8b | ||
| 
						 | 
					1df4081e50 | ||
| 
						 | 
					b9d6a03e25 | ||
| 
						 | 
					8841d87365 | ||
| 
						 | 
					d9e3f834d7 | ||
| 
						 | 
					210282d00f | ||
| 
						 | 
					17f7c6d3ed | ||
| 
						 | 
					a02bf31d50 | ||
| 
						 | 
					98677b4348 | ||
| 
						 | 
					03d5fd6cb7 | ||
| 
						 | 
					3a811ef563 | ||
| 
						 | 
					3e4f58e416 | ||
| 
						 | 
					b7be46ed8a | ||
| 
						 | 
					902ad91212 | ||
| 
						 | 
					ca584143c6 | ||
| 
						 | 
					892144dc71 | ||
| 
						 | 
					8d024d05d2 | ||
| 
						 | 
					69ad0e386e | ||
| 
						 | 
					2e88dd72d1 | ||
| 
						 | 
					7924fafb25 | ||
| 
						 | 
					7f61f413f4 | ||
| 
						 | 
					865c43080a | ||
| 
						 | 
					c0d74a3860 | ||
| 
						 | 
					3c7909ccec | ||
| 
						 | 
					48ec815e99 | ||
| 
						 | 
					80c6dc86ed | ||
| 
						 | 
					25ca2b3cc5 | ||
| 
						 | 
					f7fe170a5e | ||
| 
						 | 
					e65ab4a3f7 | ||
| 
						 | 
					2694017426 | ||
| 
						 | 
					00e75ccd7d | ||
| 
						 | 
					e907816380 | ||
| 
						 | 
					b55915c1fe | ||
| 
						 | 
					5b8b3b8384 | ||
| 
						 | 
					9f74b95015 | ||
| 
						 | 
					8b7b23cf8f | ||
| 
						 | 
					b7eb5f66dc | ||
| 
						 | 
					427be23b6e | ||
| 
						 | 
					ba767481d9 | ||
| 
						 | 
					490f28ffd1 | ||
| 
						 | 
					c7f075236b | ||
| 
						 | 
					44a2b3cf69 | ||
| 
						 | 
					f0d633b5ac | ||
| 
						 | 
					0f3f03b51d | ||
| 
						 | 
					fa7b3f0e4c | ||
| 
						 | 
					6725d7893c | ||
| 
						 | 
					11c4e786fa | ||
| 
						 | 
					b99af4fa47 | ||
| 
						 | 
					6591f17f0a | ||
| 
						 | 
					9f122037ae | ||
| 
						 | 
					cde9dfdb77 | ||
| 
						 | 
					f0349f5266 | ||
| 
						 | 
					4807c4e636 | ||
| 
						 | 
					c1cafbddfe | ||
| 
						 | 
					bad7ac62a7 | ||
| 
						 | 
					39219230b2 | ||
| 
						 | 
					1e5fa014ba | ||
| 
						 | 
					0efec7c094 | ||
| 
						 | 
					c3a892e165 | ||
| 
						 | 
					2e02da291a | ||
| 
						 | 
					a39f479163 | ||
| 
						 | 
					e50d568f25 | ||
| 
						 | 
					0c471b84f7 | ||
| 
						 | 
					1e59617d2c | ||
| 
						 | 
					e93f545c74 | ||
| 
						 | 
					a1437f1ad0 | ||
| 
						 | 
					1d8cb34bc8 | ||
| 
						 | 
					7a6f99a607 | ||
| 
						 | 
					93a39e8782 | ||
| 
						 | 
					a1dff15252 | ||
| 
						 | 
					ee2c0f7701 | ||
| 
						 | 
					d3a6537fce | ||
| 
						 | 
					b0b797b396 | ||
| 
						 | 
					2de5b5cf4a | ||
| 
						 | 
					2625ce7875 | ||
| 
						 | 
					65f3adca21 | ||
| 
						 | 
					ecde730ec4 | ||
| 
						 | 
					e553829a59 | ||
| 
						 | 
					7cc12a3d63 | ||
| 
						 | 
					ad98f2c20d | ||
| 
						 | 
					dc8ca3dfaf | ||
| 
						 | 
					ae128734ac | ||
| 
						 | 
					f86bbd718d | ||
| 
						 | 
					283aed75cf | ||
| 
						 | 
					15d78412bc | ||
| 
						 | 
					1fd9216ca4 | ||
| 
						 | 
					a7eb18db4e | ||
| 
						 | 
					5ecb00ed23 | ||
| 
						 | 
					5e89b0c82d | ||
| 
						 | 
					22b7b07932 | ||
| 
						 | 
					57bc0d7895 | ||
| 
						 | 
					5334778dbd | ||
| 
						 | 
					1dd953b0c0 | ||
| 
						 | 
					fa3dbfd8d6 | ||
| 
						 | 
					4eb57b590b | ||
| 
						 | 
					12bf203167 | ||
| 
						 | 
					cf2d479437 | ||
| 
						 | 
					413fed9858 | ||
| 
						 | 
					60f14cca38 | ||
| 
						 | 
					4f54760c4b | ||
| 
						 | 
					c0e7a0124d | ||
| 
						 | 
					b8cf379fd6 | ||
| 
						 | 
					085a03d107 | ||
| 
						 | 
					ab788a2ed1 | ||
| 
						 | 
					4c6e07c309 | ||
| 
						 | 
					e311cc0140 | ||
| 
						 | 
					a5c9229084 | ||
| 
						 | 
					a0c032b2ff | ||
| 
						 | 
					03ec91f943 | ||
| 
						 | 
					7233b72145 | ||
| 
						 | 
					1656841f25 | ||
| 
						 | 
					799511d472 | ||
| 
						 | 
					ffb90f4cb5 | ||
| 
						 | 
					e46b124ca4 | ||
| 
						 | 
					c6b9f3a13d | ||
| 
						 | 
					6d5b606c46 | ||
| 
						 | 
					dd09b17eae | ||
| 
						 | 
					caa7049e2b | ||
| 
						 | 
					b2615bcc76 | ||
| 
						 | 
					1c0ded41af | ||
| 
						 | 
					7bbdfb3d84 | ||
| 
						 | 
					0086d2771d | ||
| 
						 | 
					98bc7d4fb7 | ||
| 
						 | 
					be9df69116 | ||
| 
						 | 
					f80a5ae1de | ||
| 
						 | 
					b1a148905a | ||
| 
						 | 
					8457fca570 | ||
| 
						 | 
					999897f587 | ||
| 
						 | 
					ab2d1ca41e | ||
| 
						 | 
					ee489ee6d7 | ||
| 
						 | 
					6250dcb1dc | ||
| 
						 | 
					797f9170d7 | ||
| 
						 | 
					071686ac6e | ||
| 
						 | 
					70c9c05153 | ||
| 
						 | 
					bf84670aaa | ||
| 
						 | 
					d35c0137b7 | ||
| 
						 | 
					ae39724a63 | ||
| 
						 | 
					8da254ea74 | ||
| 
						 | 
					47c8bcc8c9 | ||
| 
						 | 
					9523e28179 | ||
| 
						 | 
					a4d5ca633a | ||
| 
						 | 
					3102c550ff | ||
| 
						 | 
					51dd80c48b | ||
| 
						 | 
					14e870e2ec | ||
| 
						 | 
					a6265aa0df | ||
| 
						 | 
					4c870f4be9 | ||
| 
						 | 
					a29e37a4c1 | ||
| 
						 | 
					aabe013dd0 | ||
| 
						 | 
					07984e0b81 | ||
| 
						 | 
					7ec3603996 | ||
| 
						 | 
					b991de0f15 | ||
| 
						 | 
					601f0ede61 | ||
| 
						 | 
					0d32a3b4fe | ||
| 
						 | 
					650f9a2d9e | ||
| 
						 | 
					05839597bf | ||
| 
						 | 
					8eac8bcbfc | ||
| 
						 | 
					8dd5ea0729 | ||
| 
						 | 
					d98e7def76 | ||
| 
						 | 
					5b25c8ccd0 | ||
| 
						 | 
					135abb5d74 | ||
| 
						 | 
					12cad28ee8 | ||
| 
						 | 
					b840be9875 | ||
| 
						 | 
					863daa29cb | ||
| 
						 | 
					3cf845fbfb | ||
| 
						 | 
					c49bee8d0b | ||
| 
						 | 
					0dfb771671 | ||
| 
						 | 
					452d98f329 | ||
| 
						 | 
					a981f517f3 | ||
| 
						 | 
					736bacde90 | ||
| 
						 | 
					df0eb17172 | ||
| 
						 | 
					f274ec0652 | ||
| 
						 | 
					b7593369fb | ||
| 
						 | 
					ef407ea50c | ||
| 
						 | 
					345b9a3217 | ||
| 
						 | 
					af719e60c5 | ||
| 
						 | 
					84022a12fd | ||
| 
						 | 
					c7b55aa6f4 | ||
| 
						 | 
					5e70a131e9 | ||
| 
						 | 
					1e83e6662f | ||
| 
						 | 
					b6c049cb3c | ||
| 
						 | 
					39d7b014cf | ||
| 
						 | 
					bd645f5095 | ||
| 
						 | 
					856f24eb7e | ||
| 
						 | 
					f060db5ec5 | ||
| 
						 | 
					180eb810cf | ||
| 
						 | 
					25f32ce8b8 | ||
| 
						 | 
					5eaf15574a | ||
| 
						 | 
					467e76aa32 | ||
| 
						 | 
					63bda7de11 | ||
| 
						 | 
					ec474a4bd2 | ||
| 
						 | 
					74ff9828de | ||
| 
						 | 
					25530fff71 | ||
| 
						 | 
					df2bd0e6fb | ||
| 
						 | 
					1ed0c6926e | ||
| 
						 | 
					7a2b49a629 | ||
| 
						 | 
					a33105dcd1 | ||
| 
						 | 
					a5b5952598 | ||
| 
						 | 
					c6e936d6c2 | ||
| 
						 | 
					ab2abee1fe | ||
| 
						 | 
					67d79b92e6 | ||
| 
						 | 
					9ba956ca8b | ||
| 
						 | 
					c50ecda715 | ||
| 
						 | 
					9d928b240b | ||
| 
						 | 
					870fa2797c | ||
| 
						 | 
					8d1efc81f6 | ||
| 
						 | 
					2b6dbb07e8 | ||
| 
						 | 
					7caf3f8429 | ||
| 
						 | 
					1a6f88f218 | ||
| 
						 | 
					06cb16580e | ||
| 
						 | 
					2b690fff78 | ||
| 
						 | 
					7058a8c006 | ||
| 
						 | 
					b71db1a9a5 | ||
| 
						 | 
					420c96d17b | ||
| 
						 | 
					6817978ddb | ||
| 
						 | 
					efedfe12ff | ||
| 
						 | 
					90ab7c7c48 | ||
| 
						 | 
					fa9e38b36f | ||
| 
						 | 
					33bda862da | ||
| 
						 | 
					ef2b5eea53 | ||
| 
						 | 
					45279951aa | ||
| 
						 | 
					47b4581907 | ||
| 
						 | 
					b5d6597c0a | ||
| 
						 | 
					4a87df8e79 | ||
| 
						 | 
					7715e4de61 | ||
| 
						 | 
					982a08b80d | ||
| 
						 | 
					157718a7a3 | ||
| 
						 | 
					72b95c4a66 | ||
| 
						 | 
					4fe894cbe7 | ||
| 
						 | 
					0c9f22ac66 | ||
| 
						 | 
					bde8d2dd6b | ||
| 
						 | 
					6e27c52336 | ||
| 
						 | 
					efeba4a7f1 | ||
| 
						 | 
					a9d44b95bd | ||
| 
						 | 
					34bdaaa33f | ||
| 
						 | 
					508fa48aa6 | ||
| 
						 | 
					66b461a5ab | ||
| 
						 | 
					e3d70f2c43 | ||
| 
						 | 
					5502fb271d | ||
| 
						 | 
					e6f96a7a86 | ||
| 
						 | 
					005391ca5b | ||
| 
						 | 
					3a3d6d7b9a | ||
| 
						 | 
					4ded22b00b | ||
| 
						 | 
					b615d12897 | ||
| 
						 | 
					21244add31 | ||
| 
						 | 
					e7b09536bf | ||
| 
						 | 
					a0b06ecbd4 | ||
| 
						 | 
					3f873b0c39 | ||
| 
						 | 
					05bf66dff0 | ||
| 
						 | 
					069ca5df40 | ||
| 
						 | 
					eb817807bc | ||
| 
						 | 
					fc6f64742c | ||
| 
						 | 
					d040fa2a7d | ||
| 
						 | 
					4d46eac733 | ||
| 
						 | 
					85691130b1 | ||
| 
						 | 
					c4d78a3469 | ||
| 
						 | 
					dd4535b7f1 | ||
| 
						 | 
					1734e53410 | ||
| 
						 | 
					843fe45dee | ||
| 
						 | 
					51dabeafaa | ||
| 
						 | 
					05fc4a4cb7 | ||
| 
						 | 
					f3c0c7c0b3 | ||
| 
						 | 
					c2aefbb3e1 | ||
| 
						 | 
					296ddebed1 | ||
| 
						 | 
					922b7dbd46 | ||
| 
						 | 
					ffcf5ab999 | ||
| 
						 | 
					592565aef5 | ||
| 
						 | 
					53f76a1dad | ||
| 
						 | 
					ce4b719459 | ||
| 
						 | 
					19ac723e48 | ||
| 
						 | 
					a1ded68a49 | ||
| 
						 | 
					8a927a1b6a | ||
| 
						 | 
					eab10c91b7 | ||
| 
						 | 
					6c19b0e438 | ||
| 
						 | 
					6f15c062a3 | ||
| 
						 | 
					afe3b1918d | ||
| 
						 | 
					eaeda12c54 | ||
| 
						 | 
					60df88777e | ||
| 
						 | 
					3dc1621200 | ||
| 
						 | 
					14cbca87c8 | ||
| 
						 | 
					ce1087165d | ||
| 
						 | 
					aafd21c7d9 | ||
| 
						 | 
					9611833e33 | ||
| 
						 | 
					62d576880b | ||
| 
						 | 
					378e511e04 | ||
| 
						 | 
					1f9ba7b326 | ||
| 
						 | 
					3010f03414 | ||
| 
						 | 
					938abb0236 | ||
| 
						 | 
					1256f34736 | ||
| 
						 | 
					d1ac40391e | ||
| 
						 | 
					33a3550df4 | ||
| 
						 | 
					1c668252c9 | ||
| 
						 | 
					55ee4c9553 | ||
| 
						 | 
					ad1cbe34b4 | ||
| 
						 | 
					aa58390673 | ||
| 
						 | 
					5aa9c8f44c | ||
| 
						 | 
					e62ad97937 | ||
| 
						 | 
					6d81286b08 | ||
| 
						 | 
					40ebd4704a | ||
| 
						 | 
					241d033f37 | ||
| 
						 | 
					5e6c713d9c | ||
| 
						 | 
					c76e6769db | ||
| 
						 | 
					497b61f4ab | ||
| 
						 | 
					28c7f37204 | ||
| 
						 | 
					c0910498e8 | ||
| 
						 | 
					bfa5fd3add | ||
| 
						 | 
					f43e284b22 | ||
| 
						 | 
					c67bb2ac9f | ||
| 
						 | 
					d58431a097 | ||
| 
						 | 
					ff07226814 | ||
| 
						 | 
					65b31ffbb2 | ||
| 
						 | 
					adcd9289c2 | ||
| 
						 | 
					71ae473187 | ||
| 
						 | 
					7e1b3b9157 | ||
| 
						 | 
					f673fb960a | ||
| 
						 | 
					7d30c8cebc | ||
| 
						 | 
					d645ce86e9 | ||
| 
						 | 
					7b6cfc17c4 | ||
| 
						 | 
					5063de59b1 | ||
| 
						 | 
					e0ed3aa141 | ||
| 
						 | 
					3b6c3d6d64 | ||
| 
						 | 
					e07fab17b1 | ||
| 
						 | 
					3da161131a | ||
| 
						 | 
					b1f4200608 | ||
| 
						 | 
					2d4f7847d8 | ||
| 
						 | 
					81a26d988a | ||
| 
						 | 
					1d524784ff | ||
| 
						 | 
					a6b61df983 | ||
| 
						 | 
					72670833cb | ||
| 
						 | 
					1902c6bf94 | ||
| 
						 | 
					7a90d92aef | ||
| 
						 | 
					a5fb74f3f2 | ||
| 
						 | 
					adbb2e09df | ||
| 
						 | 
					39b9f65d0d | ||
| 
						 | 
					cf9629b9c7 | ||
| 
						 | 
					8907c8dd3d | ||
| 
						 | 
					c1a278b0eb | ||
| 
						 | 
					21ab8f4640 | ||
| 
						 | 
					e1ef0bd4fd | ||
| 
						 | 
					151babd168 | ||
| 
						 | 
					9fd8254ada | ||
| 
						 | 
					5329241831 | ||
| 
						 | 
					e876e210da | ||
| 
						 | 
					e6d1bcdf82 | ||
| 
						 | 
					c3d9c40a74 | ||
| 
						 | 
					4014a8ff0d | ||
| 
						 | 
					63c36773e4 | ||
| 
						 | 
					e2b827d8b1 | ||
| 
						 | 
					31a8dd2f2f | ||
| 
						 | 
					27a70171f1 | ||
| 
						 | 
					1fd7215def | ||
| 
						 | 
					acd91c0164 | ||
| 
						 | 
					9cb74e8135 | ||
| 
						 | 
					b788a3daa5 | ||
| 
						 | 
					04162c3944 | ||
| 
						 | 
					5cac54044b | ||
| 
						 | 
					ae958aa1a5 | ||
| 
						 | 
					b966b2108d | ||
| 
						 | 
					9ec32d15ab | ||
| 
						 | 
					adc1eedda3 | ||
| 
						 | 
					6d28127154 | ||
| 
						 | 
					646acbc0b2 | ||
| 
						 | 
					74b1205783 | ||
| 
						 | 
					f7567db01f | ||
| 
						 | 
					ef328ab392 | ||
| 
						 | 
					22365b2c55 | ||
| 
						 | 
					35507ce97e | ||
| 
						 | 
					d5b4c6dfd3 | ||
| 
						 | 
					234f9472c2 | ||
| 
						 | 
					a2119a660a | ||
| 
						 | 
					dadebb2196 | ||
| 
						 | 
					bec858c77f | ||
| 
						 | 
					cc1e8514f8 | ||
| 
						 | 
					b5d74751b1 | ||
| 
						 | 
					9cdf8772b3 | ||
| 
						 | 
					bd041df0cc | ||
| 
						 | 
					124e28b14e | ||
| 
						 | 
					a6f2f1afce | ||
| 
						 | 
					f7327524fc | ||
| 
						 | 
					e74ee37db5 | ||
| 
						 | 
					4bf5692888 | ||
| 
						 | 
					c2f60abe55 | ||
| 
						 | 
					be7683c79b | ||
| 
						 | 
					269a760f3d | ||
| 
						 | 
					6430410158 | ||
| 
						 | 
					ba258e65a0 | ||
| 
						 | 
					1934257636 | ||
| 
						 | 
					fba52c45e8 | ||
| 
						 | 
					2728c74b6c | ||
| 
						 | 
					46ec0f24f6 | ||
| 
						 | 
					9dc44d9bab | ||
| 
						 | 
					ea9b72ef79 | ||
| 
						 | 
					9212f8a709 | ||
| 
						 | 
					3862949a46 | ||
| 
						 | 
					c23535bc96 | ||
| 
						 | 
					e7c1b19161 | ||
| 
						 | 
					cc0a694c36 | ||
| 
						 | 
					af9b97b55f | ||
| 
						 | 
					f43b4e8cd8 | ||
| 
						 | 
					8430c55733 | ||
| 
						 | 
					ff043fa00f | ||
| 
						 | 
					040f5422f2 | ||
| 
						 | 
					c3aac8ddb4 | ||
| 
						 | 
					0b1635e371 | ||
| 
						 | 
					74f971284e | ||
| 
						 | 
					4f65cf8fb3 | ||
| 
						 | 
					b2d472fc50 | ||
| 
						 | 
					0fb57ecffc | ||
| 
						 | 
					237c761f67 | ||
| 
						 | 
					c5461c4596 | ||
| 
						 | 
					31a3bfed54 | ||
| 
						 | 
					4432a8164a | ||
| 
						 | 
					e9a9bdda13 | ||
| 
						 | 
					75f1c5ec33 | ||
| 
						 | 
					509a34f0fa | ||
| 
						 | 
					679565603a | ||
| 
						 | 
					cf029a81ac | ||
| 
						 | 
					2aeb0025cf | ||
| 
						 | 
					c11e5501aa | ||
| 
						 | 
					f0831174c3 | ||
| 
						 | 
					0c15d4977f | ||
| 
						 | 
					991da8ea2f | ||
| 
						 | 
					772de2596d | ||
| 
						 | 
					be54db83c9 | ||
| 
						 | 
					cfe1893d2c | ||
| 
						 | 
					1536ae30ee | ||
| 
						 | 
					81297e6c23 | ||
| 
						 | 
					f73e403ae5 | ||
| 
						 | 
					f2b35c3aab | ||
| 
						 | 
					f22f1cf4f4 | ||
| 
						 | 
					3c0c3c3c5f | ||
| 
						 | 
					9d2407dbc5 | ||
| 
						 | 
					28a58717be | ||
| 
						 | 
					f0ebf6c120 | ||
| 
						 | 
					7f79591522 | ||
| 
						 | 
					3be7b9ef59 | ||
| 
						 | 
					bd5de06c67 | ||
| 
						 | 
					49a57354f2 | ||
| 
						 | 
					5b4e9152ad | ||
| 
						 | 
					b8c153df54 | ||
| 
						 | 
					2310ac2c39 | ||
| 
						 | 
					89edc330f1 | ||
| 
						 | 
					1f975b6e05 | ||
| 
						 | 
					97d5e1b49b | ||
| 
						 | 
					75c0bd250e | ||
| 
						 | 
					7d4e9a019f | ||
| 
						 | 
					ddbf2626d7 | ||
| 
						 | 
					8e803116f1 | ||
| 
						 | 
					4b17e86c96 | ||
| 
						 | 
					265dc87da9 | ||
| 
						 | 
					bc87234fed | ||
| 
						 | 
					1c6dec3ffe | ||
| 
						 | 
					bee32fb05a | ||
| 
						 | 
					c98200aaa3 | ||
| 
						 | 
					ac5c8bea9c | ||
| 
						 | 
					b2cf9efc3a | ||
| 
						 | 
					a189b3a5c4 | ||
| 
						 | 
					60e76ed474 | ||
| 
						 | 
					5b27e491d4 | ||
| 
						 | 
					284a0afb1d | ||
| 
						 | 
					e8cd4d9b70 | ||
| 
						 | 
					ccf89512f6 | ||
| 
						 | 
					2ebc35e18b | ||
| 
						 | 
					69b05aca38 | ||
| 
						 | 
					c9a08ad178 | ||
| 
						 | 
					8e6ffa6a6f | 
							
								
								
									
										30
									
								
								AUTHORS
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								AUTHORS
									
									
									
									
									
								
							@@ -1,13 +1,33 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001,2002 by Alexander Barton,
 | 
			
		||||
                      (c)2001-2003 by Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
                  ngIRCd ist freie Software und steht unter
 | 
			
		||||
                       der GNU General Public License.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                           -- AUTHORS / Autoren --
 | 
			
		||||
                       -- AUTHORS and CONTRIBUTORS --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Alexander Barton, alex@arthur.ath.cx
 | 
			
		||||
Main Authors
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
Alexander Barton, <alex@barton.de> (alex)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Contributors
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
Goetz Hoffart, <goetz@hoffart.de> (goetz)
 | 
			
		||||
Ilja Osthoff, <i.osthoff@gmx.net> (ilja)
 | 
			
		||||
Sean Reifschneider, <jafo-rpms@tummy.com>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Code snippets
 | 
			
		||||
~~~~~~~~~~~~~
 | 
			
		||||
J. Kercheval: pattern matching functions
 | 
			
		||||
Patrick Powell, <papowell@astart.com>: snprintf()-function
 | 
			
		||||
Andrew Tridgell & Martin Pool: strl{cpy|cat}()-functions
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: AUTHORS,v 1.5.2.1 2003/11/07 20:51:08 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										327
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										327
									
								
								ChangeLog
									
									
									
									
									
								
							@@ -1,21 +1,325 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001,2002 by Alexander Barton,
 | 
			
		||||
                      (c)2001-2003 by Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
                  ngIRCd ist freie Software und steht unter
 | 
			
		||||
                       der GNU General Public License.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                        -- ChangeLog / Aenderungen --
 | 
			
		||||
                               -- ChangeLog --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.3.x, ??.??.2002
 | 
			
		||||
ngIRCd 0.7.5 (2003-11-07)
 | 
			
		||||
 | 
			
		||||
  - Fixed ban behavior: users which are banned from a channel can't no
 | 
			
		||||
    longer send PRIVMSG's to this channel (fixes Bug #47).
 | 
			
		||||
  - Fixed and enhanced the "penalty handling" of the server: commands that
 | 
			
		||||
    require more resources block the client for a short time.
 | 
			
		||||
  - Changed the internal time resolution to one second.
 | 
			
		||||
  - New configuration variable "MaxConnectionsIP" to limit the number of
 | 
			
		||||
    simultaneous connections from a single IP that the server will accept.
 | 
			
		||||
    This configuration options lowers the risk of denial of service attacks
 | 
			
		||||
    (DoS), the default is 5 connections per client IP.
 | 
			
		||||
  - Fixed build problems under Mac OS X 10.3.
 | 
			
		||||
  - Use "-pipe" when compiling with gcc, speeds things up a little :-)
 | 
			
		||||
  - Added new configuration variable "Listen" to bind all listening
 | 
			
		||||
    sockets of the server to a single IP address.
 | 
			
		||||
  - Suppress misleading error message of diff during make run.
 | 
			
		||||
  - Enhanced test-suite and made it work on GNU/Hurd.
 | 
			
		||||
  - Fixed minor typo in debug output :-)
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.7.1 (2003-07-18)
 | 
			
		||||
 | 
			
		||||
  - Included files to build Debian packages (located in "debian/").
 | 
			
		||||
  - Updated config.guess and config.sub to newer upstream versions.
 | 
			
		||||
  - NJOIN propagates user channel modes correctly again ... Upsa.
 | 
			
		||||
  - Made Makefile more compatible with "make -j<n>".
 | 
			
		||||
  - Added support for GNU/Hurd.
 | 
			
		||||
  - Fixed a compiler warning related to an unnecessary assert().
 | 
			
		||||
  - Enhanced VERSION command when using debug versions.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.7.0 (2003-05-01)
 | 
			
		||||
 | 
			
		||||
  - "ServerName" is checked better now: a dot (".") is required.
 | 
			
		||||
  - The KILL command verifies and logs more parameters.
 | 
			
		||||
 | 
			
		||||
  ngIRCd 0.7.0-pre2 (2003-04-27)
 | 
			
		||||
  - CVS build system fixes (made autogen.sh more portable).
 | 
			
		||||
  - Fixed compilation and test-suite on Solaris (tested with 2.6).
 | 
			
		||||
  - New documentation file "doc/Platforms.txt" describing the status of
 | 
			
		||||
    ngIRCd on the various tested platforms.
 | 
			
		||||
  - Test for broken GCC on Mac OS X and disable "-pedantic" in this case.
 | 
			
		||||
  - Disable "-ansi" on Cygwin: system headers are incompatible.
 | 
			
		||||
  - The server tried to connect to other servers only once when DNS or
 | 
			
		||||
    socket failures occurred.
 | 
			
		||||
  - Fixed --configtest: There is no variable "ServerPwd", it's "Password".
 | 
			
		||||
 | 
			
		||||
  ngIRCd 0.7.0-pre1 (2003-04-22)
 | 
			
		||||
  - New signal handler (more secure, actions are executed outside).
 | 
			
		||||
  - GCC: the compiler is now called with more warning options enabled.
 | 
			
		||||
  - Replaced a lot of str[n]cpy(), str[n]cat() and sprintf() calls with the
 | 
			
		||||
    more secure functions strlcpy(), strlcat() and snprintf(). On systems
 | 
			
		||||
    that don't support strlcpy() and strlcat(), these functions are included
 | 
			
		||||
    in the libngportab now (with prototypes in portab.h).
 | 
			
		||||
  - If the server can't close a socket, it panics now. This is an error that
 | 
			
		||||
    can't occur during normal operation so there is something broken.
 | 
			
		||||
  - The order of log messages during disconnects is more "natural" now ;-)
 | 
			
		||||
  - Cleaned up handling of server configuration structures: modifying and
 | 
			
		||||
    removing servers during runtime works more reliable now.
 | 
			
		||||
  - Compression code from "conn.[ch]" is now found in new "conn-zip.[ch]"
 | 
			
		||||
  - Moved some connection functions from "conn.[ch]" to "conn-func.[ch]".
 | 
			
		||||
  - New command CONNECT to enable and add server links. The syntax is not
 | 
			
		||||
    RFC-compatible: use "CONNECT <name> <port>" to enable and connect an
 | 
			
		||||
    configured server and "CONNECT <name> <port> <host> <mypwd> <peerpwd>"
 | 
			
		||||
    to add a new server (ngIRCd tries to connect new servers only once!).
 | 
			
		||||
  - Added DISCONNECT command ("DISCONNECT <name>") to disable servers.
 | 
			
		||||
  - Restructured the documentation: Now the main language is English. The
 | 
			
		||||
    german documentation has been removed (until there is a maintainer).
 | 
			
		||||
  - Enhanced killing of users caused by a nickname collision.
 | 
			
		||||
  - Better error detection for status code ("numerics") forwarding.
 | 
			
		||||
  - Moved tool functions to own library: "libngtool".
 | 
			
		||||
  - New command TRACE (you can trace only servers at the moment).
 | 
			
		||||
  - New command HELP that lists all understood commands.
 | 
			
		||||
  - There should no longer remain "unknown connections" (see e.g. LUSERS)
 | 
			
		||||
    if an outgoing server link can't be established.
 | 
			
		||||
  - Added AC_PREREQ(2.50) to configure.in for better autoconf compatibility.
 | 
			
		||||
  - Conn_Close() now handles recursive calls for the same link correctly.
 | 
			
		||||
  - ngIRCd can register itself with Rendezvous: to enable support pass the
 | 
			
		||||
    new switch "--with-rendezvous" to configure.
 | 
			
		||||
  - Added support for TCP Wrappers library: pass "--with-tcp-wrappers" to
 | 
			
		||||
    configure to enable it.
 | 
			
		||||
  - Changed some configure options to use "--with"/"--without" as prefix
 | 
			
		||||
    instead of "--enable"/"--disable": "--without-syslog", "--without-zlib",
 | 
			
		||||
    "--with-tcp-wrappers", and "--with-rendezvous".
 | 
			
		||||
  - Better error reporting to clients on connect.
 | 
			
		||||
  - Enhanced manual pages ngircd(8) and ngircd.conf(5).
 | 
			
		||||
  - Documentation is now installed in $(datadir)/doc/ngircd.
 | 
			
		||||
  - Enhanced hanling of NJOIN in case of nick collisions.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.6.1, 2003-01-21
 | 
			
		||||
 | 
			
		||||
  - Fixed KILL: you can't crash the server by killing yourself any more,
 | 
			
		||||
    ngIRCd no longer sends a QUIT to other servers after the KILL, and you
 | 
			
		||||
    can kill only valid users now.
 | 
			
		||||
  - The server no longer forwards commands to ordinary users, instead it
 | 
			
		||||
    answers with the correct error message ("no such server") now.
 | 
			
		||||
  - WHOIS commands weren't always forwarded as requested.
 | 
			
		||||
  - The server sets a correct default AWAY message now when propagating
 | 
			
		||||
    between servers (bug introduced in 0.6.0).
 | 
			
		||||
  - Fixed up and enhanced CHANINFO command: channel keys and user limits
 | 
			
		||||
    are synchronized between servers now, too.
 | 
			
		||||
  - MODE returns the key and user limit for channel members correctly now.
 | 
			
		||||
  - Non-members of a channel could crash the server when trying to change
 | 
			
		||||
    its modes or modes of its members.
 | 
			
		||||
  - The server didn't validate weather a target user is a valid channel
 | 
			
		||||
    member when changing his channel user modes which could crash ngIRCd.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Older changes (sorry, only available in german language):
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.6.0, 2002-12-24
 | 
			
		||||
 | 
			
		||||
  ngIRCd 0.6.0-pre2, 2002-12-23
 | 
			
		||||
  - neuer Numeric 005 ("Features") beim Connect.
 | 
			
		||||
  - LUSERS erweitert: nun wird die maximale Anzahl der lokalen und globalen
 | 
			
		||||
    Clients, die dem Server bzw. im Netzwerk seit dem letzten (Re-)Start
 | 
			
		||||
    dem Server gleichzeitig bekannt waren, angezeigt.
 | 
			
		||||
 | 
			
		||||
  ngIRCd 0.6.0-pre1, 2002-12-18
 | 
			
		||||
  - beim Schliessen einer Verbindung zeigt der Server nun vor dem ERROR
 | 
			
		||||
    noch eine Statistik ueber die empfangene und gesendete Datenmenge an.
 | 
			
		||||
  - der Server wartet bei einer eingehenden Verbindung nun laenger auf den
 | 
			
		||||
    Resolver (4 Sekunden), wenn das Ergebnis eintrifft setzt er aber den
 | 
			
		||||
    Login sofort fort (bisher wurde immer mind. 1 Sekunde gewartet).
 | 
			
		||||
  - Connection-Strukturen werden nun "pool-weise" verwaltet; der Pool wird
 | 
			
		||||
    bei Bedarf bis zu einem konfigurierten Limit vergroessert.
 | 
			
		||||
  - Mit der neuen Konfigurationsvariable "MaxConnections" (Sektion "Global")
 | 
			
		||||
    kann die maximale Anzahl gleichzeitiger Verbindungen begrenzt werden.
 | 
			
		||||
    Der Default ist -1, "unlimitiert".
 | 
			
		||||
  - der Server erkennt nun, ob bereits eine eingehende Verbindung von einem
 | 
			
		||||
    Peer-Server besteht und versucht dann nicht mehr, selber eine eigene
 | 
			
		||||
    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).
 | 
			
		||||
  - 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
 | 
			
		||||
    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.
 | 
			
		||||
  - Der Server kann nun zur Laufzeit die Konfiguration neu einlesen: dies
 | 
			
		||||
    macht er nach dem Befehl REHASH oder wenn ein HUP-Signal empfangen wird.
 | 
			
		||||
  - Channel-Mode "P" ("persistent") kann nur noch von IRC-Operatoren gesetzt
 | 
			
		||||
    werden. Grund: User koennen den Server sonst leicht "Channel-Flooden".
 | 
			
		||||
  - MOTD kann nun an andere Server geforwarded werden.
 | 
			
		||||
  - IRC-Befehl "TIME" implementiert.
 | 
			
		||||
  - Server-Server-Links koennen nun komprimiert werden, dazu wird die zlib
 | 
			
		||||
    (www.zlib.org) benoetigt. Unterstuetzt die Gegenseite die Komprimierung
 | 
			
		||||
    nicht, wird automatisch unkomprimiert kommuniziert. Das Verfahren ist
 | 
			
		||||
    kompatibel mit dem Original-ircd 2.10.3, d.h. beide Server koennen
 | 
			
		||||
    miteinander ueber komprimiert Links kommunizieren.
 | 
			
		||||
  - Handling der Schreibpuffer umgestellt: Server sollte schneller arbeiten.
 | 
			
		||||
  - Prefix-Fehler werden besser protokolliert (mit verursachendem Befehl).
 | 
			
		||||
  - SQUIT wird nicht mehr doppelt an andere Server weitergeleitet.
 | 
			
		||||
  - Der Server versucht nun vor dem Schliessen einer Verbindung Daten, die
 | 
			
		||||
    noch im Schreibpuffer stehen, zu senden.
 | 
			
		||||
  - Source in weiteres Modul "irc-info" aufgespalten.
 | 
			
		||||
  - Konfigurationsvariablen werden besser validiert: Laengen, Zahlen, ...
 | 
			
		||||
  - neuen Befehl STATS begonnen: bisher unterstuetzt wird "l" und "m".
 | 
			
		||||
  - bei ISON und USERHOST fehlte im Ergebnis-String der korrekte Absender.
 | 
			
		||||
  - IRC Operatoren koennen nun mit KILL User toeten. Achtung: ein Grund muss
 | 
			
		||||
    zwingend als zweiter Parameter angegeben werden!
 | 
			
		||||
  - neue Konfigurations-Variable "MaxJoins": Hiermit kann die maximale Zahl
 | 
			
		||||
    der Channels, in denen ein User Mitglied sein kann, begrent werden.
 | 
			
		||||
  - neuer, deutlich flexiblerer Parser fuer den MODE Befehl.
 | 
			
		||||
  - neue Channel-Modes l (User-Limit) und k (Channel-Key) implementiert.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.5.4, 24.11.2002
 | 
			
		||||
 | 
			
		||||
  - Fehler-Handling von connect() gefixed: der Server kann sich nun auch   
 | 
			
		||||
    unter A/UX wieder zu anderen verbinden.
 | 
			
		||||
  - in den Konfigurationsvariablen ServerUID und ServerGID kann nun nicht
 | 
			
		||||
    nur die numerische ID, sondern auch der Name des Users bzw. der Gruppe
 | 
			
		||||
    verwendet werden. Beim Start des Daemons wird nun beides angezeigt.
 | 
			
		||||
  - Besseres Logging von Prefix-Fehlern.
 | 
			
		||||
  - angenommene Sockets werden nun korrekt auf "non-blocking" konfiguriert,
 | 
			
		||||
    beim Senden und Empfangen werden Blockierungen besser abgefangen.
 | 
			
		||||
  - RPL_UMODEIS hat Code 221, nicht 211 ... *argl*
 | 
			
		||||
  - select() in Try_Write() hat falschen (keinen!) Timeout verwendet;
 | 
			
		||||
    die "Zeit-Aufloesung" des Servers sind zudem nun 2 Sekunden (TIME_RES).
 | 
			
		||||
    Insgesamt sollte die Reaktionszeit des Server nun besser sein.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.5.3, 08.11.2002
 | 
			
		||||
 | 
			
		||||
  - NOTICE liefert nun wirklich nie mehr einen Fehler, auch dann nicht,
 | 
			
		||||
    wenn der sendende Client noch gar nicht registriert ist.
 | 
			
		||||
  - ein "schneller Server-Reconnect" wird nur noch dann versucht, wenn die
 | 
			
		||||
    Verbindung zuvor ordentlich (="lange genug") in Ordnung war; somit also
 | 
			
		||||
    nicht meht, wenn der Peer-Server gleich beim Connect ein ERROR liefert.
 | 
			
		||||
    Das vermeidet "Connect-Orgien".
 | 
			
		||||
  - einige Datentypen aufgeraumt: z.B. sind viele INT32s nun LONGs. Das ist
 | 
			
		||||
    auf Platformen mit 8-Byte-Integern kompatibler.
 | 
			
		||||
  - RPL_YOURHOST_MSG ist nun ircII- und RFC-kompatibel ;-)
 | 
			
		||||
  - Segfault unter hoher Netzaktivitaet behoben: in Conn_Close() wird die
 | 
			
		||||
    Connection-Struktur nun frueher als "ungueltig" markiert.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.5.2, 04.10.2002
 | 
			
		||||
 | 
			
		||||
  - Buffer Overflow in Read_Resolver_Result() behoben.
 | 
			
		||||
  - Format-String-Bugs, die zum Abbruch des Servers fuehrten, behoben.
 | 
			
		||||
  - Maximale Laenge eines IRC-Prefix wurde falsch berechnet.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.5.1, 03.10.2002
 | 
			
		||||
 | 
			
		||||
  - in RPL_YOURHOST_MSG wurde ein fehlerhafter Versionsstring geliefert.
 | 
			
		||||
  - Test-Suite: start-server.sh, stop-server.sh und stress-server.sh koennen
 | 
			
		||||
    nun "manuell" von der Kommandozeile gestartet werden, stress-server.sh
 | 
			
		||||
    startet per Default nur noch 5 Sessions, eine andere Zahl kann auf der
 | 
			
		||||
    Kommandozeile uebergeben werden (Syntax: "stress-server.sh <count>").
 | 
			
		||||
  - In bestimmten Faellen hat der Server versucht auf einen bereits wieder
 | 
			
		||||
    geschlossenen Socket Daten zu schreiben; das fuehrte zu einem Abbruch des
 | 
			
		||||
    Servers durch ein assert(). Nun wird geprueft, ob der Socket noch ok ist.
 | 
			
		||||
  - im "contrib"-Verzeichnis befindet sich nun eine RPM-Spec-Datei, aus den
 | 
			
		||||
    .tar.gz's koennen nun mit "rpm -ta <archiv>" RPM's erzeugt werden. Danke
 | 
			
		||||
    an Sean Reifschneider <jafo@tummy.com>!
 | 
			
		||||
  - Syntax von RPL_MYINFO_MSG korrigiert: liefert nun vier Parameter.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.5.0, 20.09.2002
 | 
			
		||||
 | 
			
		||||
  - Dokumentation aktualisiert.
 | 
			
		||||
  - Fehler bei Validierung von "AdminInfo2" behoben.
 | 
			
		||||
  - Test der Flags fuer "ps" in der Testsuite verbessert, ist nun zu mehr
 | 
			
		||||
    Plattformen kompatibler.
 | 
			
		||||
 | 
			
		||||
  ngIRCd 0.5.0-pre2, 17.09.2002
 | 
			
		||||
  - Fix in IRC_WriteStrServersPrefix() war "badly broken" -- behoben.
 | 
			
		||||
 | 
			
		||||
  ngIRCd 0.5.0-pre1, 16.09.2002
 | 
			
		||||
  - Manual-Pages ngircd.8 und ngircd.conf.5 begonnen.
 | 
			
		||||
  - Wird der Netzwerk-Sniffer aktiviert (--sniffer), so schaltet der
 | 
			
		||||
    ngIRCd nun automatisch in den Debug-Modus.
 | 
			
		||||
  - auf Systemen, die inet_aton() nicht kennen (wie z.B. A/UX), kann der
 | 
			
		||||
    ngIRCd nun dennoch auch aktiv Server-Links aufbauen.
 | 
			
		||||
  - h_errno wird auf Systemen, die das nicht kennen (wie z.B. HP-UX 10.20)
 | 
			
		||||
    nicht mehr verwendet. Somit compiliert der ngIRCd nun auch dort :-)
 | 
			
		||||
  - um auf dem Ziel-System nicht vorhandene Funktionen nachzubilden wird nun
 | 
			
		||||
    die "libngportab" erzeugt; genutzt wird dies bisher fuer vsnprintf().
 | 
			
		||||
    Nun compiliert der ngIRCd auch unter Solaris 2.5.1.
 | 
			
		||||
  - "persistente Channels" (Mode 'P') implementiert: diese koennen in der
 | 
			
		||||
    Konfigurationsdatei definiert werden (Sektion "Channel", vgl. Beispiel-
 | 
			
		||||
    Konfiguration "sample-ngircd.conf") und bleiben auch dann bestehen,
 | 
			
		||||
    wenn kein User mehr im Channel ist. Zu Channel-Operatoren werden bisher
 | 
			
		||||
    nur IRC-Operatoren, die den Channel betreten. Die persistenten Channels
 | 
			
		||||
    werden durch das Flag "P" gelennzeichnet, welches normal durch Channel-
 | 
			
		||||
    Op's gesetzt und geloescht werden kann.
 | 
			
		||||
  - bei "--configtest" werden keine leere Abschnitte mehr ausgegeben.
 | 
			
		||||
  - Source in weitere Module aufgespalten: lists, irc-op und resolve.
 | 
			
		||||
  - #include's aufgeraeumt: Header includieren keine anderen mehr.
 | 
			
		||||
  - KICK implementiert (bisher kann nur ein User aus einem Channel geckicked
 | 
			
		||||
    werden, Listen, wir im RFC vorgesehen, werden bisher nicht unterstuetzt).
 | 
			
		||||
  - INVITE, den Channel-Mode "i" sowie Invite-Lists ueber den MODE-Befehl
 | 
			
		||||
    (setzen, erfragen und loeschen) implementiert.
 | 
			
		||||
  - Source an ansi2knr fuer pre-ANSI-Compiler angepasst; ansi2knr in Source-
 | 
			
		||||
    Tree aufgenommen und in Build-System integriert; der ngIRCd compiliert
 | 
			
		||||
    nun z.B. unter A/UX mit dem nativen Compiler von Apple.
 | 
			
		||||
  - TOPIC lieferte bei unbekanntem Channel einen falschen Fehlercode.
 | 
			
		||||
  - LIST versteht nun Wildcards und kann an andere Server geforwarded werden.
 | 
			
		||||
  - wurde ein KILL fuer nicht-lokale Clients empfangen, so wurden die
 | 
			
		||||
    Verwaltungs-Strukturen nicht korrekt freigegeben.
 | 
			
		||||
  - empfangene NJOIN's wurden "zerhackt" an andere Server weitergegeben.
 | 
			
		||||
  - neue Konfigurationsoption "OperCanUseMode" (Sektion "Global"):
 | 
			
		||||
    ist sie aktiv, koennen IRC-Operatoren immer Channel-Modes setzen.
 | 
			
		||||
  - Dokumentation des neuen IRC+-Protokolls begonnen: doc/Protocol.txt
 | 
			
		||||
  - 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+-
 | 
			
		||||
    Protokoll unterstuetzen, Channel-Modes und Topics.
 | 
			
		||||
  - neue Option "--disable-ircplus" fuer das configure-Script, um das
 | 
			
		||||
    IRC+-Protokoll abzuschalten (per Default ist es aktiviert).
 | 
			
		||||
  - Ban-Lists (setzen, erfragen und loeschen) implementiert.
 | 
			
		||||
  - wird der Server mit "-n"/"--nodaemon" gestartet, so werden keine Mel-
 | 
			
		||||
    dungen mehr ueber Syslog ausgegeben, sondern nur noch auf der Konsole.
 | 
			
		||||
  - "Test-Suite" begonnen (in "make check" integriert): Dabei wird ein
 | 
			
		||||
    speziell konfigurierter Server auf Port 6789 gestartet, mit dem dann
 | 
			
		||||
    einige Tests durchgefuehrt werden (u.a. "Stress-Test" mit 50 Clients).
 | 
			
		||||
  - zu lange Operator-Namen in der Konfiguration wurden falsch gekuerzt.
 | 
			
		||||
  - kleine Anpassung an AIX 3.2.5: nun laeuft der ngIRCd auch dort :-)
 | 
			
		||||
  - ADMIN-Befehl implementiert. Die Daten hierzu werden in der Konfig-Datei
 | 
			
		||||
    im [Global]-Abschnitt mit den Variablen "AdminInfo1", "AdminInfo2" und
 | 
			
		||||
    "AdminEMail" konfiguriert.
 | 
			
		||||
  
 | 
			
		||||
ngIRCd 0.4.3, 11.06.2002
 | 
			
		||||
 | 
			
		||||
  - Bei PRIVMSG und NOTICE hat der ngIRCd nicht ueberpruft, ob das Ziel
 | 
			
		||||
    ueberhaupt ein User ist. War es keiner, so fuehrte dies zu einem
 | 
			
		||||
    Abbruch des Servers [es wurde assert() aufgerufen].
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.4.2, 29.04.2002
 | 
			
		||||
 | 
			
		||||
  - LUSERS verzaehlt sich bei eigenen Server-Links nicht mehr.
 | 
			
		||||
  - QUIT wird nun auch von noch nicht registrierten Clients akzeptiert.
 | 
			
		||||
  - IRC-Funktion LIST implementiert; bisher werden allerdings noch keine
 | 
			
		||||
    Wildcards (bis auf "*") unterstuetzt.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.4.1, 08.04.2002
 | 
			
		||||
 | 
			
		||||
  - Bei Server-Links wird nicht mehr an Hand der Anzahl der Parameter
 | 
			
		||||
    eines empfangenen SERVER-Befehls, sondern "intern" erkannt, ob es
 | 
			
		||||
    sich um eine ein- oder ausgehende Verbindung handelt und somit das
 | 
			
		||||
    eigene PASS-SERVER-Paar gesendet werden muss oder nicht. Da sich
 | 
			
		||||
    verschiedene Versionen des Original-ircd's anders verhalten, schlug
 | 
			
		||||
    die Anmeldung je nach Gehenseite evtl. fehl.
 | 
			
		||||
  - Bei einem NICK-Befehl eines lokalen Client konnte der Server ab-
 | 
			
		||||
    stuerzen, da ein Format-String einer Log-Meldung fehlerhaft war.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.4.0, 01.04.2002
 | 
			
		||||
 | 
			
		||||
  - IRC-Befehle nochmal auf weitere Source-Dateien aufgespalten.
 | 
			
		||||
  - WHO implementiert (bisher ohne komplette Unerstuetzung von Masks).
 | 
			
		||||
  - WHO implementiert (bisher ohne komplette Unterstuetzung von Masks).
 | 
			
		||||
  - Der AWAY-Mode wurde nicht ueber mehrere Server-Links weitergegeben.
 | 
			
		||||
  - stderr wird nun in eine Datei umgelenkt (/usr/local/var/ngircd.err).
 | 
			
		||||
  - stderr wird nun in eine Datei umgelenkt (/tmp/ngircd-<PID>.err).
 | 
			
		||||
    Laeuft der Server nicht im Debug-Modus, so wird diese bei Programm-
 | 
			
		||||
    ende geloescht. Sollte der Server abstuerzen, finden sich hier evtl.
 | 
			
		||||
    zusaetzliche Informationen.
 | 
			
		||||
@@ -23,7 +327,6 @@ ngIRCd 0.3.x, ??.??.2002
 | 
			
		||||
  - die Beispiel-Konfigurationsdatei (doc/sample-ngircd.conf) wird als
 | 
			
		||||
    ngircd.conf installiert, wenn noch keine "echte" Konfigurationsdatei
 | 
			
		||||
    vorhanden ist.
 | 
			
		||||
  - bei "ngircd --help" werden nun die eincompilierten Pfade angezeigt.
 | 
			
		||||
  - bei WHO, WHOIS und NAMES wird nun nur noch der Status "Operator" oder
 | 
			
		||||
    "voiced" geliefert -- nicht mehr beides.
 | 
			
		||||
  - Server-Gruppen implementiert: es wird immer nur zu einem Server in
 | 
			
		||||
@@ -31,19 +334,20 @@ ngIRCd 0.3.x, ??.??.2002
 | 
			
		||||
    nicht, so wird der naechste probiert (Variable "Group" in der Kon-
 | 
			
		||||
    figurationsdatei, Sektion [Server]).
 | 
			
		||||
  - IRC_PING() ist, wenn nicht im "strict RFC"-Mode, toleranter und ak-
 | 
			
		||||
    zeptiert beliebig viele Parameter: z.B. BitchX sendet soetwas.
 | 
			
		||||
    zeptiert beliebig viele Parameter (z.B. BitchX sendet soetwas).
 | 
			
		||||
  - die "Portab-Header" werden nicht mehr benoetigt, die System-Erkennung
 | 
			
		||||
    wird nun ausschliesslich vom configure-Script durchgefuehrt. System-
 | 
			
		||||
    abhaengige Definitionen finden sich nun unter src/portrab/.
 | 
			
		||||
  - Clients und Channels werden nicht mehr ueber ihren Namen, sondern
 | 
			
		||||
    einen Hash-Wert gesucht: sollte deutlich schneller sein.
 | 
			
		||||
  - neuer Kommandozeilen-Parameter "--configtest": die Konfiguration wird
 | 
			
		||||
    gelesen und die dann verwendeten Werte angezeigt.
 | 
			
		||||
    gelesen und dann die verwendeten Werte angezeigt.
 | 
			
		||||
  - Client-Mode "s" (Server Notices) implementiert.
 | 
			
		||||
  - mit dem neuen Kommandozeilen-Parameter "--config"/"-f" kann eine
 | 
			
		||||
    alternative Konfigurationsdatei angegeben werden.
 | 
			
		||||
  - nach dem Start kann der ngIRCd, wenn er mit root-Rechten laeuft,
 | 
			
		||||
    zu einer anderen User-ID und Group-ID wechseln.
 | 
			
		||||
  - URL der Homepage wird u.a. bei "--version" mit angezeigt.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.3.0, 02.03.2002
 | 
			
		||||
 | 
			
		||||
@@ -127,7 +431,6 @@ ngIRCd 0.1.0, 29.01.2002
 | 
			
		||||
  - Clients werden nun korrekt sowohl nur ueber den Nickname als auch die
 | 
			
		||||
    komplette "Host Mask" erkannt.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.0.3, 16.01.2002
 | 
			
		||||
 | 
			
		||||
  - Server-Links vollstaendig implementiert: der ngIRCd kann nun auch
 | 
			
		||||
@@ -174,4 +477,4 @@ ngIRCd 0.0.1, 31.12.2001
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: ChangeLog,v 1.54 2002/03/29 23:41:23 alex Exp $
 | 
			
		||||
$Id: ChangeLog,v 1.188.2.18 2003/11/07 20:51:08 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										179
									
								
								INSTALL
									
									
									
									
									
								
							
							
						
						
									
										179
									
								
								INSTALL
									
									
									
									
									
								
							@@ -1,90 +1,161 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001,2002 by Alexander Barton,
 | 
			
		||||
                      (c)2001-2003 by Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
                  ngIRCd ist freie Software und steht unter
 | 
			
		||||
                       der GNU General Public License.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                         -- INSTALL / Installation --
 | 
			
		||||
                                -- INSTALL --
 | 
			
		||||
 | 
			
		||||
                         
 | 
			
		||||
 | 
			
		||||
I. Upgrade Information
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Differences to version 0.6.x
 | 
			
		||||
 | 
			
		||||
- Some options of the configure script have been renamed:
 | 
			
		||||
    --disable-syslog  ->  --without-syslog
 | 
			
		||||
    --disable-zlib    ->  --without-zlib
 | 
			
		||||
  Please call "./configure --help" to review the full list of options!
 | 
			
		||||
 | 
			
		||||
Differences to version 0.5.x
 | 
			
		||||
 | 
			
		||||
- Starting with version 0.6.0, other servers are identified using asynchronous
 | 
			
		||||
  passwords: therefore the variable "Password" in [Server]-sections has been
 | 
			
		||||
  replaced by "MyPassword" and "PeerPassword".
 | 
			
		||||
 | 
			
		||||
- New configuration variables, section [Global]: MaxConnections, MaxJoins
 | 
			
		||||
  (see example configuration file "doc/sample-ngircd.conf"!).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ngIRCd ist fuer UNIXoide-Systeme konzipiert. Dieser Text beschreibt den
 | 
			
		||||
"Standardfall": ein UNIX bzw. UNIX-aehnliches System, das von GNU automake
 | 
			
		||||
und GNU autoconf ("configure") unterstuetzt wird.
 | 
			
		||||
II. Standard Installation
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
ngIRCd is developed for UNIX-based systems, which means that the installation
 | 
			
		||||
on modern UNIX-like systems that are supported by GNU autoconf and GNU
 | 
			
		||||
automake ("configure") should be no problem.
 | 
			
		||||
 | 
			
		||||
The normal installation procedure after getting (and expanding) the source
 | 
			
		||||
files (using a distribution archive or CVS) is as following:
 | 
			
		||||
 | 
			
		||||
  1) ./autogen.sh	[only necessary when using CVS]
 | 
			
		||||
  2) ./configure
 | 
			
		||||
  3) make
 | 
			
		||||
  4) make install
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
I. Voraussetzungen
 | 
			
		||||
~~~~~~~~~~~~~~~~~~
 | 
			
		||||
1): "autogen.sh"
 | 
			
		||||
 | 
			
		||||
ngIRCd benoetigt "Alex' Portability Headers" (portab.h). Diese koennen von
 | 
			
		||||
der Homepage heruntergeladen werden:
 | 
			
		||||
The first step, autogen.sh, is only necessary if the configure-script isn't
 | 
			
		||||
already generated. This never happens in official ("stable") releases in
 | 
			
		||||
tar.gz-archives, but when using CVS.
 | 
			
		||||
 | 
			
		||||
<http://arthur.ath.cx/~alex/ngircd/#download>
 | 
			
		||||
This step is therefore only interesting for developers.
 | 
			
		||||
 | 
			
		||||
Vor dem configure-Lauf des ngIRCd muessen dies Header auf dem System in-
 | 
			
		||||
stalliert sein, anonsten bricht configure ab.
 | 
			
		||||
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).
 | 
			
		||||
 | 
			
		||||
Again: "end users" do not need this step!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
II. Quick Start
 | 
			
		||||
~~~~~~~~~~~~~~~
 | 
			
		||||
2): "./configure"
 | 
			
		||||
 | 
			
		||||
In der Regel sind folgende Schritte ausreichend:
 | 
			
		||||
The configure-script is used to detect local system dependencies.
 | 
			
		||||
 | 
			
		||||
   1) ./autogen.sh	[nur erforderlich, wenn ueber CVS bezogen]
 | 
			
		||||
   2) ./configure
 | 
			
		||||
   3) make
 | 
			
		||||
In the perfect case, configure should recognise all needed libraries, header
 | 
			
		||||
files and so on. If this shouldn't work, "./configure --help" shows all
 | 
			
		||||
possible options.
 | 
			
		||||
 | 
			
		||||
In addition, you can pass some command line options to "configure" to enable
 | 
			
		||||
and/or disable some features of ngIRCd. All these options are shown using
 | 
			
		||||
"./configure --help", too.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
zu 1) autogen.sh:
 | 
			
		||||
3): "make"
 | 
			
		||||
 | 
			
		||||
Der erste Schritt, autogen.sh, ist nur notwendig, wenn das configure-Script
 | 
			
		||||
noch nicht vorhanden ist. Dies ist nie bei offiziellen ("stabilen") Versionen
 | 
			
		||||
in tar.gz-Archiven der Fall, jedoch nie, wenn der Source-Code ueber CVS
 | 
			
		||||
bezogen wurde.
 | 
			
		||||
 | 
			
		||||
Dieser Absatz ist also eigentlich ausschliesslich fuer Entwickler interessant.
 | 
			
		||||
 | 
			
		||||
autogen.sh erzeugt die fuer das configure-Script notwendigen Makefile.in's
 | 
			
		||||
sowie das configure-Script selber und weitere fuer den make-Lauf erforderliche
 | 
			
		||||
Dateien. Dazu wird sowohl GNU automake als auch GNU autoconf (in aktuellen
 | 
			
		||||
Versionen!) benoetigt.
 | 
			
		||||
 | 
			
		||||
(nochmal: "Endanwender" mussen diesen Schritt i.d.R. nicht ausfuehren!)
 | 
			
		||||
The make command uses the Makefiles produced by configure and compiles the
 | 
			
		||||
ngIRCd daemon.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
zu 2) ./configure:
 | 
			
		||||
4): "make install"
 | 
			
		||||
 | 
			
		||||
Mit dem configure-Script wird ngIRCd, wie GNU Software meistens, an das
 | 
			
		||||
lokale System angepasst und die erforderlichen Makefile's erzeugt.
 | 
			
		||||
Use "make install" to install the server and a sample configuration file on
 | 
			
		||||
the local system. Normally, root privileges are necessary to complete this
 | 
			
		||||
step. If there is already an older configuration file present, it won't be
 | 
			
		||||
overwritten.
 | 
			
		||||
 | 
			
		||||
Im Optimalfall sollte configure alle benoetigten Libraries, Header etc. selber
 | 
			
		||||
erkennen und entsprechend reagieren. Sollte dies einmal nicht der Fall sein,
 | 
			
		||||
so zeigt "./configure --help" moegliche Optionen.
 | 
			
		||||
This files will be installed by default:
 | 
			
		||||
 | 
			
		||||
- /usr/local/sbin/ngircd: executable server
 | 
			
		||||
- /usr/local/etc/ngircd.conf: sample configuration (if not already present)
 | 
			
		||||
- /usr/local/share/doc/ngircd/: documentation
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
zu 3) make:
 | 
			
		||||
II. Useful make-targets
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Der make-Befehl bearbeitet die vom configure-Script erzeugten Makefile's und
 | 
			
		||||
uebersetzt die comBase-Library und die Testprogramme.
 | 
			
		||||
The Makefile produced by the configure-script contains always these useful
 | 
			
		||||
targets:
 | 
			
		||||
 | 
			
		||||
 - clean: delete every product from the compiler/linker
 | 
			
		||||
   next step: -> make
 | 
			
		||||
 | 
			
		||||
 - distclean: the above plus erase all generated Makefiles
 | 
			
		||||
   next step: -> ./configure
 | 
			
		||||
 | 
			
		||||
 - maintainer-clean: erase all automatic generated files
 | 
			
		||||
   next step: -> ./autogen.sh
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
III. Nuetzliche make-Targets
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
III. Sample configuration file ngircd.conf
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Die vom configure-Script erzeugten Makefile's enthalten immer die folgenden
 | 
			
		||||
nuetzlichen Targets:
 | 
			
		||||
In the sample configuration file, there are comments beginning with "#" OR
 | 
			
		||||
";" -- this is only for the better understanding of the file.
 | 
			
		||||
 | 
			
		||||
 - clean: alle Erzeugnisse des Compilers/Linkers loeschen.
 | 
			
		||||
   Naechster Schritt: -> make
 | 
			
		||||
The file is separated in four blocks: [Global], [Operator], [Server], and
 | 
			
		||||
[Channel].
 | 
			
		||||
 | 
			
		||||
 - distclean: zusaetzliche alle Makefile's loeschen.
 | 
			
		||||
   Naechster Schritt: -> ./configure
 | 
			
		||||
In the [Global] section, there is the main configuration like the server
 | 
			
		||||
name and the ports, on which the server should be listening. IRC operators
 | 
			
		||||
of this server are defined in [Operator] blocks. [Server] is the section
 | 
			
		||||
where server links are configured. And [Channel] blocks are used to
 | 
			
		||||
configure pre-defined ("persistent") IRC channels.
 | 
			
		||||
 | 
			
		||||
 - maintainer-clean: alle automat. erzeugten Dateien loeschen.
 | 
			
		||||
   Naechster Schritt: -> ./autogen.sh
 | 
			
		||||
The meaning of the variables in the configuration file is explained in the 
 | 
			
		||||
"doc/sample-ngircd.conf", which is used as sample configuration file in
 | 
			
		||||
/usr/local/etc after running "make install" (if you don't already have one)
 | 
			
		||||
and in the "ngircd.conf" manual page.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
IV. Command line options
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
These parameters could be passed to the ngIRCd:
 | 
			
		||||
 | 
			
		||||
-f, --config <file>
 | 
			
		||||
	The daemon uses the file <file> as configuration file rather than
 | 
			
		||||
	the standard configuration /usr/local/etc/ngircd.conf.
 | 
			
		||||
 | 
			
		||||
-n, --nodaemon
 | 
			
		||||
	ngIRCd should be running as a foreground process.
 | 
			
		||||
 | 
			
		||||
-p, --passive
 | 
			
		||||
	Server-links won't be automatically established.
 | 
			
		||||
 | 
			
		||||
--configtest
 | 
			
		||||
	Reads, validates and dumps the configuration file as interpreted
 | 
			
		||||
	by the server. Then exits.
 | 
			
		||||
 | 
			
		||||
Use "--help" to see a short help text describing all available parameters
 | 
			
		||||
the server understands, with "--version" the ngIRCd shows its version
 | 
			
		||||
number. In both cases the server exits after the output.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: INSTALL,v 1.5 2002/03/03 13:07:01 alex Exp $
 | 
			
		||||
$Id: INSTALL,v 1.15.2.1 2003/04/22 20:00:32 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										23
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								Makefile.am
									
									
									
									
									
								
							@@ -1,20 +1,19 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
# Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
 | 
			
		||||
#
 | 
			
		||||
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
# der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
# 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.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile.am,v 1.8 2002/03/25 19:39:48 alex Exp $
 | 
			
		||||
# $Id: Makefile.am,v 1.10.4.2 2003/07/09 21:14:08 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
AUTOMAKE_OPTIONS = gnu
 | 
			
		||||
 | 
			
		||||
SUBDIRS = doc MacOSX src
 | 
			
		||||
SUBDIRS = doc MacOSX src man contrib debian
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -rf autom4te.cache
 | 
			
		||||
@@ -25,4 +24,10 @@ maintainer-clean-local:
 | 
			
		||||
lint:
 | 
			
		||||
	make -C src/ngircd lint
 | 
			
		||||
 | 
			
		||||
rpm: distcheck
 | 
			
		||||
	rpm -ta ngircd-*.tar.gz
 | 
			
		||||
 | 
			
		||||
deb:
 | 
			
		||||
	dpkg-buildpackage -rfakeroot
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										105
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								NEWS
									
									
									
									
									
								
							@@ -1,19 +1,108 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001,2002 by Alexander Barton,
 | 
			
		||||
                      (c)2001-2003 by Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
                  ngIRCd ist freie Software und steht unter
 | 
			
		||||
                       der GNU General Public License.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                           -- NEWS / Neuigkeiten --
 | 
			
		||||
                                  -- NEWS --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.3.x, ??.??.2002
 | 
			
		||||
ngIRCd 0.7.5 (2003-07-11)
 | 
			
		||||
 | 
			
		||||
  - WHO implementiert (bisher ohne komplette Unerstuetzung von Masks).
 | 
			
		||||
  - stderr wird nun in eine Datei umgelenkt (/usr/local/var/ngircd.err).
 | 
			
		||||
  - New configuration variable "MaxConnectionsIP" to limit the number of
 | 
			
		||||
    simultaneous connections from a single IP that the server will accept.
 | 
			
		||||
    This configuration options lowers the risk of denial of service attacks
 | 
			
		||||
    (DoS), the default is 5 connections per client IP.
 | 
			
		||||
  - Added new configuration variable "Listen" to bind all listening
 | 
			
		||||
    sockets of the server to a single IP address.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.7.1 (2003-07-18)
 | 
			
		||||
 | 
			
		||||
  - Added support for GNU/Hurd.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.7.0 (2003-05-01)
 | 
			
		||||
 | 
			
		||||
  - New command CONNECT to enable and add server links. The syntax is not
 | 
			
		||||
    RFC-compatible: use "CONNECT <name> <port>" to enable and connect an
 | 
			
		||||
    configured server and "CONNECT <name> <port> <host> <mypwd> <peerpwd>"
 | 
			
		||||
    to add a new server (ngIRCd tries to connect new servers only once!).
 | 
			
		||||
  - Added DISCONNECT command ("DISCONNECT <name>") to disable servers.
 | 
			
		||||
  - New command TRACE (you can trace only servers at the moment).
 | 
			
		||||
  - New command HELP that lists all understood commands.
 | 
			
		||||
  - ngIRCd can register itself with Rendezvous: to enable support pass the
 | 
			
		||||
    new switch "--with-rendezvous" to configure.
 | 
			
		||||
  - Added support for TCP Wrappers library: pass "--with-tcp-wrappers" to
 | 
			
		||||
    configure to enable it.
 | 
			
		||||
  - Changed some configure options to use "--with"/"--without" as prefix
 | 
			
		||||
    insetead of "--enable"/"--disable": "--without-syslog", "--without-zlib",
 | 
			
		||||
    "--with-tcp-wrappers", and "--with-rendezvous".
 | 
			
		||||
  - Enhanced manual pages ngircd(8) and ngircd.conf(5).
 | 
			
		||||
  - Documentation is now installed in $(datadir)/doc/ngircd.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Older news (sorry, only available in german language):
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.6.0, 2002-12-24
 | 
			
		||||
 | 
			
		||||
  - beim Schliessen einer Verbindung zeigt der Server nun vor dem ERROR
 | 
			
		||||
    noch eine Statistik ueber die empfangene und gesendete Datenmenge an.
 | 
			
		||||
  - Connection-Strukturen werden nun "pool-weise" verwaltet; der Pool wird
 | 
			
		||||
    bei Bedarf bis zu einem konfigurierten Limit vergroessert.
 | 
			
		||||
  - Mit der neuen Konfigurationsvariable "MaxConnections" (Sekion "Global")
 | 
			
		||||
    kann die maximale Anzahl gleichzeitiger Verbindungen begrenzt werden.
 | 
			
		||||
    Der Default ist -1, "unlimitiert".
 | 
			
		||||
  - der Server erkennt nun, ob bereits eine eingehende Verbindung von einem
 | 
			
		||||
    Peer-Server besteht und versucht dann nicht mehr, selber eine eigene
 | 
			
		||||
    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
 | 
			
		||||
    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.
 | 
			
		||||
  - Der Server kann nun zur Laufzeit die Konfiguration neu einlesen: dies
 | 
			
		||||
    macht er nach dem Befehl REHASH oder wenn ein HUP-Signal empfangen wird.
 | 
			
		||||
  - Server-Server-Links koennen nun komprimiert werden, dazu wird die zlib
 | 
			
		||||
    (www.zlib.org) benoetigt. Unterstuetzt die Gegenseite die Komprimierung
 | 
			
		||||
    nicht, wird automatisch unkomprimiert kommuniziert. Das Verfahren ist
 | 
			
		||||
    kompatibel mit dem Original-ircd 2.10.3, d.h. beide Server koennen
 | 
			
		||||
    miteinander ueber komprimiert Links kommunizieren.
 | 
			
		||||
  - neue Konfigurations-Variable "MaxJoins": Hiermit kann die maximale Zahl
 | 
			
		||||
    der Channels, in denen ein User Mitglied sein kann, begrent werden.
 | 
			
		||||
  - neue Channel-Modes l (User-Limit) und k (Channel-Key) implementiert.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.5.0, 20.09.2002
 | 
			
		||||
 | 
			
		||||
  - AIX (3.2.5), HP-UX (10.20), IRIX (6.5), NetBSD (1.5.3/m68k) und Solaris
 | 
			
		||||
    (2.5.1, 2.6) gehoeren nun auch zu den unterstuetzten Platformen.
 | 
			
		||||
  - Unter A/UX (und evtl. weiteren Systemen) kompiliert der ngIRCd nun mit
 | 
			
		||||
    dem "nativen" (ggf. pre-ANSI) Compiler.
 | 
			
		||||
  - "persistente Channels" (Mode 'P') implementiert: diese koennen in der
 | 
			
		||||
    Konfigurationsdatei definiert werden (Sektion "Channel", vgl. Beispiel-
 | 
			
		||||
    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+-
 | 
			
		||||
    Protokoll unterstuetzen, Channel-Modes und Topics. Fuer den ADMIN-Befehl
 | 
			
		||||
    gibt es neue Konfigurationsoptionen (Sektion "Global"): "AdminInfo1",
 | 
			
		||||
    "AdminInfo2" und "AdminEMail".
 | 
			
		||||
  - Invite- und Ban-Lists implementiert.
 | 
			
		||||
  - neue Konfigurationsoption "OperCanUseMode" (Sektion "Global"):
 | 
			
		||||
    ist sie aktiv, koennen IRC-Operatoren immer Channel-Modes setzen.
 | 
			
		||||
  - "Test-Suite" begonnen: mit "make check" wird sie durchlaufen.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.4.2, 29.04.2002
 | 
			
		||||
 | 
			
		||||
  - IRC-Funktion LIST implementiert; bisher werden allerdings noch keine
 | 
			
		||||
    Regular Expressions (bis auf "*") unterstuetzt.
 | 
			
		||||
 | 
			
		||||
ngIRCd 0.4.0, 01.04.2002
 | 
			
		||||
 | 
			
		||||
  - WHO implementiert (bisher ohne komplette Unterstuetzung von Masks).
 | 
			
		||||
  - stderr wird nun in eine Datei umgelenkt (/ngircd-<PID>.err).
 | 
			
		||||
    Laeuft der Server nicht im Debug-Modus, so wird diese bei Programm-
 | 
			
		||||
    ende geloescht. Sollte der Server abstuerzen, finden sich hier evtl.
 | 
			
		||||
    zusaetzliche Informationen.
 | 
			
		||||
@@ -85,4 +174,4 @@ ngIRCd 0.0.1, 31.12.2001
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: NEWS,v 1.25 2002/03/29 23:41:23 alex Exp $
 | 
			
		||||
$Id: NEWS,v 1.53.2.5 2003/11/07 20:51:08 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										116
									
								
								README
									
									
									
									
									
								
							
							
						
						
									
										116
									
								
								README
									
									
									
									
									
								
							@@ -1,68 +1,86 @@
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001,2002 by Alexander Barton,
 | 
			
		||||
                      (c)2001-2003 by Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
                  ngIRCd ist freie Software und steht unter
 | 
			
		||||
                       der GNU General Public License.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                           -- README / Liesmich --
 | 
			
		||||
                                -- README --
 | 
			
		||||
                           
 | 
			
		||||
                      Ilja Osthoff, <ilja@glide.ath.cx>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
I. Einfuehrung
 | 
			
		||||
~~~~~~~~~~~~~~
 | 
			
		||||
I. Introduction
 | 
			
		||||
~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
ngIRCd ist ein Server fuer den Internet Relay Chat (IRC). Er ist von Grund
 | 
			
		||||
auf neu geschrieben, also nicht wie die meisten anderen IRCd's vom Urvater,
 | 
			
		||||
dem Daemon des IRCNet abgeleitet.
 | 
			
		||||
 | 
			
		||||
Zur Zeit befindet sich der ngIRCd noch in Entwicklung, teilweise fehlen noch
 | 
			
		||||
Features oder sind noch nicht "final" implementiert. 
 | 
			
		||||
 | 
			
		||||
Channels sind inzwischen implementiert (seit Version 0.1.0), privates Chatten
 | 
			
		||||
mit /msg und /query funktioniert ebenso. Server-Links werden dabei unter-
 | 
			
		||||
stuetzt. Einige User- und Channel-Modes sind implementiert, hier kennt der
 | 
			
		||||
Server jedoch noch nicht alles.
 | 
			
		||||
 | 
			
		||||
Bisher (mehr oder wenig vollstaendig) implementierte IRC-Befehle:
 | 
			
		||||
 | 
			
		||||
AWAY, DIE, ERROR, ISON, JOIN, KILL, LINKS, LUSERS, MODE, MOTD, NAMES, NICK,
 | 
			
		||||
NOTICE, NJOIN, OPER, PART, PASS, PING, PONG, PRIVMSG, QUIT, RESTART, SERVER,
 | 
			
		||||
SQUIT, TOPIC, USER, USERHOST, VERSION, WHO, WHOIS.
 | 
			
		||||
 | 
			
		||||
Ueber Rueckmeldungen, Bug-Reports und Patches freue ich mich! Also los, haut
 | 
			
		||||
in die Tasten! :-))
 | 
			
		||||
 | 
			
		||||
Via E-Mail erreichst du mich als <alex@arthur.ath.cx> bzw. <alex@barton.de>.
 | 
			
		||||
Die Homepage des ngIRCd findest du unter <http://arthur.ath.cx/~alex/ngircd/>.
 | 
			
		||||
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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Hinweise zur Installation findest du in der Datei INSTALL.
 | 
			
		||||
Alle Autoren von ngIRCd sind in AUTHORS aufgefuehrt.
 | 
			
		||||
In der Datei COPYING steht die GNU General Public License.
 | 
			
		||||
Das README liest du gerade ,-)
 | 
			
		||||
II. Status
 | 
			
		||||
~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
At present, the ngIRCd is under active development, some features are not
 | 
			
		||||
implemented, some only partly.
 | 
			
		||||
 | 
			
		||||
Till today (more or less complete) implemented IRC-commands:
 | 
			
		||||
 | 
			
		||||
ADMIN, AWAY, CHANINFO, CONNECT, DIE, DISCONNECT, ERROR, HELP, INVITE, ISON,
 | 
			
		||||
JOIN, KICK, KILL, LINKS, LIST, LUSERS, MODE, MOTD, NAMES, NICK, NJOIN,
 | 
			
		||||
NOTICE, OPER, PART, PASS, PING, PONG, PRIVMSG, QUIT, REHASH, RESTART, SERVER,
 | 
			
		||||
SQUIT, STATS, TIME, TOPIC, TRACE, USER, USERHOST, VERSION, WHO, WHOIS.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
II. Vorteile
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
III. Features (or: why use ngIRCd?)
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
- keine Probleme mit Servern, deren IP-Adressen nicht statisch sind,
 | 
			
		||||
- uebersichtliche ("schlanke") Konfigurationsdatei,
 | 
			
		||||
- frei verfuegbarer, moderner und "aufgeraeumter" C-Quellcode.
 | 
			
		||||
- ngIRCd wird aktiv weiter entwickelt.
 | 
			
		||||
- 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.
 | 
			
		||||
- supported platforms (tested versions): AIX (3.2.5), A/UX (3.0.1), FreeBSD
 | 
			
		||||
  (4.5), HP-UX (10.20), IRIX (6.5), Linux (2.x), Mac OS X (10.x), NetBSD
 | 
			
		||||
  (1.5.2/i386, 1.5.3/m68k), Solaris (2.5.1, 2.6), and Windows with Cygwin.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
III. Unterstuetzte Plattformen
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
IV. Documentation
 | 
			
		||||
~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
- A/UX
 | 
			
		||||
- FreeBSD
 | 
			
		||||
- Linux
 | 
			
		||||
- Mac OS X
 | 
			
		||||
- NetBSD
 | 
			
		||||
- Windows mit Cygwin
 | 
			
		||||
More documentation can be found in the "doc/" directory and the homepage of
 | 
			
		||||
the ngIRCd: <http://arthur.ath.cx/~alex/ngircd/>.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
V. Download
 | 
			
		||||
~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
The homepage of the ngIRCd is: <http://arthur.ath.cx/~alex/ngircd>; you
 | 
			
		||||
will find the newest information about the ngIRCd and the most recent
 | 
			
		||||
("stable") releases there.
 | 
			
		||||
 | 
			
		||||
If you are interested in the latest development versions (which are not
 | 
			
		||||
always stable), then please read the section "CVS" on the homepage and
 | 
			
		||||
the file "doc/CVS.txt" which describes the use of CVS, the "Concurrent
 | 
			
		||||
Versioning System".
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
VI. Bugs
 | 
			
		||||
~~~~~~~~
 | 
			
		||||
 | 
			
		||||
If you find bugs in the ngIRCd (which might be there :-), please report
 | 
			
		||||
them at the following URL:
 | 
			
		||||
 | 
			
		||||
<http://arthur.ath.cx/~alex/ngircd/#bugs>
 | 
			
		||||
 | 
			
		||||
There you can read about known bugs and limitations, too.
 | 
			
		||||
 | 
			
		||||
If you have critics, patches or something else, please feel free to post a
 | 
			
		||||
mail to: <alex@barton.de> or <alex@arthur.ath.cx>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: README,v 1.8 2002/03/21 23:25:15 alex Exp $
 | 
			
		||||
$Id: README,v 1.17 2003/03/09 22:03:58 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +1,15 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
#
 | 
			
		||||
# $Id: autogen.sh,v 1.3 2002/03/12 14:37:51 alex Exp $
 | 
			
		||||
# $Id: autogen.sh,v 1.6.2.1 2003/04/22 10:18:41 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
if [ -f configure ]; then
 | 
			
		||||
	echo "autogen.sh: configure-Skript existiert bereits ..."
 | 
			
		||||
fi
 | 
			
		||||
WANT_AUTOMAKE=1.6
 | 
			
		||||
export WANT_AUTOMAKE
 | 
			
		||||
 | 
			
		||||
aclocal && \
 | 
			
		||||
 autoheader && \
 | 
			
		||||
 automake --add-missing && \
 | 
			
		||||
 autoconf && \
 | 
			
		||||
 echo "Okay, autogen.sh war erfolgreich."
 | 
			
		||||
 echo "Okay, autogen.sh done."
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										340
									
								
								config.guess
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										340
									
								
								config.guess
									
									
									
									
										vendored
									
									
								
							@@ -1,9 +1,9 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
# Attempt to guess a canonical system name.
 | 
			
		||||
#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 | 
			
		||||
#   2000, 2001, 2002 Free Software Foundation, Inc.
 | 
			
		||||
#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 | 
			
		||||
 | 
			
		||||
timestamp='2002-03-04'
 | 
			
		||||
timestamp='2003-10-07'
 | 
			
		||||
 | 
			
		||||
# 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
 | 
			
		||||
@@ -88,30 +88,42 @@ if test $# != 0; then
 | 
			
		||||
  exit 1
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
trap 'exit 1' 1 2 15
 | 
			
		||||
 | 
			
		||||
dummy=dummy-$$
 | 
			
		||||
trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
 | 
			
		||||
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
 | 
			
		||||
# compiler to aid in system detection is discouraged as it requires
 | 
			
		||||
# temporary files to be created and, as you can see below, it is a
 | 
			
		||||
# headache to deal with in a portable fashion.
 | 
			
		||||
 | 
			
		||||
# CC_FOR_BUILD -- compiler used by this script.
 | 
			
		||||
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
 | 
			
		||||
# use `HOST_CC' if defined, but it is deprecated.
 | 
			
		||||
 | 
			
		||||
set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
 | 
			
		||||
 ,,)    echo "int dummy(){}" > $dummy.c ;
 | 
			
		||||
	for c in cc gcc c89 ; do
 | 
			
		||||
	  ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
 | 
			
		||||
	  if test $? = 0 ; then
 | 
			
		||||
# Portable tmp directory creation inspired by the Autoconf team.
 | 
			
		||||
 | 
			
		||||
set_cc_for_build='
 | 
			
		||||
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
 | 
			
		||||
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
 | 
			
		||||
: ${TMPDIR=/tmp} ;
 | 
			
		||||
 { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
 | 
			
		||||
 { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
 | 
			
		||||
 { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
 | 
			
		||||
 { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
 | 
			
		||||
dummy=$tmp/dummy ;
 | 
			
		||||
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
 | 
			
		||||
case $CC_FOR_BUILD,$HOST_CC,$CC in
 | 
			
		||||
 ,,)    echo "int x;" > $dummy.c ;
 | 
			
		||||
	for c in cc gcc c89 c99 ; do
 | 
			
		||||
	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
 | 
			
		||||
	     CC_FOR_BUILD="$c"; break ;
 | 
			
		||||
	  fi ;
 | 
			
		||||
	done ;
 | 
			
		||||
	rm -f $dummy.c $dummy.o $dummy.rel ;
 | 
			
		||||
	if test x"$CC_FOR_BUILD" = x ; then
 | 
			
		||||
	  CC_FOR_BUILD=no_compiler_found ;
 | 
			
		||||
	fi
 | 
			
		||||
	;;
 | 
			
		||||
 ,,*)   CC_FOR_BUILD=$CC ;;
 | 
			
		||||
 ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
 | 
			
		||||
esac'
 | 
			
		||||
esac ;'
 | 
			
		||||
 | 
			
		||||
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
 | 
			
		||||
# (ghazi@noc.rutgers.edu 1994-08-24)
 | 
			
		||||
@@ -142,6 +154,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 | 
			
		||||
	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
 | 
			
		||||
	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
 | 
			
		||||
	case "${UNAME_MACHINE_ARCH}" in
 | 
			
		||||
	    armeb) machine=armeb-unknown ;;
 | 
			
		||||
	    arm*) machine=arm-unknown ;;
 | 
			
		||||
	    sh3el) machine=shl-unknown ;;
 | 
			
		||||
	    sh3eb) machine=sh-unknown ;;
 | 
			
		||||
@@ -167,7 +180,18 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
	# The OS release
 | 
			
		||||
	release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
 | 
			
		||||
	# Debian GNU/NetBSD machines have a different userland, and
 | 
			
		||||
	# thus, need a distinct triplet. However, they do not need
 | 
			
		||||
	# kernel version information, so it can be replaced with a
 | 
			
		||||
	# suitable tag, in the style of linux-gnu.
 | 
			
		||||
	case "${UNAME_VERSION}" in
 | 
			
		||||
	    Debian*)
 | 
			
		||||
		release='-gnu'
 | 
			
		||||
		;;
 | 
			
		||||
	    *)
 | 
			
		||||
		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
 | 
			
		||||
	# contains redundant information, the shorter form:
 | 
			
		||||
	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
 | 
			
		||||
@@ -216,65 +240,52 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
 | 
			
		||||
	if test $UNAME_RELEASE = "V4.0"; then
 | 
			
		||||
		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
 | 
			
		||||
	fi
 | 
			
		||||
	# According to Compaq, /usr/sbin/psrinfo has been available on
 | 
			
		||||
	# OSF/1 and Tru64 systems produced since 1995.  I hope that
 | 
			
		||||
	# covers most systems running today.  This code pipes the CPU
 | 
			
		||||
	# types through head -n 1, so we only detect the type of CPU 0.
 | 
			
		||||
	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
 | 
			
		||||
	case "$ALPHA_CPU_TYPE" in
 | 
			
		||||
	    "EV4 (21064)")
 | 
			
		||||
		UNAME_MACHINE="alpha" ;;
 | 
			
		||||
	    "EV4.5 (21064)")
 | 
			
		||||
		UNAME_MACHINE="alpha" ;;
 | 
			
		||||
	    "LCA4 (21066/21068)")
 | 
			
		||||
		UNAME_MACHINE="alpha" ;;
 | 
			
		||||
	    "EV5 (21164)")
 | 
			
		||||
		UNAME_MACHINE="alphaev5" ;;
 | 
			
		||||
	    "EV5.6 (21164A)")
 | 
			
		||||
		UNAME_MACHINE="alphaev56" ;;
 | 
			
		||||
	    "EV5.6 (21164PC)")
 | 
			
		||||
		UNAME_MACHINE="alphapca56" ;;
 | 
			
		||||
	    "EV5.7 (21164PC)")
 | 
			
		||||
		UNAME_MACHINE="alphapca57" ;;
 | 
			
		||||
	    "EV6 (21264)")
 | 
			
		||||
		UNAME_MACHINE="alphaev6" ;;
 | 
			
		||||
	    "EV6.7 (21264A)")
 | 
			
		||||
		UNAME_MACHINE="alphaev67" ;;
 | 
			
		||||
	    "EV6.8CB (21264C)")
 | 
			
		||||
		UNAME_MACHINE="alphaev68" ;;
 | 
			
		||||
	    "EV6.8AL (21264B)")
 | 
			
		||||
		UNAME_MACHINE="alphaev68" ;;
 | 
			
		||||
	    "EV6.8CX (21264D)")
 | 
			
		||||
		UNAME_MACHINE="alphaev68" ;;
 | 
			
		||||
	    "EV6.9A (21264/EV69A)")
 | 
			
		||||
		UNAME_MACHINE="alphaev69" ;;
 | 
			
		||||
	    "EV7 (21364)")
 | 
			
		||||
		UNAME_MACHINE="alphaev7" ;;
 | 
			
		||||
	    "EV7.9 (21364A)")
 | 
			
		||||
		UNAME_MACHINE="alphaev79" ;;
 | 
			
		||||
	esac
 | 
			
		||||
	# A Vn.n version is a released version.
 | 
			
		||||
	# A Tn.n version is a released field test version.
 | 
			
		||||
	# A Xn.n version is an unreleased experimental baselevel.
 | 
			
		||||
	# 1.2 uses "1.2" for uname -r.
 | 
			
		||||
	cat <<EOF >$dummy.s
 | 
			
		||||
	.data
 | 
			
		||||
\$Lformat:
 | 
			
		||||
	.byte 37,100,45,37,120,10,0	# "%d-%x\n"
 | 
			
		||||
 | 
			
		||||
	.text
 | 
			
		||||
	.globl main
 | 
			
		||||
	.align 4
 | 
			
		||||
	.ent main
 | 
			
		||||
main:
 | 
			
		||||
	.frame \$30,16,\$26,0
 | 
			
		||||
	ldgp \$29,0(\$27)
 | 
			
		||||
	.prologue 1
 | 
			
		||||
	.long 0x47e03d80 # implver \$0
 | 
			
		||||
	lda \$2,-1
 | 
			
		||||
	.long 0x47e20c21 # amask \$2,\$1
 | 
			
		||||
	lda \$16,\$Lformat
 | 
			
		||||
	mov \$0,\$17
 | 
			
		||||
	not \$1,\$18
 | 
			
		||||
	jsr \$26,printf
 | 
			
		||||
	ldgp \$29,0(\$26)
 | 
			
		||||
	mov 0,\$16
 | 
			
		||||
	jsr \$26,exit
 | 
			
		||||
	.end main
 | 
			
		||||
EOF
 | 
			
		||||
	eval $set_cc_for_build
 | 
			
		||||
	$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
 | 
			
		||||
	if test "$?" = 0 ; then
 | 
			
		||||
		case `./$dummy` in
 | 
			
		||||
			0-0)
 | 
			
		||||
				UNAME_MACHINE="alpha"
 | 
			
		||||
				;;
 | 
			
		||||
			1-0)
 | 
			
		||||
				UNAME_MACHINE="alphaev5"
 | 
			
		||||
				;;
 | 
			
		||||
			1-1)
 | 
			
		||||
				UNAME_MACHINE="alphaev56"
 | 
			
		||||
				;;
 | 
			
		||||
			1-101)
 | 
			
		||||
				UNAME_MACHINE="alphapca56"
 | 
			
		||||
				;;
 | 
			
		||||
			2-303)
 | 
			
		||||
				UNAME_MACHINE="alphaev6"
 | 
			
		||||
				;;
 | 
			
		||||
			2-307)
 | 
			
		||||
				UNAME_MACHINE="alphaev67"
 | 
			
		||||
				;;
 | 
			
		||||
			2-1307)
 | 
			
		||||
				UNAME_MACHINE="alphaev68"
 | 
			
		||||
				;;
 | 
			
		||||
		esac
 | 
			
		||||
	fi
 | 
			
		||||
	rm -f $dummy.s $dummy
 | 
			
		||||
	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    Alpha*:OpenVMS:*:*)
 | 
			
		||||
	echo alpha-hp-vms
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    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
 | 
			
		||||
@@ -313,6 +324,13 @@ EOF
 | 
			
		||||
    NILE*:*:*:dcosx)
 | 
			
		||||
	echo pyramid-pyramid-svr4
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    DRS?6000:unix:4.0:6*)
 | 
			
		||||
	echo sparc-icl-nx6
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    DRS?6000:UNIX_SV:4.2*:7*)
 | 
			
		||||
	case `/usr/bin/uname -p` in
 | 
			
		||||
	    sparc) echo sparc-icl-nx7 && exit 0 ;;
 | 
			
		||||
	esac ;;
 | 
			
		||||
    sun4H:SunOS:5.*:*)
 | 
			
		||||
	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
@@ -419,15 +437,20 @@ EOF
 | 
			
		||||
	  exit (-1);
 | 
			
		||||
	}
 | 
			
		||||
EOF
 | 
			
		||||
	$CC_FOR_BUILD $dummy.c -o $dummy \
 | 
			
		||||
	  && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
 | 
			
		||||
	  && rm -f $dummy.c $dummy && exit 0
 | 
			
		||||
	rm -f $dummy.c $dummy
 | 
			
		||||
	$CC_FOR_BUILD -o $dummy $dummy.c \
 | 
			
		||||
	  && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
 | 
			
		||||
	  && exit 0
 | 
			
		||||
	echo mips-mips-riscos${UNAME_RELEASE}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    Motorola:PowerMAX_OS:*:*)
 | 
			
		||||
	echo powerpc-motorola-powermax
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    Motorola:*:4.3:PL8-*)
 | 
			
		||||
	echo powerpc-harris-powermax
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
 | 
			
		||||
	echo powerpc-harris-powermax
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    Night_Hawk:Power_UNIX:*:*)
 | 
			
		||||
	echo powerpc-harris-powerunix
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
@@ -500,8 +523,7 @@ EOF
 | 
			
		||||
			exit(0);
 | 
			
		||||
			}
 | 
			
		||||
EOF
 | 
			
		||||
		$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
 | 
			
		||||
		rm -f $dummy.c $dummy
 | 
			
		||||
		$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
 | 
			
		||||
		echo rs6000-ibm-aix3.2.5
 | 
			
		||||
	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
 | 
			
		||||
		echo rs6000-ibm-aix3.2.4
 | 
			
		||||
@@ -599,11 +621,21 @@ EOF
 | 
			
		||||
                  exit (0);
 | 
			
		||||
              }
 | 
			
		||||
EOF
 | 
			
		||||
		    (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null) && HP_ARCH=`./$dummy`
 | 
			
		||||
		    if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
 | 
			
		||||
		    rm -f $dummy.c $dummy
 | 
			
		||||
		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
 | 
			
		||||
		    test -z "$HP_ARCH" && HP_ARCH=hppa
 | 
			
		||||
		fi ;;
 | 
			
		||||
	esac
 | 
			
		||||
	if [ ${HP_ARCH} = "hppa2.0w" ]
 | 
			
		||||
	then
 | 
			
		||||
	    # avoid double evaluation of $set_cc_for_build
 | 
			
		||||
	    test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
 | 
			
		||||
	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
 | 
			
		||||
	    then
 | 
			
		||||
		HP_ARCH="hppa2.0w"
 | 
			
		||||
	    else
 | 
			
		||||
		HP_ARCH="hppa64"
 | 
			
		||||
	    fi
 | 
			
		||||
	fi
 | 
			
		||||
	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    ia64:HP-UX:*:*)
 | 
			
		||||
@@ -637,8 +669,7 @@ EOF
 | 
			
		||||
	  exit (0);
 | 
			
		||||
	}
 | 
			
		||||
EOF
 | 
			
		||||
	$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
 | 
			
		||||
	rm -f $dummy.c $dummy
 | 
			
		||||
	$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
 | 
			
		||||
	echo unknown-hitachi-hiuxwe2
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
 | 
			
		||||
@@ -696,15 +727,15 @@ EOF
 | 
			
		||||
    CRAY*TS:*:*:*)
 | 
			
		||||
	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    CRAY*T3D:*:*:*)
 | 
			
		||||
	echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    CRAY*T3E:*:*:*)
 | 
			
		||||
	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    CRAY*SV1:*:*:*)
 | 
			
		||||
	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    *:UNICOS/mp:*:*)
 | 
			
		||||
	echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    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/\///'`
 | 
			
		||||
@@ -721,7 +752,21 @@ EOF
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    *:FreeBSD:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
 | 
			
		||||
	# Determine whether the default compiler uses glibc.
 | 
			
		||||
	eval $set_cc_for_build
 | 
			
		||||
	sed 's/^	//' << EOF >$dummy.c
 | 
			
		||||
	#include <features.h>
 | 
			
		||||
	#if __GLIBC__ >= 2
 | 
			
		||||
	LIBC=gnu
 | 
			
		||||
	#else
 | 
			
		||||
	LIBC=
 | 
			
		||||
	#endif
 | 
			
		||||
EOF
 | 
			
		||||
	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
 | 
			
		||||
	# GNU/KFreeBSD systems have a "k" prefix to indicate we are using
 | 
			
		||||
	# FreeBSD's kernel, but not the complete OS.
 | 
			
		||||
	case ${LIBC} in gnu) kernel_only='k' ;; esac
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    i*:CYGWIN*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-cygwin
 | 
			
		||||
@@ -732,14 +777,17 @@ EOF
 | 
			
		||||
    i*:PW*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-pw32
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    x86:Interix*:3*)
 | 
			
		||||
	echo i386-pc-interix3
 | 
			
		||||
    x86:Interix*:[34]*)
 | 
			
		||||
	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
 | 
			
		||||
	echo i${UNAME_MACHINE}-pc-mks
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    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
 | 
			
		||||
	# UNAME_MACHINE based on the output of uname instead of i386?
 | 
			
		||||
	echo i386-pc-interix
 | 
			
		||||
	echo i586-pc-interix
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    i*:UWIN*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-uwin
 | 
			
		||||
@@ -751,16 +799,24 @@ EOF
 | 
			
		||||
	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    *:GNU:*:*)
 | 
			
		||||
	# the GNU system
 | 
			
		||||
	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    *:GNU/*:*:*)
 | 
			
		||||
	# other systems with GNU libc and userland
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    i*86:Minix:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-minix
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    arm*:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    cris:Linux:*:*)
 | 
			
		||||
	echo cris-axis-linux-gnu
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    ia64:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    m68*:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
@@ -771,19 +827,37 @@ EOF
 | 
			
		||||
	#undef CPU
 | 
			
		||||
	#undef mips
 | 
			
		||||
	#undef mipsel
 | 
			
		||||
	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) 
 | 
			
		||||
	CPU=mipsel 
 | 
			
		||||
	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
 | 
			
		||||
	CPU=mipsel
 | 
			
		||||
	#else
 | 
			
		||||
	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) 
 | 
			
		||||
	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
 | 
			
		||||
	CPU=mips
 | 
			
		||||
	#else
 | 
			
		||||
	CPU=
 | 
			
		||||
	#endif
 | 
			
		||||
	#endif 
 | 
			
		||||
	#endif
 | 
			
		||||
EOF
 | 
			
		||||
	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
 | 
			
		||||
	rm -f $dummy.c
 | 
			
		||||
	test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0
 | 
			
		||||
	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
 | 
			
		||||
	;;
 | 
			
		||||
    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 | grep ^CPU=`
 | 
			
		||||
	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
 | 
			
		||||
	;;
 | 
			
		||||
    ppc:Linux:*:*)
 | 
			
		||||
	echo powerpc-unknown-linux-gnu
 | 
			
		||||
@@ -819,6 +893,9 @@ EOF
 | 
			
		||||
    s390:Linux:*:* | s390x:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-ibm-linux
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    sh64*:Linux:*:*)
 | 
			
		||||
    	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    sh*:Linux:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-linux-gnu
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
@@ -845,7 +922,7 @@ EOF
 | 
			
		||||
		;;
 | 
			
		||||
	  a.out-i386-linux)
 | 
			
		||||
		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
 | 
			
		||||
		exit 0 ;;		
 | 
			
		||||
		exit 0 ;;
 | 
			
		||||
	  coff-i386)
 | 
			
		||||
		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
 | 
			
		||||
		exit 0 ;;
 | 
			
		||||
@@ -876,9 +953,11 @@ EOF
 | 
			
		||||
	LIBC=gnuaout
 | 
			
		||||
	#endif
 | 
			
		||||
	#endif
 | 
			
		||||
	#ifdef __dietlibc__
 | 
			
		||||
	LIBC=dietlibc
 | 
			
		||||
	#endif
 | 
			
		||||
EOF
 | 
			
		||||
	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
 | 
			
		||||
	rm -f $dummy.c
 | 
			
		||||
	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
 | 
			
		||||
	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
 | 
			
		||||
	;;
 | 
			
		||||
@@ -896,6 +975,23 @@ EOF
 | 
			
		||||
        # Use sysv4.2uw... so that sysv4* matches it.
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    i*86:OS/2:*:*)
 | 
			
		||||
	# If we were able to find `uname', then EMX Unix compatibility
 | 
			
		||||
	# is probably installed.
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-os2-emx
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    i*86:XTS-300:*:STOP)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-stop
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    i*86:atheos:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-atheos
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
 | 
			
		||||
	echo i386-unknown-lynxos${UNAME_RELEASE}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    i*86:*DOS:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-msdosdjgpp
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
 | 
			
		||||
	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
 | 
			
		||||
	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
 | 
			
		||||
@@ -917,22 +1013,19 @@ EOF
 | 
			
		||||
		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
 | 
			
		||||
		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
 | 
			
		||||
	elif /bin/uname -X 2>/dev/null >/dev/null ; then
 | 
			
		||||
		UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
 | 
			
		||||
		(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
 | 
			
		||||
		(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
 | 
			
		||||
		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
 | 
			
		||||
		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
 | 
			
		||||
		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
 | 
			
		||||
			&& UNAME_MACHINE=i586
 | 
			
		||||
		(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
 | 
			
		||||
		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
 | 
			
		||||
			&& UNAME_MACHINE=i686
 | 
			
		||||
		(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
 | 
			
		||||
		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
 | 
			
		||||
			&& UNAME_MACHINE=i686
 | 
			
		||||
		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
 | 
			
		||||
	else
 | 
			
		||||
		echo ${UNAME_MACHINE}-pc-sysv32
 | 
			
		||||
	fi
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    i*86:*DOS:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-msdosdjgpp
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    pc:*:*:*)
 | 
			
		||||
	# Left here for compatibility:
 | 
			
		||||
        # uname -m prints for DJGPP always 'pc', but it prints nothing about
 | 
			
		||||
@@ -956,9 +1049,15 @@ EOF
 | 
			
		||||
	# "miniframe"
 | 
			
		||||
	echo m68010-convergent-sysv
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    mc68k:UNIX:SYSTEM5:3.51m)
 | 
			
		||||
	echo m68k-convergent-sysv
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    M680?0:D-NIX:5.3:*)
 | 
			
		||||
	echo m68k-diab-dnix
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    M68*:*:R3V[567]*:*)
 | 
			
		||||
	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
 | 
			
		||||
    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0)
 | 
			
		||||
    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
 | 
			
		||||
	OS_REL=''
 | 
			
		||||
	test -r /etc/.relid \
 | 
			
		||||
	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
 | 
			
		||||
@@ -975,9 +1074,6 @@ EOF
 | 
			
		||||
    mc68030:UNIX_System_V:4.*:*)
 | 
			
		||||
	echo m68k-atari-sysv4
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
 | 
			
		||||
	echo i386-unknown-lynxos${UNAME_RELEASE}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    TSUNAMI:LynxOS:2.*:*)
 | 
			
		||||
	echo sparc-unknown-lynxos${UNAME_RELEASE}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
@@ -1049,6 +1145,9 @@ EOF
 | 
			
		||||
    SX-5:SUPER-UX:*:*)
 | 
			
		||||
	echo sx5-nec-superux${UNAME_RELEASE}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    SX-6:SUPER-UX:*:*)
 | 
			
		||||
	echo sx6-nec-superux${UNAME_RELEASE}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    Power*:Rhapsody:*:*)
 | 
			
		||||
	echo powerpc-apple-rhapsody${UNAME_RELEASE}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
@@ -1056,20 +1155,24 @@ EOF
 | 
			
		||||
	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    *:Darwin:*:*)
 | 
			
		||||
	echo `uname -p`-apple-darwin${UNAME_RELEASE}
 | 
			
		||||
	case `uname -p` in
 | 
			
		||||
	    *86) UNAME_PROCESSOR=i686 ;;
 | 
			
		||||
	    powerpc) UNAME_PROCESSOR=powerpc ;;
 | 
			
		||||
	esac
 | 
			
		||||
	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    *:procnto*:*:* | *:QNX:[0123456789]*:*)
 | 
			
		||||
	if test "${UNAME_MACHINE}" = "x86pc"; then
 | 
			
		||||
	UNAME_PROCESSOR=`uname -p`
 | 
			
		||||
	if test "$UNAME_PROCESSOR" = "x86"; then
 | 
			
		||||
		UNAME_PROCESSOR=i386
 | 
			
		||||
		UNAME_MACHINE=pc
 | 
			
		||||
		echo i386-${UNAME_MACHINE}-nto-qnx
 | 
			
		||||
	else
 | 
			
		||||
		echo `uname -p`-${UNAME_MACHINE}-nto-qnx
 | 
			
		||||
	fi
 | 
			
		||||
	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    *:QNX:*:4*)
 | 
			
		||||
	echo i386-pc-qnx
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    NSR-[GKLNPTVW]:NONSTOP_KERNEL:*:*)
 | 
			
		||||
    NSR-[DGKLNPTVWY]:NONSTOP_KERNEL:*:*)
 | 
			
		||||
	echo nsr-tandem-nsk${UNAME_RELEASE}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    *:NonStop-UX:*:*)
 | 
			
		||||
@@ -1092,11 +1195,6 @@ EOF
 | 
			
		||||
	fi
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-plan9
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    i*86:OS/2:*:*)
 | 
			
		||||
	# If we were able to find `uname', then EMX Unix compatibility
 | 
			
		||||
	# is probably installed.
 | 
			
		||||
	echo ${UNAME_MACHINE}-pc-os2-emx
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    *:TOPS-10:*:*)
 | 
			
		||||
	echo pdp10-unknown-tops10
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
@@ -1115,11 +1213,8 @@ EOF
 | 
			
		||||
    *:ITS:*:*)
 | 
			
		||||
	echo pdp10-unknown-its
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    i*86:XTS-300:*:STOP)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-stop
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
    i*86:atheos:*:*)
 | 
			
		||||
	echo ${UNAME_MACHINE}-unknown-atheos
 | 
			
		||||
    SEI:*:*:SEIUX)
 | 
			
		||||
        echo mips-sei-seiux${UNAME_RELEASE}
 | 
			
		||||
	exit 0 ;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
@@ -1241,8 +1336,7 @@ main ()
 | 
			
		||||
}
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
 | 
			
		||||
rm -f $dummy.c $dummy
 | 
			
		||||
$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
 | 
			
		||||
 | 
			
		||||
# Apollos put the system type in the environment.
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										191
									
								
								config.sub
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										191
									
								
								config.sub
									
									
									
									
										vendored
									
									
								
							@@ -1,9 +1,9 @@
 | 
			
		||||
#! /bin/sh
 | 
			
		||||
# Configuration validation subroutine script.
 | 
			
		||||
#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 | 
			
		||||
#   2000, 2001, 2002 Free Software Foundation, Inc.
 | 
			
		||||
#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 | 
			
		||||
 | 
			
		||||
timestamp='2002-03-04'
 | 
			
		||||
timestamp='2003-10-07'
 | 
			
		||||
 | 
			
		||||
# This file is (in principle) common to ALL GNU software.
 | 
			
		||||
# The presence of a machine in this file suggests that SOME GNU software
 | 
			
		||||
@@ -118,7 +118,7 @@ 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* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
 | 
			
		||||
  nto-qnx* | linux-gnu* | linux-dietlibc | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
 | 
			
		||||
    os=-$maybe_os
 | 
			
		||||
    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
 | 
			
		||||
    ;;
 | 
			
		||||
@@ -228,28 +228,42 @@ case $basic_machine in
 | 
			
		||||
	| a29k \
 | 
			
		||||
	| 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 \
 | 
			
		||||
	| c4x | clipper \
 | 
			
		||||
	| d10v | d30v | dsp16xx \
 | 
			
		||||
	| fr30 \
 | 
			
		||||
	| d10v | d30v | dlx | dsp16xx \
 | 
			
		||||
	| fr30 | frv \
 | 
			
		||||
	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
 | 
			
		||||
	| i370 | i860 | i960 | ia64 \
 | 
			
		||||
	| ip2k | iq2000 \
 | 
			
		||||
	| m32r | m68000 | m68k | m88k | mcore \
 | 
			
		||||
	| mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
 | 
			
		||||
	| mips64vr4100 | mips64vr4100el | mips64vr4300 \
 | 
			
		||||
	| mips64vr4300el | mips64vr5000 | mips64vr5000el \
 | 
			
		||||
	| mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
 | 
			
		||||
	| mipsisa32 \
 | 
			
		||||
	| mips | mipsbe | mipseb | mipsel | mipsle \
 | 
			
		||||
	| mips16 \
 | 
			
		||||
	| mips64 | mips64el \
 | 
			
		||||
	| mips64vr | mips64vrel \
 | 
			
		||||
	| mips64orion | mips64orionel \
 | 
			
		||||
	| mips64vr4100 | mips64vr4100el \
 | 
			
		||||
	| mips64vr4300 | mips64vr4300el \
 | 
			
		||||
	| mips64vr5000 | mips64vr5000el \
 | 
			
		||||
	| mipsisa32 | mipsisa32el \
 | 
			
		||||
	| mipsisa32r2 | mipsisa32r2el \
 | 
			
		||||
	| mipsisa64 | mipsisa64el \
 | 
			
		||||
	| mipsisa64r2 | mipsisa64r2el \
 | 
			
		||||
	| mipsisa64sb1 | mipsisa64sb1el \
 | 
			
		||||
	| mipsisa64sr71k | mipsisa64sr71kel \
 | 
			
		||||
	| mipstx39 | mipstx39el \
 | 
			
		||||
	| mn10200 | mn10300 \
 | 
			
		||||
	| msp430 \
 | 
			
		||||
	| ns16k | ns32k \
 | 
			
		||||
	| openrisc | or32 \
 | 
			
		||||
	| pdp10 | pdp11 | pj | pjl \
 | 
			
		||||
	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
 | 
			
		||||
	| pyramid \
 | 
			
		||||
	| sh | sh[34] | sh[34]eb | shbe | shle | sh64 \
 | 
			
		||||
	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
 | 
			
		||||
	| sh64 | sh64le \
 | 
			
		||||
	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
 | 
			
		||||
	| strongarm \
 | 
			
		||||
	| tahoe | thumb | tic80 | tron \
 | 
			
		||||
	| tahoe | thumb | tic4x | tic80 | tron \
 | 
			
		||||
	| v850 | v850e \
 | 
			
		||||
	| we32k \
 | 
			
		||||
	| x86 | xscale | xstormy16 | xtensa \
 | 
			
		||||
@@ -281,34 +295,50 @@ case $basic_machine in
 | 
			
		||||
	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
 | 
			
		||||
	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
 | 
			
		||||
	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
 | 
			
		||||
	| arm-*  | armbe-* | armle-* | armv*-* \
 | 
			
		||||
	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
 | 
			
		||||
	| avr-* \
 | 
			
		||||
	| bs2000-* \
 | 
			
		||||
	| c[123]* | c30-* | [cjt]90-* | c54x-* \
 | 
			
		||||
	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
 | 
			
		||||
	| clipper-* | cydra-* \
 | 
			
		||||
	| d10v-* | d30v-* \
 | 
			
		||||
	| d10v-* | d30v-* | dlx-* \
 | 
			
		||||
	| elxsi-* \
 | 
			
		||||
	| f30[01]-* | f700-* | fr30-* | fx80-* \
 | 
			
		||||
	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
 | 
			
		||||
	| h8300-* | h8500-* \
 | 
			
		||||
	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
 | 
			
		||||
	| i*86-* | i860-* | i960-* | ia64-* \
 | 
			
		||||
	| ip2k-* | iq2000-* \
 | 
			
		||||
	| m32r-* \
 | 
			
		||||
	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
 | 
			
		||||
	| m88110-* | m88k-* | mcore-* \
 | 
			
		||||
	| mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
 | 
			
		||||
	| mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
 | 
			
		||||
	| mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
 | 
			
		||||
	| mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
 | 
			
		||||
	| none-* | np1-* | ns16k-* | ns32k-* \
 | 
			
		||||
	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
 | 
			
		||||
	| mips16-* \
 | 
			
		||||
	| mips64-* | mips64el-* \
 | 
			
		||||
	| mips64vr-* | mips64vrel-* \
 | 
			
		||||
	| mips64orion-* | mips64orionel-* \
 | 
			
		||||
	| mips64vr4100-* | mips64vr4100el-* \
 | 
			
		||||
	| mips64vr4300-* | mips64vr4300el-* \
 | 
			
		||||
	| mips64vr5000-* | mips64vr5000el-* \
 | 
			
		||||
	| mipsisa32-* | mipsisa32el-* \
 | 
			
		||||
	| mipsisa32r2-* | mipsisa32r2el-* \
 | 
			
		||||
	| mipsisa64-* | mipsisa64el-* \
 | 
			
		||||
	| mipsisa64r2-* | mipsisa64r2el-* \
 | 
			
		||||
	| mipsisa64sb1-* | mipsisa64sb1el-* \
 | 
			
		||||
	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
 | 
			
		||||
	| mipstx39-* | mipstx39el-* \
 | 
			
		||||
	| msp430-* \
 | 
			
		||||
	| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
 | 
			
		||||
	| orion-* \
 | 
			
		||||
	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
 | 
			
		||||
	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
 | 
			
		||||
	| pyramid-* \
 | 
			
		||||
	| romp-* | rs6000-* \
 | 
			
		||||
	| sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \
 | 
			
		||||
	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
 | 
			
		||||
	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
 | 
			
		||||
	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
 | 
			
		||||
	| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
 | 
			
		||||
	| tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
 | 
			
		||||
	| tahoe-* | thumb-* \
 | 
			
		||||
	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
 | 
			
		||||
	| tron-* \
 | 
			
		||||
	| v850-* | v850e-* | vax-* \
 | 
			
		||||
	| we32k-* \
 | 
			
		||||
	| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
 | 
			
		||||
@@ -346,6 +376,9 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=a29k-none
 | 
			
		||||
		os=-bsd
 | 
			
		||||
		;;
 | 
			
		||||
	amd64)
 | 
			
		||||
		basic_machine=x86_64-pc
 | 
			
		||||
		;;
 | 
			
		||||
	amdahl)
 | 
			
		||||
		basic_machine=580-amdahl
 | 
			
		||||
		os=-sysv
 | 
			
		||||
@@ -695,6 +728,10 @@ case $basic_machine in
 | 
			
		||||
	np1)
 | 
			
		||||
		basic_machine=np1-gould
 | 
			
		||||
		;;
 | 
			
		||||
	nv1)
 | 
			
		||||
		basic_machine=nv1-cray
 | 
			
		||||
		os=-unicosmp
 | 
			
		||||
		;;
 | 
			
		||||
	nsr-tandem)
 | 
			
		||||
		basic_machine=nsr-tandem
 | 
			
		||||
		;;
 | 
			
		||||
@@ -728,49 +765,55 @@ case $basic_machine in
 | 
			
		||||
	pbb)
 | 
			
		||||
		basic_machine=m68k-tti
 | 
			
		||||
		;;
 | 
			
		||||
        pc532 | pc532-*)
 | 
			
		||||
	pc532 | pc532-*)
 | 
			
		||||
		basic_machine=ns32k-pc532
 | 
			
		||||
		;;
 | 
			
		||||
	pentium | p5 | k5 | k6 | nexgen | viac3)
 | 
			
		||||
		basic_machine=i586-pc
 | 
			
		||||
		;;
 | 
			
		||||
	pentiumpro | p6 | 6x86 | athlon)
 | 
			
		||||
	pentiumpro | p6 | 6x86 | athlon | athlon_*)
 | 
			
		||||
		basic_machine=i686-pc
 | 
			
		||||
		;;
 | 
			
		||||
	pentiumii | pentium2)
 | 
			
		||||
	pentiumii | pentium2 | pentiumiii | pentium3)
 | 
			
		||||
		basic_machine=i686-pc
 | 
			
		||||
		;;
 | 
			
		||||
	pentium4)
 | 
			
		||||
		basic_machine=i786-pc
 | 
			
		||||
		;;
 | 
			
		||||
	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
 | 
			
		||||
		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	pentiumpro-* | p6-* | 6x86-* | athlon-*)
 | 
			
		||||
		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	pentiumii-* | pentium2-*)
 | 
			
		||||
	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
 | 
			
		||||
		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	pentium4-*)
 | 
			
		||||
		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	pn)
 | 
			
		||||
		basic_machine=pn-gould
 | 
			
		||||
		;;
 | 
			
		||||
	power)	basic_machine=power-ibm
 | 
			
		||||
		;;
 | 
			
		||||
	ppc)	basic_machine=powerpc-unknown
 | 
			
		||||
	        ;;
 | 
			
		||||
		;;
 | 
			
		||||
	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	ppcle | powerpclittle | ppc-le | powerpc-little)
 | 
			
		||||
		basic_machine=powerpcle-unknown
 | 
			
		||||
	        ;;
 | 
			
		||||
		;;
 | 
			
		||||
	ppcle-* | powerpclittle-*)
 | 
			
		||||
		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	ppc64)	basic_machine=powerpc64-unknown
 | 
			
		||||
	        ;;
 | 
			
		||||
		;;
 | 
			
		||||
	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
 | 
			
		||||
		basic_machine=powerpc64le-unknown
 | 
			
		||||
	        ;;
 | 
			
		||||
		;;
 | 
			
		||||
	ppc64le-* | powerpc64little-*)
 | 
			
		||||
		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
 | 
			
		||||
		;;
 | 
			
		||||
@@ -801,6 +844,16 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=a29k-amd
 | 
			
		||||
		os=-udi
 | 
			
		||||
		;;
 | 
			
		||||
	sb1)
 | 
			
		||||
		basic_machine=mipsisa64sb1-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	sb1el)
 | 
			
		||||
		basic_machine=mipsisa64sb1el-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	sei)
 | 
			
		||||
		basic_machine=mips-sei
 | 
			
		||||
		os=-seiux
 | 
			
		||||
		;;
 | 
			
		||||
	sequent)
 | 
			
		||||
		basic_machine=i386-sequent
 | 
			
		||||
		;;
 | 
			
		||||
@@ -808,6 +861,9 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=sh-hitachi
 | 
			
		||||
		os=-hms
 | 
			
		||||
		;;
 | 
			
		||||
	sh64)
 | 
			
		||||
		basic_machine=sh64-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	sparclite-wrs | simso-wrs)
 | 
			
		||||
		basic_machine=sparclite-wrs
 | 
			
		||||
		os=-vxworks
 | 
			
		||||
@@ -866,7 +922,7 @@ case $basic_machine in
 | 
			
		||||
	sun386 | sun386i | roadrunner)
 | 
			
		||||
		basic_machine=i386-sun
 | 
			
		||||
		;;
 | 
			
		||||
        sv1)
 | 
			
		||||
	sv1)
 | 
			
		||||
		basic_machine=sv1-cray
 | 
			
		||||
		os=-unicos
 | 
			
		||||
		;;
 | 
			
		||||
@@ -874,10 +930,6 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=i386-sequent
 | 
			
		||||
		os=-dynix
 | 
			
		||||
		;;
 | 
			
		||||
	t3d)
 | 
			
		||||
		basic_machine=alpha-cray
 | 
			
		||||
		os=-unicos
 | 
			
		||||
		;;
 | 
			
		||||
	t3e)
 | 
			
		||||
		basic_machine=alphaev5-cray
 | 
			
		||||
		os=-unicos
 | 
			
		||||
@@ -890,6 +942,14 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=tic54x-unknown
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	tic55x | c55x*)
 | 
			
		||||
		basic_machine=tic55x-unknown
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	tic6x | c6x*)
 | 
			
		||||
		basic_machine=tic6x-unknown
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	tx39)
 | 
			
		||||
		basic_machine=mipstx39-unknown
 | 
			
		||||
		;;
 | 
			
		||||
@@ -924,8 +984,8 @@ case $basic_machine in
 | 
			
		||||
		os=-vms
 | 
			
		||||
		;;
 | 
			
		||||
	vpp*|vx|vx-*)
 | 
			
		||||
               basic_machine=f301-fujitsu
 | 
			
		||||
               ;;
 | 
			
		||||
		basic_machine=f301-fujitsu
 | 
			
		||||
		;;
 | 
			
		||||
	vxworks960)
 | 
			
		||||
		basic_machine=i960-wrs
 | 
			
		||||
		os=-vxworks
 | 
			
		||||
@@ -946,11 +1006,7 @@ case $basic_machine in
 | 
			
		||||
		basic_machine=hppa1.1-winbond
 | 
			
		||||
		os=-proelf
 | 
			
		||||
		;;
 | 
			
		||||
	windows32)
 | 
			
		||||
		basic_machine=i386-pc
 | 
			
		||||
		os=-windows32-msvcrt
 | 
			
		||||
		;;
 | 
			
		||||
        xps | xps100)
 | 
			
		||||
	xps | xps100)
 | 
			
		||||
		basic_machine=xps100-honeywell
 | 
			
		||||
		;;
 | 
			
		||||
	ymp)
 | 
			
		||||
@@ -996,7 +1052,7 @@ case $basic_machine in
 | 
			
		||||
	we32k)
 | 
			
		||||
		basic_machine=we32k-att
 | 
			
		||||
		;;
 | 
			
		||||
	sh3 | sh4 | sh3eb | sh4eb)
 | 
			
		||||
	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
 | 
			
		||||
		basic_machine=sh-unknown
 | 
			
		||||
		;;
 | 
			
		||||
	sh64)
 | 
			
		||||
@@ -1005,7 +1061,7 @@ case $basic_machine in
 | 
			
		||||
	sparc | sparcv9 | sparcv9b)
 | 
			
		||||
		basic_machine=sparc-sun
 | 
			
		||||
		;;
 | 
			
		||||
        cydra)
 | 
			
		||||
	cydra)
 | 
			
		||||
		basic_machine=cydra-cydrome
 | 
			
		||||
		;;
 | 
			
		||||
	orion)
 | 
			
		||||
@@ -1020,10 +1076,6 @@ case $basic_machine in
 | 
			
		||||
	pmac | pmac-mpw)
 | 
			
		||||
		basic_machine=powerpc-apple
 | 
			
		||||
		;;
 | 
			
		||||
	c4x*)
 | 
			
		||||
		basic_machine=c4x-none
 | 
			
		||||
		os=-coff
 | 
			
		||||
		;;
 | 
			
		||||
	*-unknown)
 | 
			
		||||
		# Make sure to match an already-canonicalized machine name.
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1079,18 +1131,19 @@ case $os in
 | 
			
		||||
	      | -aos* \
 | 
			
		||||
	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
 | 
			
		||||
	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
 | 
			
		||||
	      | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
 | 
			
		||||
	      | -hiux* | -386bsd* | -knetbsd* | -netbsd* | -openbsd* | -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* | -uxpv* | -beos* | -mpeix* | -udk* \
 | 
			
		||||
	      | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
 | 
			
		||||
	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 | 
			
		||||
	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 | 
			
		||||
	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
 | 
			
		||||
	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
 | 
			
		||||
	      | -morphos* | -superux* | -rtmk* | -rtmk-nova*)
 | 
			
		||||
	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
 | 
			
		||||
	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
 | 
			
		||||
	# Remember, each alternative MUST END IN *, to match a version number.
 | 
			
		||||
		;;
 | 
			
		||||
	-qnx*)
 | 
			
		||||
@@ -1102,8 +1155,10 @@ case $os in
 | 
			
		||||
			;;
 | 
			
		||||
		esac
 | 
			
		||||
		;;
 | 
			
		||||
	-nto-qnx*)
 | 
			
		||||
		;;
 | 
			
		||||
	-nto*)
 | 
			
		||||
		os=-nto-qnx
 | 
			
		||||
		os=`echo $os | sed -e 's|nto|nto-qnx|'`
 | 
			
		||||
		;;
 | 
			
		||||
	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
 | 
			
		||||
	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
 | 
			
		||||
@@ -1112,6 +1167,9 @@ case $os in
 | 
			
		||||
	-mac*)
 | 
			
		||||
		os=`echo $os | sed -e 's|mac|macos|'`
 | 
			
		||||
		;;
 | 
			
		||||
	-linux-dietlibc)
 | 
			
		||||
		os=-linux-dietlibc
 | 
			
		||||
		;;
 | 
			
		||||
	-linux*)
 | 
			
		||||
		os=`echo $os | sed -e 's|linux|linux-gnu|'`
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1155,7 +1213,7 @@ case $os in
 | 
			
		||||
		os=-rtmk-nova
 | 
			
		||||
		;;
 | 
			
		||||
	-ns2 )
 | 
			
		||||
	        os=-nextstep2
 | 
			
		||||
		os=-nextstep2
 | 
			
		||||
		;;
 | 
			
		||||
	-nsk*)
 | 
			
		||||
		os=-nsk
 | 
			
		||||
@@ -1194,8 +1252,14 @@ case $os in
 | 
			
		||||
	-xenix)
 | 
			
		||||
		os=-xenix
 | 
			
		||||
		;;
 | 
			
		||||
        -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
 | 
			
		||||
	        os=-mint
 | 
			
		||||
	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
 | 
			
		||||
		os=-mint
 | 
			
		||||
		;;
 | 
			
		||||
	-aros*)
 | 
			
		||||
		os=-aros
 | 
			
		||||
		;;
 | 
			
		||||
	-kaos*)
 | 
			
		||||
		os=-kaos
 | 
			
		||||
		;;
 | 
			
		||||
	-none)
 | 
			
		||||
		;;
 | 
			
		||||
@@ -1228,11 +1292,14 @@ case $basic_machine in
 | 
			
		||||
	arm*-semi)
 | 
			
		||||
		os=-aout
 | 
			
		||||
		;;
 | 
			
		||||
    c4x-* | tic4x-*)
 | 
			
		||||
        os=-coff
 | 
			
		||||
        ;;
 | 
			
		||||
	# This must come before the *-dec entry.
 | 
			
		||||
	pdp10-*)
 | 
			
		||||
		os=-tops20
 | 
			
		||||
		;;
 | 
			
		||||
        pdp11-*)
 | 
			
		||||
	pdp11-*)
 | 
			
		||||
		os=-none
 | 
			
		||||
		;;
 | 
			
		||||
	*-dec | vax-*)
 | 
			
		||||
@@ -1325,19 +1392,19 @@ case $basic_machine in
 | 
			
		||||
	*-next)
 | 
			
		||||
		os=-nextstep3
 | 
			
		||||
		;;
 | 
			
		||||
        *-gould)
 | 
			
		||||
	*-gould)
 | 
			
		||||
		os=-sysv
 | 
			
		||||
		;;
 | 
			
		||||
        *-highlevel)
 | 
			
		||||
	*-highlevel)
 | 
			
		||||
		os=-bsd
 | 
			
		||||
		;;
 | 
			
		||||
	*-encore)
 | 
			
		||||
		os=-bsd
 | 
			
		||||
		;;
 | 
			
		||||
        *-sgi)
 | 
			
		||||
	*-sgi)
 | 
			
		||||
		os=-irix
 | 
			
		||||
		;;
 | 
			
		||||
        *-siemens)
 | 
			
		||||
	*-siemens)
 | 
			
		||||
		os=-sysv4
 | 
			
		||||
		;;
 | 
			
		||||
	*-masscomp)
 | 
			
		||||
@@ -1409,7 +1476,7 @@ case $basic_machine in
 | 
			
		||||
			-ptx*)
 | 
			
		||||
				vendor=sequent
 | 
			
		||||
				;;
 | 
			
		||||
			-vxsim* | -vxworks*)
 | 
			
		||||
			-vxsim* | -vxworks* | -windiss*)
 | 
			
		||||
				vendor=wrs
 | 
			
		||||
				;;
 | 
			
		||||
			-aux*)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										320
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										320
									
								
								configure.in
									
									
									
									
									
								
							@@ -1,23 +1,23 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
# Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
 | 
			
		||||
#
 | 
			
		||||
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
# der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
# 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.
 | 
			
		||||
#
 | 
			
		||||
# $Id: configure.in,v 1.39 2002/03/30 18:02:39 alex Exp $
 | 
			
		||||
# $Id: configure.in,v 1.89.2.11 2003/11/07 20:51:08 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# -- Initialisierung --
 | 
			
		||||
 | 
			
		||||
AC_INIT
 | 
			
		||||
AC_PREREQ(2.50)
 | 
			
		||||
AC_INIT(ngircd, 0.7.5)
 | 
			
		||||
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
 | 
			
		||||
AC_CANONICAL_TARGET
 | 
			
		||||
AC_CONFIG_SRCDIR(src/config.h.in)
 | 
			
		||||
AM_INIT_AUTOMAKE(ngircd,0.3.0-CVS)
 | 
			
		||||
AM_INIT_AUTOMAKE(1.6)
 | 
			
		||||
AM_CONFIG_HEADER(src/config.h)
 | 
			
		||||
 | 
			
		||||
# -- Templates fuer config.h --
 | 
			
		||||
@@ -27,6 +27,10 @@ AH_TEMPLATE([HAVE_socklen_t], [Define if socklen_t exists])
 | 
			
		||||
AH_TEMPLATE([SNIFFER], [Define if IRC sniffer should be enabled])
 | 
			
		||||
AH_TEMPLATE([STRICT_RFC], [Define if ngIRCd should behave strict RFC compliant])
 | 
			
		||||
AH_TEMPLATE([USE_SYSLOG], [Define if syslog should be used for logging])
 | 
			
		||||
AH_TEMPLATE([USE_ZLIB], [Define if zlib compression should be enabled])
 | 
			
		||||
AH_TEMPLATE([USE_TCPWRAP], [Define if TCP wrappers should be used])
 | 
			
		||||
AH_TEMPLATE([IRCPLUS], [Define if IRC+ protocol should be used])
 | 
			
		||||
AH_TEMPLATE([RENDEZVOUS], [Define if Rendezvous support should be included])
 | 
			
		||||
 | 
			
		||||
AH_TEMPLATE([TARGET_OS], [Target operating system name])
 | 
			
		||||
AH_TEMPLATE([TARGET_VENDOR], [Target system vendor])
 | 
			
		||||
@@ -35,7 +39,6 @@ AH_TEMPLATE([TARGET_CPU], [Target CPU name])
 | 
			
		||||
# -- C Compiler --
 | 
			
		||||
 | 
			
		||||
AC_PROG_CC
 | 
			
		||||
AC_LANG_C
 | 
			
		||||
 | 
			
		||||
# -- Hilfsprogramme --
 | 
			
		||||
 | 
			
		||||
@@ -45,19 +48,58 @@ AC_PROG_LN_S
 | 
			
		||||
AC_PROG_MAKE_SET
 | 
			
		||||
AC_PROG_RANLIB
 | 
			
		||||
 | 
			
		||||
# -- Compiler Features --
 | 
			
		||||
 | 
			
		||||
AC_LANG_C
 | 
			
		||||
 | 
			
		||||
AM_C_PROTOTYPES
 | 
			
		||||
AC_C_CONST
 | 
			
		||||
 | 
			
		||||
# -- Defines --
 | 
			
		||||
 | 
			
		||||
os=`uname`
 | 
			
		||||
 | 
			
		||||
if test "$os" = "Linux" -o $os = "GNU"; then
 | 
			
		||||
	# define _POSIX_SOURCE, _GNU_SOURCE and _BSD_SOURCE when compiling
 | 
			
		||||
	# on Linux or Hurd (glibc-based systems):
 | 
			
		||||
	AC_MSG_RESULT([detected ${os}, defining _POSIX_SOURCE, _GNU_SOURCE and _BSD_SOURCE])
 | 
			
		||||
	add_DEFINES="-D_POSIX_SOURCE -D_GNU_SOURCE -D_BSD_SOURCE $add_DEFINES"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test "$os" = "A/UX"; then
 | 
			
		||||
	# define _POSIX_SOURCE when compiling on A/UX:
 | 
			
		||||
	AC_MSG_RESULT([detected A/UX, defining _POSIX_SOURCE])
 | 
			
		||||
	add_DEFINES="-D_POSIX_SOURCE $add_DEFINES"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test "$os" = "HP-UX"; then
 | 
			
		||||
	# define _XOPEN_SOURCE_EXTENDED when compiling on HP-UX (11.11):
 | 
			
		||||
	AC_MSG_RESULT([detected HP-UX, defining _XOPEN_SOURCE_EXTENDED])
 | 
			
		||||
	add_DEFINES="-D_XOPEN_SOURCE_EXTENDED $add_DEFINES"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if test "$os" = "SunOS"; then
 | 
			
		||||
	# define _XOPEN_SOURCE, _XOPEN_SOURCE_EXTENDED=1 and __EXTENSIONS__
 | 
			
		||||
	# when compiling on SunOS (tested with 5.6):
 | 
			
		||||
	AC_MSG_RESULT([detected SunOS, defining _XOPEN_SOURCE, _XOPEN_SOURCE_EXTENDED=1 and __EXTENSIONS__])
 | 
			
		||||
	add_DEFINES="-D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1 -D__EXTENSIONS__ $add_DEFINES"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# -- Header --
 | 
			
		||||
 | 
			
		||||
AC_HEADER_STDC
 | 
			
		||||
 | 
			
		||||
AC_HEADER_TIME
 | 
			
		||||
 | 
			
		||||
AC_CHECK_HEADERS(arpa/inet.h)
 | 
			
		||||
AC_HEADER_SYS_WAIT
 | 
			
		||||
 | 
			
		||||
AC_CHECK_HEADERS([ \
 | 
			
		||||
	errno.h fcntl.h netdb.h netinet/in.h stdlib.h string.h \
 | 
			
		||||
	sys/socket.h sys/time.h sys/wait.h unistd.h \
 | 
			
		||||
	ctype.h errno.h fcntl.h netdb.h netinet/in.h stdlib.h string.h \
 | 
			
		||||
	strings.h sys/socket.h sys/time.h unistd.h \
 | 
			
		||||
	],,AC_MSG_ERROR([required C header missing!]))
 | 
			
		||||
 | 
			
		||||
AC_CHECK_HEADERS([arpa/inet.h ctype.h malloc.h stdint.h varargs.h])
 | 
			
		||||
 | 
			
		||||
# -- Datentypen --
 | 
			
		||||
 | 
			
		||||
AC_MSG_CHECKING(whether socklen_t exists)
 | 
			
		||||
@@ -73,61 +115,129 @@ AC_TRY_COMPILE([
 | 
			
		||||
	AC_MSG_RESULT(no)
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
AC_TYPE_SIGNAL
 | 
			
		||||
 | 
			
		||||
AC_TYPE_SIZE_T
 | 
			
		||||
 | 
			
		||||
# -- Libraries --
 | 
			
		||||
 | 
			
		||||
AC_CHECK_LIB(UTIL,memmove)
 | 
			
		||||
AC_CHECK_LIB(socket,bind)
 | 
			
		||||
AC_CHECK_LIB(nsl,gethostent)
 | 
			
		||||
 | 
			
		||||
# -- Funktionen --
 | 
			
		||||
 | 
			
		||||
AC_FUNC_MALLOC
 | 
			
		||||
 | 
			
		||||
AC_FUNC_FORK
 | 
			
		||||
 | 
			
		||||
AC_FUNC_STRFTIME
 | 
			
		||||
 | 
			
		||||
AC_CHECK_FUNCS([ \
 | 
			
		||||
	bind gethostbyaddr gethostbyname gethostname inet_ntoa memmove \
 | 
			
		||||
	memset select setsockopt socket strcasecmp strchr strerror strftime \
 | 
			
		||||
	strstr vsnprintf waitpid \
 | 
			
		||||
	memset setsockopt socket strcasecmp strchr strerror strstr waitpid \
 | 
			
		||||
	],,AC_MSG_ERROR([required function missing!]))
 | 
			
		||||
 | 
			
		||||
AC_CHECK_FUNCS(inet_aton)
 | 
			
		||||
AC_CHECK_FUNCS(inet_aton isdigit sigaction snprintf vsnprintf strlcpy strlcat)
 | 
			
		||||
 | 
			
		||||
AC_CHECK_FUNCS(sigaction)
 | 
			
		||||
AC_CHECK_FUNCS(select,[AC_CHECK_HEADERS(sys/select.h)],
 | 
			
		||||
	AC_MSG_ERROR([required function select() is missing!])
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# -- Konfigurationsoptionen --
 | 
			
		||||
 | 
			
		||||
AC_ARG_ENABLE(syslog,
 | 
			
		||||
	[  --disable-syslog        disable syslog (autodetected by default)],
 | 
			
		||||
	[	if test "$enableval" = "yes"; then
 | 
			
		||||
			AC_CHECK_HEADER(syslog.h,
 | 
			
		||||
				[	AC_DEFINE(USE_SYSLOG, 1)
 | 
			
		||||
					AC_CHECK_LIB(be,syslog)
 | 
			
		||||
				],
 | 
			
		||||
				AC_MSG_ERROR([Can't enable syslog: syslog.h not found!])
 | 
			
		||||
x_syslog_on=no
 | 
			
		||||
AC_ARG_WITH(syslog,
 | 
			
		||||
	[  --without-syslog        disable syslog (autodetected by default)],
 | 
			
		||||
	[	if test "$withval" = "yes"; then
 | 
			
		||||
			AC_CHECK_LIB(be, syslog)
 | 
			
		||||
			AC_CHECK_FUNCS(syslog, x_syslog_on=yes,
 | 
			
		||||
				AC_MSG_ERROR([Can't enable syslog!])
 | 
			
		||||
			)
 | 
			
		||||
		else
 | 
			
		||||
			AC_MSG_RESULT([disabling syslog])
 | 
			
		||||
		fi
 | 
			
		||||
	],
 | 
			
		||||
	[	AC_CHECK_HEADER(syslog.h,
 | 
			
		||||
			[	AC_DEFINE(USE_SYSLOG, 1)
 | 
			
		||||
				AC_CHECK_LIB(be,syslog)
 | 
			
		||||
			]
 | 
			
		||||
		)
 | 
			
		||||
	[
 | 
			
		||||
		AC_CHECK_LIB(be, syslog)
 | 
			
		||||
		AC_CHECK_FUNCS(syslog, x_syslog_on=yes)
 | 
			
		||||
	]
 | 
			
		||||
)
 | 
			
		||||
if test "$x_syslog_on" = "yes"; then
 | 
			
		||||
	AC_DEFINE(USE_SYSLOG, 1)
 | 
			
		||||
	AC_CHECK_HEADERS(syslog.h)
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
x_zlib_on=no
 | 
			
		||||
AC_ARG_WITH(zlib,
 | 
			
		||||
	[  --without-zlib          disable zlib compression (autodetected by default)],
 | 
			
		||||
	[	if test "$withval" = "yes"; then
 | 
			
		||||
			AC_CHECK_LIB(z, deflate)
 | 
			
		||||
			AC_CHECK_FUNCS(deflate, x_zlib_on=yes,
 | 
			
		||||
				AC_MSG_ERROR([Can't enable zlib!])
 | 
			
		||||
			)
 | 
			
		||||
		fi
 | 
			
		||||
	],
 | 
			
		||||
	[	AC_CHECK_LIB(z, deflate)
 | 
			
		||||
		AC_CHECK_FUNCS(deflate, x_zlib_on=yes)
 | 
			
		||||
	]
 | 
			
		||||
)
 | 
			
		||||
if test "$x_zlib_on" = "yes"; then
 | 
			
		||||
	AC_DEFINE(USE_ZLIB, 1)
 | 
			
		||||
	AC_CHECK_HEADERS(zlib.h)
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
x_tcpwrap_on=no
 | 
			
		||||
AC_ARG_WITH(tcp-wrappers,
 | 
			
		||||
	[  --with-tcp-wrappers     enable TCP wrappers support],
 | 
			
		||||
	[	if test "$withval" = "yes"; then
 | 
			
		||||
			AC_CHECK_LIB(wrap, tcpd_warn)
 | 
			
		||||
			AC_MSG_CHECKING(for hosts_access)
 | 
			
		||||
			AC_TRY_LINK([
 | 
			
		||||
				#include <tcpd.h>
 | 
			
		||||
				],[
 | 
			
		||||
				void *ptr;
 | 
			
		||||
				ptr = hosts_access;
 | 
			
		||||
				],[
 | 
			
		||||
				AC_MSG_RESULT(yes)
 | 
			
		||||
				AC_DEFINE(USE_TCPWRAP, 1)
 | 
			
		||||
				x_tcpwrap_on=yes
 | 
			
		||||
				],[
 | 
			
		||||
				AC_MSG_RESULT(no)
 | 
			
		||||
				AC_MSG_ERROR([Can't enable TCP wrappers!])
 | 
			
		||||
			])
 | 
			
		||||
		fi
 | 
			
		||||
	]
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
AC_ARG_ENABLE(strict-rfc,
 | 
			
		||||
	[  --enable-strict-rfc     strict RFC conformance, may break clients],
 | 
			
		||||
	if test "$enableval" = "yes"; then
 | 
			
		||||
		AC_DEFINE(STRICT_RFC, 1)
 | 
			
		||||
		AC_MSG_RESULT([enabling strict RFC conformance])
 | 
			
		||||
	fi
 | 
			
		||||
x_rendezvous_on=no
 | 
			
		||||
AC_ARG_WITH(rendezvous,
 | 
			
		||||
	[  --with-rendezvous       enable support for "Rendezvous"],
 | 
			
		||||
	[	if test "$withval" = "yes"; then
 | 
			
		||||
			AC_CHECK_FUNCS(DNSServiceRegistrationCreate, x_rendezvous_on=yes,
 | 
			
		||||
				AC_MSG_ERROR([Can't enable Rendezvous!])
 | 
			
		||||
			)
 | 
			
		||||
		fi
 | 
			
		||||
	]
 | 
			
		||||
)
 | 
			
		||||
if test "$x_rendezvous_on" = "yes"; then
 | 
			
		||||
	AC_DEFINE(RENDEZVOUS, 1)
 | 
			
		||||
	AC_CHECK_HEADERS(DNSServiceDiscovery/DNSServiceDiscovery.h mach/port.h)
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
x_ircplus_on=yes
 | 
			
		||||
AC_ARG_ENABLE(ircplus,
 | 
			
		||||
	[  --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)
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
x_sniffer_on=no; x_debug_on=no
 | 
			
		||||
AC_ARG_ENABLE(sniffer,
 | 
			
		||||
	[  --enable-sniffer        enable network traffic monitor (enables debug mode!)],
 | 
			
		||||
	[  --enable-sniffer        enable IRC traffic sniffer (enables debug mode)],
 | 
			
		||||
	if test "$enableval" = "yes"; then
 | 
			
		||||
		AC_DEFINE(SNIFFER, 1)
 | 
			
		||||
		AC_MSG_RESULT([enabling network traffic monitor])
 | 
			
		||||
		x_debug_on=yes
 | 
			
		||||
		x_sniffer_on=yes; x_debug_on=yes
 | 
			
		||||
	fi
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -137,9 +247,17 @@ AC_ARG_ENABLE(debug,
 | 
			
		||||
)
 | 
			
		||||
if test "$x_debug_on" = "yes"; then
 | 
			
		||||
	AC_DEFINE(DEBUG, 1)
 | 
			
		||||
	AC_MSG_RESULT([enabling additional debug output])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
x_strict_rfc_on=no
 | 
			
		||||
AC_ARG_ENABLE(strict-rfc,
 | 
			
		||||
	[  --enable-strict-rfc     strict RFC conformance -- may break clients!],
 | 
			
		||||
	if test "$enableval" = "yes"; then
 | 
			
		||||
		AC_DEFINE(STRICT_RFC, 1)
 | 
			
		||||
		x_strict_rfc_on=yes
 | 
			
		||||
	fi
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# -- Definitionen --
 | 
			
		||||
 | 
			
		||||
AC_DEFINE_UNQUOTED(TARGET_CPU, "$target_cpu" )
 | 
			
		||||
@@ -149,18 +267,44 @@ AC_DEFINE_UNQUOTED(TARGET_OS, "$target_os" )
 | 
			
		||||
# -- Variablen --
 | 
			
		||||
 | 
			
		||||
if test "$GCC" = "yes"; then
 | 
			
		||||
	CFLAGS="-Wall $CFLAGS"
 | 
			
		||||
	the_CFLAGS="-Wmissing-declarations -Wpointer-arith -Wstrict-prototypes"
 | 
			
		||||
	ansi=" -ansi"
 | 
			
		||||
	pedantic=" -pedantic"
 | 
			
		||||
 | 
			
		||||
	$CC --version | grep 20020420 >/dev/null 2>&1
 | 
			
		||||
	if test $? -eq 0; then
 | 
			
		||||
		# Mac OS X (and Darwin?) ship with a slightly broken
 | 
			
		||||
		# prerelease of GCC 3.1 which don't like -pedantic:
 | 
			
		||||
		AC_MSG_RESULT([detected broken GNU C compiler, disabling "-pedantic"])
 | 
			
		||||
		pedantic=""
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	$CC --version | grep 20030304 >/dev/null 2>&1
 | 
			
		||||
	if test $? -eq 0; then
 | 
			
		||||
		# Mac OS X 10.3 (and Darwin 7.0?) have a strange gcc (or
 | 
			
		||||
		# system header files?) which produces lots of errors when
 | 
			
		||||
		# using -ansi; so we don't =:-)
 | 
			
		||||
		AC_MSG_RESULT([detected broken GNU C compiler, disabling "-ansi"])
 | 
			
		||||
		ansi=""
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	uname | grep "CYGWIN" >/dev/null 2>&1
 | 
			
		||||
	if test $? -eq 0; then
 | 
			
		||||
		# The include files of Cygwin don't like -ansi,
 | 
			
		||||
		# so we disable it:
 | 
			
		||||
		AC_MSG_RESULT([detected Cygwin, disabling "-ansi"])
 | 
			
		||||
		ansi=""
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
	add_CFLAGS="-pipe -Wall -W${ansi}${pedantic} $CFLAGS $CFLAGS_ADD"
 | 
			
		||||
else
 | 
			
		||||
	the_CFLAGS="$CFLAGS"
 | 
			
		||||
	add_CFLAGS="$CFLAGS_ADD"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
CFLAGS="$CFLAGS -DSYSCONFDIR='\"\$(sysconfdir)\"'"
 | 
			
		||||
CFLAGS="$the_CFLAGS $add_CFLAGS $add_DEFINES -DSYSCONFDIR='\"\$(sysconfdir)\"'"
 | 
			
		||||
 | 
			
		||||
if test `uname` = "A/UX"; then
 | 
			
		||||
	# unter A/UX sollte _POSIX_SOURCE definiert sein.
 | 
			
		||||
	AC_MSG_RESULT([detected A/UX, defining _POSIX_SOURCE])
 | 
			
		||||
	CFLAGS="$CFLAGS -D_POSIX_SOURCE"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# -- Ausgabe --
 | 
			
		||||
# -- Ausgabe der Dateien --
 | 
			
		||||
 | 
			
		||||
AC_OUTPUT([ \
 | 
			
		||||
	Makefile \
 | 
			
		||||
@@ -169,7 +313,77 @@ AC_OUTPUT([ \
 | 
			
		||||
	MacOSX/ngircd.pbproj/Makefile \
 | 
			
		||||
	src/Makefile \
 | 
			
		||||
	src/portab/Makefile \
 | 
			
		||||
	src/tool/Makefile \
 | 
			
		||||
	src/ngircd/Makefile \
 | 
			
		||||
	src/testsuite/Makefile \
 | 
			
		||||
	man/Makefile \
 | 
			
		||||
	contrib/Makefile \
 | 
			
		||||
	debian/Makefile \
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
# -- Result --
 | 
			
		||||
 | 
			
		||||
echo
 | 
			
		||||
echo "ngIRCd has been configured with the following options:"
 | 
			
		||||
echo
 | 
			
		||||
 | 
			
		||||
# Someone please show me a better way :)  [borrowed by OpenSSH]
 | 
			
		||||
B=`eval echo ${bindir}` ; B=`eval echo ${B}`
 | 
			
		||||
S=`eval echo ${sbindir}` ; S=`eval echo ${S}`
 | 
			
		||||
C=`eval echo ${sysconfdir}` ; C=`eval echo ${C}`
 | 
			
		||||
M=`eval echo ${mandir}` ; M=`eval echo ${M}`
 | 
			
		||||
D=`eval echo ${datadir}/doc/${PACKAGE}` ; D=`eval echo ${D}`
 | 
			
		||||
 | 
			
		||||
echo "               Host: ${host}"
 | 
			
		||||
echo "           Compiler: ${CC}"
 | 
			
		||||
echo "     Compiler flags: ${the_CFLAGS}"
 | 
			
		||||
test -n "$add_CFLAGS"	&& echo "                     ${add_CFLAGS}"
 | 
			
		||||
test -n "$add_DEFINES"	&& echo "                     ${add_DEFINES}"
 | 
			
		||||
test -n "$CPPFLAGS"	&& echo " Preprocessor flags: ${CPPFLAGS}"
 | 
			
		||||
test -n "$LDFLAGS"	&& echo "       Linker flags: ${LDFLAGS}"
 | 
			
		||||
test -n "$LIBS"		&& echo "          Libraries: ${LIBS}"
 | 
			
		||||
echo
 | 
			
		||||
echo "    'ngircd' binary: $S"
 | 
			
		||||
echo " Configuration file: $C"
 | 
			
		||||
echo "       Manual pages: $M"
 | 
			
		||||
echo "      Documentation: $D"
 | 
			
		||||
echo
 | 
			
		||||
 | 
			
		||||
echo $ECHO_N "     Syslog support: $ECHO_C"
 | 
			
		||||
test "$x_syslog_on" = "yes" \
 | 
			
		||||
	&& echo $ECHO_N "yes $ECHO_C" \
 | 
			
		||||
	|| echo $ECHO_N "no  $ECHO_C"
 | 
			
		||||
echo $ECHO_N "  Enable debug code: $ECHO_C"
 | 
			
		||||
test "$x_debug_on" = "yes" \
 | 
			
		||||
	&& echo "yes" \
 | 
			
		||||
	|| echo "no"
 | 
			
		||||
 | 
			
		||||
echo $ECHO_N "   zlib compression: $ECHO_C"
 | 
			
		||||
test "$x_zlib_on" = "yes" \
 | 
			
		||||
	&& echo $ECHO_N "yes $ECHO_C" \
 | 
			
		||||
	|| echo $ECHO_N "no  $ECHO_C"
 | 
			
		||||
echo $ECHO_N "        IRC sniffer: $ECHO_C"
 | 
			
		||||
test "$x_sniffer_on" = "yes" \
 | 
			
		||||
	&& echo "yes" \
 | 
			
		||||
	|| echo "no"
 | 
			
		||||
 | 
			
		||||
echo $ECHO_N "   Use TCP Wrappers: $ECHO_C"
 | 
			
		||||
test "$x_tcpwrap_on" = "yes" \
 | 
			
		||||
	&& echo $ECHO_N "yes $ECHO_C" \
 | 
			
		||||
	|| echo $ECHO_N "no  $ECHO_C"
 | 
			
		||||
echo $ECHO_N "    Strict RFC mode: $ECHO_C"
 | 
			
		||||
test "$x_strict_rfc_on" = "yes" \
 | 
			
		||||
	&& echo "yes" \
 | 
			
		||||
	|| echo "no"
 | 
			
		||||
 | 
			
		||||
echo $ECHO_N " Rendezvous support: $ECHO_C"
 | 
			
		||||
test "$x_rendezvous_on" = "yes"	\
 | 
			
		||||
	&& echo $ECHO_N "yes $ECHO_C" \
 | 
			
		||||
	|| echo $ECHO_N "no  $ECHO_C"
 | 
			
		||||
echo $ECHO_N "      IRC+ protocol: $ECHO_C"
 | 
			
		||||
test "$x_ircplus_on" = "yes" \
 | 
			
		||||
	&& echo "yes" \
 | 
			
		||||
	|| echo "no"
 | 
			
		||||
echo
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								contrib/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								contrib/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
#
 | 
			
		||||
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
# der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
# 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.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile.am,v 1.1 2002/10/01 09:57:08 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = ngircd.spec
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
							
								
								
									
										54
									
								
								contrib/ngircd.spec
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								contrib/ngircd.spec
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
%define name    ngircd
 | 
			
		||||
%define version 0.7.5
 | 
			
		||||
%define release 1
 | 
			
		||||
%define prefix  %{_prefix}
 | 
			
		||||
 | 
			
		||||
Summary:      Next Generation Internet Relay Chat Daemon
 | 
			
		||||
Name:         %{name}
 | 
			
		||||
Version:      %{version}
 | 
			
		||||
Release:      %{release}
 | 
			
		||||
Copyright:    GPL
 | 
			
		||||
Group:        Networking/Daemons
 | 
			
		||||
URL:          http://arthur.ath.cx/~alex/ngircd/
 | 
			
		||||
Source:       %{name}-%{version}.tar.gz
 | 
			
		||||
Packager:     Sean Reifschneider <jafo-rpms@tummy.com>
 | 
			
		||||
BuildRoot:    /var/tmp/%{name}-root
 | 
			
		||||
 | 
			
		||||
%description
 | 
			
		||||
ngIRCd is a free open source daemon for 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.
 | 
			
		||||
 | 
			
		||||
Why should you use ngIRCd? Because ...
 | 
			
		||||
 | 
			
		||||
   * ... there are no problems with servers on changing or non-static IP
 | 
			
		||||
         addresses.
 | 
			
		||||
   * ... there is a small and lean configuration file.
 | 
			
		||||
   * ... there is a free, modern and open source C source code.
 | 
			
		||||
   * ... it is still under active development. 
 | 
			
		||||
 | 
			
		||||
%prep
 | 
			
		||||
%setup
 | 
			
		||||
%build
 | 
			
		||||
%configure
 | 
			
		||||
make
 | 
			
		||||
 | 
			
		||||
%install
 | 
			
		||||
[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"
 | 
			
		||||
%makeinstall
 | 
			
		||||
(
 | 
			
		||||
   cd "$RPM_BUILD_ROOT"
 | 
			
		||||
   ( cd usr/sbin; mv *-ngircd ngircd )
 | 
			
		||||
   ( cd usr/share/man/man5; mv *-ngircd.conf.5 ngircd.conf.5 )
 | 
			
		||||
   ( cd usr/share/man/man8; mv *-ngircd.8 ngircd.8 )
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
%clean
 | 
			
		||||
[ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != / ] && rm -rf "$RPM_BUILD_ROOT"
 | 
			
		||||
 | 
			
		||||
%files
 | 
			
		||||
%defattr(755,root,root)
 | 
			
		||||
%doc AUTHORS  COPYING  ChangeLog  INSTALL NEWS  README
 | 
			
		||||
%config(noreplace) /etc
 | 
			
		||||
%{_prefix}/sbin
 | 
			
		||||
%{_prefix}/share/man/
 | 
			
		||||
							
								
								
									
										19
									
								
								debian/Makefile.am
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								debian/Makefile.am
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
 | 
			
		||||
#
 | 
			
		||||
# This program is free software; you can redistribute it and/or modify
 | 
			
		||||
# it under the terms of the GNU General Public License as published by
 | 
			
		||||
# the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
# (at your option) any later version.
 | 
			
		||||
# Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile.am,v 1.1.2.1 2003/07/09 21:08:55 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = changelog compat control copyright ngircd.init rules
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
							
								
								
									
										59
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
ngircd (0.7.5-0.1ab) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New upstream version.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@Arthur.Ath.CX>  Fri,  7 Nov 2003 21:59:58 +0100
 | 
			
		||||
 | 
			
		||||
ngircd (0.7.1-0.1ab) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * New upstream version :-)
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@Arthur.Ath.CX>  Fri, 18 Jul 2003 22:53:02 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (0.7.0-0.7ab) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Fixed up post installation script (added interpreter, fixed chmod call).
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@Arthur.Ath.CX>  Sun, 13 Jul 2003 00:52:38 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (0.7.0-0.6ab) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Added /etc/default/ngircd.
 | 
			
		||||
  * Included own post installation script.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@Arthur.Ath.CX>  Sat, 12 Jul 2003 20:31:09 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (0.7.0-0.5ab) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Enhanced init script.
 | 
			
		||||
  * Included NJOIN fix from actual CVS "HEAD" branch.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@Arthur.Ath.CX>  Wed,  9 Jul 2003 22:40:49 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (0.7.0-0.4ab) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Reverted use of dh_installexamples.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@Arthur.Ath.CX>  Thu, 22 May 2003 00:15:03 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (0.7.0-0.3ab) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Removed "debian/docs" and "debian/conffiles"; debhelper takes care of
 | 
			
		||||
    this for us automagically.
 | 
			
		||||
  * Excluded "etc/ngircd.conf" from dh_fixperms.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@Arthur.Ath.CX>  Wed, 21 May 2003 23:25:05 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (0.7.0-0.2ab) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Fixed wrong variable substitution in init script.
 | 
			
		||||
  * Added some CVS "Id-Tags" (but not checked in, yet).
 | 
			
		||||
  * Removed own "Provides:" from control file.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Wed, 21 May 2003 12:32:34 +0200
 | 
			
		||||
 | 
			
		||||
ngircd (0.7.0-0.1ab) unstable; urgency=low
 | 
			
		||||
 | 
			
		||||
  * Initial Release.
 | 
			
		||||
 | 
			
		||||
 -- Alexander Barton <alex@barton.de>  Wed, 21 May 2003 02:36:52 +0200
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/compat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/compat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
4
 | 
			
		||||
							
								
								
									
										23
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
Source: ngircd
 | 
			
		||||
Section: net
 | 
			
		||||
Priority: optional
 | 
			
		||||
Maintainer: Alexander Barton <alex@barton.de>
 | 
			
		||||
Build-Depends: debhelper (>> 4.0.0), libz-dev
 | 
			
		||||
Standards-Version: 3.5.8
 | 
			
		||||
 | 
			
		||||
Package: ngircd
 | 
			
		||||
Architecture: any
 | 
			
		||||
Depends: ${shlibs:Depends} ${misc:Depends}
 | 
			
		||||
Description: A lightweight daemon for the Internet Relay Chat (IRC)
 | 
			
		||||
 The ngIRCd is a free open source daemon for 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.
 | 
			
		||||
 .
 | 
			
		||||
 Advantages:
 | 
			
		||||
  - no problems with servers on changing or non-static IP addresses.
 | 
			
		||||
  - small and lean configuration file.
 | 
			
		||||
  - free, modern and open source C source code.
 | 
			
		||||
  - still under active development.
 | 
			
		||||
 .
 | 
			
		||||
 ngIRCd is compatible to the "original" ircd 2.10.3p3, so you can run
 | 
			
		||||
 mixed networks.
 | 
			
		||||
							
								
								
									
										13
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
This package was debianized by Alexander Barton <alex@barton.de> on
 | 
			
		||||
Tue, 20 May 2003 15:47:40 +0200.
 | 
			
		||||
 | 
			
		||||
It was downloaded from ftp://Arthur.Ath.CX/pub/Users/alex/ngircd/
 | 
			
		||||
 | 
			
		||||
Upstream Author(s): Alexander Barton <alex@barton.de>
 | 
			
		||||
 | 
			
		||||
This software is copyright (c) 1999-2003 by Alexander Barton.
 | 
			
		||||
 | 
			
		||||
You are free to distribute this software under the terms of the
 | 
			
		||||
GNU General Public License.
 | 
			
		||||
On Debian systems, the complete text of the GNU General Public
 | 
			
		||||
License can be found in /usr/share/common-licenses/GPL file.
 | 
			
		||||
							
								
								
									
										12
									
								
								debian/ngircd.default
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								debian/ngircd.default
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
#
 | 
			
		||||
# Defaults for ngIRCd start and stop script
 | 
			
		||||
#
 | 
			
		||||
# $Id: ngircd.default,v 1.1.2.1 2003/07/12 18:23:24 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# Parameters to pass to the ngircd daemon on startup, see ngircd(8) for
 | 
			
		||||
# possible options (default: empty).
 | 
			
		||||
 | 
			
		||||
PARAMS=""
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
							
								
								
									
										71
									
								
								debian/ngircd.init
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								debian/ngircd.init
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd start and stop script for Debian-based systems
 | 
			
		||||
#
 | 
			
		||||
# $Id: ngircd.init,v 1.1.2.1 2003/07/09 21:12:00 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
 | 
			
		||||
DAEMON=/usr/sbin/ngircd
 | 
			
		||||
NAME=ngIRCd
 | 
			
		||||
DESC="IRC daemon"
 | 
			
		||||
PARAMS=""
 | 
			
		||||
 | 
			
		||||
test -x $DAEMON || exit 0
 | 
			
		||||
 | 
			
		||||
test -f /etc/default/ngircd && . /etc/default/ngircd
 | 
			
		||||
 | 
			
		||||
Check_Config()
 | 
			
		||||
{
 | 
			
		||||
	$DAEMON --configtest >/dev/null 2>&1
 | 
			
		||||
	if [ $? -ne 0 ]; then
 | 
			
		||||
		echo "Configuration of $NAME is not valide, won't (re)start!"
 | 
			
		||||
		echo "Please run \"$DAEMON --configtest\" manually and fix it up ..."
 | 
			
		||||
		exit 1
 | 
			
		||||
	fi
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Try_Start()
 | 
			
		||||
{
 | 
			
		||||
	start-stop-daemon --start --quiet --exec $DAEMON -- $PARAMS
 | 
			
		||||
	if [ $? -ne 0 ]; then
 | 
			
		||||
		echo "$NAME failed!"
 | 
			
		||||
		exit 1
 | 
			
		||||
	fi
 | 
			
		||||
	echo "$NAME."
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
case "$1" in
 | 
			
		||||
  start)
 | 
			
		||||
	Check_Config
 | 
			
		||||
	echo -n "Starting $DESC: "
 | 
			
		||||
	Try_Start
 | 
			
		||||
	;;
 | 
			
		||||
  stop)
 | 
			
		||||
	echo -n "Stopping $DESC: "
 | 
			
		||||
	start-stop-daemon --stop --quiet --exec $DAEMON \
 | 
			
		||||
	  && echo "$NAME." \
 | 
			
		||||
	  || echo "(none running)"
 | 
			
		||||
	;;
 | 
			
		||||
  reload|force-reload)
 | 
			
		||||
	Check_Config
 | 
			
		||||
	echo "Reloading $DESC configuration files."
 | 
			
		||||
	start-stop-daemon --stop --signal 1 --quiet --exec $DAEMON
 | 
			
		||||
	;;
 | 
			
		||||
  restart)
 | 
			
		||||
	Check_Config
 | 
			
		||||
	echo -n "Restarting $DESC: "
 | 
			
		||||
	start-stop-daemon --stop --quiet --oknodo --exec $DAEMON
 | 
			
		||||
	sleep 1
 | 
			
		||||
	Try_Start
 | 
			
		||||
	;;
 | 
			
		||||
  *)
 | 
			
		||||
	N=/etc/init.d/$NAME
 | 
			
		||||
	echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
 | 
			
		||||
	exit 1
 | 
			
		||||
	;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
exit 0
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
							
								
								
									
										22
									
								
								debian/ngircd.postinst
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								debian/ngircd.postinst
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
#
 | 
			
		||||
# Debian post-installation script
 | 
			
		||||
# $Id: ngircd.postinst,v 1.1.2.3 2003/07/12 22:57:00 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
if [ -f /etc/ngircd/ngircd.conf ]; then
 | 
			
		||||
	# make sure that configuration file is not world readable
 | 
			
		||||
	chmod o= /etc/ngircd/ngircd.conf
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [ -x "/etc/init.d/ngircd" ]; then
 | 
			
		||||
	# setup init scripts and startup ngircd
 | 
			
		||||
	update-rc.d ngircd defaults >/dev/null
 | 
			
		||||
	if [ -x /usr/sbin/invoke-rc.d ]; then
 | 
			
		||||
		invoke-rc.d ngircd start
 | 
			
		||||
	else
 | 
			
		||||
		/etc/init.d/ngircd start
 | 
			
		||||
	fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
							
								
								
									
										94
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
#!/usr/bin/make -f
 | 
			
		||||
# debian/rules for ngIRCd
 | 
			
		||||
#
 | 
			
		||||
# $Id: rules,v 1.1.2.1 2003/07/09 21:12:00 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
# Based on the sample debian/rules that uses debhelper,
 | 
			
		||||
# GNU copyright 1997 to 1999 by Joey Hess.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# Uncomment this to turn on verbose mode.
 | 
			
		||||
#export DH_VERBOSE=1
 | 
			
		||||
 | 
			
		||||
# These are used for cross-compiling and for saving the configure script
 | 
			
		||||
# from having to guess our platform (since we know it already)
 | 
			
		||||
DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
 | 
			
		||||
DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
 | 
			
		||||
 | 
			
		||||
CFLAGS = -Wall -g
 | 
			
		||||
 | 
			
		||||
ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
 | 
			
		||||
	CFLAGS += -O0
 | 
			
		||||
else
 | 
			
		||||
	CFLAGS += -O2
 | 
			
		||||
endif
 | 
			
		||||
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
 | 
			
		||||
	INSTALL_PROGRAM += -s
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
config.status: configure
 | 
			
		||||
	dh_testdir
 | 
			
		||||
	# Add here commands to configure the package.
 | 
			
		||||
	./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) \
 | 
			
		||||
	  --prefix=/usr --sysconfdir=/etc/ngircd --mandir=\$${prefix}/share/man \
 | 
			
		||||
	  --with-syslog --with-zlib
 | 
			
		||||
 | 
			
		||||
build: build-stamp
 | 
			
		||||
 | 
			
		||||
build-stamp:  config.status
 | 
			
		||||
	dh_testdir
 | 
			
		||||
 | 
			
		||||
	# Add here commands to compile the package.
 | 
			
		||||
	$(MAKE)
 | 
			
		||||
 | 
			
		||||
	touch build-stamp
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	dh_testdir
 | 
			
		||||
	dh_testroot
 | 
			
		||||
	rm -f build-stamp 
 | 
			
		||||
 | 
			
		||||
	# Add here commands to clean up after the build process.
 | 
			
		||||
	-$(MAKE) distclean
 | 
			
		||||
ifneq "$(wildcard /usr/share/misc/config.sub)" ""
 | 
			
		||||
	cp -f /usr/share/misc/config.sub config.sub
 | 
			
		||||
endif
 | 
			
		||||
ifneq "$(wildcard /usr/share/misc/config.guess)" ""
 | 
			
		||||
	cp -f /usr/share/misc/config.guess config.guess
 | 
			
		||||
endif
 | 
			
		||||
	dh_clean
 | 
			
		||||
 | 
			
		||||
install: build
 | 
			
		||||
	dh_testdir
 | 
			
		||||
	dh_testroot
 | 
			
		||||
	dh_clean -k
 | 
			
		||||
	dh_installdirs
 | 
			
		||||
 | 
			
		||||
	# Add here commands to install the package into debian/ngircd.
 | 
			
		||||
	$(MAKE) install DESTDIR=$(CURDIR)/debian/ngircd
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Build architecture-independent files here.
 | 
			
		||||
binary-indep: build install
 | 
			
		||||
# We have nothing to do by default.
 | 
			
		||||
 | 
			
		||||
# Build architecture-dependent files here.
 | 
			
		||||
binary-arch: build install
 | 
			
		||||
	dh_testdir
 | 
			
		||||
	dh_testroot
 | 
			
		||||
	dh_installchangelogs ChangeLog
 | 
			
		||||
	dh_installdocs
 | 
			
		||||
	dh_installinit
 | 
			
		||||
	dh_strip
 | 
			
		||||
	dh_compress
 | 
			
		||||
	dh_fixperms -Xetc/ngircd.conf
 | 
			
		||||
	dh_installdeb
 | 
			
		||||
	dh_shlibdeps
 | 
			
		||||
	dh_gencontrol
 | 
			
		||||
	dh_md5sums
 | 
			
		||||
	dh_builddeb
 | 
			
		||||
 | 
			
		||||
binary: binary-indep binary-arch
 | 
			
		||||
.PHONY: build clean binary-indep binary-arch binary install 
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
@@ -1,27 +0,0 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001,2002 by Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
                  ngIRCd ist freie Software und steht unter
 | 
			
		||||
                       der GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                             -- CC-Speed.txt --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ngIRCd-0.2.1-pre (2002-02-25):
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
[nach make-Zeiten sortiert]
 | 
			
		||||
 | 
			
		||||
Intel PIII, 1 GHz, 256 MB Ram, FreeBSD 4.4:         configure: 00:10, make: 00:05
 | 
			
		||||
Intel PIII, 1 GHz, 256 MB Ram, Linux 2.4.10:        configure: 00:06, make: 00:06
 | 
			
		||||
Intel PIII, 1 GHz, 256 MB Ram, BeOS R5:             configure: 00:19, make: 00:07
 | 
			
		||||
Intel PIII, 1 GHz, 256 MB Ram, Win2k+CygWin:        configure: 00:27, make: 00:08
 | 
			
		||||
AMD K6/2, 400 Mhz, 256 MB Ram, Linux 2.4.12:        configure: 00:14, make: 00:12
 | 
			
		||||
PowerMac G4, 400 Mhz, 768 MB Ram, Mac OS X 10.1.2:  configure: 00:32, make: 00:19
 | 
			
		||||
Macintosh SE/30, 68030 16 MHz, 32 MB, A/UX 3.0.1:   configure: 07:33, make: 12:02
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: CC-Speed.txt,v 1.1 2002/02/25 14:02:32 alex Exp $
 | 
			
		||||
							
								
								
									
										64
									
								
								doc/CVS.txt
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								doc/CVS.txt
									
									
									
									
									
								
							@@ -1,64 +1,56 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001,2002 by Alexander Barton,
 | 
			
		||||
                      (c)2001-2003 by Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
                  ngIRCd ist freie Software und steht unter
 | 
			
		||||
                       der GNU General Public License.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                                 -- CVS.txt --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Die Sourcen des ngIRCd werden mit dem "Concurrent Versions System" (CVS)
 | 
			
		||||
verwaltet. Somit koennen ohne Probleme mehrere Leute gleichzeitig die Sourcen
 | 
			
		||||
bearbeitet.
 | 
			
		||||
The source code of ngIRCd is maintained using the "Concurrent Versions
 | 
			
		||||
System" (CVS). Thereby several developers can work with the source tree at
 | 
			
		||||
the same time.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
I. Anonymer "Nur-Lesen"-Zugang
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
Anonymer Zugriff auf die CVS-Repository von ngIRCd ist im "nur-lesen"-Modus
 | 
			
		||||
moeglich. Dazu sind folgende Schritte noetig:
 | 
			
		||||
I. Anonymous read-only Access
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
To access the source tree anonymously in read-only mode, follow these steps:
 | 
			
		||||
 | 
			
		||||
Beim CVS-Server anmelden
 | 
			
		||||
Login to the CVS server:
 | 
			
		||||
 | 
			
		||||
 $ cvs -d:pserver:anonymous@arthur.ath.cx:/usr/local/CVS/ngircd login
 | 
			
		||||
 | 
			
		||||
Als Benutzername wird "anonymous" mit einem leeren Passwort verwendet.
 | 
			
		||||
Nun ein "Check-Out" der Quellcodes durchfuehren:
 | 
			
		||||
Use "anonymous" as user name and no password (just hit Return). Now you can
 | 
			
		||||
check out the sources:
 | 
			
		||||
 | 
			
		||||
 $ cvs -d:pserver:anonymous@arthur.ath.cx:/usr/local/CVS/ngircd checkout ngircd
 | 
			
		||||
 | 
			
		||||
Dadurch wird im aktuellen Verzeichnis der neue Ordner "ngircd" mit allen
 | 
			
		||||
Quell-Dateien des ngIRCd erzeugt.
 | 
			
		||||
Thereby a new folder "ngircd" will be created containing all the individual
 | 
			
		||||
source files.
 | 
			
		||||
 | 
			
		||||
Dieses ist der "Arbeitsordner", alle CVS-Befehle werden in Zukunft aus
 | 
			
		||||
diesem Ordner bzw. einem Unterordner davon ausgefuehrt.
 | 
			
		||||
This is the "working folder", all CVS commands will be executed from within
 | 
			
		||||
this folder in the future.
 | 
			
		||||
 | 
			
		||||
Wichtig: wenn ngIRCd "frisch" aus dem CVS compiliert werden soll, so
 | 
			
		||||
existiert das configure-Script noch nicht. Dieses muss zunaechst mit dem
 | 
			
		||||
Script "autogen.sh" erzeugt werden. Letzteres setzt ein installiertes GNU
 | 
			
		||||
automake und GNU autoconf voraus!
 | 
			
		||||
Please note: When checking out a fresh copy of ngIRCd from CVS, 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.
 | 
			
		||||
 | 
			
		||||
CVS-Tree aktualisieren:
 | 
			
		||||
Updating the CVS tree:
 | 
			
		||||
 | 
			
		||||
 $ cvs update
 | 
			
		||||
 $ cvs update -d -P [<filename>]
 | 
			
		||||
 | 
			
		||||
Dieser Befehl aktualisiert alle Dateien im aktuellen Verzeichnis sowie allen
 | 
			
		||||
Unterverzeichnissen.
 | 
			
		||||
 | 
			
		||||
 $ cvs update <filename>
 | 
			
		||||
 | 
			
		||||
So kann eine einzelne Datei aktualisiert werden (auch dann, wenn sie lokal
 | 
			
		||||
z.B. geloescht wurde -- praktisch, um eigene "Experimente" rueckgaengig zu
 | 
			
		||||
machen ;-))
 | 
			
		||||
You can update a single file or the complete source tree.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
III. Schreibzugriff
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
Wer Schreibzugriff auf die CVS-Repository wuenscht, der moege sich bitte
 | 
			
		||||
mit Alex Barton, <alex@barton.de> in Verbindung setzen.
 | 
			
		||||
III. Write Access
 | 
			
		||||
~~~~~~~~~~~~~~~~~
 | 
			
		||||
If you want to contribute a couple of patches and write access to the CVS
 | 
			
		||||
repository would be handy, please contact Alex Barton, <alex@barton.de>.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: CVS.txt,v 1.5 2002/02/15 15:15:22 alex Exp $
 | 
			
		||||
$Id: CVS.txt,v 1.7 2003/03/26 22:34:33 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										82
									
								
								doc/FAQ.txt
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								doc/FAQ.txt
									
									
									
									
									
								
							@@ -1,61 +1,67 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001,2002 by Alexander Barton,
 | 
			
		||||
                      (c)2001-2003 by Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
                  ngIRCd ist freie Software und steht unter
 | 
			
		||||
                       der GNU General Public License.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                    -- FAQ: Frequently Asked Questions --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
I. Allgemein
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
Q: Kann der ngIRCd im Netz zusammen mit "normalen" Servern betrieben werden?
 | 
			
		||||
A: Ja. ngIRCd ist zum Original kompatibel, getestet wird dies zur Zeit mit
 | 
			
		||||
   der Version 2.10.3p3 des ircd.
 | 
			
		||||
I. General
 | 
			
		||||
~~~~~~~~~~
 | 
			
		||||
Q: Is it possible to link the ngIRCd with non-ngIRCd servers?
 | 
			
		||||
A: Yes. ngIRCd is compatible to the original ircd used by IRCNet. Actually
 | 
			
		||||
   this is being tested with version 2.10.3p3.
 | 
			
		||||
 | 
			
		||||
Q: Gibt es eine Homepage mit Informationen und Downloads?
 | 
			
		||||
A: Ja. Die URL ist <http://arthur.ath.cx/~alex/ngircd/>.
 | 
			
		||||
Q: Is there a homepage with further information and downloads?
 | 
			
		||||
A: Yes. Please visit <http://arthur.ath.cx/~alex/ngircd/>.
 | 
			
		||||
 | 
			
		||||
Q: Why should I use ngIRCd instead of the original one?
 | 
			
		||||
A: ngIRCd offers several benefits: no problems with dynamic IPs, easy to
 | 
			
		||||
   configure, open source (GPL), under active development.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
II. Compilieren
 | 
			
		||||
II. Compilation
 | 
			
		||||
~~~~~~~~~~~~~~~
 | 
			
		||||
Q: Ich habe die Sourcen von ngIRCd ueber CVS installiert. Nun kann ich
 | 
			
		||||
   ./configure nicht ausfuehren, da es nicht existiert!?
 | 
			
		||||
A: Bei Builds direkt aus dem CVS-Tree muss das configure-Script zunaechst
 | 
			
		||||
   durch GNU autoconf sowie die Makefile.in's durch GNU automake generiert
 | 
			
		||||
   werden. Um dies zu vereinfachen existiert das Script "./autogen.sh".
 | 
			
		||||
   GNU automake und GNU autoconf werden -- im Gegensatz zu Builds aus den
 | 
			
		||||
   Sourcen eines .tar.gz-Archivs -- hierbei benoetigt!
 | 
			
		||||
Q: I did a "CVS checkout" but can't execute ./configure because the script
 | 
			
		||||
   is missing in the generated directory!?
 | 
			
		||||
A: When using development versions via CVS, the configure script as well as
 | 
			
		||||
   the Makefile.in templates must be generated using GNU automake and GNU
 | 
			
		||||
   autoconf. To simplify this task run the ./autogen.sh script which will
 | 
			
		||||
   execute the required tools for you; then continue with executing the
 | 
			
		||||
   ./configure script as usual.
 | 
			
		||||
 | 
			
		||||
Q: ./autogen.sh bricht mit der Meldung "autoheader: command not found" ab.
 | 
			
		||||
A: GNU autoconf ist nicht installiert, wird jedoch bei Builds direkt aus
 | 
			
		||||
   dem CVS-Tree benoetigt.
 | 
			
		||||
Q: The ./autogen.sh script complains "aclocal: command not found".
 | 
			
		||||
A: GNU automake is missing on your system but required for building CVS
 | 
			
		||||
   versions of ngIRCd. Install GNU automake 1.6 or later and try again.
 | 
			
		||||
 | 
			
		||||
Q: ./autogen.sh bricht mit der Meldung "autoconf: Undefined macros:
 | 
			
		||||
   AC_FUNC_MALLOC" bzw. "AC_CONFIG_SRCDIR" ab.
 | 
			
		||||
A: Auf dem System ist eine zu alte Version von GNU autoconf installiert.
 | 
			
		||||
   Ein Update auf z.B. Version 2.52 loest dieses Problem (eine installiete
 | 
			
		||||
   alte Version sollte ggf. zunaechst entfernt werden, bei RPM-Paketen z.B.
 | 
			
		||||
   mit dem Befehl "rpm -e autoconf").
 | 
			
		||||
Q: The ./autogen.sh script stops with "autoheader: command not found".
 | 
			
		||||
A: GNU autoconf is missing on your system but required for building CVS
 | 
			
		||||
   versions of ngIRCd. Install GNU autoconf 2.52 or later and try again.
 | 
			
		||||
 | 
			
		||||
Q: The ./autogen.sh script fails and the message "automake: configure.in:
 | 
			
		||||
   AM_INIT_AUTOMAKE must be used" is displayed.
 | 
			
		||||
A: Most probably you are using version 1.5 of GNU automake which seems to be
 | 
			
		||||
   incompatible to the build system of ngIRCd. Solution: upgrade to at least
 | 
			
		||||
   version 1.6 of GNU automake.
 | 
			
		||||
   (If you are using Debian 3.0 "Woody" you can try to downgrade to version
 | 
			
		||||
   1.4 of GNU automake shipped with this distribution; it should work, too.)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
III. Bugs!?
 | 
			
		||||
~~~~~~~~~~~
 | 
			
		||||
Q: Gibt es eine Liste der bekannten Bugs bzw. Feature-Wuensche?
 | 
			
		||||
A: Ja. Es existiert ein Bug-Tracking-System fuer den ngIRCd (Bugzilla):
 | 
			
		||||
   URL: <http://arthur.ath.cx/bugzilla/ngircd/>. Dort koennen Bugs ge-
 | 
			
		||||
   meldet und Feature-Wunsche kundgetan werden. Bekannte Bugs koennen in
 | 
			
		||||
   der Datenbank gesucht und aufgelistet werden.
 | 
			
		||||
   Einen Account zum Suchen und Melden von Bugs bzw. Feature-Wuenschen
 | 
			
		||||
   kannst du dir dort selber anlegen.
 | 
			
		||||
Q: Is there a list of known bugs and desired feature enhancements?
 | 
			
		||||
A: Yes. Have a look at the bug tracking system (Bugzilla) for ngIRCd located
 | 
			
		||||
   at <http://arthur.ath.cx/bugzilla/ngircd/>. There you can file bug reports
 | 
			
		||||
   and feature requests as well as search the bug database.
 | 
			
		||||
 | 
			
		||||
Q: Was mache ich, wenn ich einen Bug gefunden habe?
 | 
			
		||||
A: Am besten traegst du ihn in das Bug-Tracking-System des ngIRCd ein:
 | 
			
		||||
   URL: <http://arthur.ath.cx/bugzilla/ngircd/>
 | 
			
		||||
Q: What should I do if I found a bug?
 | 
			
		||||
A: Please file a bug report at <http://arthur.ath.cx/bugzilla/ngircd/>!
 | 
			
		||||
   The author of the particular component will be notified automagically :-)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: FAQ.txt,v 1.2 2002/02/19 20:05:02 alex Exp $
 | 
			
		||||
$Id: FAQ.txt,v 1.5.2.1 2003/04/29 13:45:09 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
# Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
 | 
			
		||||
#
 | 
			
		||||
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
# der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
@@ -9,19 +9,31 @@
 | 
			
		||||
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
 | 
			
		||||
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile.am,v 1.7 2002/03/30 15:33:14 alex Exp $
 | 
			
		||||
# $Id: Makefile.am,v 1.16.2.1 2003/04/22 23:52:48 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = CC-Speed.txt CVS.txt FAQ.txt README-AUX.txt README-BeOS.txt \
 | 
			
		||||
	RFC.txt sample-ngircd.conf
 | 
			
		||||
EXTRA_DIST = CVS.txt FAQ.txt Protocol.txt Platforms.txt \
 | 
			
		||||
	README-AUX.txt README-BeOS.txt RFC.txt sample-ngircd.conf
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in
 | 
			
		||||
 | 
			
		||||
docdir = $(datadir)/doc/$(PACKAGE)
 | 
			
		||||
 | 
			
		||||
documents = $(EXTRA_DIST) ../AUTHORS ../COPYING ../ChangeLog ../INSTALL \
 | 
			
		||||
	../NEWS ../README
 | 
			
		||||
 | 
			
		||||
install-data-hook:
 | 
			
		||||
	$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
 | 
			
		||||
	if [ ! -f $(DESTDIR)$(sysconfdir)/ngircd.conf ]; then \
 | 
			
		||||
	  $(INSTALL) -m 600 -c $(srcdir)/sample-ngircd.conf $(DESTDIR)$(sysconfdir)/ngircd.conf; \
 | 
			
		||||
	  fi
 | 
			
		||||
	 fi
 | 
			
		||||
	$(mkinstalldirs) $(DESTDIR)$(docdir)
 | 
			
		||||
	for f in $(documents); do \
 | 
			
		||||
	  $(INSTALL) -m 644 -c $(srcdir)/$$f $(DESTDIR)$(docdir)/; \
 | 
			
		||||
	 done
 | 
			
		||||
 | 
			
		||||
uninstall-hook:
 | 
			
		||||
	rm -rf $(DESTDIR)$(docdir)
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										56
									
								
								doc/Platforms.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								doc/Platforms.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001-2003 by Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                              -- Platforms.txt --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
This file lists the status of all platforms on which the ngIRCd has been
 | 
			
		||||
tested. Included is the date and version of the last "official" test and
 | 
			
		||||
the name of the tester/maintainer.
 | 
			
		||||
 | 
			
		||||
If you successfully compiled and tested ngIRCd on a platform that isn't
 | 
			
		||||
listed here, please contact Alexander Barton, <alex@barton.de>, so that this
 | 
			
		||||
list can be updated. Thanks for your help!
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                              the executable works ("runs") as expected --+
 | 
			
		||||
                                tests run successfully ("make check") --+ |
 | 
			
		||||
                                           ngIRCd compiles ("make") --+ | |
 | 
			
		||||
                                                ./configure works --+ | | |
 | 
			
		||||
                                                                    | | | |
 | 
			
		||||
Platform                    Compiler     ngIRCd     Date     Tester C M T R See
 | 
			
		||||
--------------------------- ------------ ---------- -------- ------ - - - - ---
 | 
			
		||||
i386/pc/solaris2.9          gcc 3.2.2    0.7.x-CVS  03-04-28 alex   Y Y Y Y
 | 
			
		||||
i386/unknown/freebsd5.0     gcc 3.2.1    0.7.0      03-05-15 alex   Y Y Y Y
 | 
			
		||||
i386/unknown/gnu0.3         gcc 3.2.3    CVSHEAD    03-05-05 alex   Y Y n Y
 | 
			
		||||
i386/unknown/netbsdelf1.6.1 gcc 2.95.3   0.7.x-CVS  03-04-23 alex   Y Y Y Y
 | 
			
		||||
i686/pc/cygwin              gcc 3.2      0.7.x-CVS  03-04-24 alex   Y Y n Y
 | 
			
		||||
i686/pc/linux-gnu           gcc 2.95/3.x 0.7.0      03-05-15 alex   Y Y Y Y (1)
 | 
			
		||||
m68k/apple/aux3.1.1         Orig. A/UX   0.7.x-CVS  03-04-22 alex   Y Y Y Y (2)
 | 
			
		||||
m68k/hp/hp-ux9.10           Orig. HPUX   0.7.x-CVS  03-04-30 goetz  Y Y Y Y
 | 
			
		||||
powerpc/apple/darwin6.5     gcc 3.1      0.7.x-CVS  03-04-23 alex   Y Y Y Y
 | 
			
		||||
sparc/sun/solaris2.6        gcc 2.95.3   0.7.x-CVS  03-04-22 alex   Y Y Y Y
 | 
			
		||||
sparc/sun/solaris2.7        gcc 3.3      CVSHEAD    03-07-06 alex   Y Y Y Y
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Notes
 | 
			
		||||
~~~~~
 | 
			
		||||
(1) i686/pc/linux-gnu:
 | 
			
		||||
    ngIRCd has been tested with various Linux distributions, such as SuSE,
 | 
			
		||||
    RedHat, Debian, and Gentoo using Kernels 2.2.x or 2.4.x and various
 | 
			
		||||
    versions of the GNU C compiler (2.95.3, 3.0, 3.2 and 3.3). The eldest
 | 
			
		||||
    glibc used was glibc-2.0.7. ngIRCd compiled and run on all these systems
 | 
			
		||||
    without problems.
 | 
			
		||||
 | 
			
		||||
(2) This compiler is an pre-ANSI C compiler, therefore the source code is
 | 
			
		||||
    automatically converted using the included ansi2knr tool while building.
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: Platforms.txt,v 1.1.2.5 2003/07/18 20:48:20 alex Exp $
 | 
			
		||||
							
								
								
									
										107
									
								
								doc/Protocol.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								doc/Protocol.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001-2003 by Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                              -- Protocol.txt --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
I. Compatibility
 | 
			
		||||
~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
The ngIRCd implements the Internet Relay Chat (IRC) protocol version 2.10
 | 
			
		||||
as defined in RFC ("request for comment") 1459 and 2810-2813. These (and
 | 
			
		||||
probably further relevant RFCs) are listed in doc/RFC.txt.
 | 
			
		||||
 | 
			
		||||
Unfortunately, even the "original" ircd doesn't follow these specifications
 | 
			
		||||
in all details. But because the ngIRCd should be a fully compatible
 | 
			
		||||
replacement for this server ("ircd") it tries to emulate these differences.
 | 
			
		||||
 | 
			
		||||
If you don't like this behavior please ./configure the ngIRCd using the
 | 
			
		||||
"--enable-strict-rfc" command line option. But please note: not all IRC
 | 
			
		||||
clients are compatible with such an server, some can't even connect at all!
 | 
			
		||||
Therefore this option isn't desired for "normal operation".
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
II. The IRC+ Protocol
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Starting with version 0.5.0, the ngIRCd extends the original IRC protocol
 | 
			
		||||
as defined in RFC 2810-2813. This enhanced protocol is named "IRC+". It is
 | 
			
		||||
backwards compatible to the "plain" IRC protocol and will only be used by
 | 
			
		||||
the ngIRCd if it detects that the peer supports it as well.
 | 
			
		||||
 | 
			
		||||
The "PASSV" command is used to detect the protocol and peer versions (see
 | 
			
		||||
RFC 2813, section 4.1.1).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
II.1 Register new server link
 | 
			
		||||
 | 
			
		||||
     Command: PASS
 | 
			
		||||
  Parameters: <password> <version> <flags> [<options>]
 | 
			
		||||
     Used by: servers only (with these parameters)
 | 
			
		||||
 | 
			
		||||
<password> is the password for this new server link as defined in the server
 | 
			
		||||
configuration which is sent to the peer or received from it.
 | 
			
		||||
 | 
			
		||||
<version> consists of two parts and is at least 4, at most 14 characters
 | 
			
		||||
long: the first four bytes contain the IRC protocol version number, whereas
 | 
			
		||||
the first two bytes represent the major version, the last two bytes the
 | 
			
		||||
minor version (the string "0210" indicates version 2.10, e.g.).
 | 
			
		||||
 | 
			
		||||
The following optional(!) 10 bytes contain an implementation-dependent
 | 
			
		||||
version number. Servers supporting the IRC+ protocol as defined in this
 | 
			
		||||
document provide the string "-IRC+" here.
 | 
			
		||||
 | 
			
		||||
<flags> consists of two parts separated with the character "|" and is at
 | 
			
		||||
most 100 bytes long. The first part contains the name of the implementation
 | 
			
		||||
(ngIRCd sets this to "ngIRCd", the original ircd to "IRC", e.g.). The second
 | 
			
		||||
part is implementation-dependent and should only be parsed if the peer
 | 
			
		||||
supports the IRC+ protocol as well. In this case the following syntax is
 | 
			
		||||
used: "<serverversion>[:<serverflags>]".
 | 
			
		||||
 | 
			
		||||
<serverversion> is an ASCII representation of the clear-text server version
 | 
			
		||||
number, <serverflags> indicates the supported IRC+ protocol extensions (and
 | 
			
		||||
may be empty!).
 | 
			
		||||
 | 
			
		||||
The optional parameter <options> is used to propagate server options as
 | 
			
		||||
defined in RFC 2813, section 4.1.1.
 | 
			
		||||
 | 
			
		||||
The following <serverflags> are defined at the moment:
 | 
			
		||||
 | 
			
		||||
- o: IRC operators are allowed to change channel- and channel-user-modes
 | 
			
		||||
     even if they aren't channel-operator of the affected channel.
 | 
			
		||||
 | 
			
		||||
- C: The server supports the CHANINFO command.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
II.2 Exchange channel-modes, topics, and persistent channels
 | 
			
		||||
 | 
			
		||||
     Command: CHANINFO
 | 
			
		||||
  Parameters: <channel> +<modes> <key> <maxusers> [<topic>]
 | 
			
		||||
     Used by: servers only
 | 
			
		||||
 | 
			
		||||
CHANINFO is used by servers to inform each other about a channel: its
 | 
			
		||||
modes, channel key, user limits and its topic. <topic> is optional.
 | 
			
		||||
 | 
			
		||||
If the channel already exists on the server receiving the CHANINFO command,
 | 
			
		||||
it only adopts the <modes> (or the <topic>) if there are no modes (or topic)
 | 
			
		||||
already set. It there are already values set the server ignores the
 | 
			
		||||
corresponding parameter.
 | 
			
		||||
 | 
			
		||||
If the channel doesn't exists at all it will be created.
 | 
			
		||||
 | 
			
		||||
The parameter <key> must be ignored if a channel has no key (the parameter
 | 
			
		||||
<modes> doesn't list the "k" channel mode). In this case <key> should
 | 
			
		||||
contain "*" because the parameter <key> is required by the CHANINFO syntax
 | 
			
		||||
and therefore can't be omitted. The parameter <limit> must be ignored when
 | 
			
		||||
a channel has no user limit (the parameter <modes> doesn't list the "l"
 | 
			
		||||
channel mode). In this case <limit> should be "0".
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: Protocol.txt,v 1.9.2.1 2003/04/29 13:42:24 alex Exp $
 | 
			
		||||
@@ -1,47 +1,67 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
                    ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001,2002 by Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
                     (c)2001-2003 by Alexander Barton,
 | 
			
		||||
                   alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
                  ngIRCd ist freie Software und steht unter
 | 
			
		||||
                       der GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                             -- README-AUX.txt --
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                  terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Seit Version 0.2.2-pre gehoert Apple A/UX zu den offiziell unterstuetzten
 | 
			
		||||
Platformen. Er ist im vollen Funktionsumfang nutzbar.
 | 
			
		||||
 | 
			
		||||
Folgende Software wird jedoch benoetigt:
 | 
			
		||||
 | 
			
		||||
  - GNU C Compiler (gcc)
 | 
			
		||||
    Bezugsquellen:
 | 
			
		||||
    http://www.rezepte-im-web.de/appleux/gcc281.tar.gz
 | 
			
		||||
    ftp://arthur.ath.cx/pub/AUX/Software/Development/gcc281.tar.gz
 | 
			
		||||
 | 
			
		||||
  - GNU make
 | 
			
		||||
    Bezugsquellen:
 | 
			
		||||
    http://www.rezepte-im-web.de/appleux/make-3.79.tar.gz
 | 
			
		||||
    ftp://arthur.ath.cx/pub/AUX/Software/Development/make-3.79.tar.gz
 | 
			
		||||
 | 
			
		||||
  - GNU sed
 | 
			
		||||
    Bezugsquellen:
 | 
			
		||||
    http://www.rezepte-im-web.de/appleux/sed-3.02.tar.gz
 | 
			
		||||
    ftp://arthur.ath.cx/pub/AUX/Software/Tools/sed-3.02.tar.gz
 | 
			
		||||
 | 
			
		||||
  - libUTIL.a
 | 
			
		||||
    Bezugsquellen:
 | 
			
		||||
    http://ftp.mayn.de/pub/apple/apple_unix/Sys_stuff/libUTIL-2.1.tar.gz
 | 
			
		||||
    ftp://arthur.ath.cx/pub/AUX/Software/Libraries/libUTIL-2.1.tar.gz
 | 
			
		||||
 | 
			
		||||
Nachdem diese Pakete entsprechend installiert sind, reicht ein ganz normales
 | 
			
		||||
"./configure" und "make" aus, um den ngIRCd unter A/UX zu compilieren.
 | 
			
		||||
                           -- README-AUX.txt --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Hier die Zeiten von Alex System (Macintosh SE/30, 32 MB, A/UX 3.0.1):
 | 
			
		||||
configure: 7:33, make: 12:02
 | 
			
		||||
Since version 0.2.2-pre Apple's A/UX belongs to the officially supported 
 | 
			
		||||
platforms. It is not restricted in any way.
 | 
			
		||||
 | 
			
		||||
Since version 0.5.0 ngIRCd's source compiles with the native A/UX c 
 | 
			
		||||
compiler. GNU C isn't a must-have anymore.
 | 
			
		||||
 | 
			
		||||
The following software packages are needed:
 | 
			
		||||
 | 
			
		||||
 - GNU sed
 | 
			
		||||
   Source:
 | 
			
		||||
   http://www.rezepte-im-web.de/appleux/sed-3.02.tar.gz
 | 
			
		||||
   ftp://arthur.ath.cx/pub/AUX/Software/Tools/sed-3.02.tar.gz
 | 
			
		||||
 | 
			
		||||
   A/UX comes with /bin/sed which isn't supporting all functions needed
 | 
			
		||||
   by GNU automake/autoconf.
 | 
			
		||||
 | 
			
		||||
   Warning: When installing GNU sed please make sure that A/UX doesn't
 | 
			
		||||
   use the old one anymore which means set the $PATH or replace /bin/sed
 | 
			
		||||
   at all.
 | 
			
		||||
 | 
			
		||||
 - libUTIL.a
 | 
			
		||||
   Source:
 | 
			
		||||
   http://ftp.mayn.de/pub/apple/apple_unix/Sys_stuff/libUTIL-2.1.tar.gz
 | 
			
		||||
   ftp://arthur.ath.cx/pub/AUX/Software/Libraries/libUTIL-2.1.tar.gz
 | 
			
		||||
 | 
			
		||||
   This library contains functions that are common on other UNIX
 | 
			
		||||
   systems but not on A/UX e.g. memmove(), strerror() und strdup().
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
After installation of these packages just do a "./configure" and "make" to
 | 
			
		||||
compile ngIRCd on A/UX.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
A few hints in case of errors:
 | 
			
		||||
 | 
			
		||||
 - Either there's an 'install' on your system which is completely broken
 | 
			
		||||
   (so 'configure' uses its own shell script) or use a fully functionable one.
 | 
			
		||||
   There's at least one binary "out there" causing problems. The one
 | 
			
		||||
   of the GNU fileutils works fine:
 | 
			
		||||
   ftp://arthur.ath.cx/pub/UNIX/AUX/Software/Tools/fileutils-4.0.tar.gz
 | 
			
		||||
 | 
			
		||||
 - The precompiled binary of the old 'bash' shouldn't be installed within
 | 
			
		||||
   /bin (better do this in /usr/local/bin) because 'configure' would
 | 
			
		||||
   choose it as its shell which wouldn't work.
 | 
			
		||||
 | 
			
		||||
 - Because of limitations of /bin/sh on A/UX it can't be used to create
 | 
			
		||||
   the 'config.status' script. Better rename /bin/sh to /bin/sh.AUX and
 | 
			
		||||
   replace it by a symbolic link to /bin/ksh (ln -s /bin/ksh /bin/sh as
 | 
			
		||||
   root).
 | 
			
		||||
   These procedure should'nt cause you into problems and is recommended
 | 
			
		||||
   even if you don't use ngIRCd.
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: README-AUX.txt,v 1.1 2002/02/25 14:02:32 alex Exp $
 | 
			
		||||
$Id: README-AUX.txt,v 1.8 2003/04/21 21:59:34 goetz Exp $
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,21 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001,2002 by Alexander Barton,
 | 
			
		||||
                      (c)2001-2003 by Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
                  ngIRCd ist freie Software und steht unter
 | 
			
		||||
                       der GNU General Public License.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                             -- README-BeOS.txt --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      +-------------------------------------------------------------+
 | 
			
		||||
      | This text is only available in german at the moment, sorry! |
 | 
			
		||||
      | Contributors for this text or the BeOS port are welcome :-) |
 | 
			
		||||
      +-------------------------------------------------------------+
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
BeOS gehoert im Moment (noch?) nicht zu den offiziell unterstuetzten Plat-
 | 
			
		||||
formen: der ngIRCd enthaelt zwar bereits einige Anpassungen an BeOS und
 | 
			
		||||
compiliert auch, jedoch bricht er bei jedem Connect-Versuch eines Clients
 | 
			
		||||
@@ -22,7 +28,7 @@ von Pipes verschiedener Prozesse umgehen kann: sobald der Resolver asyncron
 | 
			
		||||
gestartet wird, also Pipe-Handles im select() vorhanden sind, fuehrt das zu
 | 
			
		||||
obiger Meldung.
 | 
			
		||||
 | 
			
		||||
Theoretische "L<EFBFBD>sung"/Workaround:
 | 
			
		||||
Theoretische "Loesung"/Workaround:
 | 
			
		||||
Den Resolver unter BeOS nicht verwenden, sondern mit IP-Adressen arbeiten.
 | 
			
		||||
Nachteil: der ngIRCd koennte sich nicht zu Servern verbinden, die dynamische
 | 
			
		||||
Adressen benutzen -- dazu muesste er den Namen aufloesen. Ansonsten sollte
 | 
			
		||||
@@ -32,5 +38,16 @@ Also: wenn es jemand implementieren will ... ;-))
 | 
			
		||||
 | 
			
		||||
Vielleicht mache ich es auch irgendwann mal selber. Mal sehen.
 | 
			
		||||
 | 
			
		||||
2002-05-19:
 | 
			
		||||
Ich habe gerade damit ein wenig gespielt und den Source hier so geaendert,
 | 
			
		||||
dass unter BeOS keine Resolver-Subprozesse mehr erzeugt werden, sondern mit
 | 
			
		||||
den "rohen" IP-Adressen gearbeitet wird. Das funktioniert so weit auch,
 | 
			
		||||
allerdings verschluckt sich BeOS nun bei anderen Funktionen, so zum Beispiel
 | 
			
		||||
bei close(), wenn ein Socket eines Clients geschlossen werden soll!?
 | 
			
		||||
Sehr komisch.
 | 
			
		||||
Wer Interesse daran hat, das weiter zu verfolgen, der moege sich bitte mit
 | 
			
		||||
mir in Verbindung setzen (alex@barton.de), ich maile gerne meine Patches zu.
 | 
			
		||||
Fuer eine Aenderung im CVS ist es aber meiner Meinung nach noch zu frueh ...
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: README-BeOS.txt,v 1.1 2002/02/25 14:02:32 alex Exp $
 | 
			
		||||
$Id: README-BeOS.txt,v 1.6.2.1 2003/07/18 20:48:20 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								doc/RFC.txt
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								doc/RFC.txt
									
									
									
									
									
								
							@@ -1,16 +1,17 @@
 | 
			
		||||
 | 
			
		||||
                     ngIRCd - Next Generation IRC Server
 | 
			
		||||
 | 
			
		||||
                      (c)2001,2002 by Alexander Barton,
 | 
			
		||||
                      (c)2001-2003 by Alexander Barton,
 | 
			
		||||
                    alex@barton.de, http://www.barton.de/
 | 
			
		||||
 | 
			
		||||
                  ngIRCd ist freie Software und steht unter
 | 
			
		||||
                       der GNU General Public License.
 | 
			
		||||
               ngIRCd is free software and published under the
 | 
			
		||||
                   terms of the GNU General Public License.
 | 
			
		||||
 | 
			
		||||
                                 -- RFC.txt --
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Das IRC-Protokoll ist in diesen RFC's (Request For Comments) dokumentiert:
 | 
			
		||||
The Internet Relay Chat (IRC) protocol is documented in these Request for
 | 
			
		||||
Comments (RFC), which you can get e.g. via <http://www.faqs.org/>:
 | 
			
		||||
 | 
			
		||||
  1459	Oikarinen, J. & D. Reed, "Internet Relay Chat Protocol",
 | 
			
		||||
	May 1993, [IRC].
 | 
			
		||||
@@ -29,4 +30,4 @@ Das IRC-Protokoll ist in diesen RFC's (Request For Comments) dokumentiert:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- 
 | 
			
		||||
$Id: RFC.txt,v 1.4 2002/01/23 18:20:04 alex Exp $
 | 
			
		||||
$Id: RFC.txt,v 1.6 2003/03/07 20:42:20 alex Exp $
 | 
			
		||||
 
 | 
			
		||||
@@ -1,108 +1,149 @@
 | 
			
		||||
# $Id: sample-ngircd.conf,v 1.8 2002/03/30 13:03:12 alex Exp $
 | 
			
		||||
# $Id: sample-ngircd.conf,v 1.20.2.3 2003/11/07 20:51:09 alex Exp $
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Das ist eine Beispiel-Konfiguration fuer den ngIRCd, die an die
 | 
			
		||||
# jeweiligen Beduerfnisse angepasst werden kann/muss.
 | 
			
		||||
# This is a sample configuration file for the ngIRCd, which must adept to
 | 
			
		||||
# the local preferences and needs.
 | 
			
		||||
#
 | 
			
		||||
# Kommentare werden mit "#" oder ";" eingeleitet.
 | 
			
		||||
# Comments are started with "#" or ";".
 | 
			
		||||
#
 | 
			
		||||
# Author: Alexander Barton, <alex@barton.de>
 | 
			
		||||
# Initial translation by Ilja Osthoff, <ilja@glide.ath.cx>
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
[Global]
 | 
			
		||||
 | 
			
		||||
	#
 | 
			
		||||
	# Im [Global]-Abschnitt der Konfigurationsdatei wird der Server
 | 
			
		||||
	# "an sich" konfiguriert. Notwendig ist nur die Variable "Name",
 | 
			
		||||
	# Info ist in der Regel ebengalls anzupassen. Fuer alle uebrigen
 | 
			
		||||
	# Variablen koennen oft die Defaults benutzt werden.
 | 
			
		||||
	#
 | 
			
		||||
 | 
			
		||||
	# Servername im IRC-Netz
 | 
			
		||||
	# The [Global] section of this file is used to define the main
 | 
			
		||||
	# configuration of the server, like the server name and the ports
 | 
			
		||||
	# on which the server should be listening.
 | 
			
		||||
	
 | 
			
		||||
	# Server name in the IRC network, must contain at least one dot
 | 
			
		||||
	# (".") and be unique in the IRC network.
 | 
			
		||||
	Name = irc.the.net
 | 
			
		||||
 | 
			
		||||
	# Info-Text des Servers
 | 
			
		||||
	
 | 
			
		||||
	# Info text of the server. This will be shown by WHOIS and
 | 
			
		||||
	# LINKS requests for example.
 | 
			
		||||
	Info = Server Info Text
 | 
			
		||||
	
 | 
			
		||||
	# Global password for all users needed to connect to the server
 | 
			
		||||
	;Password = abc
 | 
			
		||||
	
 | 
			
		||||
	# Information about the server and the administrator, used by the
 | 
			
		||||
	# ADMIN command.
 | 
			
		||||
	;AdminInfo1 = Description
 | 
			
		||||
	;AdminInfo2 = Location
 | 
			
		||||
	;AdminEMail = admin@irc.server
 | 
			
		||||
 
 | 
			
		||||
	# Ports on which the server should listen. There may be more than
 | 
			
		||||
	# one port, separated with ";". (Default: 6667)
 | 
			
		||||
	;Ports = 6667, 6668, 66694
 | 
			
		||||
 | 
			
		||||
	# Ports, auf denen Verbindungen angenommen werden sollen. Es koennen
 | 
			
		||||
	# mehrere Ports mit "," getrennt angegeben werden. (Default: 6667)
 | 
			
		||||
	;Ports = 6667, 6668, 6669
 | 
			
		||||
 | 
			
		||||
	# Textdatei mit der "Message of the Day" (MOTD)
 | 
			
		||||
	# IP address on which the server should listen. (Default: empty,
 | 
			
		||||
	# so the server listens on all IP addresses of the system)
 | 
			
		||||
	;Listen = 1.2.3.4
 | 
			
		||||
	
 | 
			
		||||
	# Text file with the "message of the day" (MOTD). This message will
 | 
			
		||||
	# be shown to all users connecting to the server:
 | 
			
		||||
	;MotdFile = /usr/local/etc/ngircd.motd
 | 
			
		||||
 | 
			
		||||
	# User-ID, unter der der Daemon laufen soll (dazu muss der Server
 | 
			
		||||
	# jedoch mit root-Rechten gestartet werden).
 | 
			
		||||
	# ACHTUNG: Die Konfigurations- und MOTD-Datei muessen fuer diesen
 | 
			
		||||
	# Benutzer lesbar sein, ansonsten schlaegt ein RESTART fehl!
 | 
			
		||||
	# User ID under which the server should run; you can use the name
 | 
			
		||||
	# of the user or the numerical ID. ATTENTION: For this to work the
 | 
			
		||||
	# server must have been started with root privileges! In addition,
 | 
			
		||||
	# the configuration and MOTD files must be readable by this user,
 | 
			
		||||
	# otherwise RESTART and REHASH won't work!
 | 
			
		||||
	;ServerUID = 65534
 | 
			
		||||
 | 
			
		||||
	# Group-ID, zu der der Daemon wechseln soll (hierzu muss der Server
 | 
			
		||||
	# jedoch mit root-Rechten gestartet werden)
 | 
			
		||||
	# Group ID under which the ngircd should run; you can use the name
 | 
			
		||||
	# of the group or the numerical ID. ATTENTION: For this to work the
 | 
			
		||||
	# server must have been started with root privileges!
 | 
			
		||||
	;ServerGID = 65534
 | 
			
		||||
 | 
			
		||||
	# Nach <PingTimeout> Sekunden verschickt der Server bei Inaktivitaet
 | 
			
		||||
	# von einem Client diesem ein PING.
 | 
			
		||||
	# After <PingTimeout> seconds of inactivity the server will send a
 | 
			
		||||
	# PING to the peer to test whether it is alive or not.
 | 
			
		||||
	;PingTimeout = 120
 | 
			
		||||
 | 
			
		||||
	# Antwortet ein Client, der ein PING bekam, nicht innerhalb von
 | 
			
		||||
	# <PongTimeout> Sekunden mit einem PONG, so wird er disconnectiert.
 | 
			
		||||
	# If a client fails to answer a PING with a PONG within <PongTimeout>
 | 
			
		||||
	# seconds, it will be disconnected by the server.
 | 
			
		||||
	;PongTimeout = 20
 | 
			
		||||
 | 
			
		||||
	# Der Server versucht alle <ConnectRetry> Sekunden, noch nicht bzw.
 | 
			
		||||
	# nicht mehr connectierte Server-Links aufzubauen.
 | 
			
		||||
	# The server tries every <ConnectRetry> seconds to establish a link
 | 
			
		||||
	# to not yet (or no longer) connected servers.
 | 
			
		||||
	;ConnectRetry = 60
 | 
			
		||||
 | 
			
		||||
	# Should IRC Operators be allowed to use the MODE command even if
 | 
			
		||||
	# they are not(!) channel-operators?
 | 
			
		||||
	;OperCanUseMode = no
 | 
			
		||||
 | 
			
		||||
	# Maximum number of simultaneous connection the server is allowed
 | 
			
		||||
	# to accept (<=0: unlimited):
 | 
			
		||||
	;MaxConnections = -1
 | 
			
		||||
	
 | 
			
		||||
	# Maximum number of simultaneous connections from a single IP address
 | 
			
		||||
	# the server will accept (<=0: unlimited):
 | 
			
		||||
	;MaxConnectionsIP = 5
 | 
			
		||||
 | 
			
		||||
	# Maximum number of channels a user can be member of (<=0: no limit):
 | 
			
		||||
	;MaxJoins = 10
 | 
			
		||||
 | 
			
		||||
[Operator]
 | 
			
		||||
 | 
			
		||||
	#
 | 
			
		||||
	# Mit einem [Operator]-Block wird der Name und das Passwort eines
 | 
			
		||||
	# IRC-Operators konfiguriert. Es darf mehrere [Operator]-Bloecke
 | 
			
		||||
	# geben (fuer jeden Operator einen).
 | 
			
		||||
	#
 | 
			
		||||
 | 
			
		||||
	# ID des IRC-Operators (muss nicht mit dem Nick identisch sein).
 | 
			
		||||
	# [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)
 | 
			
		||||
	;Name = TheOper
 | 
			
		||||
 | 
			
		||||
	# Passwort des IRC-Operators
 | 
			
		||||
	# Password of the IRC operator
 | 
			
		||||
	;Password = ThePwd
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[Server]
 | 
			
		||||
 | 
			
		||||
	# Other servers are configured in [Server] sections. If you
 | 
			
		||||
	# configure a port for the connection, then this ngircd tries to
 | 
			
		||||
	# connect to to the other server on the given port; if not it waits
 | 
			
		||||
	# for the other server to connect.
 | 
			
		||||
	# There may be more than one server block.
 | 
			
		||||
	#
 | 
			
		||||
	# In [Server]-Bloecken werden Server konfiguriert, zu denen dieser
 | 
			
		||||
	# Server sich verbinden soll bzw. von denen Verbindungen angekommen
 | 
			
		||||
	# werden duerfen.
 | 
			
		||||
	# Es koennen mehrere Server konfiguriert werden, d.h. [Server]-
 | 
			
		||||
	# Bloecke koennen mehrfach vorkommen.
 | 
			
		||||
	# Ist fuer einen Server ein Port konfiguriert, so versucht dieser
 | 
			
		||||
	# Server die Gegenseite zu connectieren. Ist kein Port vorgegeben,
 | 
			
		||||
	# so wartet dieser Server auf eine Verbindung der Gegenseite.
 | 
			
		||||
	#
 | 
			
		||||
	# Server-Gruppen:
 | 
			
		||||
	# Fuer jeden Server kann (optinal!) eine Gruppe konfiguriert werden,
 | 
			
		||||
	# zu der er gehoert (wird nur beachtet, wenn ein Port konfiguriert
 | 
			
		||||
	# ist!): eine solche Server-Gruppe wird quasi als ein Server ange-
 | 
			
		||||
	# sehen, der ngIRCd baut also nur eine Verbindung auf. Schlaegt die
 | 
			
		||||
	# Verbindung zu einem Server in einer Gruppe fehl, so wird der
 | 
			
		||||
	# naechste Server in der Gruppe probiert.
 | 
			
		||||
	#
 | 
			
		||||
 | 
			
		||||
	# Hostname des Servers
 | 
			
		||||
	# Server Groups:
 | 
			
		||||
	# The ngIRCd allows "server groups": You can assign an "ID" to every
 | 
			
		||||
	# server with which you want this ngIRCd to link. If a server of a
 | 
			
		||||
	# group won't answer, the ngIRCd tries to connect to the next server
 | 
			
		||||
	# in the given group. But the ngircd never tries to connect to two
 | 
			
		||||
	# servers with the same group ID.
 | 
			
		||||
	
 | 
			
		||||
	# IRC name of the server
 | 
			
		||||
	;Name = irc2.the.net
 | 
			
		||||
   
 | 
			
		||||
	# Internet host name of the peer
 | 
			
		||||
	;Host = connect-to-host.the.net
 | 
			
		||||
 | 
			
		||||
	# IRC-Name des Servers
 | 
			
		||||
	;Name = irc2.the.net
 | 
			
		||||
 | 
			
		||||
	# Port, zu dem dieser Server eine Verbindung herstellen soll. Wird
 | 
			
		||||
	# kein Port angegeben, so wird auf eine Verbindung der Gegenseite
 | 
			
		||||
	# gewartet.
 | 
			
		||||
	# Port of the server to which the ngIRCd should connect. If you
 | 
			
		||||
	# assign no port the ngIRCd waits for incoming connections.
 | 
			
		||||
	;Port = 6666
 | 
			
		||||
 | 
			
		||||
	# Passwort fuer diese Verbindung
 | 
			
		||||
	;Password = ThePwd1
 | 
			
		||||
	# Own password for the connection. This password has to be configured
 | 
			
		||||
	# as "PeerPassword" on the other server.
 | 
			
		||||
	;MyPassword = MySecret
 | 
			
		||||
 | 
			
		||||
	# Gruppe, zu der dieser Server gehoert (optional).
 | 
			
		||||
	# Foreign password for this connection. This password has to be
 | 
			
		||||
	# configured as "MyPassword" on the other server.
 | 
			
		||||
	;PeerPassword = PeerSecret
 | 
			
		||||
	
 | 
			
		||||
	# Group of this server (optional)
 | 
			
		||||
	;Group = 123
 | 
			
		||||
 | 
			
		||||
[Channel]
 | 
			
		||||
	# Pre-defined channels can be configured in [Channel] sections.
 | 
			
		||||
	# Such channels are created by the server when starting up and even
 | 
			
		||||
	# persist when there are no more members left.
 | 
			
		||||
	# Persistent channels are marked with the mode 'P', which can be set
 | 
			
		||||
	# and unset by IRC operators like other modes on the fly.
 | 
			
		||||
	# There may be more than one [Channel] block.
 | 
			
		||||
	
 | 
			
		||||
	# Name of the channel
 | 
			
		||||
	;Name = #TheName
 | 
			
		||||
 | 
			
		||||
	# Topic for this channel
 | 
			
		||||
	;Topic = a great topic
 | 
			
		||||
	
 | 
			
		||||
	# Initial channel modes
 | 
			
		||||
	;Modes = tn
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								man/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								man/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
#
 | 
			
		||||
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
# der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
# 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.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile.am,v 1.5 2002/04/04 13:02:41 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
man_MANS = ngircd.conf.5 ngircd.8
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = $(man_MANS)
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
							
								
								
									
										83
									
								
								man/ngircd.8
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								man/ngircd.8
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
.\"
 | 
			
		||||
.\" $Id: ngircd.8,v 1.8 2003/03/10 00:58:06 alex Exp $
 | 
			
		||||
.\"
 | 
			
		||||
.TH ngircd 8 "March 2003" ngircd "ngIRCd Manual"
 | 
			
		||||
.SH NAME
 | 
			
		||||
ngircd \- the next generation IRC daemon
 | 
			
		||||
.SH SYNOPSIS
 | 
			
		||||
.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).
 | 
			
		||||
.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).
 | 
			
		||||
.PP
 | 
			
		||||
Currently supported platforms (tested versions) are: AIX (3.2.5 with IBM XL
 | 
			
		||||
C Compiler), A/UX (3.x, Apple pre-ANSI C Compiler and GNU C), FreeBSD
 | 
			
		||||
(4.5/i386, GNU C), HP-UX (10.20, GNU C), IRIX (6.5, SGI MIPSpro C 7.30),
 | 
			
		||||
Linux (2.2.x/i386, 2.4.x/i386 and 2.4.x/hppa, GNU C), Mac OS X (10.x, GNU C),
 | 
			
		||||
NetBSD (1.5.2/i386 and 1.5.3/m68k, GNU C), Solaris (2.5.1 and 2.6, GNU C),
 | 
			
		||||
and Windows with Cygwin (GNU C).
 | 
			
		||||
.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.
 | 
			
		||||
.SH OPTIONS
 | 
			
		||||
The default behaviour of
 | 
			
		||||
.BR ngircd
 | 
			
		||||
is to read its standard configuration file (see below), to detach from the
 | 
			
		||||
controlling terminal and to wait for clients.
 | 
			
		||||
.PP
 | 
			
		||||
You can use these options to modify this default:
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-\-configtest\fR
 | 
			
		||||
Read, validate and display the configuration; then exit.
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-f\fR \fIfile\fR, \fB\-\-config\fR \fIfile\fR
 | 
			
		||||
Use
 | 
			
		||||
.I file
 | 
			
		||||
as configuration file.
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-n\fR, \fB\-\-nodaemon\fR
 | 
			
		||||
Don't fork a child and don't detach from controlling terminal.
 | 
			
		||||
All log messages go to the console.
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-p\fR, \fB\-\-passive\fR
 | 
			
		||||
Disable automatic connections to other servers. You can use the IRC command
 | 
			
		||||
CONNECT later on as IRC Operator to link this ngIRCd to other servers.
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-\-version\fR
 | 
			
		||||
Output version information and exit.
 | 
			
		||||
.TP
 | 
			
		||||
\fB\-\-help\fR
 | 
			
		||||
Display a brief help text and exit.
 | 
			
		||||
.SH FILES
 | 
			
		||||
.I /usr/local/etc/ngircd.conf
 | 
			
		||||
.RS
 | 
			
		||||
The system wide default configuration file.
 | 
			
		||||
.RE
 | 
			
		||||
.I /usr/local/etc/ngircd.motd
 | 
			
		||||
.RS
 | 
			
		||||
Default "message of the day" (MOTD).
 | 
			
		||||
.RE
 | 
			
		||||
.SH AUTHOR
 | 
			
		||||
Alexander Barton,
 | 
			
		||||
.UR mailto:alex@barton.de
 | 
			
		||||
alex@barton.de
 | 
			
		||||
.UE
 | 
			
		||||
.br
 | 
			
		||||
Homepage:
 | 
			
		||||
.UR http://arthur.ath.cx/~alex/ngircd/
 | 
			
		||||
http://arthur.ath.cx/~alex/ngircd/
 | 
			
		||||
.UE
 | 
			
		||||
.SH "SEE ALSO"
 | 
			
		||||
.BR ngircd.conf (5),
 | 
			
		||||
.BR ircd (8)
 | 
			
		||||
.\"
 | 
			
		||||
.\" -eof-
 | 
			
		||||
							
								
								
									
										215
									
								
								man/ngircd.conf.5
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								man/ngircd.conf.5
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,215 @@
 | 
			
		||||
.\"
 | 
			
		||||
.\" $Id: ngircd.conf.5,v 1.9.2.2 2003/11/07 20:51:10 alex Exp $
 | 
			
		||||
.\"
 | 
			
		||||
.TH ngircd.conf 5 "Mai 2003" ngircd "ngIRCd Manual"
 | 
			
		||||
.SH NAME
 | 
			
		||||
ngircd.conf \- configuration file of ngIRCd
 | 
			
		||||
.SH SYNOPSIS
 | 
			
		||||
.B /usr/local/etc/ngircd.conf
 | 
			
		||||
.SH DESCRIPTION
 | 
			
		||||
.BR ngircd.conf
 | 
			
		||||
is the configuration file for
 | 
			
		||||
.BR ngircd (8)
 | 
			
		||||
which you should adept to your local preferences and needs.
 | 
			
		||||
.SH "FILE FORMAT"
 | 
			
		||||
The file consists of sections and parameters. A section begins with the name
 | 
			
		||||
of the section in square brackets and continues until the next section
 | 
			
		||||
begins.
 | 
			
		||||
.PP
 | 
			
		||||
Sections contain parameters of the form
 | 
			
		||||
.PP
 | 
			
		||||
.RS
 | 
			
		||||
.I name
 | 
			
		||||
=
 | 
			
		||||
.I value
 | 
			
		||||
.RE
 | 
			
		||||
.PP
 | 
			
		||||
Any line beginning with a semicolon (';') or a hash ('#') character is
 | 
			
		||||
treated as a comment and ignored.
 | 
			
		||||
.PP
 | 
			
		||||
The file format is line-based - that means, each newline-terminated line
 | 
			
		||||
represents either a comment, a section name or a parameter.
 | 
			
		||||
.PP
 | 
			
		||||
Section and parameter names are not case sensitive.
 | 
			
		||||
.SH "SECTION OVERVIEW"
 | 
			
		||||
The file is separated in four blocks: [Global], [Operator], [Server],
 | 
			
		||||
and [Channel].
 | 
			
		||||
.PP
 | 
			
		||||
In the
 | 
			
		||||
.I [Global]
 | 
			
		||||
section, there is the main configuration like the server name and the
 | 
			
		||||
ports, on which the server should be listening. IRC operators of this
 | 
			
		||||
server are defined in
 | 
			
		||||
.I [Operator]
 | 
			
		||||
blocks.
 | 
			
		||||
.I [Server]
 | 
			
		||||
is the section where server links are configured. And
 | 
			
		||||
.I [Channel]
 | 
			
		||||
blocks are used to configure pre-defined ("persistent") IRC channels.
 | 
			
		||||
.SH [GLOBAL]
 | 
			
		||||
The
 | 
			
		||||
.I [Global]
 | 
			
		||||
section is used to define the server main configuration, like the server
 | 
			
		||||
name and the ports on which the server should be listening.
 | 
			
		||||
.TP
 | 
			
		||||
\fBName\fR
 | 
			
		||||
Server name in the IRC network
 | 
			
		||||
.TP
 | 
			
		||||
\fBInfo\fR
 | 
			
		||||
Info text of the server. This will be shown by WHOIS and LINKS requests for
 | 
			
		||||
example.
 | 
			
		||||
.TP
 | 
			
		||||
\fBAdminInfo1\fR, \fBAdminInfo2\fR, \fBAdminEMail\fR
 | 
			
		||||
Information about the server and the administrator, used by the ADMIN
 | 
			
		||||
command.
 | 
			
		||||
.TP
 | 
			
		||||
\fBPorts\fR
 | 
			
		||||
Ports on which the server should listen. There may be more than one port,
 | 
			
		||||
separated with ';'. Default: 6667.
 | 
			
		||||
.TP
 | 
			
		||||
\fBListen\fR
 | 
			
		||||
The ip address on which the server should listen. Default is empty, so
 | 
			
		||||
the server listens on all configured ip addresses and interfaces.
 | 
			
		||||
.TP
 | 
			
		||||
\fBMotdFile\fR
 | 
			
		||||
Text file with the "message of the day" (MOTD). This message will be shown
 | 
			
		||||
to all users connecting to the server.
 | 
			
		||||
.TP
 | 
			
		||||
\fBServerUID\fR
 | 
			
		||||
User ID under which the server should run; you can use the name of the user
 | 
			
		||||
or the numerical ID.
 | 
			
		||||
.PP
 | 
			
		||||
.RS
 | 
			
		||||
.B Attention:
 | 
			
		||||
.br
 | 
			
		||||
For this to work the server must have been
 | 
			
		||||
started with root privileges! In addition, the configuration and MOTD files
 | 
			
		||||
must be readable by this user, otherwise RESTART and REHASH won't work!
 | 
			
		||||
.RE
 | 
			
		||||
.TP
 | 
			
		||||
\fBServerGID\fR
 | 
			
		||||
Group ID under which the ngIRCd should run; you can use the name of the
 | 
			
		||||
group or the numerical ID.
 | 
			
		||||
.PP
 | 
			
		||||
.RS
 | 
			
		||||
.B Attention:
 | 
			
		||||
.br
 | 
			
		||||
For this to work the server must have
 | 
			
		||||
been started with root privileges!
 | 
			
		||||
.RE
 | 
			
		||||
.TP
 | 
			
		||||
\fBPingTimeout\fR
 | 
			
		||||
After <PingTimeout> seconds of inactivity the server will send a PING to
 | 
			
		||||
the peer to test whether it is alive or not. Default: 120.
 | 
			
		||||
.TP
 | 
			
		||||
\fBPongTimeout\fR
 | 
			
		||||
If a client fails to answer a PING with a PONG within <PongTimeout>
 | 
			
		||||
seconds, it will be disconnected by the server. Default: 20.
 | 
			
		||||
.TP
 | 
			
		||||
\fBConnectRetry\fR
 | 
			
		||||
The server tries every <ConnectRetry> seconds to establish a link to not yet
 | 
			
		||||
(or no longer) connected servers. Default: 60.
 | 
			
		||||
.TP
 | 
			
		||||
\fBOperCanUseMode\fR
 | 
			
		||||
Should IRC Operators be allowed to use the MODE command even if they are
 | 
			
		||||
not(!) channel-operators? Default: no.
 | 
			
		||||
.TP
 | 
			
		||||
\fBMaxConnections\fR
 | 
			
		||||
Maximum number of simultaneous connection the server is allowed to accept
 | 
			
		||||
(<=0: unlimited). Default: -1.
 | 
			
		||||
.TP
 | 
			
		||||
\fBMaxConnectionsIP\fR
 | 
			
		||||
Maximum number of simultaneous connections from a single IP address that
 | 
			
		||||
the server will accept (<=0: unlimited). This configuration options lowers
 | 
			
		||||
the risk of denial of service attacks (DoS). Default: 5.
 | 
			
		||||
.TP
 | 
			
		||||
\fBMaxJoins\fR
 | 
			
		||||
Maximum number of channels a user can be member of (<=0: no limit).
 | 
			
		||||
Default: 10.
 | 
			
		||||
.SH [OPERATOR]
 | 
			
		||||
.I [Operator]
 | 
			
		||||
sections are used to define IRC Operators. There may be more than one
 | 
			
		||||
.I [Operator]
 | 
			
		||||
block, one for each local operator.
 | 
			
		||||
.TP
 | 
			
		||||
\fBName\fR
 | 
			
		||||
ID of the operator (may be different of the nick name).
 | 
			
		||||
.TP
 | 
			
		||||
\fBPassword\fR
 | 
			
		||||
Password of the IRC operator.
 | 
			
		||||
.SH [SERVER]
 | 
			
		||||
Other servers are configured in
 | 
			
		||||
.I [Server]
 | 
			
		||||
sections. If you configure a port for the connection, then this ngIRCd
 | 
			
		||||
tries to connect to to the other server on the given port; if not, it waits
 | 
			
		||||
for the other server to connect.
 | 
			
		||||
.PP
 | 
			
		||||
The ngIRCd allows "server groups": You can assign an "ID" to every server
 | 
			
		||||
with which you want this ngIRCd to link. If a server of a group won't
 | 
			
		||||
answer, the ngIRCd tries to connect to the next server in the given group.
 | 
			
		||||
But ngIRCd never tries to connect to two servers with the same group ID.
 | 
			
		||||
.PP
 | 
			
		||||
There may be more than one
 | 
			
		||||
.I [Server]
 | 
			
		||||
block.
 | 
			
		||||
.TP
 | 
			
		||||
\fBName\fR
 | 
			
		||||
IRC name of the server
 | 
			
		||||
.TP
 | 
			
		||||
\fBHost\fR
 | 
			
		||||
Internet host name of the peer
 | 
			
		||||
.TP
 | 
			
		||||
\fBPort\fR
 | 
			
		||||
Port of the server to which the ngIRCd should connect. If you assign no port
 | 
			
		||||
the ngIRCd waits for incoming connections.
 | 
			
		||||
.TP
 | 
			
		||||
\fBMyPassword\fR
 | 
			
		||||
Own password for this connection. This password has to be configured as
 | 
			
		||||
"PeerPassword" on the other server.
 | 
			
		||||
.TP
 | 
			
		||||
\fBPeerPassword\fR
 | 
			
		||||
Foreign password for this connection. This password has to be configured as
 | 
			
		||||
"MyPassword" on the other server.
 | 
			
		||||
.TP
 | 
			
		||||
\fBGroup\fR
 | 
			
		||||
Group of this server (optional).
 | 
			
		||||
.SH [CHANNEL]
 | 
			
		||||
Pre-defined channels can be configured in
 | 
			
		||||
.I [Channel]
 | 
			
		||||
sections. Such channels are created by the server when starting up and even
 | 
			
		||||
persist when there are no more members left.
 | 
			
		||||
.PP
 | 
			
		||||
Persistent channels are marked with the mode 'P', which can be set and unset
 | 
			
		||||
by IRC operators like other modes on the fly.
 | 
			
		||||
.PP
 | 
			
		||||
There may be more than one
 | 
			
		||||
.I [Channel]
 | 
			
		||||
block.
 | 
			
		||||
.TP
 | 
			
		||||
\fBName\fR
 | 
			
		||||
Name of the channel
 | 
			
		||||
.TP
 | 
			
		||||
\fBTopic\fR
 | 
			
		||||
Topic for this channel
 | 
			
		||||
.TP
 | 
			
		||||
\fBModes\fR
 | 
			
		||||
Initial channel modes.
 | 
			
		||||
.SH HINTS
 | 
			
		||||
It's wise to use "ngircd --configtest" to validate the configuration file
 | 
			
		||||
after changing it. See
 | 
			
		||||
.BR ngircd (8)
 | 
			
		||||
for details.
 | 
			
		||||
.SH AUTHOR
 | 
			
		||||
Alexander Barton,
 | 
			
		||||
.UR mailto:alex@barton.de
 | 
			
		||||
alex@barton.de
 | 
			
		||||
.UE
 | 
			
		||||
.br
 | 
			
		||||
Homepage:
 | 
			
		||||
.UR http://arthur.ath.cx/~alex/ngircd/
 | 
			
		||||
http://arthur.ath.cx/~alex/ngircd/
 | 
			
		||||
.UE
 | 
			
		||||
.SH "SEE ALSO"
 | 
			
		||||
.BR ngircd (8)
 | 
			
		||||
.\"
 | 
			
		||||
.\" -eof-
 | 
			
		||||
@@ -2,17 +2,16 @@
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
#
 | 
			
		||||
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
# der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
# 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.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile.am,v 1.3 2002/03/12 14:37:51 alex Exp $
 | 
			
		||||
# $Id: Makefile.am,v 1.5 2003/01/13 12:20:16 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
SUBDIRS = portab ngircd
 | 
			
		||||
SUBDIRS = portab tool ngircd testsuite
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in config.h config.h.in stamp-h.in
 | 
			
		||||
 
 | 
			
		||||
@@ -1,41 +1,48 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
# Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
 | 
			
		||||
#
 | 
			
		||||
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
# der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
# 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.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile.am,v 1.19 2002/03/29 22:52:12 alex Exp $
 | 
			
		||||
# $Id: Makefile.am,v 1.39.2.2 2003/11/07 20:51:10 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
AM_CFLAGS = -I$(srcdir)/../portab
 | 
			
		||||
AUTOMAKE_OPTIONS = ../portab/ansi2knr
 | 
			
		||||
 | 
			
		||||
INCLUDES = -I$(srcdir)/../portab -I$(srcdir)/../tool
 | 
			
		||||
 | 
			
		||||
LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN
 | 
			
		||||
 | 
			
		||||
sbin_PROGRAMS = ngircd
 | 
			
		||||
 | 
			
		||||
ngircd_SOURCES = ngircd.c channel.c client.c conf.c conn.c hash.c irc.c \
 | 
			
		||||
	irc-channel.c irc-login.c irc-mode.c irc-oper.c irc-server.c \
 | 
			
		||||
	irc-write.c log.c parse.c tool.c
 | 
			
		||||
ngircd_SOURCES = ngircd.c channel.c client.c conf.c conn.c conn-zip.c conn-func.c \
 | 
			
		||||
	hash.c irc.c irc-channel.c irc-info.c irc-login.c irc-mode.c irc-op.c \
 | 
			
		||||
	irc-oper.c irc-server.c irc-write.c lists.c log.c match.c parse.c \
 | 
			
		||||
	rendezvous.c resolve.c
 | 
			
		||||
 | 
			
		||||
noinst_HEADERS = ngircd.h channel.h client.h conf.h conn.h hash.h irc.h \
 | 
			
		||||
	irc-channel.h irc-login.h irc-mode.h irc-oper.h irc-server.h \
 | 
			
		||||
	irc-write.h log.h parse.h tool.h \
 | 
			
		||||
ngircd_LDFLAGS = -L../portab -L../tool
 | 
			
		||||
 | 
			
		||||
ngircd_LDADD = -lngportab -lngtool
 | 
			
		||||
 | 
			
		||||
noinst_HEADERS = ngircd.h channel.h client.h conf.h conn.h conn-zip.h conn-func.h \
 | 
			
		||||
	hash.h irc.h irc-channel.h irc-info.h irc-login.h irc-mode.h irc-op.h \
 | 
			
		||||
	irc-oper.h irc-server.h irc-write.h lists.h log.h match.h parse.h \
 | 
			
		||||
	rendezvous.h resolve.h \
 | 
			
		||||
	messages.h defines.h
 | 
			
		||||
 | 
			
		||||
clean-local:
 | 
			
		||||
	rm -f check-version check-help lint.out
 | 
			
		||||
	rm -f check-version check-help lint.out cvs-version.*
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in
 | 
			
		||||
 | 
			
		||||
check-version: Makefile
 | 
			
		||||
	echo "#!/bin/sh" > check-version
 | 
			
		||||
	echo "./ngircd --version | grep version > /dev/null 2>&1" >> check-version
 | 
			
		||||
	echo "./ngircd --version | grep ngircd > /dev/null 2>&1" >> check-version
 | 
			
		||||
	chmod 755 check-version
 | 
			
		||||
 | 
			
		||||
check-help: Makefile
 | 
			
		||||
@@ -47,13 +54,26 @@ lint:
 | 
			
		||||
	rm -f lint.out
 | 
			
		||||
	for f in *.c; do \
 | 
			
		||||
	 echo "checking $$f ..."; \
 | 
			
		||||
	 splint $$f $(LINTARGS) -I./.. $(AM_CFLAGS) > lint.out 2>&1; \
 | 
			
		||||
	 splint $$f $(LINTARGS) -I./.. -I./../portab $(AM_CFLAGS) > lint.out 2>&1; \
 | 
			
		||||
	 grep "no warnings" lint.out > /dev/null 2>&1; \
 | 
			
		||||
	 if [ $$? -ne 0 ]; then \
 | 
			
		||||
	  echo; cat lint.out; echo; \
 | 
			
		||||
	 fi; \
 | 
			
		||||
	done;
 | 
			
		||||
 | 
			
		||||
ngircd.c: cvs-version.h
 | 
			
		||||
 | 
			
		||||
cvs-version.h: cvs-date
 | 
			
		||||
 | 
			
		||||
cvs-date:
 | 
			
		||||
	grep VERSION ../config.h | grep "CVS" \
 | 
			
		||||
	 && echo "#define CVSDATE \"$$( grep "\$$Id" $(srcdir)/*.c \
 | 
			
		||||
	    | $(AWK) "{ print \$$9 }" | sort | tail -1 \
 | 
			
		||||
	    | sed -e "s/\//-/g" )\"" > cvs-version.new \
 | 
			
		||||
	 || echo "" > cvs-version.new
 | 
			
		||||
	diff cvs-version.h cvs-version.new 2>/dev/null \
 | 
			
		||||
	 || cp cvs-version.new cvs-version.h
 | 
			
		||||
 | 
			
		||||
TESTS = check-version check-help
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
 
 | 
			
		||||
@@ -2,16 +2,13 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: channel.c,v 1.20 2002/03/25 16:54:26 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * channel.c: Management der Channels
 | 
			
		||||
 * Channel management
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -20,42 +17,102 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: channel.c,v 1.42.2.1 2003/11/07 20:51:10 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "hash.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "hash.h"
 | 
			
		||||
#include "lists.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define REMOVE_PART 0
 | 
			
		||||
#define REMOVE_QUIT 1
 | 
			
		||||
#define REMOVE_KICK 2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL CHANNEL *My_Channels;
 | 
			
		||||
LOCAL CL2CHAN *My_Cl2Chan;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL CHANNEL *New_Chan( CHAR *Name );
 | 
			
		||||
LOCAL CL2CHAN *Get_Cl2Chan( CHANNEL *Chan, CLIENT *Client );
 | 
			
		||||
LOCAL CL2CHAN *Add_Client( CHANNEL *Chan, CLIENT *Client );
 | 
			
		||||
LOCAL BOOLEAN Remove_Client( CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, CHAR *Reason, BOOLEAN ServerPART );
 | 
			
		||||
LOCAL CL2CHAN *Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan );
 | 
			
		||||
LOCAL CL2CHAN *Get_Next_Cl2Chan( CL2CHAN *Start, CLIENT *Client, CHANNEL *Chan );
 | 
			
		||||
LOCAL BOOLEAN Delete_Channel( CHANNEL *Chan );
 | 
			
		||||
LOCAL CL2CHAN *Get_Cl2Chan PARAMS(( CHANNEL *Chan, CLIENT *Client ));
 | 
			
		||||
LOCAL CL2CHAN *Add_Client PARAMS(( CHANNEL *Chan, CLIENT *Client ));
 | 
			
		||||
LOCAL BOOLEAN Remove_Client PARAMS(( INT Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, CHAR *Reason, BOOLEAN InformServer ));
 | 
			
		||||
LOCAL CL2CHAN *Get_First_Cl2Chan PARAMS(( CLIENT *Client, CHANNEL *Chan ));
 | 
			
		||||
LOCAL CL2CHAN *Get_Next_Cl2Chan PARAMS(( CL2CHAN *Start, CLIENT *Client, CHANNEL *Chan ));
 | 
			
		||||
LOCAL BOOLEAN Delete_Channel PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Channel_Init( VOID )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Channel_Init( VOID )
 | 
			
		||||
{
 | 
			
		||||
	My_Channels = NULL;
 | 
			
		||||
	My_Cl2Chan = NULL;
 | 
			
		||||
} /* Channel_Init */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Channel_Exit( VOID )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Channel_InitPredefined( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Vordefinierte persistente Channels erzeugen */
 | 
			
		||||
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	CHAR *c;
 | 
			
		||||
	INT i;
 | 
			
		||||
	
 | 
			
		||||
	for( i = 0; i < Conf_Channel_Count; i++ )
 | 
			
		||||
	{
 | 
			
		||||
		/* Ist ein Name konfiguriert? */
 | 
			
		||||
		if( ! Conf_Channel[i].name[0] ) continue;
 | 
			
		||||
 | 
			
		||||
		/* Gueltiger Channel-Name? */
 | 
			
		||||
		if( ! Channel_IsValidName( Conf_Channel[i].name ))
 | 
			
		||||
		{
 | 
			
		||||
			Log( LOG_ERR, "Can't create pre-defined channel: invalid name: \"%s\"!", Conf_Channel[i].name );
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Gibt es den Channel bereits? */
 | 
			
		||||
		chan = Channel_Search( Conf_Channel[i].name );
 | 
			
		||||
		if( chan )
 | 
			
		||||
		{
 | 
			
		||||
			Log( LOG_INFO, "Can't create pre-defined channel \"%s\": name already in use.", Conf_Channel[i].name );
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		/* Channel anlegen */
 | 
			
		||||
		chan = Channel_Create( Conf_Channel[i].name );
 | 
			
		||||
		if( chan )
 | 
			
		||||
		{
 | 
			
		||||
			Channel_ModeAdd( chan, 'P' );
 | 
			
		||||
			Channel_SetTopic( chan, Conf_Channel[i].topic );
 | 
			
		||||
			c = Conf_Channel[i].modes;
 | 
			
		||||
			while( *c ) Channel_ModeAdd( chan, *c++ );
 | 
			
		||||
			Log( LOG_INFO, "Created pre-defined channel \"%s\".", Conf_Channel[i].name );
 | 
			
		||||
		}
 | 
			
		||||
		else Log( LOG_ERR, "Can't create pre-defined channel \"%s\"!", Conf_Channel[i].name );
 | 
			
		||||
	}
 | 
			
		||||
} /* Channel_InitPredefined */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Channel_Exit( VOID )
 | 
			
		||||
{
 | 
			
		||||
	CHANNEL *c, *c_next;
 | 
			
		||||
	CL2CHAN *cl2chan, *cl2chan_next;
 | 
			
		||||
@@ -80,7 +137,8 @@ GLOBAL VOID Channel_Exit( VOID )
 | 
			
		||||
} /* Channel_Exit */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_Join( CLIENT *Client, CHAR *Name )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Channel_Join( CLIENT *Client, CHAR *Name )
 | 
			
		||||
{
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	
 | 
			
		||||
@@ -104,12 +162,8 @@ GLOBAL BOOLEAN Channel_Join( CLIENT *Client, CHAR *Name )
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* Gibt es noch nicht? Dann neu anlegen: */
 | 
			
		||||
		chan = New_Chan( Name );
 | 
			
		||||
		chan = Channel_Create( Name );
 | 
			
		||||
		if( ! chan ) return FALSE;
 | 
			
		||||
 | 
			
		||||
		/* Verketten */
 | 
			
		||||
		chan->next = My_Channels;
 | 
			
		||||
		My_Channels = chan;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* User dem Channel hinzufuegen */
 | 
			
		||||
@@ -118,12 +172,14 @@ GLOBAL BOOLEAN Channel_Join( CLIENT *Client, CHAR *Name )
 | 
			
		||||
} /* Channel_Join */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_Part( CLIENT *Client, CLIENT *Origin, CHAR *Name, CHAR *Reason )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Channel_Part( CLIENT *Client, CLIENT *Origin, CHAR *Name, CHAR *Reason )
 | 
			
		||||
{
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Name != NULL );
 | 
			
		||||
	assert( Reason != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Channel suchen */
 | 
			
		||||
	chan = Channel_Search( Name );
 | 
			
		||||
@@ -134,31 +190,77 @@ GLOBAL BOOLEAN Channel_Part( CLIENT *Client, CLIENT *Origin, CHAR *Name, CHAR *R
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* User aus Channel entfernen */
 | 
			
		||||
	if( ! Remove_Client( chan, Client, Origin, Reason, TRUE )) return FALSE;
 | 
			
		||||
	if( ! Remove_Client( REMOVE_PART, chan, Client, Origin, Reason, TRUE )) return FALSE;
 | 
			
		||||
	else return TRUE;
 | 
			
		||||
} /* Channel_Part */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Channel_RemoveClient( CLIENT *Client, CHAR *Reason )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Channel_Kick( CLIENT *Client, CLIENT *Origin, CHAR *Name, CHAR *Reason )
 | 
			
		||||
{
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Origin != NULL );
 | 
			
		||||
	assert( Name != NULL );
 | 
			
		||||
	assert( Reason != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Channel suchen */
 | 
			
		||||
	chan = Channel_Search( Name );
 | 
			
		||||
	if( ! chan )
 | 
			
		||||
	{
 | 
			
		||||
		IRC_WriteStrClient( Origin, ERR_NOSUCHCHANNEL_MSG, Client_ID( Origin ), Name );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Ist der User Mitglied in dem Channel? */
 | 
			
		||||
	if( ! Channel_IsMemberOf( chan, Origin ))
 | 
			
		||||
	{
 | 
			
		||||
		IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG, Client_ID( Origin ), Name );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Ist der User Channel-Operator? */
 | 
			
		||||
	if( ! strchr( Channel_UserModes( chan, Origin ), 'o' ))
 | 
			
		||||
	{
 | 
			
		||||
		IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Name);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Ist der Ziel-User Mitglied im Channel? */
 | 
			
		||||
	if( ! Channel_IsMemberOf( chan, Client ))
 | 
			
		||||
	{
 | 
			
		||||
		IRC_WriteStrClient( Origin, ERR_USERNOTINCHANNEL_MSG, Client_ID( Origin ), Client_ID( Client ), Name );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Remove_Client( REMOVE_KICK, chan, Client, Origin, Reason, TRUE );
 | 
			
		||||
} /* Channel_Kick */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Channel_Quit( CLIENT *Client, CHAR *Reason )
 | 
			
		||||
{
 | 
			
		||||
	CHANNEL *c, *next_c;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Reason != NULL );
 | 
			
		||||
 | 
			
		||||
	c = My_Channels;
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		next_c = c->next;
 | 
			
		||||
		Remove_Client( c, Client, Client_ThisServer( ), Reason, FALSE );
 | 
			
		||||
		Remove_Client( REMOVE_QUIT, c, Client, Client, Reason, FALSE );
 | 
			
		||||
		c = next_c;
 | 
			
		||||
	}
 | 
			
		||||
} /* Channel_RemoveClient */
 | 
			
		||||
} /* Channel_Quit */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Channel_Count( VOID )
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Channel_Count( VOID )
 | 
			
		||||
{
 | 
			
		||||
	CHANNEL *c;
 | 
			
		||||
	INT count;
 | 
			
		||||
	LONG count;
 | 
			
		||||
	
 | 
			
		||||
	count = 0;
 | 
			
		||||
	c = My_Channels;
 | 
			
		||||
@@ -171,34 +273,116 @@ GLOBAL INT Channel_Count( VOID )
 | 
			
		||||
} /* Channel_Count */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *Channel_Name( CHANNEL *Chan )
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Channel_MemberCount( CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	LONG count;
 | 
			
		||||
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	count = 0;
 | 
			
		||||
	cl2chan = My_Cl2Chan;
 | 
			
		||||
	while( cl2chan )
 | 
			
		||||
	{
 | 
			
		||||
		if( cl2chan->channel == Chan ) count++;
 | 
			
		||||
		cl2chan = cl2chan->next;
 | 
			
		||||
	}
 | 
			
		||||
	return count;
 | 
			
		||||
} /* Channel_MemberCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT
 | 
			
		||||
Channel_CountForUser( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	/* Count number of channels a user is member of. */
 | 
			
		||||
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	INT count;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	
 | 
			
		||||
	count = 0;
 | 
			
		||||
	cl2chan = My_Cl2Chan;
 | 
			
		||||
	while( cl2chan )
 | 
			
		||||
	{
 | 
			
		||||
		if( cl2chan->client == Client ) count++;
 | 
			
		||||
		cl2chan = cl2chan->next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return count;
 | 
			
		||||
} /* Channel_CountForUser */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT
 | 
			
		||||
Channel_PCount( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Count the number of persistent (mode 'P') channels */
 | 
			
		||||
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	INT count;
 | 
			
		||||
 | 
			
		||||
	count = 0;
 | 
			
		||||
	chan = My_Channels;
 | 
			
		||||
	while( chan )
 | 
			
		||||
	{
 | 
			
		||||
		if( strchr( chan->modes, 'P' )) count++;
 | 
			
		||||
		chan = chan->next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return count;
 | 
			
		||||
} /* Channel_PCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Channel_Name( CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	return Chan->name;
 | 
			
		||||
} /* Channel_Name */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *Channel_Modes( CHANNEL *Chan )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Channel_Modes( CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	return Chan->modes;
 | 
			
		||||
} /* Channel_Modes */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHANNEL *Channel_First( VOID )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Channel_Key( CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	return Chan->key;
 | 
			
		||||
} /* Channel_Key */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Channel_MaxUsers( CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	return Chan->maxusers;
 | 
			
		||||
} /* Channel_MaxUsers */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHANNEL *
 | 
			
		||||
Channel_First( VOID )
 | 
			
		||||
{
 | 
			
		||||
	return My_Channels;
 | 
			
		||||
} /* Channel_First */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHANNEL *Channel_Next( CHANNEL *Chan )
 | 
			
		||||
GLOBAL CHANNEL *
 | 
			
		||||
Channel_Next( CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	return Chan->next;
 | 
			
		||||
} /* Channel_Next */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHANNEL *Channel_Search( CHAR *Name )
 | 
			
		||||
GLOBAL CHANNEL *
 | 
			
		||||
Channel_Search( CHAR *Name )
 | 
			
		||||
{
 | 
			
		||||
	/* Channel-Struktur suchen */
 | 
			
		||||
	
 | 
			
		||||
@@ -222,14 +406,16 @@ GLOBAL CHANNEL *Channel_Search( CHAR *Name )
 | 
			
		||||
} /* Channel_Search */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CL2CHAN *Channel_FirstMember( CHANNEL *Chan )
 | 
			
		||||
GLOBAL CL2CHAN *
 | 
			
		||||
Channel_FirstMember( CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	return Get_First_Cl2Chan( NULL, Chan );
 | 
			
		||||
} /* Channel_FirstMember */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CL2CHAN *Channel_NextMember( CHANNEL *Chan, CL2CHAN *Cl2Chan )
 | 
			
		||||
GLOBAL CL2CHAN *
 | 
			
		||||
Channel_NextMember( CHANNEL *Chan, CL2CHAN *Cl2Chan )
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	assert( Cl2Chan != NULL );
 | 
			
		||||
@@ -237,14 +423,16 @@ GLOBAL CL2CHAN *Channel_NextMember( CHANNEL *Chan, CL2CHAN *Cl2Chan )
 | 
			
		||||
} /* Channel_NextMember */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CL2CHAN *Channel_FirstChannelOf( CLIENT *Client )
 | 
			
		||||
GLOBAL CL2CHAN *
 | 
			
		||||
Channel_FirstChannelOf( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Get_First_Cl2Chan( Client, NULL );
 | 
			
		||||
} /* Channel_FirstChannelOf */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CL2CHAN *Channel_NextChannelOf( CLIENT *Client, CL2CHAN *Cl2Chan )
 | 
			
		||||
GLOBAL CL2CHAN *
 | 
			
		||||
Channel_NextChannelOf( CLIENT *Client, CL2CHAN *Cl2Chan )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Cl2Chan != NULL );
 | 
			
		||||
@@ -252,31 +440,35 @@ GLOBAL CL2CHAN *Channel_NextChannelOf( CLIENT *Client, CL2CHAN *Cl2Chan )
 | 
			
		||||
} /* Channel_NextChannelOf */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Channel_GetClient( CL2CHAN *Cl2Chan )
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Channel_GetClient( CL2CHAN *Cl2Chan )
 | 
			
		||||
{
 | 
			
		||||
	assert( Cl2Chan != NULL );
 | 
			
		||||
	return Cl2Chan->client;
 | 
			
		||||
} /* Channel_GetClient */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHANNEL *Channel_GetChannel( CL2CHAN *Cl2Chan )
 | 
			
		||||
GLOBAL CHANNEL *
 | 
			
		||||
Channel_GetChannel( CL2CHAN *Cl2Chan )
 | 
			
		||||
{
 | 
			
		||||
	assert( Cl2Chan != NULL );
 | 
			
		||||
	return Cl2Chan->channel;
 | 
			
		||||
} /* Channel_GetChannel */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_IsValidName( CHAR *Name )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Channel_IsValidName( CHAR *Name )
 | 
			
		||||
{
 | 
			
		||||
	/* Pr<EFBFBD>fen, ob Name als Channelname gueltig */
 | 
			
		||||
	/* Pruefen, ob Name als Channelname gueltig */
 | 
			
		||||
 | 
			
		||||
	CHAR *ptr, badchars[] = " ,:\x07";
 | 
			
		||||
	CHAR *ptr, badchars[10];
 | 
			
		||||
	
 | 
			
		||||
	assert( Name != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Name[0] != '#' ) || ( strlen( Name ) >= CHANNEL_NAME_LEN )) return FALSE;
 | 
			
		||||
 | 
			
		||||
	ptr = Name;
 | 
			
		||||
	strcpy( badchars, " ,:\007" );
 | 
			
		||||
	while( *ptr )
 | 
			
		||||
	{
 | 
			
		||||
		if( strchr( badchars, *ptr )) return FALSE;
 | 
			
		||||
@@ -287,7 +479,8 @@ GLOBAL BOOLEAN Channel_IsValidName( CHAR *Name )
 | 
			
		||||
} /* Channel_IsValidName */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_ModeAdd( CHANNEL *Chan, CHAR Mode )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Channel_ModeAdd( CHANNEL *Chan, CHAR Mode )
 | 
			
		||||
{
 | 
			
		||||
	/* Mode soll gesetzt werden. TRUE wird geliefert, wenn der
 | 
			
		||||
	 * Mode neu gesetzt wurde, FALSE, wenn der Channel den Mode
 | 
			
		||||
@@ -301,14 +494,15 @@ GLOBAL BOOLEAN Channel_ModeAdd( CHANNEL *Chan, CHAR Mode )
 | 
			
		||||
	if( ! strchr( Chan->modes, x[0] ))
 | 
			
		||||
	{
 | 
			
		||||
		/* Client hat den Mode noch nicht -> setzen */
 | 
			
		||||
		strcat( Chan->modes, x );
 | 
			
		||||
		strlcat( Chan->modes, x, sizeof( Chan->modes ));
 | 
			
		||||
		return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
	else return FALSE;
 | 
			
		||||
} /* Channel_ModeAdd */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_ModeDel( CHANNEL *Chan, CHAR Mode )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Channel_ModeDel( CHANNEL *Chan, CHAR Mode )
 | 
			
		||||
{
 | 
			
		||||
	/* Mode soll geloescht werden. TRUE wird geliefert, wenn der
 | 
			
		||||
	 * Mode entfernt wurde, FALSE, wenn der Channel den Mode
 | 
			
		||||
@@ -333,7 +527,8 @@ GLOBAL BOOLEAN Channel_ModeDel( CHANNEL *Chan, CHAR Mode )
 | 
			
		||||
} /* Channel_ModeDel */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_UserModeAdd( CHANNEL *Chan, CLIENT *Client, CHAR Mode )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Channel_UserModeAdd( CHANNEL *Chan, CLIENT *Client, CHAR Mode )
 | 
			
		||||
{
 | 
			
		||||
	/* Channel-User-Mode soll gesetzt werden. TRUE wird geliefert,
 | 
			
		||||
	 * wenn der Mode neu gesetzt wurde, FALSE, wenn der User den
 | 
			
		||||
@@ -352,14 +547,15 @@ GLOBAL BOOLEAN Channel_UserModeAdd( CHANNEL *Chan, CLIENT *Client, CHAR Mode )
 | 
			
		||||
	if( ! strchr( cl2chan->modes, x[0] ))
 | 
			
		||||
	{
 | 
			
		||||
		/* Client hat den Mode noch nicht -> setzen */
 | 
			
		||||
		strcat( cl2chan->modes, x );
 | 
			
		||||
		strlcat( cl2chan->modes, x, sizeof( cl2chan->modes ));
 | 
			
		||||
		return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
	else return FALSE;
 | 
			
		||||
} /* Channel_UserModeAdd */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_UserModeDel( CHANNEL *Chan, CLIENT *Client, CHAR Mode )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Channel_UserModeDel( CHANNEL *Chan, CLIENT *Client, CHAR Mode )
 | 
			
		||||
{
 | 
			
		||||
	/* Channel-User-Mode soll geloescht werden. TRUE wird geliefert,
 | 
			
		||||
	 * wenn der Mode entfernt wurde, FALSE, wenn der User den Channel-Mode
 | 
			
		||||
@@ -389,7 +585,8 @@ GLOBAL BOOLEAN Channel_UserModeDel( CHANNEL *Chan, CLIENT *Client, CHAR Mode )
 | 
			
		||||
} /* Channel_UserModeDel */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *Channel_UserModes( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Channel_UserModes( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	/* Channel-Modes eines Users liefern */
 | 
			
		||||
	
 | 
			
		||||
@@ -405,7 +602,8 @@ GLOBAL CHAR *Channel_UserModes( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
} /* Channel_UserModes */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_IsMemberOf( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Channel_IsMemberOf( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	/* Pruefen, ob Client Mitglied in Channel ist */
 | 
			
		||||
 | 
			
		||||
@@ -417,28 +615,61 @@ GLOBAL BOOLEAN Channel_IsMemberOf( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
} /* Channel_IsMemberOf */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *Channel_Topic( CHANNEL *Chan )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Channel_Topic( CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	return Chan->topic;
 | 
			
		||||
} /* Channel_Topic */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Channel_SetTopic( CHANNEL *Chan, CHAR *Topic )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Channel_SetTopic( CHANNEL *Chan, CHAR *Topic )
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	assert( Topic != NULL );
 | 
			
		||||
	
 | 
			
		||||
	strncpy( Chan->topic, Topic, CHANNEL_TOPIC_LEN - 1 );
 | 
			
		||||
	Chan->topic[CHANNEL_TOPIC_LEN - 1] = '\0';
 | 
			
		||||
	strlcpy( Chan->topic, Topic, sizeof( Chan->topic ));
 | 
			
		||||
} /* Channel_SetTopic */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_Write( CHANNEL *Chan, CLIENT *From, CLIENT *Client, CHAR *Text )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Channel_SetModes( CHANNEL *Chan, CHAR *Modes )
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	assert( Modes != NULL );
 | 
			
		||||
 | 
			
		||||
	strlcpy( Chan->modes, Modes, sizeof( Chan->modes ));
 | 
			
		||||
} /* Channel_SetModes */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Channel_SetKey( CHANNEL *Chan, CHAR *Key )
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
	assert( Key != NULL );
 | 
			
		||||
 | 
			
		||||
	strlcpy( Chan->key, Key, sizeof( Chan->key ));
 | 
			
		||||
	Log( LOG_DEBUG, "Channel %s: Key is now \"%s\".", Chan->name, Chan->key );
 | 
			
		||||
} /* Channel_SetKey */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Channel_SetMaxUsers( CHANNEL *Chan, LONG Count )
 | 
			
		||||
{
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	Chan->maxusers = Count;
 | 
			
		||||
	Log( LOG_DEBUG, "Channel %s: Member limit is now %ld.", Chan->name, Chan->maxusers );
 | 
			
		||||
} /* Channel_SetMaxUsers */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Channel_Write( CHANNEL *Chan, CLIENT *From, CLIENT *Client, CHAR *Text )
 | 
			
		||||
{
 | 
			
		||||
	BOOLEAN is_member, has_voice, is_op, ok;
 | 
			
		||||
 | 
			
		||||
	/* Okay, Ziel ist ein Channel */
 | 
			
		||||
	/* Okay, target is a channel */
 | 
			
		||||
	is_member = has_voice = is_op = FALSE;
 | 
			
		||||
	if( Channel_IsMemberOf( Chan, From ))
 | 
			
		||||
	{
 | 
			
		||||
@@ -447,21 +678,28 @@ GLOBAL BOOLEAN Channel_Write( CHANNEL *Chan, CLIENT *From, CLIENT *Client, CHAR
 | 
			
		||||
		if( strchr( Channel_UserModes( Chan, From ), 'o' )) is_op = TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* pruefen, ob Client in Channel schreiben darf */
 | 
			
		||||
	/* Check weather client is allowed to write to channel */
 | 
			
		||||
	ok = TRUE;
 | 
			
		||||
	if( strchr( Channel_Modes( Chan ), 'n' ) && ( ! is_member )) ok = FALSE;
 | 
			
		||||
	if( strchr( Channel_Modes( Chan ), 'm' ) && ( ! is_op ) && ( ! has_voice )) ok = FALSE;
 | 
			
		||||
	
 | 
			
		||||
	/* Is the client banned? */
 | 
			
		||||
	if( Lists_CheckBanned( From, Chan ))
 | 
			
		||||
	{
 | 
			
		||||
		/* Client is banned, bus is he channel operator or has voice? */
 | 
			
		||||
		if(( ! has_voice ) && ( ! is_op )) ok = FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( ! ok ) return IRC_WriteStrClient( From, ERR_CANNOTSENDTOCHAN_MSG, Client_ID( From ), Channel_Name( Chan ));
 | 
			
		||||
 | 
			
		||||
	/* Text senden */
 | 
			
		||||
	/* Send text */
 | 
			
		||||
	if( Client_Conn( From ) > NONE ) Conn_UpdateIdle( Client_Conn( From ));
 | 
			
		||||
	return IRC_WriteStrChannelPrefix( Client, Chan, From, TRUE, "PRIVMSG %s :%s", Channel_Name( Chan ), Text );
 | 
			
		||||
} /* Channel_Write */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL CHANNEL *New_Chan( CHAR *Name )
 | 
			
		||||
GLOBAL CHANNEL *
 | 
			
		||||
Channel_Create( CHAR *Name )
 | 
			
		||||
{
 | 
			
		||||
	/* Neue Channel-Struktur anlegen */
 | 
			
		||||
 | 
			
		||||
@@ -472,23 +710,30 @@ LOCAL CHANNEL *New_Chan( CHAR *Name )
 | 
			
		||||
	c = malloc( sizeof( CHANNEL ));
 | 
			
		||||
	if( ! c )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_EMERG, "Can't allocate memory!" );
 | 
			
		||||
		Log( LOG_EMERG, "Can't allocate memory! [New_Chan]" );
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	c->next = NULL;
 | 
			
		||||
	strncpy( c->name, Name, CHANNEL_NAME_LEN - 1 );
 | 
			
		||||
	strlcpy( c->name, Name, sizeof( c->name ));
 | 
			
		||||
	c->name[CHANNEL_NAME_LEN - 1] = '\0';
 | 
			
		||||
	strcpy( c->modes, "" );
 | 
			
		||||
	strcpy( c->topic, "" );
 | 
			
		||||
	c->hash = Hash( c->name );
 | 
			
		||||
	strcpy( c->key, "" );
 | 
			
		||||
	c->maxusers = 0;
 | 
			
		||||
 | 
			
		||||
	/* Verketten */
 | 
			
		||||
	c->next = My_Channels;
 | 
			
		||||
	My_Channels = c;
 | 
			
		||||
	
 | 
			
		||||
	Log( LOG_DEBUG, "Created new channel structure for \"%s\".", Name );
 | 
			
		||||
	
 | 
			
		||||
	return c;
 | 
			
		||||
} /* New_Chan */
 | 
			
		||||
} /* Channel_Create */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL CL2CHAN *Get_Cl2Chan( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
LOCAL CL2CHAN *
 | 
			
		||||
Get_Cl2Chan( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
 | 
			
		||||
@@ -505,7 +750,8 @@ LOCAL CL2CHAN *Get_Cl2Chan( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
} /* Get_Cl2Chan */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL CL2CHAN *Add_Client( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
LOCAL CL2CHAN *
 | 
			
		||||
Add_Client( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
 | 
			
		||||
@@ -516,7 +762,7 @@ LOCAL CL2CHAN *Add_Client( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
	cl2chan = malloc( sizeof( CL2CHAN ));
 | 
			
		||||
	if( ! cl2chan )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_EMERG, "Can't allocate memory!" );
 | 
			
		||||
		Log( LOG_EMERG, "Can't allocate memory! [Add_Client]" );
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
	cl2chan->channel = Chan;
 | 
			
		||||
@@ -533,7 +779,8 @@ LOCAL CL2CHAN *Add_Client( CHANNEL *Chan, CLIENT *Client )
 | 
			
		||||
} /* Add_Client */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Remove_Client( CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, CHAR *Reason, BOOLEAN ServerPART )
 | 
			
		||||
LOCAL BOOLEAN
 | 
			
		||||
Remove_Client( INT Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, CHAR *Reason, BOOLEAN InformServer )
 | 
			
		||||
{
 | 
			
		||||
	CL2CHAN *cl2chan, *last_cl2chan;
 | 
			
		||||
	CHANNEL *c;
 | 
			
		||||
@@ -561,26 +808,50 @@ LOCAL BOOLEAN Remove_Client( CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, CHAR
 | 
			
		||||
	else My_Cl2Chan = cl2chan->next;
 | 
			
		||||
	free( cl2chan );
 | 
			
		||||
 | 
			
		||||
	if( ServerPART ) IRC_WriteStrServersPrefix( Origin, Client, "PART %s :%s", c->name, Reason );
 | 
			
		||||
	IRC_WriteStrChannelPrefix( Origin, c, Client, FALSE, "PART %s :%s", c->name, Reason );
 | 
			
		||||
	if(( Client_Conn( Origin ) > NONE ) && ( Client_Type( Origin ) == CLIENT_USER )) IRC_WriteStrClientPrefix( Origin, Client, "PART %s :%s", c->name, Reason );
 | 
			
		||||
	switch( Type )
 | 
			
		||||
	{
 | 
			
		||||
		case REMOVE_QUIT:
 | 
			
		||||
			/* QUIT: andere Server wurden bereits informiert, vgl. Client_Destroy();
 | 
			
		||||
			 * hier also "nur" noch alle User in betroffenen Channeln infomieren */
 | 
			
		||||
			assert( InformServer == FALSE );
 | 
			
		||||
			IRC_WriteStrChannelPrefix( Origin, c, Origin, FALSE, "QUIT :%s", Reason );
 | 
			
		||||
			Log( LOG_DEBUG, "User \"%s\" left channel \"%s\" (%s).", Client_Mask( Client ), c->name, Reason );
 | 
			
		||||
			break;
 | 
			
		||||
		case REMOVE_KICK:
 | 
			
		||||
			/* User wurde geKICKed: ggf. andere Server sowie alle betroffenen User
 | 
			
		||||
			 * im entsprechenden Channel informieren */
 | 
			
		||||
			if( InformServer ) IRC_WriteStrServersPrefix( Client_NextHop( Origin ), Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason );
 | 
			
		||||
			IRC_WriteStrChannelPrefix( Client, c, Origin, FALSE, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason );
 | 
			
		||||
			if(( Client_Conn( Client ) > NONE ) && ( Client_Type( Client ) == CLIENT_USER )) IRC_WriteStrClientPrefix( Client, Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason );
 | 
			
		||||
			Log( LOG_DEBUG, "User \"%s\" has been kicked of \"%s\" by \"%s\": %s.", Client_Mask( Client ), c->name, Client_ID( Origin ), Reason );
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			/* PART */
 | 
			
		||||
			if( InformServer ) IRC_WriteStrServersPrefix( Origin, Client, "PART %s :%s", c->name, Reason );
 | 
			
		||||
			IRC_WriteStrChannelPrefix( Origin, c, Client, FALSE, "PART %s :%s", c->name, Reason );
 | 
			
		||||
			if(( Client_Conn( Origin ) > NONE ) && ( Client_Type( Origin ) == CLIENT_USER )) IRC_WriteStrClientPrefix( Origin, Client, "PART %s :%s", c->name, Reason );
 | 
			
		||||
			Log( LOG_DEBUG, "User \"%s\" left channel \"%s\" (%s).", Client_Mask( Client ), c->name, Reason );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log( LOG_DEBUG, "User \"%s\" left channel \"%s\" (%s).", Client_Mask( Client ), c->name, Reason );
 | 
			
		||||
 | 
			
		||||
	/* Wenn Channel nun leer: loeschen */
 | 
			
		||||
	if( ! Get_First_Cl2Chan( NULL, Chan )) Delete_Channel( Chan );
 | 
			
		||||
	/* Wenn Channel nun leer und nicht pre-defined: loeschen */
 | 
			
		||||
	if( ! strchr( Channel_Modes( Chan ), 'P' ))
 | 
			
		||||
	{
 | 
			
		||||
		if( ! Get_First_Cl2Chan( NULL, Chan )) Delete_Channel( Chan );
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
	return TRUE;
 | 
			
		||||
} /* Remove_Client */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL CL2CHAN *Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan )
 | 
			
		||||
LOCAL CL2CHAN *
 | 
			
		||||
Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	return Get_Next_Cl2Chan( My_Cl2Chan, Client, Chan );
 | 
			
		||||
} /* Get_First_Cl2Chan */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL CL2CHAN *Get_Next_Cl2Chan( CL2CHAN *Start, CLIENT *Client, CHANNEL *Channel )
 | 
			
		||||
LOCAL CL2CHAN *
 | 
			
		||||
Get_Next_Cl2Chan( CL2CHAN *Start, CLIENT *Client, CHANNEL *Channel )
 | 
			
		||||
{
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
 | 
			
		||||
@@ -597,7 +868,8 @@ LOCAL CL2CHAN *Get_Next_Cl2Chan( CL2CHAN *Start, CLIENT *Client, CHANNEL *Channe
 | 
			
		||||
} /* Get_Next_Cl2Chan */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Delete_Channel( CHANNEL *Chan )
 | 
			
		||||
LOCAL BOOLEAN
 | 
			
		||||
Delete_Channel( CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	/* Channel-Struktur loeschen */
 | 
			
		||||
	
 | 
			
		||||
@@ -615,6 +887,9 @@ LOCAL BOOLEAN Delete_Channel( CHANNEL *Chan )
 | 
			
		||||
 | 
			
		||||
	Log( LOG_DEBUG, "Freed channel structure for \"%s\".", Chan->name );
 | 
			
		||||
 | 
			
		||||
	/* Invite- und Ban-Lists aufraeumen */
 | 
			
		||||
	Lists_DeleteChannel( chan );
 | 
			
		||||
 | 
			
		||||
	/* Neu verketten und freigeben */
 | 
			
		||||
	if( last_chan ) last_chan->next = chan->next;
 | 
			
		||||
	else My_Channels = chan->next;
 | 
			
		||||
 
 | 
			
		||||
@@ -2,24 +2,21 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: channel.h,v 1.16 2002/03/25 19:11:01 alex Exp $
 | 
			
		||||
 * $Id: channel.h,v 1.26 2002/12/16 23:05:24 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * channel.h: Management der Channels (Header)
 | 
			
		||||
 * Channel management (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __channel_h__
 | 
			
		||||
#define __channel_h__
 | 
			
		||||
 | 
			
		||||
#include "client.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(__channel_c__) | defined(S_SPLINT_S)
 | 
			
		||||
 | 
			
		||||
@@ -28,10 +25,12 @@
 | 
			
		||||
typedef struct _CHANNEL
 | 
			
		||||
{
 | 
			
		||||
	struct _CHANNEL *next;
 | 
			
		||||
	CHAR name[CHANNEL_NAME_LEN];	/* Name des Channel */
 | 
			
		||||
	UINT32 hash;			/* Hash ueber (kleingeschrieben) Namen */
 | 
			
		||||
	CHAR modes[CHANNEL_MODE_LEN];	/* Channel-Modes */
 | 
			
		||||
	CHAR topic[CHANNEL_TOPIC_LEN];	/* Topic des Channels */
 | 
			
		||||
	CHAR name[CHANNEL_NAME_LEN];	/* Name of the channel */
 | 
			
		||||
	UINT32 hash;			/* Hash of the (lowecase!) name */
 | 
			
		||||
	CHAR modes[CHANNEL_MODE_LEN];	/* Channel modes */
 | 
			
		||||
	CHAR topic[CHANNEL_TOPIC_LEN];	/* Topic of the channel */
 | 
			
		||||
	CHAR key[CLIENT_PASS_LEN];	/* Channel key ("password", mode "k" ) */
 | 
			
		||||
	LONG maxusers;			/* Maximum number of members (mode "l") */
 | 
			
		||||
} CHANNEL;
 | 
			
		||||
 | 
			
		||||
typedef struct _CLIENT2CHAN
 | 
			
		||||
@@ -50,47 +49,60 @@ typedef POINTER CL2CHAN;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Channel_Init( VOID );
 | 
			
		||||
GLOBAL VOID Channel_Exit( VOID );
 | 
			
		||||
GLOBAL VOID Channel_Init PARAMS(( VOID ));
 | 
			
		||||
GLOBAL VOID Channel_InitPredefined PARAMS((  VOID ));
 | 
			
		||||
GLOBAL VOID Channel_Exit PARAMS(( VOID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_Join( CLIENT *Client, CHAR *Name );
 | 
			
		||||
GLOBAL BOOLEAN Channel_Part( CLIENT *Client, CLIENT *Origin, CHAR *Name, CHAR *Reason );
 | 
			
		||||
GLOBAL BOOLEAN Channel_Join PARAMS(( CLIENT *Client, CHAR *Name ));
 | 
			
		||||
GLOBAL BOOLEAN Channel_Part PARAMS(( CLIENT *Client, CLIENT *Origin, CHAR *Name, CHAR *Reason ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Channel_RemoveClient( CLIENT *Client, CHAR *Reason );
 | 
			
		||||
GLOBAL VOID Channel_Quit PARAMS(( CLIENT *Client, CHAR *Reason ));
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Channel_Count( VOID );
 | 
			
		||||
GLOBAL VOID Channel_Kick PARAMS((  CLIENT *Client, CLIENT *Origin, CHAR *Name, CHAR *Reason ));
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *Channel_Name( CHANNEL *Chan );
 | 
			
		||||
GLOBAL CHAR *Channel_Modes( CHANNEL *Chan );
 | 
			
		||||
GLOBAL CHAR *Channel_Topic( CHANNEL *Chan );
 | 
			
		||||
GLOBAL LONG Channel_Count PARAMS(( VOID ));
 | 
			
		||||
GLOBAL LONG Channel_MemberCount PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL INT Channel_CountForUser PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL INT Channel_PCount PARAMS(( VOID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Channel_SetTopic( CHANNEL *Chan, CHAR *Topic );
 | 
			
		||||
GLOBAL CHAR *Channel_Name PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL CHAR *Channel_Modes PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL CHAR *Channel_Topic PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL CHAR *Channel_Key PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL LONG Channel_MaxUsers PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
 | 
			
		||||
GLOBAL CHANNEL *Channel_Search( CHAR *Name );
 | 
			
		||||
GLOBAL VOID Channel_SetTopic PARAMS(( CHANNEL *Chan, CHAR *Topic ));
 | 
			
		||||
GLOBAL VOID Channel_SetModes PARAMS(( CHANNEL *Chan, CHAR *Modes ));
 | 
			
		||||
GLOBAL VOID Channel_SetKey PARAMS(( CHANNEL *Chan, CHAR *Key ));
 | 
			
		||||
GLOBAL VOID Channel_SetMaxUsers PARAMS(( CHANNEL *Chan, LONG Count ));
 | 
			
		||||
 | 
			
		||||
GLOBAL CHANNEL *Channel_First( VOID );
 | 
			
		||||
GLOBAL CHANNEL *Channel_Next( CHANNEL *Chan );
 | 
			
		||||
GLOBAL CHANNEL *Channel_Search PARAMS(( CHAR *Name ));
 | 
			
		||||
 | 
			
		||||
GLOBAL CL2CHAN *Channel_FirstMember( CHANNEL *Chan );
 | 
			
		||||
GLOBAL CL2CHAN *Channel_NextMember( CHANNEL *Chan, CL2CHAN *Cl2Chan );
 | 
			
		||||
GLOBAL CL2CHAN *Channel_FirstChannelOf( CLIENT *Client );
 | 
			
		||||
GLOBAL CL2CHAN *Channel_NextChannelOf( CLIENT *Client, CL2CHAN *Cl2Chan );
 | 
			
		||||
GLOBAL CHANNEL *Channel_First PARAMS(( VOID ));
 | 
			
		||||
GLOBAL CHANNEL *Channel_Next PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Channel_GetClient( CL2CHAN *Cl2Chan );
 | 
			
		||||
GLOBAL CHANNEL *Channel_GetChannel( CL2CHAN *Cl2Chan );
 | 
			
		||||
GLOBAL CL2CHAN *Channel_FirstMember PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
GLOBAL CL2CHAN *Channel_NextMember PARAMS(( CHANNEL *Chan, CL2CHAN *Cl2Chan ));
 | 
			
		||||
GLOBAL CL2CHAN *Channel_FirstChannelOf PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CL2CHAN *Channel_NextChannelOf PARAMS(( CLIENT *Client, CL2CHAN *Cl2Chan ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_IsValidName( CHAR *Name );
 | 
			
		||||
GLOBAL CLIENT *Channel_GetClient PARAMS(( CL2CHAN *Cl2Chan ));
 | 
			
		||||
GLOBAL CHANNEL *Channel_GetChannel PARAMS(( CL2CHAN *Cl2Chan ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_ModeAdd( CHANNEL *Chan, CHAR Mode );
 | 
			
		||||
GLOBAL BOOLEAN Channel_ModeDel( CHANNEL *Chan, CHAR Mode );
 | 
			
		||||
GLOBAL BOOLEAN Channel_IsValidName PARAMS(( CHAR *Name ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_UserModeAdd( CHANNEL *Chan, CLIENT *Client, CHAR Mode );
 | 
			
		||||
GLOBAL BOOLEAN Channel_UserModeDel( CHANNEL *Chan, CLIENT *Client, CHAR Mode );
 | 
			
		||||
GLOBAL CHAR *Channel_UserModes( CHANNEL *Chan, CLIENT *Client );
 | 
			
		||||
GLOBAL BOOLEAN Channel_ModeAdd PARAMS(( CHANNEL *Chan, CHAR Mode ));
 | 
			
		||||
GLOBAL BOOLEAN Channel_ModeDel PARAMS(( CHANNEL *Chan, CHAR Mode ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_IsMemberOf( CHANNEL *Chan, CLIENT *Client );
 | 
			
		||||
GLOBAL BOOLEAN Channel_UserModeAdd PARAMS(( CHANNEL *Chan, CLIENT *Client, CHAR Mode ));
 | 
			
		||||
GLOBAL BOOLEAN Channel_UserModeDel PARAMS(( CHANNEL *Chan, CLIENT *Client, CHAR Mode ));
 | 
			
		||||
GLOBAL CHAR *Channel_UserModes PARAMS(( CHANNEL *Chan, CLIENT *Client ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_Write( CHANNEL *Chan, CLIENT *From, CLIENT *Client, CHAR *Text );
 | 
			
		||||
GLOBAL BOOLEAN Channel_IsMemberOf PARAMS(( CHANNEL *Chan, CLIENT *Client ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Channel_Write PARAMS(( CHANNEL *Chan, CLIENT *From, CLIENT *Client, CHAR *Text ));
 | 
			
		||||
 | 
			
		||||
GLOBAL CHANNEL *Channel_Create PARAMS(( CHAR *Name ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -2,23 +2,13 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: client.c,v 1.53 2002/03/27 20:52:58 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * client.c: Management aller Clients
 | 
			
		||||
 *
 | 
			
		||||
 * Der Begriff "Client" ist in diesem Fall evtl. etwas verwirrend: Clients sind
 | 
			
		||||
 * alle Verbindungen, die im gesamten(!) IRC-Netzwerk bekannt sind. Das sind IRC-
 | 
			
		||||
 * Clients (User), andere Server und IRC-Services.
 | 
			
		||||
 * Ueber welchen IRC-Server die Verbindung nun tatsaechlich in das Netzwerk her-
 | 
			
		||||
 * gestellt wurde, muss der jeweiligen Struktur entnommen werden. Ist es dieser
 | 
			
		||||
 * Server gewesen, so existiert eine entsprechende CONNECTION-Struktur.
 | 
			
		||||
 * Client management.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -27,6 +17,8 @@
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: client.c,v 1.74 2003/03/31 15:54:21 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
@@ -35,14 +27,16 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
 | 
			
		||||
#include <imp.h>
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "hash.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
@@ -51,18 +45,30 @@
 | 
			
		||||
#include <exp.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define GETID_LEN (CLIENT_NICK_LEN-1) + 1 + (CLIENT_USER_LEN-1) + 1 + (CLIENT_HOST_LEN-1) + 1
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL CLIENT *This_Server, *My_Clients;
 | 
			
		||||
LOCAL CHAR GetID_Buffer[CLIENT_ID_LEN];
 | 
			
		||||
LOCAL CHAR GetID_Buffer[GETID_LEN];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL INT Count( CLIENT_TYPE Type );
 | 
			
		||||
LOCAL INT MyCount( CLIENT_TYPE Type );
 | 
			
		||||
LOCAL LONG Count PARAMS(( CLIENT_TYPE Type ));
 | 
			
		||||
LOCAL LONG MyCount PARAMS(( CLIENT_TYPE Type ));
 | 
			
		||||
 | 
			
		||||
LOCAL CLIENT *New_Client_Struct( VOID );
 | 
			
		||||
LOCAL VOID Generate_MyToken( CLIENT *Client );
 | 
			
		||||
LOCAL CLIENT *New_Client_Struct PARAMS(( VOID ));
 | 
			
		||||
LOCAL VOID Generate_MyToken PARAMS(( CLIENT *Client ));
 | 
			
		||||
LOCAL VOID Adjust_Counters PARAMS(( CLIENT *Client ));
 | 
			
		||||
 | 
			
		||||
#ifndef Client_DestroyNow
 | 
			
		||||
GLOBAL VOID Client_DestroyNow PARAMS((CLIENT *Client ));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_Init( VOID )
 | 
			
		||||
LONG Max_Users = 0, My_Max_Users = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_Init( VOID )
 | 
			
		||||
{
 | 
			
		||||
	struct hostent *h;
 | 
			
		||||
	
 | 
			
		||||
@@ -70,7 +76,7 @@ GLOBAL VOID Client_Init( VOID )
 | 
			
		||||
	if( ! This_Server )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_EMERG, "Can't allocate client structure for server! Going down." );
 | 
			
		||||
		Log( LOG_ALERT, PACKAGE" exiting due to fatal errors!" );
 | 
			
		||||
		Log( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME );
 | 
			
		||||
		exit( 1 );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -84,7 +90,7 @@ GLOBAL VOID Client_Init( VOID )
 | 
			
		||||
 | 
			
		||||
	gethostname( This_Server->host, CLIENT_HOST_LEN );
 | 
			
		||||
	h = gethostbyname( This_Server->host );
 | 
			
		||||
	if( h ) strcpy( This_Server->host, h->h_name );
 | 
			
		||||
	if( h ) strlcpy( This_Server->host, h->h_name, sizeof( This_Server->host ));
 | 
			
		||||
 | 
			
		||||
	Client_SetID( This_Server, Conf_ServerName );
 | 
			
		||||
	Client_SetInfo( This_Server, Conf_ServerInfo );
 | 
			
		||||
@@ -93,12 +99,14 @@ GLOBAL VOID Client_Init( VOID )
 | 
			
		||||
} /* Client_Init */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_Exit( VOID )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_Exit( VOID )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c, *next;
 | 
			
		||||
	INT cnt;
 | 
			
		||||
 | 
			
		||||
	Client_Destroy( This_Server, "Server going down.", NULL, FALSE );
 | 
			
		||||
	if( NGIRCd_SignalRestart ) Client_Destroy( This_Server, "Server going down (restarting).", NULL, FALSE );
 | 
			
		||||
	else Client_Destroy( This_Server, "Server going down.", NULL, FALSE );
 | 
			
		||||
	
 | 
			
		||||
	cnt = 0;
 | 
			
		||||
	c = My_Clients;
 | 
			
		||||
@@ -113,34 +121,39 @@ GLOBAL VOID Client_Exit( VOID )
 | 
			
		||||
} /* Client_Exit */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_ThisServer( VOID )
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Client_ThisServer( VOID )
 | 
			
		||||
{
 | 
			
		||||
	return This_Server;
 | 
			
		||||
} /* Client_ThisServer */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_NewLocal( CONN_ID Idx, CHAR *Hostname, INT Type, BOOLEAN Idented )
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Client_NewLocal( CONN_ID Idx, CHAR *Hostname, INT Type, BOOLEAN Idented )
 | 
			
		||||
{
 | 
			
		||||
	/* Neuen lokalen Client erzeugen: Wrapper-Funktion fuer Client_New(). */
 | 
			
		||||
	return Client_New( Idx, This_Server, NULL, Type, NULL, NULL, Hostname, NULL, 0, 0, NULL, Idented );
 | 
			
		||||
} /* Client_NewLocal */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_NewRemoteServer( CLIENT *Introducer, CHAR *Hostname, CLIENT *TopServer, INT Hops, INT Token, CHAR *Info, BOOLEAN Idented )
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Client_NewRemoteServer( CLIENT *Introducer, CHAR *Hostname, CLIENT *TopServer, INT Hops, INT Token, CHAR *Info, BOOLEAN Idented )
 | 
			
		||||
{
 | 
			
		||||
	/* Neuen Remote-Client erzeugen: Wrapper-Funktion fuer Client_New (). */
 | 
			
		||||
	return Client_New( NONE, Introducer, TopServer, CLIENT_SERVER, Hostname, NULL, Hostname, Info, Hops, Token, NULL, Idented );
 | 
			
		||||
} /* Client_NewRemoteServer */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_NewRemoteUser( CLIENT *Introducer, CHAR *Nick, INT Hops, CHAR *User, CHAR *Hostname, INT Token, CHAR *Modes, CHAR *Info, BOOLEAN Idented )
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Client_NewRemoteUser( CLIENT *Introducer, CHAR *Nick, INT Hops, CHAR *User, CHAR *Hostname, INT Token, CHAR *Modes, CHAR *Info, BOOLEAN Idented )
 | 
			
		||||
{
 | 
			
		||||
	/* Neuen Remote-Client erzeugen: Wrapper-Funktion fuer Client_New (). */
 | 
			
		||||
	return Client_New( NONE, Introducer, NULL, CLIENT_USER, Nick, User, Hostname, Info, Hops, Token, Modes, Idented );
 | 
			
		||||
} /* Client_NewRemoteUser */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_New( CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, INT Type, CHAR *ID, CHAR *User, CHAR *Hostname, CHAR *Info, INT Hops, INT Token, CHAR *Modes, BOOLEAN Idented )
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Client_New( CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, INT Type, CHAR *ID, CHAR *User, CHAR *Hostname, CHAR *Info, INT Hops, INT Token, CHAR *Modes, BOOLEAN Idented )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *client;
 | 
			
		||||
 | 
			
		||||
@@ -166,17 +179,21 @@ GLOBAL CLIENT *Client_New( CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, I
 | 
			
		||||
	if( Type == CLIENT_SERVER ) Generate_MyToken( client );
 | 
			
		||||
 | 
			
		||||
	/* ist der User away? */
 | 
			
		||||
	if( strchr( client->modes, 'a' )) strcpy( client->away, DEFAULT_AWAY_MSG );
 | 
			
		||||
	if( strchr( client->modes, 'a' )) strlcpy( client->away, DEFAULT_AWAY_MSG, sizeof( client->away ));
 | 
			
		||||
 | 
			
		||||
	/* Verketten */
 | 
			
		||||
	client->next = (POINTER *)My_Clients;
 | 
			
		||||
	My_Clients = client;
 | 
			
		||||
 | 
			
		||||
	/* Adjust counters */
 | 
			
		||||
	Adjust_Counters( client );
 | 
			
		||||
 | 
			
		||||
	return client;
 | 
			
		||||
} /* Client_New */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_Destroy( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN SendQuit )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_Destroy( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN SendQuit )
 | 
			
		||||
{
 | 
			
		||||
	/* Client entfernen. */
 | 
			
		||||
	
 | 
			
		||||
@@ -190,7 +207,7 @@ GLOBAL VOID Client_Destroy( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN
 | 
			
		||||
	if( ! txt ) txt = "Reason unknown.";
 | 
			
		||||
 | 
			
		||||
	/* Netz-Split-Nachricht vorbereiten (noch nicht optimal) */
 | 
			
		||||
	if( Client->type == CLIENT_SERVER ) sprintf( msg, "%s: lost server %s", This_Server->id, Client->id );
 | 
			
		||||
	if( Client->type == CLIENT_SERVER ) snprintf( msg, sizeof( msg ), "%s: lost server %s", This_Server->id, Client->id );
 | 
			
		||||
 | 
			
		||||
	last = NULL;
 | 
			
		||||
	c = My_Clients;
 | 
			
		||||
@@ -239,7 +256,7 @@ GLOBAL VOID Client_Destroy( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN
 | 
			
		||||
						else IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "QUIT :" );
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				Channel_RemoveClient( c, FwdMsg ? FwdMsg : c->id );
 | 
			
		||||
				Channel_Quit( c, FwdMsg ? FwdMsg : c->id );
 | 
			
		||||
			}
 | 
			
		||||
			else if( c->type == CLIENT_SERVER )
 | 
			
		||||
			{
 | 
			
		||||
@@ -250,7 +267,7 @@ GLOBAL VOID Client_Destroy( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				/* andere Server informieren */
 | 
			
		||||
				if( ! NGIRCd_Quit )
 | 
			
		||||
				if( ! NGIRCd_SignalQuit )
 | 
			
		||||
				{
 | 
			
		||||
					if( FwdMsg ) IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "SQUIT %s :%s", c->id, FwdMsg );
 | 
			
		||||
					else IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "SQUIT %s :", c->id );
 | 
			
		||||
@@ -279,132 +296,168 @@ GLOBAL VOID Client_Destroy( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN
 | 
			
		||||
} /* Client_Destroy */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_SetHostname( CLIENT *Client, CHAR *Hostname )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_DestroyNow( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	/* Destroy client structure immediately. This function is only
 | 
			
		||||
	 * intended for the connection layer to remove client structures
 | 
			
		||||
	 * of connections that can't be established! */
 | 
			
		||||
 | 
			
		||||
	CLIENT *last, *c;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
	last = NULL;
 | 
			
		||||
	c = My_Clients;
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		if( c == Client )
 | 
			
		||||
		{
 | 
			
		||||
			/* Wir haben den Client gefunden: entfernen */
 | 
			
		||||
			if( last ) last->next = c->next;
 | 
			
		||||
			else My_Clients = (CLIENT *)c->next;
 | 
			
		||||
			free( c );
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		last = c;
 | 
			
		||||
		c = (CLIENT *)c->next;
 | 
			
		||||
	}
 | 
			
		||||
} /* Client_DestroyNow */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_SetHostname( CLIENT *Client, CHAR *Hostname )
 | 
			
		||||
{
 | 
			
		||||
	/* Hostname eines Clients setzen */
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Hostname != NULL );
 | 
			
		||||
	
 | 
			
		||||
	strncpy( Client->host, Hostname, CLIENT_HOST_LEN - 1 );
 | 
			
		||||
	Client->host[CLIENT_HOST_LEN - 1] = '\0';
 | 
			
		||||
	strlcpy( Client->host, Hostname, sizeof( Client->host ));
 | 
			
		||||
} /* Client_SetHostname */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_SetID( CLIENT *Client, CHAR *ID )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_SetID( CLIENT *Client, CHAR *ID )
 | 
			
		||||
{
 | 
			
		||||
	/* Hostname eines Clients setzen, Hash-Wert berechnen */
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( ID != NULL );
 | 
			
		||||
	
 | 
			
		||||
	strncpy( Client->id, ID, CLIENT_ID_LEN - 1 );
 | 
			
		||||
	Client->id[CLIENT_ID_LEN - 1] = '\0';
 | 
			
		||||
	strlcpy( Client->id, ID, sizeof( Client->id ));
 | 
			
		||||
 | 
			
		||||
	/* Hash */
 | 
			
		||||
	Client->hash = Hash( Client->id );
 | 
			
		||||
} /* Client_SetID */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_SetUser( CLIENT *Client, CHAR *User, BOOLEAN Idented )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_SetUser( CLIENT *Client, CHAR *User, BOOLEAN Idented )
 | 
			
		||||
{
 | 
			
		||||
	/* Username eines Clients setzen */
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( User != NULL );
 | 
			
		||||
	
 | 
			
		||||
	if( Idented ) strncpy( Client->user, User, CLIENT_USER_LEN - 1 );
 | 
			
		||||
	if( Idented ) strlcpy( Client->user, User, sizeof( Client->user ));
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		Client->user[0] = '~';
 | 
			
		||||
		strncpy( Client->user + 1, User, CLIENT_USER_LEN - 2 );
 | 
			
		||||
		strlcpy( Client->user + 1, User, sizeof( Client->user ) - 1 );
 | 
			
		||||
	}
 | 
			
		||||
	Client->user[CLIENT_USER_LEN - 1] = '\0';
 | 
			
		||||
} /* Client_SetUser */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_SetInfo( CLIENT *Client, CHAR *Info )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_SetInfo( CLIENT *Client, CHAR *Info )
 | 
			
		||||
{
 | 
			
		||||
	/* Hostname eines Clients setzen */
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Info != NULL );
 | 
			
		||||
	
 | 
			
		||||
	strncpy( Client->info, Info, CLIENT_INFO_LEN - 1 );
 | 
			
		||||
	Client->info[CLIENT_INFO_LEN - 1] = '\0';
 | 
			
		||||
	strlcpy( Client->info, Info, sizeof( Client->info ));
 | 
			
		||||
} /* Client_SetInfo */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_SetModes( CLIENT *Client, CHAR *Modes )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_SetModes( CLIENT *Client, CHAR *Modes )
 | 
			
		||||
{
 | 
			
		||||
	/* Hostname eines Clients setzen */
 | 
			
		||||
	/* Modes eines Clients setzen */
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Modes != NULL );
 | 
			
		||||
 | 
			
		||||
	strncpy( Client->modes, Modes, CLIENT_MODE_LEN - 1 );
 | 
			
		||||
	Client->modes[CLIENT_MODE_LEN - 1] = '\0';
 | 
			
		||||
	strlcpy( Client->modes, Modes, sizeof( Client->modes ));
 | 
			
		||||
} /* Client_SetModes */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_SetPassword( CLIENT *Client, CHAR *Pwd )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_SetFlags( CLIENT *Client, CHAR *Flags )
 | 
			
		||||
{
 | 
			
		||||
	/* Flags eines Clients setzen */
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Flags != NULL );
 | 
			
		||||
 | 
			
		||||
	strlcpy( Client->flags, Flags, sizeof( Client->flags ));
 | 
			
		||||
} /* Client_SetFlags */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_SetPassword( CLIENT *Client, CHAR *Pwd )
 | 
			
		||||
{
 | 
			
		||||
	/* Von einem Client geliefertes Passwort */
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Pwd != NULL );
 | 
			
		||||
	
 | 
			
		||||
	strncpy( Client->pwd, Pwd, CLIENT_PASS_LEN - 1 );
 | 
			
		||||
	Client->pwd[CLIENT_PASS_LEN - 1] = '\0';
 | 
			
		||||
	strlcpy( Client->pwd, Pwd, sizeof( Client->pwd ));
 | 
			
		||||
} /* Client_SetPassword */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_SetAway( CLIENT *Client, CHAR *Txt )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_SetAway( CLIENT *Client, CHAR *Txt )
 | 
			
		||||
{
 | 
			
		||||
	/* Von einem Client gelieferte AWAY-Nachricht */
 | 
			
		||||
	/* Set AWAY reason of client */
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Txt != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Txt )
 | 
			
		||||
	{
 | 
			
		||||
		/* Client AWAY setzen */
 | 
			
		||||
		strncpy( Client->away, Txt, CLIENT_AWAY_LEN - 1 );
 | 
			
		||||
		Client->away[CLIENT_AWAY_LEN - 1] = '\0';
 | 
			
		||||
		Client_ModeAdd( Client, 'a' );
 | 
			
		||||
		Log( LOG_DEBUG, "User \"%s\" is away: %s", Client_Mask( Client ), Txt );
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* AWAY loeschen */
 | 
			
		||||
		Client_ModeDel( Client, 'a' );
 | 
			
		||||
		Log( LOG_DEBUG, "User \"%s\" is no longer away.", Client_Mask( Client ));
 | 
			
		||||
	}
 | 
			
		||||
	strlcpy( Client->away, Txt, sizeof( Client->away ));
 | 
			
		||||
	Log( LOG_DEBUG, "User \"%s\" is away: %s", Client_Mask( Client ), Txt );
 | 
			
		||||
} /* Client_SetAway */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_SetType( CLIENT *Client, INT Type )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_SetType( CLIENT *Client, INT Type )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	Client->type = Type;
 | 
			
		||||
	if( Type == CLIENT_SERVER ) Generate_MyToken( Client );
 | 
			
		||||
	Adjust_Counters( Client );
 | 
			
		||||
} /* Client_SetType */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_SetHops( CLIENT *Client, INT Hops )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_SetHops( CLIENT *Client, INT Hops )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	Client->hops = Hops;
 | 
			
		||||
} /* Client_SetHops */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_SetToken( CLIENT *Client, INT Token )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_SetToken( CLIENT *Client, INT Token )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	Client->token = Token;
 | 
			
		||||
} /* Client_SetToken */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_SetIntroducer( CLIENT *Client, CLIENT *Introducer )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_SetIntroducer( CLIENT *Client, CLIENT *Introducer )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Introducer != NULL );
 | 
			
		||||
@@ -412,14 +465,16 @@ GLOBAL VOID Client_SetIntroducer( CLIENT *Client, CLIENT *Introducer )
 | 
			
		||||
} /* Client_SetIntroducer */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_SetOperByMe( CLIENT *Client, BOOLEAN OperByMe )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Client_SetOperByMe( CLIENT *Client, BOOLEAN OperByMe )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	Client->oper_by_me = OperByMe;
 | 
			
		||||
} /* Client_SetOperByMe */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Client_ModeAdd( CLIENT *Client, CHAR Mode )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Client_ModeAdd( CLIENT *Client, CHAR Mode )
 | 
			
		||||
{
 | 
			
		||||
	/* Mode soll gesetzt werden. TRUE wird geliefert, wenn der
 | 
			
		||||
	 * Mode neu gesetzt wurde, FALSE, wenn der Client den Mode
 | 
			
		||||
@@ -433,14 +488,15 @@ GLOBAL BOOLEAN Client_ModeAdd( CLIENT *Client, CHAR Mode )
 | 
			
		||||
	if( ! strchr( Client->modes, x[0] ))
 | 
			
		||||
	{
 | 
			
		||||
		/* Client hat den Mode noch nicht -> setzen */
 | 
			
		||||
		strcat( Client->modes, x );
 | 
			
		||||
		strlcat( Client->modes, x, sizeof( Client->modes ));
 | 
			
		||||
		return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
	else return FALSE;
 | 
			
		||||
} /* Client_ModeAdd */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Client_ModeDel( CLIENT *Client, CHAR Mode )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Client_ModeDel( CLIENT *Client, CHAR Mode )
 | 
			
		||||
{
 | 
			
		||||
	/* Mode soll geloescht werden. TRUE wird geliefert, wenn der
 | 
			
		||||
	* Mode entfernt wurde, FALSE, wenn der Client den Mode
 | 
			
		||||
@@ -465,7 +521,8 @@ GLOBAL BOOLEAN Client_ModeDel( CLIENT *Client, CHAR Mode )
 | 
			
		||||
} /* Client_ModeDel */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_GetFromConn( CONN_ID Idx )
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Client_GetFromConn( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Client-Struktur, die zur lokalen Verbindung Idx gehoert,
 | 
			
		||||
	 * liefern. Wird keine gefunden, so wird NULL geliefert. */
 | 
			
		||||
@@ -484,7 +541,8 @@ GLOBAL CLIENT *Client_GetFromConn( CONN_ID Idx )
 | 
			
		||||
} /* Client_GetFromConn */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_Search( CHAR *Nick )
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Client_Search( CHAR *Nick )
 | 
			
		||||
{
 | 
			
		||||
	/* Client-Struktur, die den entsprechenden Nick hat, liefern.
 | 
			
		||||
	 * Wird keine gefunden, so wird NULL geliefert. */
 | 
			
		||||
@@ -496,8 +554,7 @@ GLOBAL CLIENT *Client_Search( CHAR *Nick )
 | 
			
		||||
	assert( Nick != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Nick kopieren und ggf. Host-Mask abschneiden */
 | 
			
		||||
	strncpy( search_id, Nick, CLIENT_ID_LEN - 1 );
 | 
			
		||||
	search_id[CLIENT_ID_LEN - 1] = '\0';
 | 
			
		||||
	strlcpy( search_id, Nick, sizeof( search_id ));
 | 
			
		||||
	ptr = strchr( search_id, '!' );
 | 
			
		||||
	if( ptr ) *ptr = '\0';
 | 
			
		||||
 | 
			
		||||
@@ -517,7 +574,8 @@ GLOBAL CLIENT *Client_Search( CHAR *Nick )
 | 
			
		||||
} /* Client_Search */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_GetFromToken( CLIENT *Client, INT Token )
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Client_GetFromToken( CLIENT *Client, INT Token )
 | 
			
		||||
{
 | 
			
		||||
	/* Client-Struktur, die den entsprechenden Introducer (=Client)
 | 
			
		||||
	 * und das gegebene Token hat, liefern. Wird keine gefunden,
 | 
			
		||||
@@ -538,21 +596,24 @@ GLOBAL CLIENT *Client_GetFromToken( CLIENT *Client, INT Token )
 | 
			
		||||
} /* Client_GetFromToken */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Client_Type( CLIENT *Client )
 | 
			
		||||
GLOBAL INT
 | 
			
		||||
Client_Type( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Client->type;
 | 
			
		||||
} /* Client_Type */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CONN_ID Client_Conn( CLIENT *Client )
 | 
			
		||||
GLOBAL CONN_ID
 | 
			
		||||
Client_Conn( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Client->conn_id;
 | 
			
		||||
} /* Client_Conn */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *Client_ID( CLIENT *Client )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Client_ID( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
@@ -565,14 +626,16 @@ GLOBAL CHAR *Client_ID( CLIENT *Client )
 | 
			
		||||
} /* Client_ID */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *Client_Info( CLIENT *Client )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Client_Info( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Client->info;
 | 
			
		||||
} /* Client_Info */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *Client_User( CLIENT *Client )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Client_User( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	if( Client->user[0] ) return Client->user;
 | 
			
		||||
@@ -580,56 +643,72 @@ GLOBAL CHAR *Client_User( CLIENT *Client )
 | 
			
		||||
} /* Client_User */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *Client_Hostname( CLIENT *Client )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Client_Hostname( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Client->host;
 | 
			
		||||
} /* Client_Hostname */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *Client_Password( CLIENT *Client )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Client_Password( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Client->pwd;
 | 
			
		||||
} /* Client_Password */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *Client_Modes( CLIENT *Client )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Client_Modes( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Client->modes;
 | 
			
		||||
} /* Client_Modes */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Client_OperByMe( CLIENT *Client )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Client_Flags( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Client->flags;
 | 
			
		||||
} /* Client_Flags */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Client_OperByMe( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Client->oper_by_me;
 | 
			
		||||
} /* Client_OperByMe */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Client_Hops( CLIENT *Client )
 | 
			
		||||
GLOBAL INT
 | 
			
		||||
Client_Hops( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Client->hops;
 | 
			
		||||
} /* Client_Hops */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Client_Token( CLIENT *Client )
 | 
			
		||||
GLOBAL INT
 | 
			
		||||
Client_Token( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Client->token;
 | 
			
		||||
} /* Client_Token */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Client_MyToken( CLIENT *Client )
 | 
			
		||||
GLOBAL INT
 | 
			
		||||
Client_MyToken( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Client->mytoken;
 | 
			
		||||
} /* Client_MyToken */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_NextHop( CLIENT *Client )
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Client_NextHop( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	
 | 
			
		||||
@@ -641,7 +720,8 @@ GLOBAL CLIENT *Client_NextHop( CLIENT *Client )
 | 
			
		||||
} /* Client_NextHop */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *Client_Mask( CLIENT *Client )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Client_Mask( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	/* Client-"ID" liefern, wie sie z.B. fuer
 | 
			
		||||
	 * Prefixe benoetigt wird. */
 | 
			
		||||
@@ -650,33 +730,37 @@ GLOBAL CHAR *Client_Mask( CLIENT *Client )
 | 
			
		||||
	
 | 
			
		||||
	if( Client->type == CLIENT_SERVER ) return Client->id;
 | 
			
		||||
 | 
			
		||||
	sprintf( GetID_Buffer, "%s!%s@%s", Client->id, Client->user, Client->host );
 | 
			
		||||
	snprintf( GetID_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user, Client->host );
 | 
			
		||||
	return GetID_Buffer;
 | 
			
		||||
} /* Client_Mask */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_Introducer( CLIENT *Client )
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Client_Introducer( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Client->introducer;
 | 
			
		||||
} /* Client_Introducer */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_TopServer( CLIENT *Client )
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Client_TopServer( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return Client->topserver;
 | 
			
		||||
} /* Client_TopServer */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Client_HasMode( CLIENT *Client, CHAR Mode )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Client_HasMode( CLIENT *Client, CHAR Mode )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	return strchr( Client->modes, Mode ) != NULL;
 | 
			
		||||
} /* Client_HasMode */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *Client_Away( CLIENT *Client )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Client_Away( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	/* AWAY-Text liefern */
 | 
			
		||||
 | 
			
		||||
@@ -685,7 +769,8 @@ GLOBAL CHAR *Client_Away( CLIENT *Client )
 | 
			
		||||
} /* Client_Away */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Client_CheckNick( CLIENT *Client, CHAR *Nick )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Client_CheckNick( CLIENT *Client, CHAR *Nick )
 | 
			
		||||
{
 | 
			
		||||
	/* Nick ueberpruefen */
 | 
			
		||||
 | 
			
		||||
@@ -711,7 +796,8 @@ GLOBAL BOOLEAN Client_CheckNick( CLIENT *Client, CHAR *Nick )
 | 
			
		||||
} /* Client_CheckNick */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Client_CheckID( CLIENT *Client, CHAR *ID )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Client_CheckID( CLIENT *Client, CHAR *ID )
 | 
			
		||||
{
 | 
			
		||||
	/* Nick ueberpruefen */
 | 
			
		||||
 | 
			
		||||
@@ -736,8 +822,9 @@ GLOBAL BOOLEAN Client_CheckID( CLIENT *Client, CHAR *ID )
 | 
			
		||||
		if( strcasecmp( c->id, ID ) == 0 )
 | 
			
		||||
		{
 | 
			
		||||
			/* die Server-ID gibt es bereits */
 | 
			
		||||
			sprintf( str, "ID \"%s\" already registered!", ID );
 | 
			
		||||
			Log( LOG_ERR, "%s (on connection %d)", str, Client->conn_id );
 | 
			
		||||
			snprintf( str, sizeof( str ), "ID \"%s\" already registered", ID );
 | 
			
		||||
			if( Client->conn_id != c->conn_id ) Log( LOG_ERR, "%s (on connection %d)!", str, c->conn_id );
 | 
			
		||||
			else Log( LOG_ERR, "%s (via network)!", str );
 | 
			
		||||
			Conn_Close( Client->conn_id, str, str, TRUE );
 | 
			
		||||
			return FALSE;
 | 
			
		||||
		}
 | 
			
		||||
@@ -748,7 +835,8 @@ GLOBAL BOOLEAN Client_CheckID( CLIENT *Client, CHAR *ID )
 | 
			
		||||
} /* Client_CheckID */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_First( VOID )
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Client_First( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Ersten Client liefern. */
 | 
			
		||||
 | 
			
		||||
@@ -756,7 +844,8 @@ GLOBAL CLIENT *Client_First( VOID )
 | 
			
		||||
} /* Client_First */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_Next( CLIENT *c )
 | 
			
		||||
GLOBAL CLIENT *
 | 
			
		||||
Client_Next( CLIENT *c )
 | 
			
		||||
{
 | 
			
		||||
	/* Naechsten Client liefern. Existiert keiner,
 | 
			
		||||
	 * so wird NULL geliefert. */
 | 
			
		||||
@@ -766,46 +855,63 @@ GLOBAL CLIENT *Client_Next( CLIENT *c )
 | 
			
		||||
} /* Client_Next */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Client_UserCount( VOID )
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Client_UserCount( VOID )
 | 
			
		||||
{
 | 
			
		||||
	return Count( CLIENT_USER );
 | 
			
		||||
} /* Client_UserCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Client_ServiceCount( VOID )
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Client_ServiceCount( VOID )
 | 
			
		||||
{
 | 
			
		||||
	return Count( CLIENT_SERVICE );;
 | 
			
		||||
} /* Client_ServiceCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Client_ServerCount( VOID )
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Client_ServerCount( VOID )
 | 
			
		||||
{
 | 
			
		||||
	return Count( CLIENT_SERVER );
 | 
			
		||||
} /* Client_ServerCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Client_MyUserCount( VOID )
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Client_MyUserCount( VOID )
 | 
			
		||||
{
 | 
			
		||||
	return MyCount( CLIENT_USER );
 | 
			
		||||
} /* Client_MyUserCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Client_MyServiceCount( VOID )
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Client_MyServiceCount( VOID )
 | 
			
		||||
{
 | 
			
		||||
	return MyCount( CLIENT_SERVICE );
 | 
			
		||||
} /* Client_MyServiceCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Client_MyServerCount( VOID )
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Client_MyServerCount( VOID )
 | 
			
		||||
{
 | 
			
		||||
	return MyCount( CLIENT_SERVER );
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	LONG cnt;
 | 
			
		||||
 | 
			
		||||
	cnt = 0;
 | 
			
		||||
	c = My_Clients;
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		if(( c->type == CLIENT_SERVER ) && ( c->hops == 1 )) cnt++;
 | 
			
		||||
		c = (CLIENT *)c->next;
 | 
			
		||||
	}
 | 
			
		||||
	return cnt;
 | 
			
		||||
} /* Client_MyServerCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Client_OperCount( VOID )
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Client_OperCount( VOID )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	INT cnt;
 | 
			
		||||
	LONG cnt;
 | 
			
		||||
 | 
			
		||||
	cnt = 0;
 | 
			
		||||
	c = My_Clients;
 | 
			
		||||
@@ -818,10 +924,11 @@ GLOBAL INT Client_OperCount( VOID )
 | 
			
		||||
} /* Client_OperCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Client_UnknownCount( VOID )
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Client_UnknownCount( VOID )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	INT cnt;
 | 
			
		||||
	LONG cnt;
 | 
			
		||||
 | 
			
		||||
	cnt = 0;
 | 
			
		||||
	c = My_Clients;
 | 
			
		||||
@@ -834,14 +941,31 @@ GLOBAL INT Client_UnknownCount( VOID )
 | 
			
		||||
} /* Client_UnknownCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Client_IsValidNick( CHAR *Nick )
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Client_MaxUserCount( VOID )
 | 
			
		||||
{
 | 
			
		||||
	return Max_Users;
 | 
			
		||||
} /* Client_MaxUserCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Client_MyMaxUserCount( VOID )
 | 
			
		||||
{
 | 
			
		||||
	return My_Max_Users;
 | 
			
		||||
} /* Client_MyMaxUserCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Client_IsValidNick( CHAR *Nick )
 | 
			
		||||
{
 | 
			
		||||
	/* Ist der Nick gueltig? */
 | 
			
		||||
 | 
			
		||||
	CHAR *ptr, goodchars[] = ";0123456789-";
 | 
			
		||||
	CHAR *ptr, goodchars[20];
 | 
			
		||||
	
 | 
			
		||||
	assert( Nick != NULL );
 | 
			
		||||
 | 
			
		||||
	strcpy( goodchars, ";0123456789-" );
 | 
			
		||||
 | 
			
		||||
	if( Nick[0] == '#' ) return FALSE;
 | 
			
		||||
	if( strchr( goodchars, Nick[0] )) return FALSE;
 | 
			
		||||
	if( strlen( Nick ) >= CLIENT_NICK_LEN ) return FALSE;
 | 
			
		||||
@@ -858,39 +982,42 @@ GLOBAL BOOLEAN Client_IsValidNick( CHAR *Nick )
 | 
			
		||||
} /* Client_IsValidNick */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL INT Count( CLIENT_TYPE Type )
 | 
			
		||||
LOCAL LONG
 | 
			
		||||
Count( CLIENT_TYPE Type )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	INT cnt;
 | 
			
		||||
	LONG cnt;
 | 
			
		||||
 | 
			
		||||
	cnt = 0;
 | 
			
		||||
	c = My_Clients;
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		if( c && ( c->type == Type )) cnt++;
 | 
			
		||||
		if( c->type == Type ) cnt++;
 | 
			
		||||
		c = (CLIENT *)c->next;
 | 
			
		||||
	}
 | 
			
		||||
	return cnt;
 | 
			
		||||
} /* Count */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL INT MyCount( CLIENT_TYPE Type )
 | 
			
		||||
LOCAL LONG
 | 
			
		||||
MyCount( CLIENT_TYPE Type )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	INT cnt;
 | 
			
		||||
	LONG cnt;
 | 
			
		||||
 | 
			
		||||
	cnt = 0;
 | 
			
		||||
	c = My_Clients;
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		if( c && ( c->introducer == This_Server ) && ( c->type == Type )) cnt++;
 | 
			
		||||
		if(( c->introducer == This_Server ) && ( c->type == Type )) cnt++;
 | 
			
		||||
		c = (CLIENT *)c->next;
 | 
			
		||||
	}
 | 
			
		||||
	return cnt;
 | 
			
		||||
} /* MyCount */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL CLIENT *New_Client_Struct( VOID )
 | 
			
		||||
LOCAL CLIENT *
 | 
			
		||||
New_Client_Struct( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Neue CLIENT-Struktur pre-initialisieren */
 | 
			
		||||
	
 | 
			
		||||
@@ -899,7 +1026,7 @@ LOCAL CLIENT *New_Client_Struct( VOID )
 | 
			
		||||
	c = malloc( sizeof( CLIENT ));
 | 
			
		||||
	if( ! c )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_EMERG, "Can't allocate memory!" );
 | 
			
		||||
		Log( LOG_EMERG, "Can't allocate memory! [New_Client_Struct]" );
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -920,12 +1047,14 @@ LOCAL CLIENT *New_Client_Struct( VOID )
 | 
			
		||||
	c->token = -1;
 | 
			
		||||
	c->mytoken = -1;
 | 
			
		||||
	strcpy( c->away, "" );
 | 
			
		||||
	strcpy( c->flags, "" );
 | 
			
		||||
 | 
			
		||||
	return c;
 | 
			
		||||
} /* New_Client */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Generate_MyToken( CLIENT *Client )
 | 
			
		||||
LOCAL VOID
 | 
			
		||||
Generate_MyToken( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	INT token;
 | 
			
		||||
@@ -948,4 +1077,24 @@ LOCAL VOID Generate_MyToken( CLIENT *Client )
 | 
			
		||||
} /* Generate_MyToken */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID
 | 
			
		||||
Adjust_Counters( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	LONG count;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Client->type != CLIENT_USER ) return;
 | 
			
		||||
	
 | 
			
		||||
	if( Client->conn_id != NONE )
 | 
			
		||||
	{
 | 
			
		||||
		/* Local connection */
 | 
			
		||||
		count = Client_MyUserCount( );
 | 
			
		||||
		if( count > My_Max_Users ) My_Max_Users = count;
 | 
			
		||||
	}
 | 
			
		||||
	count = Client_UserCount( );
 | 
			
		||||
	if( count > Max_Users ) Max_Users = count;
 | 
			
		||||
} /* Adjust_Counters */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -2,37 +2,33 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: client.h,v 1.27 2002/03/25 19:11:01 alex Exp $
 | 
			
		||||
 * $Id: client.h,v 1.34 2003/01/15 14:28:25 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * client.h: Konfiguration des ngircd (Header)
 | 
			
		||||
 * Client management (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __client_h__
 | 
			
		||||
#define __client_h__
 | 
			
		||||
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
 | 
			
		||||
#define CLIENT_UNKNOWN 1		/* connection of unknown type */
 | 
			
		||||
#define CLIENT_GOTPASS 2		/* client did send PASS */
 | 
			
		||||
#define CLIENT_GOTNICK 4		/* client did send NICK */
 | 
			
		||||
#define CLIENT_GOTUSER 8		/* client did send USER */
 | 
			
		||||
#define CLIENT_USER 16			/* client is an IRC user */
 | 
			
		||||
#define CLIENT_UNKNOWNSERVER 32		/* unregistered server connection */
 | 
			
		||||
#define CLIENT_GOTPASSSERVER 64		/* client did send PASS in "server style" */
 | 
			
		||||
#define CLIENT_SERVER 128		/* client is a server */
 | 
			
		||||
#define CLIENT_SERVICE 256		/* client is a service */
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
	CLIENT_UNKNOWN,			/* Verbindung mit (noch) unbekanntem Typ */
 | 
			
		||||
	CLIENT_GOTPASS,			/* Client hat PASS gesendet */
 | 
			
		||||
	CLIENT_GOTNICK,			/* Client hat NICK gesendet */
 | 
			
		||||
	CLIENT_GOTUSER,			/* Client hat USER gesendet */
 | 
			
		||||
	CLIENT_USER,			/* Client ist ein Benutzer (USER wurde gesendet) */
 | 
			
		||||
	CLIENT_UNKNOWNSERVER,		/* unregistrierte Server-Verbindung */
 | 
			
		||||
	CLIENT_GOTPASSSERVER,		/* Client hat PASS nach "Server-Art" gesendet */
 | 
			
		||||
	CLIENT_SERVER,			/* Client ist ein Server */
 | 
			
		||||
	CLIENT_SERVICE			/* Client ist ein Service */
 | 
			
		||||
} CLIENT_TYPE;
 | 
			
		||||
#define CLIENT_TYPE INT
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(__client_c__) | defined(S_SPLINT_S)
 | 
			
		||||
@@ -41,21 +37,22 @@ typedef enum
 | 
			
		||||
 | 
			
		||||
typedef struct _CLIENT
 | 
			
		||||
{
 | 
			
		||||
	CHAR id[CLIENT_ID_LEN];		/* Nick (User) bzw. ID (Server) */
 | 
			
		||||
	UINT32 hash;			/* Hash ueber die (kleingeschriebene) ID */
 | 
			
		||||
	POINTER *next;			/* Zeiger auf naechste Client-Struktur */
 | 
			
		||||
	CLIENT_TYPE type;		/* Typ des Client, vgl. CLIENT_TYPE */
 | 
			
		||||
	CONN_ID conn_id;		/* ID der Connection (wenn lokal) bzw. NONE (remote) */
 | 
			
		||||
	struct _CLIENT *introducer;	/* ID des Servers, der die Verbindung hat */
 | 
			
		||||
	struct _CLIENT *topserver;	/* Toplevel-Servers (nur gueltig, wenn Client ein Server ist) */
 | 
			
		||||
	CHAR pwd[CLIENT_PASS_LEN];	/* Passwort, welches der Client angegeben hat */
 | 
			
		||||
	CHAR host[CLIENT_HOST_LEN];	/* Hostname des Client */
 | 
			
		||||
	CHAR user[CLIENT_USER_LEN];	/* Benutzername ("Login") */
 | 
			
		||||
	CHAR info[CLIENT_INFO_LEN];	/* Langer Benutzername (User) bzw. Infotext (Server) */
 | 
			
		||||
	CHAR modes[CLIENT_MODE_LEN];	/* Client Modes */
 | 
			
		||||
	INT hops, token, mytoken;	/* "Hops" und "Token" (-> SERVER-Befehl) */
 | 
			
		||||
	BOOLEAN oper_by_me;		/* IRC-Operator-Status durch diesen Server? */
 | 
			
		||||
	CHAR away[CLIENT_AWAY_LEN];	/* AWAY-Text, wenn Mode 'a' gesetzt */
 | 
			
		||||
	CHAR id[CLIENT_ID_LEN];		/* nick (user) / ID (server) */
 | 
			
		||||
	UINT32 hash;			/* hash of lower-case ID */
 | 
			
		||||
	POINTER *next;			/* pointer to next client structure */
 | 
			
		||||
	CLIENT_TYPE type;		/* type of client, see CLIENT_xxx */
 | 
			
		||||
	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 user[CLIENT_USER_LEN];	/* user name ("login") */
 | 
			
		||||
	CHAR info[CLIENT_INFO_LEN];	/* long user name (user) / info text (server) */
 | 
			
		||||
	CHAR modes[CLIENT_MODE_LEN];	/* client modes */
 | 
			
		||||
	INT hops, token, mytoken;	/* "hops" and "Token" (see SERVER command) */
 | 
			
		||||
	BOOLEAN 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 */
 | 
			
		||||
} CLIENT;
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
@@ -65,74 +62,81 @@ typedef POINTER CLIENT;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_Init( VOID );
 | 
			
		||||
GLOBAL VOID Client_Exit( VOID );
 | 
			
		||||
GLOBAL VOID Client_Init PARAMS(( VOID ));
 | 
			
		||||
GLOBAL VOID Client_Exit PARAMS(( VOID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_NewLocal( CONN_ID Idx, CHAR *Hostname, INT Type, BOOLEAN Idented );
 | 
			
		||||
GLOBAL CLIENT *Client_NewRemoteServer( CLIENT *Introducer, CHAR *Hostname, CLIENT *TopServer, INT Hops, INT Token, CHAR *Info, BOOLEAN Idented );
 | 
			
		||||
GLOBAL CLIENT *Client_NewRemoteUser( CLIENT *Introducer, CHAR *Nick, INT Hops, CHAR *User, CHAR *Hostname, INT Token, CHAR *Modes, CHAR *Info, BOOLEAN Idented );
 | 
			
		||||
GLOBAL CLIENT *Client_New( CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, INT Type, CHAR *ID, CHAR *User, CHAR *Hostname, CHAR *Info, INT Hops, INT Token, CHAR *Modes, BOOLEAN Idented );
 | 
			
		||||
GLOBAL CLIENT *Client_NewLocal PARAMS(( CONN_ID Idx, CHAR *Hostname, INT Type, BOOLEAN Idented ));
 | 
			
		||||
GLOBAL CLIENT *Client_NewRemoteServer PARAMS(( CLIENT *Introducer, CHAR *Hostname, CLIENT *TopServer, INT Hops, INT Token, CHAR *Info, BOOLEAN Idented ));
 | 
			
		||||
GLOBAL CLIENT *Client_NewRemoteUser PARAMS(( CLIENT *Introducer, CHAR *Nick, INT Hops, CHAR *User, CHAR *Hostname, INT Token, CHAR *Modes, CHAR *Info, BOOLEAN Idented ));
 | 
			
		||||
GLOBAL CLIENT *Client_New PARAMS(( CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, INT Type, CHAR *ID, CHAR *User, CHAR *Hostname, CHAR *Info, INT Hops, INT Token, CHAR *Modes, BOOLEAN Idented ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_Destroy( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN SendQuit );
 | 
			
		||||
GLOBAL VOID Client_Destroy PARAMS(( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN SendQuit ));
 | 
			
		||||
#ifdef CONN_MODULE
 | 
			
		||||
GLOBAL VOID Client_DestroyNow PARAMS(( CLIENT *Client ));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_ThisServer( VOID );
 | 
			
		||||
GLOBAL CLIENT *Client_ThisServer PARAMS(( VOID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_GetFromConn( CONN_ID Idx );
 | 
			
		||||
GLOBAL CLIENT *Client_GetFromToken( CLIENT *Client, INT Token );
 | 
			
		||||
GLOBAL CLIENT *Client_GetFromConn PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL CLIENT *Client_GetFromToken PARAMS(( CLIENT *Client, INT Token ));
 | 
			
		||||
 | 
			
		||||
GLOBAL CLIENT *Client_Search( CHAR *ID );
 | 
			
		||||
GLOBAL CLIENT *Client_First( VOID );
 | 
			
		||||
GLOBAL CLIENT *Client_Next( CLIENT *c );
 | 
			
		||||
GLOBAL CLIENT *Client_Search PARAMS(( CHAR *ID ));
 | 
			
		||||
GLOBAL CLIENT *Client_First PARAMS(( VOID ));
 | 
			
		||||
GLOBAL CLIENT *Client_Next PARAMS(( CLIENT *c ));
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Client_Type( CLIENT *Client );
 | 
			
		||||
GLOBAL CONN_ID Client_Conn( CLIENT *Client );
 | 
			
		||||
GLOBAL CHAR *Client_ID( CLIENT *Client );
 | 
			
		||||
GLOBAL CHAR *Client_Mask( CLIENT *Client );
 | 
			
		||||
GLOBAL CHAR *Client_Info( CLIENT *Client );
 | 
			
		||||
GLOBAL CHAR *Client_User( CLIENT *Client );
 | 
			
		||||
GLOBAL CHAR *Client_Hostname( CLIENT *Client );
 | 
			
		||||
GLOBAL CHAR *Client_Password( CLIENT *Client );
 | 
			
		||||
GLOBAL CHAR *Client_Modes( CLIENT *Client );
 | 
			
		||||
GLOBAL CLIENT *Client_Introducer( CLIENT *Client );
 | 
			
		||||
GLOBAL BOOLEAN Client_OperByMe( CLIENT *Client );
 | 
			
		||||
GLOBAL INT Client_Hops( CLIENT *Client );
 | 
			
		||||
GLOBAL INT Client_Token( CLIENT *Client );
 | 
			
		||||
GLOBAL INT Client_MyToken( CLIENT *Client );
 | 
			
		||||
GLOBAL CLIENT *Client_TopServer( CLIENT *Client );
 | 
			
		||||
GLOBAL CLIENT *Client_NextHop( CLIENT *Client );
 | 
			
		||||
GLOBAL CHAR *Client_Away( CLIENT *Client );
 | 
			
		||||
GLOBAL INT Client_Type PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CONN_ID Client_Conn PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CHAR *Client_ID PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CHAR *Client_Mask PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CHAR *Client_Info PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CHAR *Client_User PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CHAR *Client_Hostname PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CHAR *Client_Password PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CHAR *Client_Modes PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CHAR *Client_Flags PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CLIENT *Client_Introducer PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL BOOLEAN Client_OperByMe PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL INT Client_Hops PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL INT Client_Token PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL INT Client_MyToken PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CLIENT *Client_TopServer PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CLIENT *Client_NextHop PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL CHAR *Client_Away PARAMS(( CLIENT *Client ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Client_HasMode( CLIENT *Client, CHAR Mode );
 | 
			
		||||
GLOBAL BOOLEAN Client_HasMode PARAMS(( CLIENT *Client, CHAR Mode ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Client_SetHostname( CLIENT *Client, CHAR *Hostname );
 | 
			
		||||
GLOBAL VOID Client_SetID( CLIENT *Client, CHAR *Nick );
 | 
			
		||||
GLOBAL VOID Client_SetUser( CLIENT *Client, CHAR *User, BOOLEAN Idented );
 | 
			
		||||
GLOBAL VOID Client_SetInfo( CLIENT *Client, CHAR *Info );
 | 
			
		||||
GLOBAL VOID Client_SetPassword( CLIENT *Client, CHAR *Pwd );
 | 
			
		||||
GLOBAL VOID Client_SetType( CLIENT *Client, INT Type );
 | 
			
		||||
GLOBAL VOID Client_SetHops( CLIENT *Client, INT Hops );
 | 
			
		||||
GLOBAL VOID Client_SetToken( CLIENT *Client, INT Token );
 | 
			
		||||
GLOBAL VOID Client_SetOperByMe( CLIENT *Client, BOOLEAN OperByMe );
 | 
			
		||||
GLOBAL VOID Client_SetModes( CLIENT *Client, CHAR *Modes );
 | 
			
		||||
GLOBAL VOID Client_SetIntroducer( CLIENT *Client, CLIENT *Introducer );
 | 
			
		||||
GLOBAL VOID Client_SetAway( CLIENT *Client, CHAR *Txt );
 | 
			
		||||
GLOBAL VOID Client_SetHostname PARAMS(( CLIENT *Client, CHAR *Hostname ));
 | 
			
		||||
GLOBAL VOID Client_SetID PARAMS(( CLIENT *Client, CHAR *Nick ));
 | 
			
		||||
GLOBAL VOID Client_SetUser PARAMS(( CLIENT *Client, CHAR *User, BOOLEAN Idented ));
 | 
			
		||||
GLOBAL VOID Client_SetInfo PARAMS(( CLIENT *Client, CHAR *Info ));
 | 
			
		||||
GLOBAL VOID Client_SetPassword PARAMS(( CLIENT *Client, 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 ));
 | 
			
		||||
GLOBAL VOID Client_SetOperByMe PARAMS(( CLIENT *Client, BOOLEAN OperByMe ));
 | 
			
		||||
GLOBAL VOID Client_SetModes PARAMS(( CLIENT *Client, CHAR *Modes ));
 | 
			
		||||
GLOBAL VOID Client_SetFlags PARAMS(( CLIENT *Client, CHAR *Flags ));
 | 
			
		||||
GLOBAL VOID Client_SetIntroducer PARAMS(( CLIENT *Client, CLIENT *Introducer ));
 | 
			
		||||
GLOBAL VOID Client_SetAway PARAMS(( CLIENT *Client, CHAR *Txt ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Client_ModeAdd( CLIENT *Client, CHAR Mode );
 | 
			
		||||
GLOBAL BOOLEAN Client_ModeDel( CLIENT *Client, CHAR Mode );
 | 
			
		||||
GLOBAL BOOLEAN Client_ModeAdd PARAMS(( CLIENT *Client, CHAR Mode ));
 | 
			
		||||
GLOBAL BOOLEAN Client_ModeDel PARAMS(( CLIENT *Client, CHAR Mode ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Client_CheckNick( CLIENT *Client, CHAR *Nick );
 | 
			
		||||
GLOBAL BOOLEAN Client_CheckID( CLIENT *Client, CHAR *ID );
 | 
			
		||||
GLOBAL BOOLEAN Client_CheckNick PARAMS(( CLIENT *Client, CHAR *Nick ));
 | 
			
		||||
GLOBAL BOOLEAN Client_CheckID PARAMS(( CLIENT *Client, CHAR *ID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Client_UserCount( VOID );
 | 
			
		||||
GLOBAL INT Client_ServiceCount( VOID );
 | 
			
		||||
GLOBAL INT Client_ServerCount( VOID );
 | 
			
		||||
GLOBAL INT Client_OperCount( VOID );
 | 
			
		||||
GLOBAL INT Client_UnknownCount( VOID );
 | 
			
		||||
GLOBAL INT Client_MyUserCount( VOID );
 | 
			
		||||
GLOBAL INT Client_MyServiceCount( VOID );
 | 
			
		||||
GLOBAL INT Client_MyServerCount( VOID );
 | 
			
		||||
GLOBAL LONG Client_UserCount PARAMS(( VOID ));
 | 
			
		||||
GLOBAL LONG Client_ServiceCount PARAMS(( VOID ));
 | 
			
		||||
GLOBAL LONG Client_ServerCount PARAMS(( VOID ));
 | 
			
		||||
GLOBAL LONG Client_OperCount PARAMS(( VOID ));
 | 
			
		||||
GLOBAL LONG Client_UnknownCount PARAMS(( VOID ));
 | 
			
		||||
GLOBAL LONG Client_MyUserCount PARAMS(( VOID ));
 | 
			
		||||
GLOBAL LONG Client_MyServiceCount PARAMS(( VOID ));
 | 
			
		||||
GLOBAL LONG Client_MyServerCount PARAMS(( VOID ));
 | 
			
		||||
GLOBAL LONG Client_MaxUserCount PARAMS((  VOID ));
 | 
			
		||||
GLOBAL LONG Client_MyMaxUserCount PARAMS((  VOID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Client_IsValidNick( CHAR *Nick );
 | 
			
		||||
GLOBAL BOOLEAN Client_IsValidNick PARAMS(( CHAR *Nick ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -2,16 +2,15 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: conf.h,v 1.15 2002/03/29 22:53:59 alex Exp $
 | 
			
		||||
 * $Id: conf.h,v 1.26.2.1 2003/11/07 20:51:11 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * conf.h: Konfiguration des ngircd (Header)
 | 
			
		||||
 * Configuration management (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -20,68 +19,112 @@
 | 
			
		||||
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct _Conf_Oper
 | 
			
		||||
{
 | 
			
		||||
	CHAR name[CLIENT_PASS_LEN];	/* Name (ID) des IRC-OPs */
 | 
			
		||||
	CHAR pwd[CLIENT_PASS_LEN];	/* Passwort */
 | 
			
		||||
	CHAR name[CLIENT_PASS_LEN];	/* Name (ID) of IRC operator */
 | 
			
		||||
	CHAR pwd[CLIENT_PASS_LEN];	/* Password */
 | 
			
		||||
} CONF_OPER;
 | 
			
		||||
 | 
			
		||||
typedef struct _Conf_Server
 | 
			
		||||
{
 | 
			
		||||
	CHAR host[HOST_LEN];		/* Hostname */
 | 
			
		||||
	CHAR ip[16];			/* IP-Adresse (von Resolver) */
 | 
			
		||||
	CHAR ip[16];			/* IP address (Resolver) */
 | 
			
		||||
	CHAR name[CLIENT_ID_LEN];	/* IRC-Client-ID */
 | 
			
		||||
	CHAR pwd[CLIENT_PASS_LEN];	/* Passwort */
 | 
			
		||||
	INT port;			/* Server-Port */
 | 
			
		||||
	INT group;			/* Gruppe des Servers */
 | 
			
		||||
	time_t lasttry;			/* Letzter Connect-Versuch */
 | 
			
		||||
	RES_STAT *res_stat;		/* Status des Resolver */
 | 
			
		||||
	CHAR pwd_in[CLIENT_PASS_LEN];	/* Password which must be received */
 | 
			
		||||
	CHAR pwd_out[CLIENT_PASS_LEN];	/* Password to send to peer */
 | 
			
		||||
	INT port;			/* Server port */
 | 
			
		||||
	INT group;			/* Group of server */
 | 
			
		||||
	time_t lasttry;			/* Last connect attempt */
 | 
			
		||||
	RES_STAT *res_stat;		/* Status of the resolver */
 | 
			
		||||
	INT flags;			/* Flags */
 | 
			
		||||
	CONN_ID conn_id;		/* ID of server connection or NONE */
 | 
			
		||||
} CONF_SERVER;
 | 
			
		||||
 | 
			
		||||
typedef struct _Conf_Channel
 | 
			
		||||
{
 | 
			
		||||
	CHAR name[CHANNEL_NAME_LEN];	/* Name of the channel */
 | 
			
		||||
	CHAR modes[CHANNEL_MODE_LEN];	/* Initial channel modes */
 | 
			
		||||
	CHAR topic[CHANNEL_TOPIC_LEN];	/* Initial topic */
 | 
			
		||||
} CONF_CHANNEL;
 | 
			
		||||
 | 
			
		||||
/* Name ("Nick") des Servers */
 | 
			
		||||
 | 
			
		||||
#define CONF_SFLAG_ONCE	1		/* Delete this entry after next disconnect */
 | 
			
		||||
#define CONF_SFLAG_DISABLED 2		/* This server configuration entry is disabled */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Name ("Nick") of the servers */
 | 
			
		||||
GLOBAL CHAR Conf_ServerName[CLIENT_ID_LEN];
 | 
			
		||||
 | 
			
		||||
/* Servers-Info-Text */
 | 
			
		||||
/* Server info text */
 | 
			
		||||
GLOBAL CHAR Conf_ServerInfo[CLIENT_INFO_LEN];
 | 
			
		||||
 | 
			
		||||
/* Server-Passwort */
 | 
			
		||||
/* Global server passwort */
 | 
			
		||||
GLOBAL CHAR Conf_ServerPwd[CLIENT_PASS_LEN];
 | 
			
		||||
 | 
			
		||||
/* Datei mit MOTD-Text */
 | 
			
		||||
/* Administrative information */
 | 
			
		||||
GLOBAL CHAR Conf_ServerAdmin1[CLIENT_INFO_LEN];
 | 
			
		||||
GLOBAL CHAR Conf_ServerAdmin2[CLIENT_INFO_LEN];
 | 
			
		||||
GLOBAL CHAR Conf_ServerAdminMail[CLIENT_INFO_LEN];
 | 
			
		||||
 | 
			
		||||
/* File with MOTD text */
 | 
			
		||||
GLOBAL CHAR Conf_MotdFile[FNAME_LEN];
 | 
			
		||||
 | 
			
		||||
/* Ports, auf denen der Server Verbindungen entgegen nimmt */
 | 
			
		||||
/* Ports the server should listen on */
 | 
			
		||||
GLOBAL UINT Conf_ListenPorts[MAX_LISTEN_PORTS];
 | 
			
		||||
GLOBAL INT Conf_ListenPorts_Count;
 | 
			
		||||
 | 
			
		||||
/* User- und Group-ID, zu denen der Daemon wechseln soll */
 | 
			
		||||
/* Address to which the socket should be bound or empty (=all) */
 | 
			
		||||
GLOBAL CHAR Conf_ListenAddress[16];
 | 
			
		||||
 | 
			
		||||
/* User and group ID the server should run with */
 | 
			
		||||
GLOBAL UINT Conf_UID;
 | 
			
		||||
GLOBAL UINT Conf_GID;
 | 
			
		||||
 | 
			
		||||
/* Timeouts fuer PING und PONG */
 | 
			
		||||
/* Timeouts for PING and PONG */
 | 
			
		||||
GLOBAL INT Conf_PingTimeout;
 | 
			
		||||
GLOBAL INT Conf_PongTimeout;
 | 
			
		||||
 | 
			
		||||
/* Sekunden zwischen Verbindungsversuchen zu anderen Servern */
 | 
			
		||||
/* Seconds between connect attempts to other servers */
 | 
			
		||||
GLOBAL INT Conf_ConnectRetry;
 | 
			
		||||
 | 
			
		||||
/* Operatoren */
 | 
			
		||||
/* Operators */
 | 
			
		||||
GLOBAL CONF_OPER Conf_Oper[MAX_OPERATORS];
 | 
			
		||||
GLOBAL INT Conf_Oper_Count;
 | 
			
		||||
 | 
			
		||||
/* Server */
 | 
			
		||||
/* Servers */
 | 
			
		||||
GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS];
 | 
			
		||||
GLOBAL INT Conf_Server_Count;
 | 
			
		||||
 | 
			
		||||
/* Pre-defined channels */
 | 
			
		||||
GLOBAL CONF_CHANNEL Conf_Channel[MAX_DEFCHANNELS];
 | 
			
		||||
GLOBAL INT Conf_Channel_Count;
 | 
			
		||||
 | 
			
		||||
/* Are IRC operators allowed to always use MODE? */
 | 
			
		||||
GLOBAL BOOLEAN Conf_OperCanMode;
 | 
			
		||||
 | 
			
		||||
/* Maximum number of connections to this server */
 | 
			
		||||
GLOBAL LONG Conf_MaxConnections;
 | 
			
		||||
 | 
			
		||||
/* Maximum number of channels a user can join */
 | 
			
		||||
GLOBAL INT Conf_MaxJoins;
 | 
			
		||||
 | 
			
		||||
/* Maximum number of connections per IP address */
 | 
			
		||||
GLOBAL INT Conf_MaxConnectionsIP;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Conf_Init( VOID );
 | 
			
		||||
GLOBAL INT Conf_Test( VOID );
 | 
			
		||||
GLOBAL VOID Conf_Exit( VOID );
 | 
			
		||||
GLOBAL VOID Conf_Init PARAMS((VOID ));
 | 
			
		||||
GLOBAL VOID 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 INT Conf_GetServer PARAMS(( CONN_ID Idx ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Conf_EnableServer PARAMS(( CHAR *Name, INT Port ));
 | 
			
		||||
GLOBAL BOOLEAN Conf_DisableServer PARAMS(( CHAR *Name ));
 | 
			
		||||
GLOBAL BOOLEAN Conf_AddServer PARAMS(( CHAR *Name, INT Port, CHAR *Host, CHAR *MyPwd, CHAR *PeerPwd ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										277
									
								
								src/ngircd/conn-func.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										277
									
								
								src/ngircd/conn-func.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,277 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * Connection management: Global functions
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define CONN_MODULE
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: conn-func.c,v 1.1.2.1 2003/11/07 20:51:11 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <log.h>
 | 
			
		||||
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Conn_UpdateIdle( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Idle-Timer zuruecksetzen */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	My_Connections[Idx].lastprivmsg = time( NULL );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL time_t
 | 
			
		||||
Conn_GetIdle( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Idle-Time einer Verbindung liefern (in Sekunden) */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	return time( NULL ) - My_Connections[Idx].lastprivmsg;
 | 
			
		||||
} /* Conn_GetIdle */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL time_t
 | 
			
		||||
Conn_LastPing( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Zeitpunkt des letzten PING liefern */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	return My_Connections[Idx].lastping;
 | 
			
		||||
} /* Conn_LastPing */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Conn_SetPenalty( CONN_ID Idx, time_t Seconds )
 | 
			
		||||
{
 | 
			
		||||
	/* Penalty-Delay fuer eine Verbindung (in Sekunden) setzen;
 | 
			
		||||
	 * waehrend dieser Zeit wird der entsprechende Socket vom Server
 | 
			
		||||
	 * bei Lese-Operationen komplett ignoriert. Der Delay kann mit
 | 
			
		||||
	 * dieser Funktion nur erhoeht, nicht aber verringert werden. */
 | 
			
		||||
	
 | 
			
		||||
	time_t t;
 | 
			
		||||
	
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	assert( Seconds >= 0 );
 | 
			
		||||
 | 
			
		||||
	t = time( NULL ) + Seconds;
 | 
			
		||||
	if( t > My_Connections[Idx].delaytime ) My_Connections[Idx].delaytime = t;
 | 
			
		||||
} /* Conn_SetPenalty */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Conn_ResetPenalty( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	My_Connections[Idx].delaytime = 0;
 | 
			
		||||
} /* Conn_ResetPenalty */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Conn_ClearFlags( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Alle Connection auf "nicht-markiert" setzen */
 | 
			
		||||
 | 
			
		||||
	CONN_ID i;
 | 
			
		||||
 | 
			
		||||
	for( i = 0; i < Pool_Size; i++ ) My_Connections[i].flag = 0;
 | 
			
		||||
} /* Conn_ClearFlags */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT
 | 
			
		||||
Conn_Flag( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Ist eine Connection markiert (TRUE) oder nicht? */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	return My_Connections[Idx].flag;
 | 
			
		||||
} /* Conn_Flag */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Conn_SetFlag( CONN_ID Idx, INT Flag )
 | 
			
		||||
{
 | 
			
		||||
	/* Connection markieren */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	My_Connections[Idx].flag = Flag;
 | 
			
		||||
} /* Conn_SetFlag */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CONN_ID
 | 
			
		||||
Conn_First( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Connection-Struktur der ersten Verbindung liefern;
 | 
			
		||||
	 * Ist keine Verbindung vorhanden, wird NONE geliefert. */
 | 
			
		||||
 | 
			
		||||
	CONN_ID i;
 | 
			
		||||
	
 | 
			
		||||
	for( i = 0; i < Pool_Size; i++ )
 | 
			
		||||
	{
 | 
			
		||||
		if( My_Connections[i].sock != NONE ) return i;
 | 
			
		||||
	}
 | 
			
		||||
	return NONE;
 | 
			
		||||
} /* Conn_First */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CONN_ID
 | 
			
		||||
Conn_Next( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Naechste Verbindungs-Struktur liefern; existiert keine
 | 
			
		||||
	 * weitere, so wird NONE geliefert. */
 | 
			
		||||
 | 
			
		||||
	CONN_ID i = NONE;
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	
 | 
			
		||||
	for( i = Idx + 1; i < Pool_Size; i++ )
 | 
			
		||||
	{
 | 
			
		||||
		if( My_Connections[i].sock != NONE ) return i;
 | 
			
		||||
	}
 | 
			
		||||
	return NONE;
 | 
			
		||||
} /* Conn_Next */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Conn_SetOption( CONN_ID Idx, INT Option )
 | 
			
		||||
{
 | 
			
		||||
	/* Option fuer Verbindung setzen.
 | 
			
		||||
	 * Initial sind alle Optionen _nicht_ gesetzt. */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	assert( Option != 0 );
 | 
			
		||||
 | 
			
		||||
	My_Connections[Idx].options |= Option;
 | 
			
		||||
} /* Conn_SetOption */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Conn_UnsetOption( CONN_ID Idx, INT Option )
 | 
			
		||||
{
 | 
			
		||||
	/* Option fuer Verbindung loeschen */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	assert( Option != 0 );
 | 
			
		||||
 | 
			
		||||
	My_Connections[Idx].options &= ~Option;
 | 
			
		||||
} /* Conn_UnsetOption */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT
 | 
			
		||||
Conn_Options( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	return My_Connections[Idx].options;
 | 
			
		||||
} /* Conn_Options */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL time_t
 | 
			
		||||
Conn_StartTime( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Zeitpunkt des Link-Starts liefern (in Sekunden) */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	return My_Connections[Idx].starttime;
 | 
			
		||||
} /* Conn_Uptime */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT
 | 
			
		||||
Conn_SendQ( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Laenge der Daten im Schreibbuffer liefern */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
	if( My_Connections[Idx].options & CONN_ZIP ) return My_Connections[Idx].zip.wdatalen;
 | 
			
		||||
	else
 | 
			
		||||
#endif
 | 
			
		||||
	return My_Connections[Idx].wdatalen;
 | 
			
		||||
} /* Conn_SendQ */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Conn_SendMsg( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Anzahl gesendeter Nachrichten liefern */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	return My_Connections[Idx].msg_out;
 | 
			
		||||
} /* Conn_SendMsg */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Conn_SendBytes( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Anzahl gesendeter Bytes (unkomprimiert) liefern */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	return My_Connections[Idx].bytes_out;
 | 
			
		||||
} /* Conn_SendBytes */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT
 | 
			
		||||
Conn_RecvQ( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Laenge der Daten im Lesebuffer liefern */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
	if( My_Connections[Idx].options & CONN_ZIP ) return My_Connections[Idx].zip.rdatalen;
 | 
			
		||||
	else
 | 
			
		||||
#endif
 | 
			
		||||
	return My_Connections[Idx].rdatalen;
 | 
			
		||||
} /* Conn_RecvQ */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Conn_RecvMsg( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Anzahl empfangener Nachrichten liefern */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	return My_Connections[Idx].msg_in;
 | 
			
		||||
} /* Conn_RecvMsg */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Conn_RecvBytes( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Anzahl empfangener Bytes (unkomprimiert) liefern */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	return My_Connections[Idx].bytes_in;
 | 
			
		||||
} /* Conn_RecvBytes */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Conn_ResetWCounter( VOID )
 | 
			
		||||
{
 | 
			
		||||
	WCounter = 0;
 | 
			
		||||
} /* Conn_ResetWCounter */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Conn_WCounter( VOID )
 | 
			
		||||
{
 | 
			
		||||
	return WCounter;
 | 
			
		||||
} /* Conn_WCounter */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										61
									
								
								src/ngircd/conn-func.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								src/ngircd/conn-func.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: conn-func.h,v 1.1 2002/12/30 17:14:28 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Connection management: Global functions (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __conn_func_h__
 | 
			
		||||
#define __conn_func_h__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Include the header conn.h if this header is _not_ included by any module
 | 
			
		||||
 * containing connection handling functions. So other modules must only
 | 
			
		||||
 * include this conn-func.h header. */
 | 
			
		||||
#ifndef CONN_MODULE
 | 
			
		||||
#	include "conn.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Conn_UpdateIdle PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL time_t Conn_GetIdle PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL time_t Conn_LastPing PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL time_t Conn_StartTime PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL INT Conn_SendQ PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL INT Conn_RecvQ PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL LONG Conn_SendMsg PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL LONG Conn_RecvMsg PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL LONG Conn_SendBytes PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL LONG Conn_RecvBytes PARAMS(( CONN_ID Idx ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Conn_SetPenalty PARAMS(( CONN_ID Idx, time_t Seconds ));
 | 
			
		||||
GLOBAL VOID Conn_ResetPenalty PARAMS(( CONN_ID Idx ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Conn_ClearFlags PARAMS(( VOID ));
 | 
			
		||||
GLOBAL INT Conn_Flag PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL VOID Conn_SetFlag PARAMS(( CONN_ID Idx, INT Flag ));
 | 
			
		||||
 | 
			
		||||
GLOBAL CONN_ID Conn_First PARAMS(( VOID ));
 | 
			
		||||
GLOBAL CONN_ID Conn_Next PARAMS(( CONN_ID Idx ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Conn_SetOption PARAMS(( CONN_ID Idx, INT Option ));
 | 
			
		||||
GLOBAL VOID Conn_UnsetOption PARAMS(( CONN_ID Idx, INT Option ));
 | 
			
		||||
GLOBAL INT Conn_Options PARAMS(( CONN_ID Idx ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Conn_ResetWCounter PARAMS(( VOID ));
 | 
			
		||||
GLOBAL LONG Conn_WCounter PARAMS(( VOID ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										210
									
								
								src/ngircd/conn-zip.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								src/ngircd/conn-zip.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,210 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * Connection compression using ZLIB
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
#define CONN_MODULE
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: conn-zip.c,v 1.3 2003/04/21 10:52:26 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <zlib.h>
 | 
			
		||||
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "conn-zip.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Zip_InitConn( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Kompression fuer Link initialisieren */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
 | 
			
		||||
	My_Connections[Idx].zip.in.avail_in = 0;
 | 
			
		||||
	My_Connections[Idx].zip.in.total_in = 0;
 | 
			
		||||
	My_Connections[Idx].zip.in.total_out = 0;
 | 
			
		||||
	My_Connections[Idx].zip.in.zalloc = NULL;
 | 
			
		||||
	My_Connections[Idx].zip.in.zfree = NULL;
 | 
			
		||||
	My_Connections[Idx].zip.in.data_type = Z_ASCII;
 | 
			
		||||
 | 
			
		||||
	if( inflateInit( &My_Connections[Idx].zip.in ) != Z_OK )
 | 
			
		||||
	{
 | 
			
		||||
		/* Fehler! */
 | 
			
		||||
		Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib inflate)!", Idx );
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	My_Connections[Idx].zip.out.total_in = 0;
 | 
			
		||||
	My_Connections[Idx].zip.out.total_in = 0;
 | 
			
		||||
	My_Connections[Idx].zip.out.zalloc = NULL;
 | 
			
		||||
	My_Connections[Idx].zip.out.zfree = NULL;
 | 
			
		||||
	My_Connections[Idx].zip.out.data_type = Z_ASCII;
 | 
			
		||||
 | 
			
		||||
	if( deflateInit( &My_Connections[Idx].zip.out, Z_DEFAULT_COMPRESSION ) != Z_OK )
 | 
			
		||||
	{
 | 
			
		||||
		/* Fehler! */
 | 
			
		||||
		Log( LOG_ALERT, "Can't initialize compression on connection %d (zlib deflate)!", Idx );
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	My_Connections[Idx].zip.bytes_in = My_Connections[Idx].bytes_in;
 | 
			
		||||
	My_Connections[Idx].zip.bytes_out = My_Connections[Idx].bytes_out;
 | 
			
		||||
 | 
			
		||||
	Log( LOG_INFO, "Enabled link compression (zlib) on connection %d.", Idx );
 | 
			
		||||
	Conn_SetOption( Idx, CONN_ZIP );
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
} /* Zip_InitConn */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Zip_Buffer( CONN_ID Idx, CHAR *Data, INT Len )
 | 
			
		||||
{
 | 
			
		||||
	/* Daten zum Komprimieren im "Kompressions-Puffer" sammeln.
 | 
			
		||||
	* Es wird TRUE bei Erfolg, sonst FALSE geliefert. */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	assert( Data != NULL );
 | 
			
		||||
	assert( Len > 0 );
 | 
			
		||||
 | 
			
		||||
	/* Ist noch Platz im Kompressions-Puffer? */
 | 
			
		||||
	if( ZWRITEBUFFER_LEN - My_Connections[Idx].zip.wdatalen < Len + 50 )
 | 
			
		||||
	{
 | 
			
		||||
		/* Nein! Puffer zunaechst leeren ...*/
 | 
			
		||||
		if( ! Zip_Flush( Idx )) return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Daten kopieren */
 | 
			
		||||
	memmove( My_Connections[Idx].zip.wbuf + My_Connections[Idx].zip.wdatalen, Data, Len );
 | 
			
		||||
	My_Connections[Idx].zip.wdatalen += Len;
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
} /* Zip_Buffer */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Zip_Flush( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Daten komprimieren und in Schreibpuffer kopieren.
 | 
			
		||||
	* Es wird TRUE bei Erfolg, sonst FALSE geliefert. */
 | 
			
		||||
 | 
			
		||||
	INT result, out_len;
 | 
			
		||||
	z_stream *out;
 | 
			
		||||
 | 
			
		||||
	out = &My_Connections[Idx].zip.out;
 | 
			
		||||
 | 
			
		||||
	out->next_in = (VOID *)My_Connections[Idx].zip.wbuf;
 | 
			
		||||
	out->avail_in = My_Connections[Idx].zip.wdatalen;
 | 
			
		||||
	out->next_out = (VOID *)(My_Connections[Idx].wbuf + My_Connections[Idx].wdatalen);
 | 
			
		||||
	out->avail_out = WRITEBUFFER_LEN - My_Connections[Idx].wdatalen;
 | 
			
		||||
 | 
			
		||||
	result = deflate( out, Z_SYNC_FLUSH );
 | 
			
		||||
	if(( result != Z_OK ) || ( out->avail_in > 0 ))
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_ALERT, "Compression error: code %d!?", result );
 | 
			
		||||
		Conn_Close( Idx, "Compression error!", NULL, FALSE );
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	out_len = WRITEBUFFER_LEN - My_Connections[Idx].wdatalen - out->avail_out;
 | 
			
		||||
	My_Connections[Idx].wdatalen += out_len;
 | 
			
		||||
	My_Connections[Idx].bytes_out += out_len;
 | 
			
		||||
	My_Connections[Idx].zip.bytes_out += My_Connections[Idx].zip.wdatalen;
 | 
			
		||||
	My_Connections[Idx].zip.wdatalen = 0;
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
} /* Zip_Flush */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Unzip_Buffer( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Daten entpacken und in Lesepuffer kopieren. Bei Fehlern
 | 
			
		||||
	* wird FALSE geliefert, ansonsten TRUE. Der Fall, dass keine
 | 
			
		||||
	* Daten mehr zu entpacken sind, ist _kein_ Fehler! */
 | 
			
		||||
 | 
			
		||||
	INT result, in_len, out_len;
 | 
			
		||||
	z_stream *in;
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
 | 
			
		||||
	if( My_Connections[Idx].zip.rdatalen <= 0 ) return TRUE;
 | 
			
		||||
 | 
			
		||||
	in = &My_Connections[Idx].zip.in;
 | 
			
		||||
 | 
			
		||||
	in->next_in = (VOID *)My_Connections[Idx].zip.rbuf;
 | 
			
		||||
	in->avail_in = My_Connections[Idx].zip.rdatalen;
 | 
			
		||||
	in->next_out = (VOID *)(My_Connections[Idx].rbuf + My_Connections[Idx].rdatalen);
 | 
			
		||||
	in->avail_out = READBUFFER_LEN - My_Connections[Idx].rdatalen - 1;
 | 
			
		||||
 | 
			
		||||
	result = inflate( in, Z_SYNC_FLUSH );
 | 
			
		||||
	if( result != Z_OK )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_ALERT, "Decompression error: code %d (ni=%d, ai=%d, no=%d, ao=%d)!?", result, in->next_in, in->avail_in, in->next_out, in->avail_out );
 | 
			
		||||
		Conn_Close( Idx, "Decompression error!", NULL, FALSE );
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	in_len = My_Connections[Idx].zip.rdatalen - in->avail_in;
 | 
			
		||||
	out_len = READBUFFER_LEN - My_Connections[Idx].rdatalen - 1 - in->avail_out;
 | 
			
		||||
	My_Connections[Idx].rdatalen += out_len;
 | 
			
		||||
 | 
			
		||||
	if( in->avail_in > 0 )
 | 
			
		||||
	{
 | 
			
		||||
		/* es konnten nicht alle Daten entpackt werden, vermutlich war
 | 
			
		||||
		* im Ziel-Puffer kein Platz mehr. Umkopieren ... */
 | 
			
		||||
		My_Connections[Idx].zip.rdatalen -= in_len;
 | 
			
		||||
		memmove( My_Connections[Idx].zip.rbuf, My_Connections[Idx].zip.rbuf + in_len, My_Connections[Idx].zip.rdatalen );
 | 
			
		||||
	}
 | 
			
		||||
	else My_Connections[Idx].zip.rdatalen = 0;
 | 
			
		||||
	My_Connections[Idx].zip.bytes_in += out_len;
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
} /* Unzip_Buffer */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Zip_SendBytes( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Anzahl gesendeter Bytes (komprimiert!) liefern */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	return My_Connections[Idx].zip.bytes_out;
 | 
			
		||||
} /* Zip_SendBytes */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL LONG
 | 
			
		||||
Zip_RecvBytes( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Anzahl gesendeter Bytes (komprimiert!) liefern */
 | 
			
		||||
 | 
			
		||||
	assert( Idx > NONE );
 | 
			
		||||
	return My_Connections[Idx].zip.bytes_in;
 | 
			
		||||
} /* Zip_RecvBytes */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										38
									
								
								src/ngircd/conn-zip.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/ngircd/conn-zip.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: conn-zip.h,v 1.1 2002/12/30 16:07:23 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Connection compression using ZLIB (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
 | 
			
		||||
#ifndef __conn_zip_h__
 | 
			
		||||
#define __conn_zip_h__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Zip_InitConn PARAMS(( CONN_ID Idx ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Zip_Buffer PARAMS(( CONN_ID Idx, CHAR *Data, INT Len ));
 | 
			
		||||
GLOBAL BOOLEAN Zip_Flush PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL BOOLEAN Unzip_Buffer PARAMS(( CONN_ID Idx ));
 | 
			
		||||
 | 
			
		||||
GLOBAL LONG Zip_SendBytes PARAMS(( CONN_ID Idx ));
 | 
			
		||||
GLOBAL LONG Zip_RecvBytes PARAMS(( CONN_ID Idx ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* __conn_zip_h__ */
 | 
			
		||||
 | 
			
		||||
#endif /* USE_ZLIB */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										1433
									
								
								src/ngircd/conn.c
									
									
									
									
									
								
							
							
						
						
									
										1433
									
								
								src/ngircd/conn.c
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -2,16 +2,15 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: conn.h,v 1.14 2002/03/29 22:54:35 alex Exp $
 | 
			
		||||
 * $Id: conn.h,v 1.31 2003/03/27 01:20:22 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * conn.h: Verwaltung aller Netz-Verbindungen ("connections") (Header)
 | 
			
		||||
 * Connection management (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -19,33 +18,87 @@
 | 
			
		||||
#define __conn_h__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <time.h>			/* fro time_t, see below */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define CONN_ISCLOSING 1		/* Conn_Close() already called */
 | 
			
		||||
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
#define CONN_ZIP 2			/* zlib compressed link */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef INT CONN_ID;
 | 
			
		||||
 | 
			
		||||
typedef struct _Res_Stat
 | 
			
		||||
 | 
			
		||||
#ifdef CONN_MODULE
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
#include <zlib.h>
 | 
			
		||||
typedef struct _ZipData
 | 
			
		||||
{
 | 
			
		||||
	INT pid;			/* PID des Child-Prozess */
 | 
			
		||||
	INT pipe[2];			/* Pipe fuer IPC */
 | 
			
		||||
} RES_STAT;
 | 
			
		||||
	z_stream in;			/* "Handle" for input stream */
 | 
			
		||||
	z_stream out;			/* "Handle" for output stream */
 | 
			
		||||
	CHAR rbuf[READBUFFER_LEN];	/* Read buffer */
 | 
			
		||||
	INT rdatalen;			/* Length of data in read buffer (compressed) */
 | 
			
		||||
	CHAR wbuf[WRITEBUFFER_LEN];	/* Write buffer */
 | 
			
		||||
	INT wdatalen;			/* Length of data in write buffer (uncompressed) */
 | 
			
		||||
	LONG bytes_in, bytes_out;	/* Counter for statistics (uncompressed!) */
 | 
			
		||||
} ZIPDATA;
 | 
			
		||||
#endif /* USE_ZLIB */
 | 
			
		||||
 | 
			
		||||
typedef struct _Connection
 | 
			
		||||
{
 | 
			
		||||
	INT sock;			/* Socket handle */
 | 
			
		||||
	struct sockaddr_in addr;	/* Client address */
 | 
			
		||||
	RES_STAT *res_stat;		/* Status of resolver process, if any */
 | 
			
		||||
	CHAR host[HOST_LEN];		/* Hostname */
 | 
			
		||||
	CHAR rbuf[READBUFFER_LEN];	/* Read buffer */
 | 
			
		||||
	INT rdatalen;			/* Length of data in read buffer */
 | 
			
		||||
	CHAR wbuf[WRITEBUFFER_LEN];	/* Write buffer */
 | 
			
		||||
	INT wdatalen;			/* Length of data in write buffer */
 | 
			
		||||
	time_t starttime;		/* Start time of link */
 | 
			
		||||
	time_t lastdata;		/* Last activity */
 | 
			
		||||
	time_t lastping;		/* Last PING */
 | 
			
		||||
	time_t lastprivmsg;		/* Last PRIVMSG */
 | 
			
		||||
	time_t delaytime;		/* Ignore link ("penalty") */
 | 
			
		||||
	LONG bytes_in, bytes_out;	/* Received and sent bytes */
 | 
			
		||||
	LONG msg_in, msg_out;		/* Received and sent IRC messages */
 | 
			
		||||
	INT flag;			/* Flag (see "irc-write" module) */
 | 
			
		||||
	INT options;			/* Link options */
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
	ZIPDATA zip;			/* Compression information */
 | 
			
		||||
#endif  /* USE_ZLIB */
 | 
			
		||||
} CONNECTION;
 | 
			
		||||
 | 
			
		||||
GLOBAL CONNECTION *My_Connections;
 | 
			
		||||
GLOBAL CONN_ID Pool_Size;
 | 
			
		||||
GLOBAL LONG WCounter;
 | 
			
		||||
 | 
			
		||||
#endif /* CONN_MODULE */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Conn_Init( VOID );
 | 
			
		||||
GLOBAL VOID Conn_Exit( VOID );
 | 
			
		||||
GLOBAL VOID Conn_Init PARAMS((VOID ));
 | 
			
		||||
GLOBAL VOID Conn_Exit PARAMS(( VOID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Conn_NewListener( CONST UINT Port );
 | 
			
		||||
GLOBAL INT Conn_InitListeners PARAMS(( VOID ));
 | 
			
		||||
GLOBAL VOID Conn_ExitListeners PARAMS(( VOID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Conn_Handler( INT Timeout );
 | 
			
		||||
GLOBAL BOOLEAN Conn_NewListener PARAMS(( CONST UINT Port ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Conn_Write( CONN_ID Idx, CHAR *Data, INT Len );
 | 
			
		||||
GLOBAL BOOLEAN Conn_WriteStr( CONN_ID Idx, CHAR *Format, ... );
 | 
			
		||||
GLOBAL VOID Conn_Handler PARAMS(( VOID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient );
 | 
			
		||||
GLOBAL BOOLEAN Conn_Write PARAMS(( CONN_ID Idx, CHAR *Data, INT Len ));
 | 
			
		||||
GLOBAL BOOLEAN Conn_WriteStr PARAMS(( CONN_ID Idx, CHAR *Format, ... ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Conn_UpdateIdle( CONN_ID Idx );
 | 
			
		||||
GLOBAL time_t Conn_GetIdle( CONN_ID Idx );
 | 
			
		||||
GLOBAL time_t Conn_LastPing( CONN_ID Idx );
 | 
			
		||||
GLOBAL VOID Conn_Close PARAMS(( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Conn_SyncServerStruct PARAMS(( VOID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL INT Conn_MaxFD;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: defines.h,v 1.21 2002/03/29 22:55:02 alex Exp $
 | 
			
		||||
 * $Id: defines.h,v 1.42.2.1 2003/11/07 20:51:11 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * defines.h: (globale) Konstanten
 | 
			
		||||
 * Global defines of ngIRCd.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __defines_h__
 | 
			
		||||
@@ -28,11 +27,15 @@
 | 
			
		||||
 | 
			
		||||
#define MAX_LISTEN_PORTS 16		/* max. Anzahl von Listen-Ports */
 | 
			
		||||
 | 
			
		||||
#define MAX_OPERATORS 8			/* max. Anzahl konfigurierbarer Operatoren */
 | 
			
		||||
#define MAX_OPERATORS 16		/* max. Anzahl konfigurierbarer Operatoren */
 | 
			
		||||
 | 
			
		||||
#define MAX_SERVERS 8			/* max. Anzahl konfigurierbarer Server ("Peers") */
 | 
			
		||||
#define MAX_SERVERS 16			/* max. Anzahl konfigurierbarer Server ("Peers") */
 | 
			
		||||
 | 
			
		||||
#define MAX_CONNECTIONS 100		/* max. Anzahl von Verbindungen an diesem Server */
 | 
			
		||||
#define MAX_DEFCHANNELS 16		/* max. Anzahl vorkonfigurierbarerr Channels */
 | 
			
		||||
 | 
			
		||||
#define MAX_SERVICES 8			/* maximum number of configurable services */
 | 
			
		||||
 | 
			
		||||
#define CONNECTION_POOL 100		/* Anzahl Verbindungs-Strukturen, die blockweise alloziert werden */
 | 
			
		||||
 | 
			
		||||
#define CLIENT_ID_LEN 64		/* max. ID-Laenge; vgl. RFC 2812, 1.1 und 1.2.1 */
 | 
			
		||||
#define CLIENT_NICK_LEN 10		/* max. Nick-Laenge; vgl. RFC 2812, 1.2.1 */
 | 
			
		||||
@@ -43,6 +46,7 @@
 | 
			
		||||
#define CLIENT_MODE_LEN 8		/* max. Laenge der Client-Modes */
 | 
			
		||||
#define CLIENT_INFO_LEN 64		/* max. Infotext-Laenge (Server) */
 | 
			
		||||
#define CLIENT_AWAY_LEN 128		/* max. Laenger der AWAY-Nachricht */
 | 
			
		||||
#define CLIENT_FLAGS_LEN 100		/* max. Laenger der Client-Flags */
 | 
			
		||||
 | 
			
		||||
#define CHANNEL_NAME_LEN 51		/* max. Laenge eines Channel-Namens, vgl. RFC 2812, 1.3 */
 | 
			
		||||
#define CHANNEL_MODE_LEN 8		/* max. Laenge der Channel-Modes */
 | 
			
		||||
@@ -50,31 +54,48 @@
 | 
			
		||||
 | 
			
		||||
#define COMMAND_LEN 513			/* max. Laenge eines Befehls, vgl. RFC 2812, 3.2 */
 | 
			
		||||
 | 
			
		||||
#define READBUFFER_LEN 2 * COMMAND_LEN	/* Laenge des Lesepuffers je Verbindung (Bytes) */
 | 
			
		||||
#define READBUFFER_LEN 2048		/* Laenge des Lesepuffers je Verbindung (Bytes) */
 | 
			
		||||
#define WRITEBUFFER_LEN 4096		/* Laenge des Schreibpuffers je Verbindung (Bytes) */
 | 
			
		||||
 | 
			
		||||
#define PROTOVER "0210"			/* implementierte Protokoll-Version (RFC 2813, 4.1.1) */
 | 
			
		||||
#define PROTOSUFFIX "-ngIRCd"		/* Protokoll-Suffix (RFC 2813, 4.1.1) */
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
#define ZREADBUFFER_LEN 1024		/* Laenge des Lesepuffers je Verbindung (Bytes) */
 | 
			
		||||
#define ZWRITEBUFFER_LEN 4096		/* Laenge des Schreibpuffers fuer Kompression (Bytes) */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define PASSSERVERADD PROTOVER""PROTOSUFFIX" IRC|"PACKAGE"-"VERSION" P"
 | 
			
		||||
#define PROTOVER "0210"			/* implementierte Protokoll-Version (RFC 2813, 4.1.1) */
 | 
			
		||||
#define PROTOIRC "-IRC"			/* Protokoll-Suffix (RFC 2813, 4.1.1) */
 | 
			
		||||
#define PROTOIRCPLUS "-IRC+"		/* Protokoll-Suffix f<>r IRC+-Protokoll */
 | 
			
		||||
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
# define IRCPLUSFLAGS "C"		/* IRC+-Flags, die immer zutreffen */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define STARTUP_DELAY 1			/* Erst n Sek. nach Start zu anderen Servern verbinden */
 | 
			
		||||
#define RECONNECT_DELAY 3		/* Server-Links erst nach 3 Sekunden versuchen, wieder aufzubauen */
 | 
			
		||||
 | 
			
		||||
#define USERMODES "aios"		/* unterstuetzte User-Modes */
 | 
			
		||||
#define CHANMODES "amnopqstv"		/* unterstuetzte Channel-Modes */
 | 
			
		||||
#define CHANMODES "biklImnoPtv"		/* unterstuetzte Channel-Modes */
 | 
			
		||||
 | 
			
		||||
#define CONNECTED TRUE			/* fuer die irc-xxx-Module */
 | 
			
		||||
#define DISCONNECTED FALSE
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_AWAY_MSG "Away"		/* Away-Meldung fuer User von anderen Servern */
 | 
			
		||||
 | 
			
		||||
#define CONFIG_FILE SYSCONFDIR"/ngircd.conf"
 | 
			
		||||
#define MOTD_FILE SYSCONFDIR"/ngircd.motd"
 | 
			
		||||
#define CONFIG_FILE "/ngircd.conf"
 | 
			
		||||
#define MOTD_FILE "/ngircd.motd"
 | 
			
		||||
 | 
			
		||||
#define ERROR_DIR "/tmp"
 | 
			
		||||
 | 
			
		||||
#define MAX_LOG_MSG_LEN 256		/* max. Laenge einer Log-Meldung */
 | 
			
		||||
 | 
			
		||||
#define TOKEN_OUTBOUND -2		/* Kennzeichnung fuer ausgehende Server-Links im Aufbau */
 | 
			
		||||
 | 
			
		||||
#define NOTICE_TXTPREFIX ""		/* Kennzeichnung fuer Server-NOTICEs an User */
 | 
			
		||||
 | 
			
		||||
#ifdef RENDEZVOUS
 | 
			
		||||
#define RENDEZVOUS_TYPE "_ircu._tcp."	/* Service type to register with Rendezvous */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,21 +2,20 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: hash.c,v 1.4 2002/03/25 19:11:01 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * hash.c: Hash-Werte berechnen
 | 
			
		||||
 * Hash calculation
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: hash.c,v 1.9 2002/12/26 16:25:43 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
@@ -29,18 +28,17 @@
 | 
			
		||||
#include "hash.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL UINT32 jenkins_hash( register UINT8 *k, register UINT32 length, register UINT32 initval);
 | 
			
		||||
LOCAL UINT32 jenkins_hash PARAMS(( register UINT8 *k, register UINT32 length, register UINT32 initval ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL UINT32 Hash( CHAR *String )
 | 
			
		||||
GLOBAL UINT32
 | 
			
		||||
Hash( CHAR *String )
 | 
			
		||||
{
 | 
			
		||||
	/* Hash-Wert ueber String berechnen */
 | 
			
		||||
 | 
			
		||||
	CHAR buffer[LINE_LEN];
 | 
			
		||||
 | 
			
		||||
	strncpy( buffer, String, LINE_LEN - 1 );
 | 
			
		||||
	buffer[LINE_LEN - 1] = '\0';
 | 
			
		||||
	
 | 
			
		||||
	strlcpy( buffer, String, sizeof( buffer ));
 | 
			
		||||
	return jenkins_hash( (UINT8 *)ngt_LowerStr( buffer ), strlen( buffer ), 42 );
 | 
			
		||||
} /* Hash */
 | 
			
		||||
 | 
			
		||||
@@ -75,7 +73,8 @@ GLOBAL UINT32 Hash( CHAR *String )
 | 
			
		||||
} /* mix */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL UINT32 jenkins_hash( register UINT8 *k, register UINT32 length, register UINT32 initval)
 | 
			
		||||
LOCAL UINT32
 | 
			
		||||
jenkins_hash( register UINT8 *k, register UINT32 length, register UINT32 initval )
 | 
			
		||||
{
 | 
			
		||||
	/* k: the key
 | 
			
		||||
	 * length: length of the key
 | 
			
		||||
@@ -101,7 +100,7 @@ LOCAL UINT32 jenkins_hash( register UINT8 *k, register UINT32 length, register U
 | 
			
		||||
 | 
			
		||||
	/* handle the last 11 bytes */
 | 
			
		||||
	c += length;
 | 
			
		||||
	switch(len)		/* all the case statements fall through */
 | 
			
		||||
	switch( (INT)len )	/* all the case statements fall through */
 | 
			
		||||
	{
 | 
			
		||||
		case 11: c+=((UINT32)k[10]<<24);
 | 
			
		||||
		case 10: c+=((UINT32)k[9]<<16);
 | 
			
		||||
 
 | 
			
		||||
@@ -2,16 +2,15 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: hash.h,v 1.2 2002/03/14 15:49:36 alex Exp $
 | 
			
		||||
 * $Id: hash.h,v 1.4 2002/12/12 12:23:43 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * hash.h: Hash-Werte berechnen (Header)
 | 
			
		||||
 * Hash calculation (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -19,7 +18,7 @@
 | 
			
		||||
#define __hash_h__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL UINT32 Hash( CHAR *String );
 | 
			
		||||
GLOBAL UINT32 Hash PARAMS((CHAR *String ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -2,62 +2,75 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-channel.c,v 1.3 2002/03/25 17:08:54 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * irc-channel.c: IRC-Channel-Befehle
 | 
			
		||||
 * IRC channel commands
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-channel.c,v 1.25 2003/01/08 22:04:05 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "irc.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "lists.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "match.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "irc-info.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "irc-channel.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CHAR *channame, *flags, *topic, modes[8];
 | 
			
		||||
	BOOLEAN is_new_chan;
 | 
			
		||||
	CHAR *channame, *key, *flags, *topic, modes[8];
 | 
			
		||||
	BOOLEAN is_new_chan, is_invited, is_banned;
 | 
			
		||||
	CLIENT *target;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
	/* Bad number of arguments? */
 | 
			
		||||
	if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc > 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Wer ist der Absender? */
 | 
			
		||||
	/* Who is the sender? */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
 | 
			
		||||
	else target = Client;
 | 
			
		||||
	if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	/* Are channel keys given? */
 | 
			
		||||
	if( Req->argc > 1 ) key = Req->argv[1];
 | 
			
		||||
	else key = NULL;
 | 
			
		||||
 | 
			
		||||
	/* Channel-Namen durchgehen */
 | 
			
		||||
	chan = NULL;
 | 
			
		||||
	channame = strtok( Req->argv[0], "," );
 | 
			
		||||
	while( channame )
 | 
			
		||||
	{
 | 
			
		||||
		/* wird der Channel neu angelegt? */
 | 
			
		||||
		flags = NULL;
 | 
			
		||||
		chan = flags = NULL;
 | 
			
		||||
 | 
			
		||||
		/* wird der Channel neu angelegt? */
 | 
			
		||||
		if( Channel_Search( channame )) is_new_chan = FALSE;
 | 
			
		||||
		else is_new_chan = TRUE;
 | 
			
		||||
 | 
			
		||||
@@ -66,14 +79,85 @@ GLOBAL BOOLEAN IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		{
 | 
			
		||||
			/* Channel-Flags extrahieren */
 | 
			
		||||
			flags = strchr( channame, 0x7 );
 | 
			
		||||
			if( flags ) *flags++ = '\0';
 | 
			
		||||
			if( flags )
 | 
			
		||||
			{
 | 
			
		||||
				*flags = '\0';
 | 
			
		||||
				flags++;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* neuer Channel udn lokaler Client? */
 | 
			
		||||
		if( is_new_chan && ( Client_Type( Client ) == CLIENT_USER ))
 | 
			
		||||
		/* Lokaler Client? */
 | 
			
		||||
		if( Client_Type( Client ) == CLIENT_USER )
 | 
			
		||||
		{
 | 
			
		||||
			/* Dann soll der Client Channel-Operator werden! */
 | 
			
		||||
			flags = "o";
 | 
			
		||||
			/* Test if the user has reached his maximum channel count */
 | 
			
		||||
			if( Client_Type( Client ) == CLIENT_USER )
 | 
			
		||||
			{
 | 
			
		||||
				if(( Conf_MaxJoins > 0 ) && ( Channel_CountForUser( Client ) >= Conf_MaxJoins ))
 | 
			
		||||
				{
 | 
			
		||||
					IRC_WriteStrClient( Client, ERR_TOOMANYCHANNELS_MSG, Client_ID( Client ), channame );
 | 
			
		||||
					return CONNECTED;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* Existiert der Channel bereits, oder wird er im Moment neu erzeugt? */
 | 
			
		||||
			if( is_new_chan )
 | 
			
		||||
			{
 | 
			
		||||
				/* Erster User im Channel: Operator-Flag setzen */
 | 
			
		||||
				flags = "o";
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				/* Existierenden Channel suchen */
 | 
			
		||||
				chan = Channel_Search( channame );
 | 
			
		||||
				assert( chan != NULL );
 | 
			
		||||
 | 
			
		||||
				is_banned = Lists_CheckBanned( target, chan );
 | 
			
		||||
				is_invited = Lists_CheckInvited( target, chan );
 | 
			
		||||
 | 
			
		||||
				/* Testen, ob Client gebanned ist */
 | 
			
		||||
				if(( is_banned == TRUE ) &&  ( is_invited == FALSE ))
 | 
			
		||||
				{
 | 
			
		||||
					/* Client ist gebanned (und nicht invited): */
 | 
			
		||||
					IRC_WriteStrClient( Client, ERR_BANNEDFROMCHAN_MSG, Client_ID( Client ), channame );
 | 
			
		||||
 | 
			
		||||
					/* Try next name, if any */
 | 
			
		||||
					channame = strtok( NULL, "," );
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				/* Ist der Channel "invite-only"? */
 | 
			
		||||
				if(( strchr( Channel_Modes( chan ), 'i' )) && ( is_invited == FALSE ))
 | 
			
		||||
				{
 | 
			
		||||
					/* Channel ist "invite-only" und Client wurde nicht invited: */
 | 
			
		||||
					IRC_WriteStrClient( Client, ERR_INVITEONLYCHAN_MSG, Client_ID( Client ), channame );
 | 
			
		||||
 | 
			
		||||
					/* Try next name, if any */
 | 
			
		||||
					channame = strtok( NULL, "," );
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				/* Is the channel protected by a key? */
 | 
			
		||||
				if(( strchr( Channel_Modes( chan ), 'k' )) && ( strcmp( Channel_Key( chan ), key ? key : "" ) != 0 ))
 | 
			
		||||
				{
 | 
			
		||||
					/* Bad channel key! */
 | 
			
		||||
					IRC_WriteStrClient( Client, ERR_BADCHANNELKEY_MSG, Client_ID( Client ), channame );
 | 
			
		||||
 | 
			
		||||
					/* Try next name, if any */
 | 
			
		||||
					channame = strtok( NULL, "," );
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				/* Are there already too many members? */
 | 
			
		||||
				if(( strchr( Channel_Modes( chan ), 'l' )) && ( Channel_MaxUsers( chan ) <= Channel_MemberCount( chan )))
 | 
			
		||||
				{
 | 
			
		||||
					/* Bad channel key! */
 | 
			
		||||
					IRC_WriteStrClient( Client, ERR_CHANNELISFULL_MSG, Client_ID( Client ), channame );
 | 
			
		||||
 | 
			
		||||
					/* Try next name, if any */
 | 
			
		||||
					channame = strtok( NULL, "," );
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Channel joinen (und ggf. anlegen) */
 | 
			
		||||
@@ -83,7 +167,7 @@ GLOBAL BOOLEAN IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
			channame = strtok( NULL, "," );
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		chan = Channel_Search( channame );
 | 
			
		||||
		if( ! chan ) chan = Channel_Search( channame );
 | 
			
		||||
		assert( chan != NULL );
 | 
			
		||||
 | 
			
		||||
		/* Modes setzen (wenn vorhanden) */
 | 
			
		||||
@@ -93,8 +177,11 @@ GLOBAL BOOLEAN IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
			flags++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Wenn persistenter Channel und IRC-Operator: zum Channel-OP machen */
 | 
			
		||||
		if(( strchr( Channel_Modes( chan ), 'P' )) && ( strchr( Client_Modes( target ), 'o' ))) Channel_UserModeAdd( chan, target, 'o' );
 | 
			
		||||
 | 
			
		||||
		/* Muessen Modes an andere Server gemeldet werden? */
 | 
			
		||||
		strcpy( &modes[1], Channel_UserModes( chan, target ));
 | 
			
		||||
		strlcpy( &modes[1], Channel_UserModes( chan, target ), sizeof( modes ) - 1 );
 | 
			
		||||
		if( modes[1] ) modes[0] = 0x7;
 | 
			
		||||
		else modes[0] = '\0';
 | 
			
		||||
 | 
			
		||||
@@ -106,7 +193,7 @@ GLOBAL BOOLEAN IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		if( modes[1] )
 | 
			
		||||
		{
 | 
			
		||||
			/* Modes im Channel bekannt machen */
 | 
			
		||||
			IRC_WriteStrChannelPrefix( Client, chan, target, FALSE, "MODE %s %s :%s", channame, modes, Client_ID( target ));
 | 
			
		||||
			IRC_WriteStrChannelPrefix( Client, chan, target, FALSE, "MODE %s +%s %s", channame, &modes[1], Client_ID( target ));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if( Client_Type( Client ) == CLIENT_USER )
 | 
			
		||||
@@ -130,7 +217,8 @@ GLOBAL BOOLEAN IRC_JOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
} /* IRC_JOIN */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_PART( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_PART( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *target;
 | 
			
		||||
	CHAR *chan;
 | 
			
		||||
@@ -138,8 +226,6 @@ GLOBAL BOOLEAN IRC_PART( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
@@ -166,7 +252,8 @@ GLOBAL BOOLEAN IRC_PART( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
} /* IRC_PART */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	CLIENT *from;
 | 
			
		||||
@@ -175,8 +262,6 @@ GLOBAL BOOLEAN IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc < 1 ) || ( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
@@ -186,7 +271,7 @@ GLOBAL BOOLEAN IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
 | 
			
		||||
	/* Welcher Channel? */
 | 
			
		||||
	chan = Channel_Search( Req->argv[0] );
 | 
			
		||||
	if( ! chan ) return IRC_WriteStrClient( from, ERR_NOTONCHANNEL_MSG, Client_ID( from ), Req->argv[0] );
 | 
			
		||||
	if( ! chan ) return IRC_WriteStrClient( from, ERR_NOSUCHCHANNEL_MSG, Client_ID( from ), Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
	/* Ist der User Mitglied in dem Channel? */
 | 
			
		||||
	if( ! Channel_IsMemberOf( chan, from )) return IRC_WriteStrClient( from, ERR_NOTONCHANNEL_MSG, Client_ID( from ), Req->argv[0] );
 | 
			
		||||
@@ -218,4 +303,154 @@ GLOBAL BOOLEAN IRC_TOPIC( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
} /* IRC_TOPIC */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_LIST( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CHAR *pattern;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	CLIENT *from, *target;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	if( Req->argc > 0 ) pattern = strtok( Req->argv[0], "," );
 | 
			
		||||
	else pattern = "*";
 | 
			
		||||
 | 
			
		||||
	/* From aus Prefix ermitteln */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	if( Req->argc == 2 )
 | 
			
		||||
	{
 | 
			
		||||
		/* an anderen Server forwarden */
 | 
			
		||||
		target = Client_Search( Req->argv[1] );
 | 
			
		||||
		if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
		if( target != Client_ThisServer( ))
 | 
			
		||||
		{
 | 
			
		||||
			/* Ok, anderer Server ist das Ziel: forwarden */
 | 
			
		||||
			return IRC_WriteStrClientPrefix( target, from, "LIST %s :%s", from, Req->argv[1] );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	while( pattern )
 | 
			
		||||
	{
 | 
			
		||||
		/* alle Channel durchgehen */
 | 
			
		||||
		chan = Channel_First( );
 | 
			
		||||
		while( chan )
 | 
			
		||||
		{
 | 
			
		||||
			/* Passt die Suchmaske auf diesen Channel? */
 | 
			
		||||
			if( Match( pattern, Channel_Name( chan )))
 | 
			
		||||
			{
 | 
			
		||||
				/* Treffer! */
 | 
			
		||||
				if( ! IRC_WriteStrClient( from, RPL_LIST_MSG, from, Channel_Name( chan ), Channel_MemberCount( chan ), Channel_Topic( chan ))) return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
			chan = Channel_Next( chan );
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		/* naechsten Namen ermitteln */
 | 
			
		||||
		if( Req->argc > 0 ) pattern = strtok( NULL, "," );
 | 
			
		||||
		else pattern = NULL;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return IRC_WriteStrClient( from, RPL_LISTEND_MSG, from );
 | 
			
		||||
} /* IRC_LIST */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_CHANINFO( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CHAR modes_add[COMMAND_LEN], l[16], *ptr;
 | 
			
		||||
	CLIENT *from;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	INT arg_topic;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Bad number of parameters? */
 | 
			
		||||
	if(( Req->argc < 2 ) || ( Req->argc == 4 ) || ( Req->argc > 5 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Compatibility kludge */
 | 
			
		||||
	if( Req->argc == 5 ) arg_topic = 4;
 | 
			
		||||
	else if( Req->argc == 3 ) arg_topic = 2;
 | 
			
		||||
	else arg_topic = -1;
 | 
			
		||||
 | 
			
		||||
	/* Search origin */
 | 
			
		||||
	from = Client_Search( Req->prefix );
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	/* Search or create channel */
 | 
			
		||||
	chan = Channel_Search( Req->argv[0] );
 | 
			
		||||
	if( ! chan ) chan = Channel_Create( Req->argv[0] );
 | 
			
		||||
	if( ! chan ) return CONNECTED;
 | 
			
		||||
 | 
			
		||||
	if( Req->argv[1][0] == '+' )
 | 
			
		||||
	{
 | 
			
		||||
		ptr = Channel_Modes( chan );
 | 
			
		||||
		if( ! *ptr )
 | 
			
		||||
		{
 | 
			
		||||
			/* OK, this channel doesn't have modes jet, set the received ones: */
 | 
			
		||||
			Channel_SetModes( chan, &Req->argv[1][1] );
 | 
			
		||||
 | 
			
		||||
			if( Req->argc == 5 )
 | 
			
		||||
			{
 | 
			
		||||
				if( strchr( Channel_Modes( chan ), 'k' )) Channel_SetKey( chan, Req->argv[2] );
 | 
			
		||||
				if( strchr( Channel_Modes( chan ), 'l' )) Channel_SetMaxUsers( chan, atol( Req->argv[3] ));
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				/* Delete modes which we never want to inherit */
 | 
			
		||||
				Channel_ModeDel( chan, 'l' );
 | 
			
		||||
				Channel_ModeDel( chan, 'k' );
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			strcpy( modes_add, "" );
 | 
			
		||||
			ptr = Channel_Modes( chan );
 | 
			
		||||
			while( *ptr )
 | 
			
		||||
			{
 | 
			
		||||
				if( *ptr == 'l' )
 | 
			
		||||
				{
 | 
			
		||||
					snprintf( l, sizeof( l ), " %ld", Channel_MaxUsers( chan ));
 | 
			
		||||
					strlcat( modes_add, l, sizeof( modes_add ));
 | 
			
		||||
				}
 | 
			
		||||
				if( *ptr == 'k' )
 | 
			
		||||
				{
 | 
			
		||||
					strlcat( modes_add, " ", sizeof( modes_add ));
 | 
			
		||||
					strlcat( modes_add, Channel_Key( chan ), sizeof( modes_add ));
 | 
			
		||||
				}
 | 
			
		||||
	     			ptr++;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			/* Inform members of this channel */
 | 
			
		||||
			IRC_WriteStrChannelPrefix( Client, chan, from, FALSE, "MODE %s +%s%s", Req->argv[0], Channel_Modes( chan ), modes_add );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else Log( LOG_WARNING, "CHANINFO: invalid MODE format ignored!" );
 | 
			
		||||
 | 
			
		||||
	if( arg_topic > 0 )
 | 
			
		||||
	{
 | 
			
		||||
		/* We got a topic */
 | 
			
		||||
		ptr = Channel_Topic( chan );
 | 
			
		||||
		if(( ! *ptr ) && ( Req->argv[arg_topic][0] ))
 | 
			
		||||
		{
 | 
			
		||||
			/* OK, there is no topic jet */
 | 
			
		||||
			Channel_SetTopic( chan, Req->argv[arg_topic] );
 | 
			
		||||
			IRC_WriteStrChannelPrefix( Client, chan, from, FALSE, "TOPIC %s :%s", Req->argv[0], Channel_Topic( chan ));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Forward CHANINFO to other serevrs */
 | 
			
		||||
	if( Req->argc == 5 ) IRC_WriteStrServersPrefixFlag( Client, from, 'C', "CHANINFO %s %s %s %s :%s", Req->argv[0], Req->argv[1], Req->argv[2], Req->argv[3], Req->argv[4] );
 | 
			
		||||
	else if( Req->argc == 3 ) IRC_WriteStrServersPrefixFlag( Client, from, 'C', "CHANINFO %s %s :%s", Req->argv[0], Req->argv[1], Req->argv[2] );
 | 
			
		||||
	else IRC_WriteStrServersPrefixFlag( Client, from, 'C', "CHANINFO %s %s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_CHANINFO */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -2,29 +2,29 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-channel.h,v 1.2 2002/03/12 14:37:52 alex Exp $
 | 
			
		||||
 * $Id: irc-channel.h,v 1.6 2002/12/12 12:23:43 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * irc-channel.h: IRC-Channel-Befehle (Header)
 | 
			
		||||
 * IRC channel commands (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __irc_channel_h__
 | 
			
		||||
#define __irc_channel_h__
 | 
			
		||||
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_JOIN PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_PART PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_TOPIC PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_JOIN( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_PART( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_TOPIC( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_LIST PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_CHANINFO PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										898
									
								
								src/ngircd/irc-info.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										898
									
								
								src/ngircd/irc-info.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,898 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * IRC info commands
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-info.c,v 1.16.2.2 2003/11/07 20:51:11 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "cvs-version.h"
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "conn-zip.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "tool.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "irc-info.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_ADMIN(CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *target, *prefix;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc > 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Ziel suchen */
 | 
			
		||||
	if( Req->argc == 1 ) target = Client_Search( Req->argv[0] );
 | 
			
		||||
	else target = Client_ThisServer( );
 | 
			
		||||
 | 
			
		||||
	/* Prefix ermitteln */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) prefix = Client_Search( Req->prefix );
 | 
			
		||||
	else prefix = Client;
 | 
			
		||||
	if( ! prefix ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	/* An anderen Server weiterleiten? */
 | 
			
		||||
	if( target != Client_ThisServer( ))
 | 
			
		||||
	{
 | 
			
		||||
		if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( prefix, ERR_NOSUCHSERVER_MSG, Client_ID( prefix ), Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
		/* forwarden */
 | 
			
		||||
		IRC_WriteStrClientPrefix( target, prefix, "ADMIN %s", Req->argv[0] );
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* mit Versionsinfo antworten */
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_ADMINME_MSG, Client_ID( prefix ), Conf_ServerName )) return DISCONNECTED;
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_ADMINLOC1_MSG, Client_ID( prefix ), Conf_ServerAdmin1 )) return DISCONNECTED;
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_ADMINLOC2_MSG, Client_ID( prefix ), Conf_ServerAdmin2 )) return DISCONNECTED;
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_ADMINEMAIL_MSG, Client_ID( prefix ), Conf_ServerAdminMail )) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	IRC_SetPenalty( Client, 1 );
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_ADMIN */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_ISON( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CHAR rpl[COMMAND_LEN];
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	CHAR *ptr;
 | 
			
		||||
	INT i;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc < 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	strcpy( rpl, RPL_ISON_MSG );
 | 
			
		||||
	for( i = 0; i < Req->argc; i++ )
 | 
			
		||||
	{
 | 
			
		||||
		ptr = strtok( Req->argv[i], " " );
 | 
			
		||||
		while( ptr )
 | 
			
		||||
		{
 | 
			
		||||
			ngt_TrimStr( ptr );
 | 
			
		||||
			c = Client_Search( ptr );
 | 
			
		||||
			if( c && ( Client_Type( c ) == CLIENT_USER ))
 | 
			
		||||
			{
 | 
			
		||||
				/* Dieser Nick ist "online" */
 | 
			
		||||
				strlcat( rpl, ptr, sizeof( rpl ));
 | 
			
		||||
				strlcat( rpl, " ", sizeof( rpl ));
 | 
			
		||||
			}
 | 
			
		||||
			ptr = strtok( NULL, " " );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if( rpl[strlen( rpl ) - 1] == ' ' ) rpl[strlen( rpl ) - 1] = '\0';
 | 
			
		||||
 | 
			
		||||
	return IRC_WriteStrClient( Client, rpl, Client_ID( Client ) );
 | 
			
		||||
} /* IRC_ISON */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_LINKS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *target, *from, *c;
 | 
			
		||||
	CHAR *mask;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Server-Mask ermitteln */
 | 
			
		||||
	if( Req->argc > 0 ) mask = Req->argv[Req->argc - 1];
 | 
			
		||||
	else mask = "*";
 | 
			
		||||
 | 
			
		||||
	/* Absender ermitteln */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	/* An anderen Server forwarden? */
 | 
			
		||||
	if( Req->argc == 2 )
 | 
			
		||||
	{
 | 
			
		||||
		target = Client_Search( Req->argv[0] );
 | 
			
		||||
		if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[0] );
 | 
			
		||||
		else if( target != Client_ThisServer( )) return IRC_WriteStrClientPrefix( target, from, "LINKS %s %s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Wer ist der Absender? */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
 | 
			
		||||
	else target = Client;
 | 
			
		||||
	if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	c = Client_First( );
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		if( Client_Type( c ) == CLIENT_SERVER )
 | 
			
		||||
		{
 | 
			
		||||
			if( ! IRC_WriteStrClient( target, RPL_LINKS_MSG, Client_ID( target ), Client_ID( c ), Client_ID( Client_TopServer( c ) ? Client_TopServer( c ) : Client_ThisServer( )), Client_Hops( c ), Client_Info( c ))) return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
		c = Client_Next( c );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	IRC_SetPenalty( target, 1 );
 | 
			
		||||
	return IRC_WriteStrClient( target, RPL_ENDOFLINKS_MSG, Client_ID( target ), mask );
 | 
			
		||||
} /* IRC_LINKS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_LUSERS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *target, *from;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Absender ermitteln */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	/* An anderen Server forwarden? */
 | 
			
		||||
	if( Req->argc == 2 )
 | 
			
		||||
	{
 | 
			
		||||
		target = Client_Search( Req->argv[1] );
 | 
			
		||||
		if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[1] );
 | 
			
		||||
		else if( target != Client_ThisServer( )) return IRC_WriteStrClientPrefix( target, from, "LUSERS %s %s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Wer ist der Absender? */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
 | 
			
		||||
	else target = Client;
 | 
			
		||||
	if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	IRC_Send_LUSERS( target );
 | 
			
		||||
 | 
			
		||||
	IRC_SetPenalty( target, 1 );
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_LUSERS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_MOTD( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *from, *target;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* From aus Prefix ermitteln */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	if( Req->argc == 1 )
 | 
			
		||||
	{
 | 
			
		||||
		/* an anderen Server forwarden */
 | 
			
		||||
		target = Client_Search( Req->argv[0] );
 | 
			
		||||
		if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
		if( target != Client_ThisServer( ))
 | 
			
		||||
		{
 | 
			
		||||
			/* Ok, anderer Server ist das Ziel: forwarden */
 | 
			
		||||
			return IRC_WriteStrClientPrefix( target, from, "MOTD %s", Req->argv[0] );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	IRC_SetPenalty( from, 3 );
 | 
			
		||||
	return IRC_Show_MOTD( from );
 | 
			
		||||
} /* IRC_MOTD */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_NAMES( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CHAR rpl[COMMAND_LEN], *ptr;
 | 
			
		||||
	CLIENT *target, *from, *c;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* From aus Prefix ermitteln */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	if( Req->argc == 2 )
 | 
			
		||||
	{
 | 
			
		||||
		/* an anderen Server forwarden */
 | 
			
		||||
		target = Client_Search( Req->argv[1] );
 | 
			
		||||
		if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
		if( target != Client_ThisServer( ))
 | 
			
		||||
		{
 | 
			
		||||
			/* Ok, anderer Server ist das Ziel: forwarden */
 | 
			
		||||
			return IRC_WriteStrClientPrefix( target, from, "NAMES %s :%s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( Req->argc > 0 )
 | 
			
		||||
	{
 | 
			
		||||
		/* bestimmte Channels durchgehen */
 | 
			
		||||
		ptr = strtok( Req->argv[0], "," );
 | 
			
		||||
		while( ptr )
 | 
			
		||||
		{
 | 
			
		||||
			chan = Channel_Search( ptr );
 | 
			
		||||
			if( chan )
 | 
			
		||||
			{
 | 
			
		||||
				/* Namen ausgeben */
 | 
			
		||||
				if( ! IRC_Send_NAMES( from, chan )) return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
			if( ! IRC_WriteStrClient( from, RPL_ENDOFNAMES_MSG, Client_ID( from ), ptr )) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
			/* naechsten Namen ermitteln */
 | 
			
		||||
			ptr = strtok( NULL, "," );
 | 
			
		||||
		}
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* alle Channels durchgehen */
 | 
			
		||||
	chan = Channel_First( );
 | 
			
		||||
	while( chan )
 | 
			
		||||
	{
 | 
			
		||||
		/* Namen ausgeben */
 | 
			
		||||
		if( ! IRC_Send_NAMES( from, chan )) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
		/* naechster Channel */
 | 
			
		||||
		chan = Channel_Next( chan );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Nun noch alle Clients ausgeben, die in keinem Channel sind */
 | 
			
		||||
	c = Client_First( );
 | 
			
		||||
	snprintf( rpl, sizeof( rpl ), RPL_NAMREPLY_MSG, Client_ID( from ), "*", "*" );
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		if(( Client_Type( c ) == CLIENT_USER ) && ( Channel_FirstChannelOf( c ) == NULL ) && ( ! strchr( Client_Modes( c ), 'i' )))
 | 
			
		||||
		{
 | 
			
		||||
			/* Okay, das ist ein User: anhaengen */
 | 
			
		||||
			if( rpl[strlen( rpl ) - 1] != ':' ) strlcat( rpl, " ", sizeof( rpl ));
 | 
			
		||||
			strlcat( rpl, Client_ID( c ), sizeof( rpl ));
 | 
			
		||||
 | 
			
		||||
			if( strlen( rpl ) > ( LINE_LEN - CLIENT_NICK_LEN - 4 ))
 | 
			
		||||
			{
 | 
			
		||||
				/* Zeile wird zu lang: senden! */
 | 
			
		||||
				if( ! IRC_WriteStrClient( from, "%s", rpl )) return DISCONNECTED;
 | 
			
		||||
				snprintf( rpl, sizeof( rpl ), RPL_NAMREPLY_MSG, Client_ID( from ), "*", "*" );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* naechster Client */
 | 
			
		||||
		c = Client_Next( c );
 | 
			
		||||
	}
 | 
			
		||||
	if( rpl[strlen( rpl ) - 1] != ':')
 | 
			
		||||
	{
 | 
			
		||||
		/* es wurden User gefunden */
 | 
			
		||||
		if( ! IRC_WriteStrClient( from, "%s", rpl )) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	IRC_SetPenalty( from, 1 );
 | 
			
		||||
	return IRC_WriteStrClient( from, RPL_ENDOFNAMES_MSG, Client_ID( from ), "*" );
 | 
			
		||||
} /* IRC_NAMES */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_STATS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *from, *target, *cl;
 | 
			
		||||
	CONN_ID con;
 | 
			
		||||
	CHAR query;
 | 
			
		||||
	COMMAND *cmd;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* From aus Prefix ermitteln */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	if( Req->argc == 2 )
 | 
			
		||||
	{
 | 
			
		||||
		/* an anderen Server forwarden */
 | 
			
		||||
		target = Client_Search( Req->argv[1] );
 | 
			
		||||
		if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
		if( target != Client_ThisServer( ))
 | 
			
		||||
		{
 | 
			
		||||
			/* Ok, anderer Server ist das Ziel: forwarden */
 | 
			
		||||
			return IRC_WriteStrClientPrefix( target, from, "STATS %s %s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( Req->argc > 0 ) query = Req->argv[0][0] ? Req->argv[0][0] : '*';
 | 
			
		||||
	else query = '*';
 | 
			
		||||
 | 
			
		||||
	switch ( query )
 | 
			
		||||
	{
 | 
			
		||||
		case 'l':	/* Links */
 | 
			
		||||
		case 'L':
 | 
			
		||||
			con = Conn_First( );
 | 
			
		||||
			while( con != NONE )
 | 
			
		||||
			{
 | 
			
		||||
				cl = Client_GetFromConn( con );
 | 
			
		||||
				if( cl && (( Client_Type( cl ) == CLIENT_SERVER ) || ( cl == Client )))
 | 
			
		||||
				{
 | 
			
		||||
					/* Server link or our own connection */
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
					if( Conn_Options( con ) & CONN_ZIP )
 | 
			
		||||
					{
 | 
			
		||||
						if( ! IRC_WriteStrClient( from, RPL_STATSLINKINFOZIP_MSG, Client_ID( from ), Client_Mask( cl ), Conn_SendQ( con ), Conn_SendMsg( con ), Zip_SendBytes( con ), Conn_SendBytes( con ), Conn_RecvMsg( con ), Zip_RecvBytes( con ), Conn_RecvBytes( con ), (LONG)( time( NULL ) - Conn_StartTime( con )))) return DISCONNECTED;
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
#endif
 | 
			
		||||
					{
 | 
			
		||||
						if( ! IRC_WriteStrClient( from, RPL_STATSLINKINFO_MSG, Client_ID( from ), Client_Mask( cl ), Conn_SendQ( con ), Conn_SendMsg( con ), Conn_SendBytes( con ), Conn_RecvMsg( con ), Conn_RecvBytes( con ), (LONG)( time( NULL ) - Conn_StartTime( con )))) return DISCONNECTED;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				con = Conn_Next( con );
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case 'm':	/* IRC-Befehle */
 | 
			
		||||
		case 'M':
 | 
			
		||||
			cmd = Parse_GetCommandStruct( );
 | 
			
		||||
			while( cmd->name )
 | 
			
		||||
			{
 | 
			
		||||
				if( cmd->lcount > 0 || cmd->rcount > 0 )
 | 
			
		||||
				{
 | 
			
		||||
					if( ! IRC_WriteStrClient( from, RPL_STATSCOMMANDS_MSG, Client_ID( from ), cmd->name, cmd->lcount, cmd->bytes, cmd->rcount )) return DISCONNECTED;
 | 
			
		||||
				}
 | 
			
		||||
				cmd++;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	IRC_SetPenalty( from, 2 );
 | 
			
		||||
	return IRC_WriteStrClient( from, RPL_ENDOFSTATS_MSG, Client_ID( from ), query );
 | 
			
		||||
} /* IRC_STATS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_TIME( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *from, *target;
 | 
			
		||||
	CHAR t_str[64];
 | 
			
		||||
	time_t t;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* From aus Prefix ermitteln */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	if( Req->argc == 1 )
 | 
			
		||||
	{
 | 
			
		||||
		/* an anderen Server forwarden */
 | 
			
		||||
		target = Client_Search( Req->argv[0] );
 | 
			
		||||
		if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
		if( target != Client_ThisServer( ))
 | 
			
		||||
		{
 | 
			
		||||
			/* Ok, anderer Server ist das Ziel: forwarden */
 | 
			
		||||
			return IRC_WriteStrClientPrefix( target, from, "TIME %s", Req->argv[0] );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	t = time( NULL );
 | 
			
		||||
	(VOID)strftime( t_str, 60, "%A %B %d %Y -- %H:%M %Z", localtime( &t ));
 | 
			
		||||
	return IRC_WriteStrClient( from, RPL_TIME_MSG, Client_ID( from ), Client_ID( Client_ThisServer( )), t_str );
 | 
			
		||||
} /* IRC_TIME */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_USERHOST( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CHAR rpl[COMMAND_LEN];
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	INT max, i;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc < 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	if( Req->argc > 5 ) max = 5;
 | 
			
		||||
	else max = Req->argc;
 | 
			
		||||
 | 
			
		||||
	strcpy( rpl, RPL_USERHOST_MSG );
 | 
			
		||||
	for( i = 0; i < max; i++ )
 | 
			
		||||
	{
 | 
			
		||||
		c = Client_Search( Req->argv[i] );
 | 
			
		||||
		if( c && ( Client_Type( c ) == CLIENT_USER ))
 | 
			
		||||
		{
 | 
			
		||||
			/* Dieser Nick ist "online" */
 | 
			
		||||
			strlcat( rpl, Client_ID( c ), sizeof( rpl ));
 | 
			
		||||
			if( Client_HasMode( c, 'o' )) strlcat( rpl, "*", sizeof( rpl ));
 | 
			
		||||
			strlcat( rpl, "=", sizeof( rpl ));
 | 
			
		||||
			if( Client_HasMode( c, 'a' )) strlcat( rpl, "-", sizeof( rpl ));
 | 
			
		||||
			else strlcat( rpl, "+", sizeof( rpl ));
 | 
			
		||||
			strlcat( rpl, Client_User( c ), sizeof( rpl ));
 | 
			
		||||
			strlcat( rpl, "@", sizeof( rpl ));
 | 
			
		||||
			strlcat( rpl, Client_Hostname( c ), sizeof( rpl ));
 | 
			
		||||
			strlcat( rpl, " ", sizeof( rpl ));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if( rpl[strlen( rpl ) - 1] == ' ' ) rpl[strlen( rpl ) - 1] = '\0';
 | 
			
		||||
 | 
			
		||||
	return IRC_WriteStrClient( Client, rpl, Client_ID( Client ) );
 | 
			
		||||
} /* IRC_USERHOST */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_VERSION( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *target, *prefix;
 | 
			
		||||
#ifdef CVSDATE
 | 
			
		||||
	CHAR ver[12];
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc > 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Ziel suchen */
 | 
			
		||||
	if( Req->argc == 1 ) target = Client_Search( Req->argv[0] );
 | 
			
		||||
	else target = Client_ThisServer( );
 | 
			
		||||
 | 
			
		||||
	/* Prefix ermitteln */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) prefix = Client_Search( Req->prefix );
 | 
			
		||||
	else prefix = Client;
 | 
			
		||||
	if( ! prefix ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	/* An anderen Server weiterleiten? */
 | 
			
		||||
	if( target != Client_ThisServer( ))
 | 
			
		||||
	{
 | 
			
		||||
		if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( prefix, ERR_NOSUCHSERVER_MSG, Client_ID( prefix ), Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
		/* forwarden */
 | 
			
		||||
		IRC_WriteStrClientPrefix( target, prefix, "VERSION %s", Req->argv[0] );
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* mit Versionsinfo antworten */
 | 
			
		||||
	IRC_SetPenalty( Client, 1 );
 | 
			
		||||
#ifdef CVSDATE
 | 
			
		||||
	strlcpy( ver, CVSDATE, sizeof( ver ));
 | 
			
		||||
	strncpy( ver + 4, ver + 5, 2 );
 | 
			
		||||
	strncpy( ver + 6, ver + 8, 3 );
 | 
			
		||||
	return IRC_WriteStrClient( Client, RPL_VERSION_MSG, Client_ID( prefix ), PACKAGE_NAME, ver, NGIRCd_DebugLevel, Conf_ServerName, NGIRCd_VersionAddition( ));
 | 
			
		||||
#else
 | 
			
		||||
	return IRC_WriteStrClient( Client, RPL_VERSION_MSG, Client_ID( prefix ), PACKAGE_NAME, PACKAGE_VERSION, NGIRCd_DebugLevel, Conf_ServerName, NGIRCd_VersionAddition( ));
 | 
			
		||||
#endif
 | 
			
		||||
} /* IRC_VERSION */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_WHO( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	BOOLEAN ok, only_ops;
 | 
			
		||||
	CHAR flags[8], *ptr;
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	only_ops = FALSE;
 | 
			
		||||
	chan = NULL;
 | 
			
		||||
 | 
			
		||||
	if( Req->argc == 2 )
 | 
			
		||||
	{
 | 
			
		||||
		/* Nur OPs anzeigen? */
 | 
			
		||||
		if( strcmp( Req->argv[1], "o" ) == 0 ) only_ops = TRUE;
 | 
			
		||||
#ifdef STRICT_RFC
 | 
			
		||||
		else return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( Req->argc >= 1 )
 | 
			
		||||
	{
 | 
			
		||||
		/* wurde ein Channel oder Nick-Mask angegeben? */
 | 
			
		||||
		chan = Channel_Search( Req->argv[0] );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( chan )
 | 
			
		||||
	{
 | 
			
		||||
		/* User eines Channels ausgeben */
 | 
			
		||||
		if( ! IRC_Send_WHO( Client, chan, only_ops )) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c = Client_First( );
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		if(( Client_Type( c ) == CLIENT_USER ) && ( ! strchr( Client_Modes( c ), 'i' )))
 | 
			
		||||
		{
 | 
			
		||||
			ok = FALSE;
 | 
			
		||||
			if( Req->argc == 0 ) ok = TRUE;
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				if( strcasecmp( Req->argv[0], Client_ID( c )) == 0 ) ok = TRUE;
 | 
			
		||||
				else if( strcmp( Req->argv[0], "0" ) == 0 ) ok = TRUE;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if( ok && (( ! only_ops ) || ( strchr( Client_Modes( c ), 'o' ))))
 | 
			
		||||
			{
 | 
			
		||||
				/* Flags zusammenbasteln */
 | 
			
		||||
				strcpy( flags, "H" );
 | 
			
		||||
				if( strchr( Client_Modes( c ), 'o' )) strlcat( flags, "*", sizeof( flags ));
 | 
			
		||||
 | 
			
		||||
				/* ausgeben */
 | 
			
		||||
				cl2chan = Channel_FirstChannelOf( c );
 | 
			
		||||
				if( cl2chan ) ptr = Channel_Name( Channel_GetChannel( cl2chan ));
 | 
			
		||||
				else ptr = "*";
 | 
			
		||||
				if( ! IRC_WriteStrClient( Client, RPL_WHOREPLY_MSG, Client_ID( Client ), ptr, Client_User( c ), Client_Hostname( c ), Client_ID( Client_Introducer( c )), Client_ID( c ), flags, Client_Hops( c ), Client_Info( c ))) return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* naechster Client */
 | 
			
		||||
		c = Client_Next( c );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( chan ) return IRC_WriteStrClient( Client, RPL_ENDOFWHO_MSG, Client_ID( Client ), Channel_Name( chan ));
 | 
			
		||||
	else if( Req->argc == 0 ) return IRC_WriteStrClient( Client, RPL_ENDOFWHO_MSG, Client_ID( Client ), "*" );
 | 
			
		||||
	else return IRC_WriteStrClient( Client, RPL_ENDOFWHO_MSG, Client_ID( Client ), Req->argv[0] );
 | 
			
		||||
} /* IRC_WHO */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_WHOIS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *from, *target, *c;
 | 
			
		||||
	CHAR str[LINE_LEN + 1];
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Bad number of parameters? */
 | 
			
		||||
	if(( Req->argc < 1 ) || ( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Search client */
 | 
			
		||||
	c = Client_Search( Req->argv[Req->argc - 1] );
 | 
			
		||||
	if(( ! c ) || ( Client_Type( c ) != CLIENT_USER )) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[Req->argc - 1] );
 | 
			
		||||
 | 
			
		||||
	/* Search sender of the WHOIS */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	/* Forward to other server? */
 | 
			
		||||
	if( Req->argc > 1 )
 | 
			
		||||
	{
 | 
			
		||||
		/* Search target server (can be specified as nick of that server!) */
 | 
			
		||||
		target = Client_Search( Req->argv[0] );
 | 
			
		||||
		if( ! target ) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[0] );
 | 
			
		||||
	}
 | 
			
		||||
	else target = Client_ThisServer( );
 | 
			
		||||
 | 
			
		||||
	assert( target != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Client_NextHop( target ) != Client_ThisServer( )) && ( Client_Type( Client_NextHop( target )) == CLIENT_SERVER )) return IRC_WriteStrClientPrefix( target, from, "WHOIS %s :%s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
	/* Nick, user and name */
 | 
			
		||||
	if( ! IRC_WriteStrClient( from, RPL_WHOISUSER_MSG, Client_ID( from ), Client_ID( c ), Client_User( c ), Client_Hostname( c ), Client_Info( c ))) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	/* Server */
 | 
			
		||||
	if( ! IRC_WriteStrClient( from, RPL_WHOISSERVER_MSG, Client_ID( from ), Client_ID( c ), Client_ID( Client_Introducer( c )), Client_Info( Client_Introducer( c )))) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	/* Channels */
 | 
			
		||||
	snprintf( str, sizeof( str ), RPL_WHOISCHANNELS_MSG, Client_ID( from ), Client_ID( c ));
 | 
			
		||||
	cl2chan = Channel_FirstChannelOf( c );
 | 
			
		||||
	while( cl2chan )
 | 
			
		||||
	{
 | 
			
		||||
		chan = Channel_GetChannel( cl2chan );
 | 
			
		||||
		assert( chan != NULL );
 | 
			
		||||
 | 
			
		||||
		/* Concatenate channel names */
 | 
			
		||||
		if( str[strlen( str ) - 1] != ':' ) strlcat( str, " ", sizeof( str ));
 | 
			
		||||
		if( strchr( Channel_UserModes( chan, c ), 'o' )) strlcat( str, "@", sizeof( str ));
 | 
			
		||||
		else if( strchr( Channel_UserModes( chan, c ), 'v' )) strlcat( str, "+", sizeof( str ));
 | 
			
		||||
		strlcat( str, Channel_Name( chan ), sizeof( str ));
 | 
			
		||||
 | 
			
		||||
		if( strlen( str ) > ( LINE_LEN - CHANNEL_NAME_LEN - 4 ))
 | 
			
		||||
		{
 | 
			
		||||
			/* Line becomes too long: send it! */
 | 
			
		||||
			if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
 | 
			
		||||
			snprintf( str, sizeof( str ), RPL_WHOISCHANNELS_MSG, Client_ID( from ), Client_ID( c ));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* next */
 | 
			
		||||
		cl2chan = Channel_NextChannelOf( c, cl2chan );
 | 
			
		||||
	}
 | 
			
		||||
	if( str[strlen( str ) - 1] != ':')
 | 
			
		||||
	{
 | 
			
		||||
		/* There is data left to send: */
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* IRC-Operator? */
 | 
			
		||||
	if( Client_HasMode( c, 'o' ))
 | 
			
		||||
	{
 | 
			
		||||
		if( ! IRC_WriteStrClient( from, RPL_WHOISOPERATOR_MSG, Client_ID( from ), Client_ID( c ))) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Idle (only local clients) */
 | 
			
		||||
	if( Client_Conn( c ) > NONE )
 | 
			
		||||
	{
 | 
			
		||||
		if( ! IRC_WriteStrClient( from, RPL_WHOISIDLE_MSG, Client_ID( from ), Client_ID( c ), Conn_GetIdle( Client_Conn ( c )))) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Away? */
 | 
			
		||||
	if( Client_HasMode( c, 'a' ))
 | 
			
		||||
	{
 | 
			
		||||
		if( ! IRC_WriteStrClient( from, RPL_AWAY_MSG, Client_ID( from ), Client_ID( c ), Client_Away( c ))) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* End of Whois */
 | 
			
		||||
	return IRC_WriteStrClient( from, RPL_ENDOFWHOIS_MSG, Client_ID( from ), Client_ID( c ));
 | 
			
		||||
} /* IRC_WHOIS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_WHOWAS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc < 1 ) || ( Req->argc > 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* ... */
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_WHOWAS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_Send_LUSERS( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	LONG cnt;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Users, services and serevers in the network */
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_LUSERCLIENT_MSG, Client_ID( Client ), Client_UserCount( ), Client_ServiceCount( ), Client_ServerCount( ))) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	/* Number of IRC operators */
 | 
			
		||||
	cnt = Client_OperCount( );
 | 
			
		||||
	if( cnt > 0 )
 | 
			
		||||
	{
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, RPL_LUSEROP_MSG, Client_ID( Client ), cnt )) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Unknown connections */
 | 
			
		||||
	cnt = Client_UnknownCount( );
 | 
			
		||||
	if( cnt > 0 )
 | 
			
		||||
	{
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, RPL_LUSERUNKNOWN_MSG, Client_ID( Client ), cnt )) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Number of created channels */
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_LUSERCHANNELS_MSG, Client_ID( Client ), Channel_Count( ))) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	/* Number of local users, services and servers */
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_LUSERME_MSG, Client_ID( Client ), Client_MyUserCount( ), Client_MyServiceCount( ), Client_MyServerCount( ))) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
#ifndef STRICT_RFC
 | 
			
		||||
	/* Maximum number of local users */
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_LOCALUSERS_MSG, Client_ID( Client ), Client_MyUserCount( ), Client_MyMaxUserCount( ))) return DISCONNECTED;
 | 
			
		||||
	/* Maximum number of users in the network */
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_NETUSERS_MSG, Client_ID( Client ), Client_UserCount( ), Client_MaxUserCount( ))) return DISCONNECTED;
 | 
			
		||||
#endif
 | 
			
		||||
	
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_Send_LUSERS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_Show_MOTD( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	BOOLEAN ok;
 | 
			
		||||
	CHAR line[127];
 | 
			
		||||
	FILE *fd;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
	fd = fopen( Conf_MotdFile, "r" );
 | 
			
		||||
	if( ! fd )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_WARNING, "Can't read MOTD file \"%s\": %s", Conf_MotdFile, strerror( errno ));
 | 
			
		||||
		return IRC_WriteStrClient( Client, ERR_NOMOTD_MSG, Client_ID( Client ) );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	IRC_WriteStrClient( Client, RPL_MOTDSTART_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )));
 | 
			
		||||
	while( TRUE )
 | 
			
		||||
	{
 | 
			
		||||
		if( ! fgets( line, 126, fd )) break;
 | 
			
		||||
		if( line[strlen( line ) - 1] == '\n' ) line[strlen( line ) - 1] = '\0';
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, RPL_MOTD_MSG, Client_ID( Client ), line ))
 | 
			
		||||
		{
 | 
			
		||||
			fclose( fd );
 | 
			
		||||
			return FALSE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	ok = IRC_WriteStrClient( Client, RPL_ENDOFMOTD_MSG, Client_ID( Client ) );
 | 
			
		||||
 | 
			
		||||
	fclose( fd );
 | 
			
		||||
 | 
			
		||||
	return ok;
 | 
			
		||||
} /* IRC_Show_MOTD */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_Send_NAMES( CLIENT *Client, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	BOOLEAN is_visible, is_member;
 | 
			
		||||
	CHAR str[LINE_LEN + 1];
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	CLIENT *cl;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Channel_IsMemberOf( Chan, Client )) is_member = TRUE;
 | 
			
		||||
	else is_member = FALSE;
 | 
			
		||||
 | 
			
		||||
	/* Alle Mitglieder suchen */
 | 
			
		||||
	snprintf( str, sizeof( str ), RPL_NAMREPLY_MSG, Client_ID( Client ), "=", Channel_Name( Chan ));
 | 
			
		||||
	cl2chan = Channel_FirstMember( Chan );
 | 
			
		||||
	while( cl2chan )
 | 
			
		||||
	{
 | 
			
		||||
		cl = Channel_GetClient( cl2chan );
 | 
			
		||||
 | 
			
		||||
		if( strchr( Client_Modes( cl ), 'i' )) is_visible = FALSE;
 | 
			
		||||
		else is_visible = TRUE;
 | 
			
		||||
 | 
			
		||||
		if( is_member || is_visible )
 | 
			
		||||
		{
 | 
			
		||||
			/* Nick anhaengen */
 | 
			
		||||
			if( str[strlen( str ) - 1] != ':' ) strlcat( str, " ", sizeof( str ));
 | 
			
		||||
			if( strchr( Channel_UserModes( Chan, cl ), 'o' )) strlcat( str, "@", sizeof( str ));
 | 
			
		||||
			else if( strchr( Channel_UserModes( Chan, cl ), 'v' )) strlcat( str, "+", sizeof( str ));
 | 
			
		||||
			strlcat( str, Client_ID( cl ), sizeof( str ));
 | 
			
		||||
 | 
			
		||||
			if( strlen( str ) > ( LINE_LEN - CLIENT_NICK_LEN - 4 ))
 | 
			
		||||
			{
 | 
			
		||||
				/* Zeile wird zu lang: senden! */
 | 
			
		||||
				if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
 | 
			
		||||
				snprintf( str, sizeof( str ), RPL_NAMREPLY_MSG, Client_ID( Client ), "=", Channel_Name( Chan ));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* naechstes Mitglied suchen */
 | 
			
		||||
		cl2chan = Channel_NextMember( Chan, cl2chan );
 | 
			
		||||
	}
 | 
			
		||||
	if( str[strlen( str ) - 1] != ':')
 | 
			
		||||
	{
 | 
			
		||||
		/* Es sind noch Daten da, die gesendet werden muessen */
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_Send_NAMES */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_Send_WHO( CLIENT *Client, CHANNEL *Chan, BOOLEAN OnlyOps )
 | 
			
		||||
{
 | 
			
		||||
	BOOLEAN is_visible, is_member;
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	CHAR flags[8];
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Channel_IsMemberOf( Chan, Client )) is_member = TRUE;
 | 
			
		||||
	else is_member = FALSE;
 | 
			
		||||
 | 
			
		||||
	/* Alle Mitglieder suchen */
 | 
			
		||||
	cl2chan = Channel_FirstMember( Chan );
 | 
			
		||||
	while( cl2chan )
 | 
			
		||||
	{
 | 
			
		||||
		c = Channel_GetClient( cl2chan );
 | 
			
		||||
 | 
			
		||||
		if( strchr( Client_Modes( c ), 'i' )) is_visible = FALSE;
 | 
			
		||||
		else is_visible = TRUE;
 | 
			
		||||
 | 
			
		||||
		if( is_member || is_visible )
 | 
			
		||||
		{
 | 
			
		||||
			/* Flags zusammenbasteln */
 | 
			
		||||
			strcpy( flags, "H" );
 | 
			
		||||
			if( strchr( Client_Modes( c ), 'o' )) strlcat( flags, "*", sizeof( flags ));
 | 
			
		||||
			if( strchr( Channel_UserModes( Chan, c ), 'o' )) strlcat( flags, "@", sizeof( flags ));
 | 
			
		||||
			else if( strchr( Channel_UserModes( Chan, c ), 'v' )) strlcat( flags, "+", sizeof( flags ));
 | 
			
		||||
 | 
			
		||||
			/* ausgeben */
 | 
			
		||||
			if(( ! OnlyOps ) || ( strchr( Client_Modes( c ), 'o' )))
 | 
			
		||||
			{
 | 
			
		||||
				if( ! IRC_WriteStrClient( Client, RPL_WHOREPLY_MSG, Client_ID( Client ), Channel_Name( Chan ), Client_User( c ), Client_Hostname( c ), Client_ID( Client_Introducer( c )), Client_ID( c ), flags, Client_Hops( c ), Client_Info( c ))) return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* naechstes Mitglied suchen */
 | 
			
		||||
		cl2chan = Channel_NextMember( Chan, cl2chan );
 | 
			
		||||
	}
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_Send_WHO */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										44
									
								
								src/ngircd/irc-info.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/ngircd/irc-info.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-info.h,v 1.2 2002/12/12 12:23:43 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * IRC info commands (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __irc_info_h__
 | 
			
		||||
#define __irc_info_h__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_ADMIN PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_ISON PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_LINKS PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_LUSERS PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_MOTD PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_NAMES PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_STATS PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_TIME PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_USERHOST PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_VERSION PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_WHO PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_WHOIS PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_WHOWAS PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_Send_LUSERS PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_Send_NAMES PARAMS(( CLIENT *Client, CHANNEL *Chan ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_Show_MOTD PARAMS(( CLIENT *Client ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_Send_WHO PARAMS(( CLIENT *Client, CHANNEL *Chan, BOOLEAN OnlyOps ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
@@ -2,21 +2,20 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-login.c,v 1.11 2002/03/26 23:58:34 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * irc-login.c: Anmeldung und Abmeldung im IRC
 | 
			
		||||
 * Login and logout
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-login.c,v 1.34.2.1 2003/11/07 20:51:11 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
@@ -24,21 +23,28 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "irc.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "irc.h"
 | 
			
		||||
#include "irc-info.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "irc-login.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Hello_User( CLIENT *Client );
 | 
			
		||||
LOCAL VOID Kill_Nick( CHAR *Nick, CHAR *Reason );
 | 
			
		||||
LOCAL BOOLEAN Hello_User PARAMS(( CLIENT *Client ));
 | 
			
		||||
LOCAL VOID Kill_Nick PARAMS(( CHAR *Nick, CHAR *Reason ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_PASS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_PASS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
@@ -59,13 +65,71 @@ GLOBAL BOOLEAN IRC_PASS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	}
 | 
			
		||||
	else if((( Client_Type( Client ) == CLIENT_UNKNOWN ) || ( Client_Type( Client ) == CLIENT_UNKNOWNSERVER )) && (( Req->argc == 3 ) || ( Req->argc == 4 )))
 | 
			
		||||
	{
 | 
			
		||||
		CHAR c2, c4, *type, *impl, *serverver, *flags, *ptr, *ircflags;
 | 
			
		||||
		INT protohigh, protolow;
 | 
			
		||||
 | 
			
		||||
		/* noch nicht registrierte Server-Verbindung */
 | 
			
		||||
		Log( LOG_DEBUG, "Connection %d: got PASS command (new server link) ...", Client_Conn( Client ));
 | 
			
		||||
 | 
			
		||||
		/* Passwort speichern */
 | 
			
		||||
		Client_SetPassword( Client, Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
		/* Protokollversion ermitteln */
 | 
			
		||||
		if( strlen( Req->argv[1] ) >= 4 )
 | 
			
		||||
		{
 | 
			
		||||
			c2 = Req->argv[1][2];
 | 
			
		||||
			c4 = Req->argv[1][4];
 | 
			
		||||
 | 
			
		||||
			Req->argv[1][4] = '\0';
 | 
			
		||||
			protolow = atoi( &Req->argv[1][2] );
 | 
			
		||||
			Req->argv[1][2] = '\0';
 | 
			
		||||
			protohigh = atoi( Req->argv[1] );
 | 
			
		||||
			
 | 
			
		||||
			Req->argv[1][2] = c2;
 | 
			
		||||
			Req->argv[1][4] = c4;
 | 
			
		||||
		}			
 | 
			
		||||
		else protohigh = protolow = 0;
 | 
			
		||||
 | 
			
		||||
		/* Protokoll-Typ */
 | 
			
		||||
		if( strlen( Req->argv[1] ) > 4 ) type = &Req->argv[1][4];
 | 
			
		||||
		else type = NULL;
 | 
			
		||||
 | 
			
		||||
		/* IRC-Flags (nach RFC 2813) */
 | 
			
		||||
		if( Req->argc >= 4 ) ircflags = Req->argv[3];
 | 
			
		||||
		else ircflags = "";
 | 
			
		||||
 | 
			
		||||
		/* Implementation, Version und ngIRCd-Flags */
 | 
			
		||||
		impl = Req->argv[2];
 | 
			
		||||
		ptr = strchr( impl, '|' );
 | 
			
		||||
		if( ptr ) *ptr = '\0';
 | 
			
		||||
 | 
			
		||||
		if( type && ( strcmp( type, PROTOIRCPLUS ) == 0 ))
 | 
			
		||||
		{
 | 
			
		||||
			/* auf der anderen Seite laeuft ein Server, der
 | 
			
		||||
			 * ebenfalls das IRC+-Protokoll versteht */
 | 
			
		||||
			serverver = ptr + 1;
 | 
			
		||||
			flags = strchr( serverver, ':' );
 | 
			
		||||
			if( flags )
 | 
			
		||||
			{
 | 
			
		||||
				*flags = '\0';
 | 
			
		||||
				flags++;
 | 
			
		||||
			}
 | 
			
		||||
			else flags = "";
 | 
			
		||||
			Log( LOG_INFO, "Peer announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").", impl, serverver, protohigh, protolow, flags );
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* auf der anderen Seite laeuft ein Server, der
 | 
			
		||||
			 * nur das Originalprotokoll unterstuetzt */
 | 
			
		||||
			serverver = "";
 | 
			
		||||
			if( strchr( ircflags, 'Z' )) flags = "Z";
 | 
			
		||||
			else flags = "";
 | 
			
		||||
			Log( LOG_INFO, "Peer announces itself as \"%s\" using protocol %d.%d (flags: \"%s\").", impl, protohigh, protolow, flags );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Client_SetType( Client, CLIENT_GOTPASSSERVER );
 | 
			
		||||
		Client_SetFlags( Client, flags );
 | 
			
		||||
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	else if(( Client_Type( Client ) == CLIENT_UNKNOWN  ) || ( Client_Type( Client ) == CLIENT_UNKNOWNSERVER ))
 | 
			
		||||
@@ -77,7 +141,8 @@ GLOBAL BOOLEAN IRC_PASS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
} /* IRC_PASS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_NICK( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_NICK( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *intr_c, *target, *c;
 | 
			
		||||
	CHAR *modes;
 | 
			
		||||
@@ -116,7 +181,7 @@ GLOBAL BOOLEAN IRC_NICK( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		 * wenn wir es nicht so machen. Ob es so okay ist? Hm ... */
 | 
			
		||||
		if( strcmp( Client_ID( target ), Req->argv[0] ) == 0 ) return CONNECTED;
 | 
			
		||||
#endif
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		/* pruefen, ob Nick bereits vergeben. Speziallfall: der Client
 | 
			
		||||
		 * will nur die Gross- und Kleinschreibung aendern. Das darf
 | 
			
		||||
		 * er natuerlich machen :-) */
 | 
			
		||||
@@ -140,8 +205,16 @@ GLOBAL BOOLEAN IRC_NICK( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* Nick-Aenderung */
 | 
			
		||||
			if( Client_Conn( target ) > NONE ) Log( LOG_INFO, "User \"%s\" changed nick (connection %d): \"%s\" -> \"%s\".", Client_Mask( target ), Client_ID( target ), Req->argv[0], Client_Conn( target ));
 | 
			
		||||
			else Log( LOG_DEBUG, "User \"%s\" changed nick: \"%s\" -> \"%s\".", Client_Mask( target ), Client_ID( target ), Req->argv[0] );
 | 
			
		||||
			if( Client_Conn( target ) > NONE )
 | 
			
		||||
			{
 | 
			
		||||
				/* lokaler Client */
 | 
			
		||||
				Log( LOG_INFO, "User \"%s\" changed nick (connection %d): \"%s\" -> \"%s\".", Client_Mask( target ), Client_Conn( target ), Client_ID( target ), Req->argv[0] );
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				/* Remote-Client */
 | 
			
		||||
				Log( LOG_DEBUG, "User \"%s\" changed nick: \"%s\" -> \"%s\".", Client_Mask( target ), Client_ID( target ), Req->argv[0] );
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* alle betroffenen User und Server ueber Nick-Aenderung informieren */
 | 
			
		||||
			if( Client_Type( Client ) == CLIENT_USER ) IRC_WriteStrClientPrefix( Client, Client, "NICK :%s", Req->argv[0] );
 | 
			
		||||
@@ -150,6 +223,7 @@ GLOBAL BOOLEAN IRC_NICK( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
			
 | 
			
		||||
			/* neuen Client-Nick speichern */
 | 
			
		||||
			Client_SetID( target, Req->argv[0] );
 | 
			
		||||
			IRC_SetPenalty( target, 2 );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
@@ -207,7 +281,8 @@ GLOBAL BOOLEAN IRC_NICK( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
} /* IRC_NICK */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_USER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_USER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
@@ -237,26 +312,15 @@ GLOBAL BOOLEAN IRC_USER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
} /* IRC_USER */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_QUIT( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_QUIT( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *target;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Client ) == CLIENT_USER ) || ( Client_Type( Client ) == CLIENT_SERVICE ))
 | 
			
		||||
	{
 | 
			
		||||
		/* User / Service */
 | 
			
		||||
		
 | 
			
		||||
		/* Falsche Anzahl Parameter? */
 | 
			
		||||
		if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
		if( Req->argc == 0 ) Conn_Close( Client_Conn( Client ), "Got QUIT command.", NULL, TRUE );
 | 
			
		||||
		else Conn_Close( Client_Conn( Client ), "Got QUIT command.", Req->argv[0], TRUE );
 | 
			
		||||
		
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	else if ( Client_Type( Client ) == CLIENT_SERVER )
 | 
			
		||||
	if ( Client_Type( Client ) == CLIENT_SERVER )
 | 
			
		||||
	{
 | 
			
		||||
		/* Server */
 | 
			
		||||
 | 
			
		||||
@@ -276,19 +340,29 @@ GLOBAL BOOLEAN IRC_QUIT( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	else return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* User, Service, oder noch nicht registriert */
 | 
			
		||||
		
 | 
			
		||||
		/* Falsche Anzahl Parameter? */
 | 
			
		||||
		if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
		if( Req->argc == 0 ) Conn_Close( Client_Conn( Client ), "Got QUIT command.", NULL, TRUE );
 | 
			
		||||
		else Conn_Close( Client_Conn( Client ), "Got QUIT command.", Req->argv[0], TRUE );
 | 
			
		||||
		
 | 
			
		||||
		return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
} /* IRC_QUIT */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_PING( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_PING( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *target, *from;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc < 1 ) return IRC_WriteStrClient( Client, ERR_NOORIGIN_MSG, Client_ID( Client ));
 | 
			
		||||
#ifdef STRICT_RFC
 | 
			
		||||
@@ -299,7 +373,7 @@ GLOBAL BOOLEAN IRC_PING( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	{
 | 
			
		||||
		/* es wurde ein Ziel-Client angegeben */
 | 
			
		||||
		target = Client_Search( Req->argv[1] );
 | 
			
		||||
		if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[1] );
 | 
			
		||||
		if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[1] );
 | 
			
		||||
		if( target != Client_ThisServer( ))
 | 
			
		||||
		{
 | 
			
		||||
			/* ok, forwarden */
 | 
			
		||||
@@ -315,15 +389,14 @@ GLOBAL BOOLEAN IRC_PING( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
} /* IRC_PING */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_PONG( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_PONG( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *target, *from;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc < 1 ) return IRC_WriteStrClient( Client, ERR_NOORIGIN_MSG, Client_ID( Client ));
 | 
			
		||||
	if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
@@ -332,7 +405,7 @@ GLOBAL BOOLEAN IRC_PONG( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	if( Req->argc == 2 )
 | 
			
		||||
	{
 | 
			
		||||
		target = Client_Search( Req->argv[1] );
 | 
			
		||||
		if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[1] );
 | 
			
		||||
		if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[1] );
 | 
			
		||||
		if( target != Client_ThisServer( ))
 | 
			
		||||
		{
 | 
			
		||||
			/* ok, forwarden */
 | 
			
		||||
@@ -353,7 +426,8 @@ GLOBAL BOOLEAN IRC_PONG( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
} /* IRC_PONG */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Hello_User( CLIENT *Client )
 | 
			
		||||
LOCAL BOOLEAN
 | 
			
		||||
Hello_User( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
@@ -372,34 +446,40 @@ LOCAL BOOLEAN Hello_User( CLIENT *Client )
 | 
			
		||||
	IRC_WriteStrServers( NULL, "NICK %s 1 %s %s 1 +%s :%s", Client_ID( Client ), Client_User( Client ), Client_Hostname( Client ), Client_Modes( Client ), Client_Info( Client ));
 | 
			
		||||
 | 
			
		||||
	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( )))) 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( )))) return FALSE;
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_MYINFO_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), PACKAGE_VERSION, USERMODES, CHANMODES )) return FALSE;
 | 
			
		||||
 | 
			
		||||
	/* Features */
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_ISUPPORT_MSG, Client_ID( Client ), CLIENT_NICK_LEN - 1, CHANNEL_TOPIC_LEN - 1, CLIENT_AWAY_LEN - 1, Conf_MaxJoins )) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	Client_SetType( Client, CLIENT_USER );
 | 
			
		||||
 | 
			
		||||
	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;
 | 
			
		||||
} /* Hello_User */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Kill_Nick( CHAR *Nick, CHAR *Reason )
 | 
			
		||||
LOCAL VOID
 | 
			
		||||
Kill_Nick( CHAR *Nick, CHAR *Reason )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	REQUEST r;
 | 
			
		||||
 | 
			
		||||
	assert( Nick != NULL );
 | 
			
		||||
	assert( Reason != NULL );
 | 
			
		||||
 | 
			
		||||
	r.prefix = Client_ThisServer( );
 | 
			
		||||
	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 );
 | 
			
		||||
 | 
			
		||||
	/* andere Server benachrichtigen */
 | 
			
		||||
	IRC_WriteStrServers( NULL, "KILL %s :%s", Nick, Reason );
 | 
			
		||||
 | 
			
		||||
	/* Ggf. einen eigenen Client toeten */
 | 
			
		||||
	c = Client_Search( Nick );
 | 
			
		||||
	if( c && ( Client_Conn( c ) != NONE )) Conn_Close( Client_Conn( c ), NULL, Reason, TRUE );
 | 
			
		||||
	IRC_KILL( Client_ThisServer( ), &r );
 | 
			
		||||
} /* Kill_Nick */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,32 +2,28 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-login.h,v 1.3 2002/03/12 14:37:52 alex Exp $
 | 
			
		||||
 * $Id: irc-login.h,v 1.5 2002/12/12 12:23:43 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * irc-login.h: Anmeldung und Abmeldung im IRC (Header)
 | 
			
		||||
 * Login and logout (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __irc_login_h__
 | 
			
		||||
#define __irc_login_h__
 | 
			
		||||
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_PASS( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_NICK( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_USER( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_PING( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_PONG( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_QUIT( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_PASS PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_NICK PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_USER PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_PING PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_PONG PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_QUIT PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -2,31 +2,27 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-mode.h,v 1.2 2002/03/12 14:37:52 alex Exp $
 | 
			
		||||
 * $Id: irc-mode.h,v 1.5 2002/12/12 12:23:43 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * irc-mode.h: IRC-Befehle zur Mode-Aenderung (MODE, AWAY, ...) (Header)
 | 
			
		||||
 * IRC commands for mode changes (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __irc_mode_h__
 | 
			
		||||
#define __irc_mode_h__
 | 
			
		||||
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_MODE( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_AWAY( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_MODE PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_AWAY PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										124
									
								
								src/ngircd/irc-op.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								src/ngircd/irc-op.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,124 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * Channel operator commands
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-op.c,v 1.11 2002/12/12 12:24:18 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "lists.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "irc-op.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_KICK( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *target, *from;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc < 2) || ( Req->argc > 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
	
 | 
			
		||||
	/* Ziel-User suchen */
 | 
			
		||||
	target = Client_Search( Req->argv[1] );
 | 
			
		||||
	if( ! target ) return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( from ), Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
	Channel_Kick( target, from, Req->argv[0], Req->argc == 3 ? Req->argv[2] : Client_ID( from ));
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_KICK */	
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_INVITE( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	CLIENT *target, *from;
 | 
			
		||||
	BOOLEAN remember = FALSE;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
	
 | 
			
		||||
	/* User suchen */
 | 
			
		||||
	target = Client_Search( Req->argv[0] );
 | 
			
		||||
	if(( ! target ) || ( Client_Type( target ) != CLIENT_USER )) return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
	chan = Channel_Search( Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
	if( chan )
 | 
			
		||||
	{
 | 
			
		||||
		/* Der Channel existiert bereits; ist der User Mitglied? */
 | 
			
		||||
		if( ! Channel_IsMemberOf( chan, from )) return IRC_WriteStrClient( from, ERR_NOTONCHANNEL_MSG, Client_ID( Client ), Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
		/* Ist der Channel "invite-only"? */
 | 
			
		||||
		if( strchr( Channel_Modes( chan ), 'i' ))
 | 
			
		||||
		{
 | 
			
		||||
			/* Ja. Der User muss Channel-Operator sein! */
 | 
			
		||||
			if( ! strchr( Channel_UserModes( chan, from ), 'o' )) return IRC_WriteStrClient( from, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( from ), Channel_Name( chan ));
 | 
			
		||||
			remember = TRUE;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Ist der Ziel-User bereits Mitglied? */
 | 
			
		||||
		if( Channel_IsMemberOf( chan, target )) return IRC_WriteStrClient( from, ERR_USERONCHANNEL_MSG, Client_ID( from ), Req->argv[0], Req->argv[1] );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Wenn der User gebanned ist, so muss das Invite auch gespeichert werden */
 | 
			
		||||
	if( Lists_CheckBanned( target, chan )) remember = TRUE;
 | 
			
		||||
 | 
			
		||||
	Log( LOG_DEBUG, "User \"%s\" invites \"%s\" to \"%s\" ...", Client_Mask( from ), Req->argv[0], Req->argv[1] );
 | 
			
		||||
	if( remember )
 | 
			
		||||
	{
 | 
			
		||||
		if( ! Lists_AddInvited( from, Client_Mask( target ), chan, TRUE )) return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* an Ziel-Client forwarden ... */
 | 
			
		||||
	IRC_WriteStrClientPrefix( target, from, "INVITE %s %s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
	if( Client_Conn( target ) > NONE )
 | 
			
		||||
	{
 | 
			
		||||
		/* lokaler Ziel-Client, Status-Code melden */
 | 
			
		||||
		if( ! IRC_WriteStrClientPrefix( from, target, RPL_INVITING_MSG, Client_ID( from ), Req->argv[0], Req->argv[1] )) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_INVITE */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										28
									
								
								src/ngircd/irc-op.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/ngircd/irc-op.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-op.h,v 1.3 2002/12/12 12:23:43 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Channel operator commands (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __irc_op_h__
 | 
			
		||||
#define __irc_op_h__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_KICK PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_INVITE PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
@@ -2,43 +2,48 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-oper.c,v 1.3 2002/03/27 20:52:58 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * irc-oper.c: IRC-Operator-Befehle
 | 
			
		||||
 * IRC operator commands
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-oper.c,v 1.17 2002/12/31 16:10:55 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
 | 
			
		||||
#include <exp.h>
 | 
			
		||||
#include "irc-oper.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_OPER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_OPER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	INT i;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
@@ -75,40 +80,128 @@ GLOBAL BOOLEAN IRC_OPER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
} /* IRC_OPER */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_DIE( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_DIE( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	/* Shut down server */
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	/* Not a local IRC operator? */
 | 
			
		||||
	if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
 | 
			
		||||
	
 | 
			
		||||
	/* Bad number of parameters? */
 | 
			
		||||
	if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	Log( LOG_NOTICE|LOG_snotice, "Got DIE command from \"%s\", going down!", Client_Mask( Client ));
 | 
			
		||||
	NGIRCd_Quit = TRUE;
 | 
			
		||||
	Log( LOG_NOTICE|LOG_snotice, "Got DIE command from \"%s\" ...", Client_Mask( Client ));
 | 
			
		||||
	NGIRCd_SignalQuit = TRUE;
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_DIE */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_RESTART( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_REHASH( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	/* Reload configuration file */
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Not a local IRC operator? */
 | 
			
		||||
	if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	Log( LOG_NOTICE|LOG_snotice, "Got RESTART command from \"%s\", going down!", Client_Mask( Client ));
 | 
			
		||||
	NGIRCd_Restart = TRUE;
 | 
			
		||||
	/* Bad number of parameters? */
 | 
			
		||||
	if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	Log( LOG_NOTICE|LOG_snotice, "Got REHASH command from \"%s\" ...", Client_Mask( Client ));
 | 
			
		||||
	NGIRCd_SignalRehash = TRUE;
 | 
			
		||||
	
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_REHASH */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_RESTART( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	/* Restart IRC server (fork a new process) */
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Not a local IRC operator? */
 | 
			
		||||
	if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Bad number of parameters? */
 | 
			
		||||
	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 ));
 | 
			
		||||
	NGIRCd_SignalRestart = TRUE;
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_RESTART */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_CONNECT(CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	/* Connect configured or new server */
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Not a local IRC operator? */
 | 
			
		||||
	if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Bad number of parameters? */
 | 
			
		||||
	if(( Req->argc != 2 ) && ( Req->argc != 5 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Invalid port number? */
 | 
			
		||||
	if( atoi( Req->argv[1] ) < 1 )  return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	Log( LOG_NOTICE|LOG_snotice, "Got CONNECT command from \"%s\" for \"%s\".", Client_Mask( Client ), Req->argv[0]);
 | 
			
		||||
 | 
			
		||||
	if( Req->argc == 2 )
 | 
			
		||||
	{
 | 
			
		||||
		/* Connect configured server */
 | 
			
		||||
		if( ! Conf_EnableServer( Req->argv[0], atoi( Req->argv[1] ))) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] );
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* Add server */
 | 
			
		||||
		if( ! Conf_AddServer( Req->argv[0], atoi( Req->argv[1] ), Req->argv[2], Req->argv[3], Req->argv[4] )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] );
 | 
			
		||||
	}
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_CONNECT */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_DISCONNECT(CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	/* Disconnect and disable configured server */
 | 
			
		||||
 | 
			
		||||
	CONN_ID my_conn;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Not a local IRC operator? */
 | 
			
		||||
	if(( ! Client_HasMode( Client, 'o' )) || ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Bad number of parameters? */
 | 
			
		||||
	if( Req->argc != 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	Log( LOG_NOTICE|LOG_snotice, "Got DISCONNECT command from \"%s\" for0 \"%s\".", Client_Mask( Client ), Req->argv[0]);
 | 
			
		||||
 | 
			
		||||
	/* Save ID of this connection */
 | 
			
		||||
	my_conn = Client_Conn( Client );
 | 
			
		||||
 | 
			
		||||
	/* Connect configured server */
 | 
			
		||||
	if( ! Conf_DisableServer( Req->argv[0] )) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
	/* Are we still connected or were we killed, too? */
 | 
			
		||||
	if( Client_GetFromConn( my_conn )) return CONNECTED;
 | 
			
		||||
	else return DISCONNECTED;
 | 
			
		||||
} /* IRC_CONNECT */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -2,29 +2,28 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-oper.h,v 1.2 2002/03/12 14:37:52 alex Exp $
 | 
			
		||||
 * $Id: irc-oper.h,v 1.10 2002/12/31 16:11:06 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * irc-oper.h: IRC-Operator-Befehle (Header)
 | 
			
		||||
 * IRC operator commands (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __irc_oper_h__
 | 
			
		||||
#define __irc_oper_h__
 | 
			
		||||
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_OPER( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_DIE( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_RESTART( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_OPER PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_DIE PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_REHASH PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_RESTART PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_CONNECT PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_DISCONNECT PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -2,44 +2,52 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-server.c,v 1.8 2002/03/27 20:52:58 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * irc-server.c: IRC-Befehle fuer Server-Links
 | 
			
		||||
 * IRC commands for server links
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-server.c,v 1.32.2.1 2003/07/09 18:53:08 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "conn-zip.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "irc-server.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CHAR str[LINE_LEN], *ptr;
 | 
			
		||||
	CHAR str[LINE_LEN], *ptr, *modes, *topic;
 | 
			
		||||
	CLIENT *from, *c, *cl;
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	INT max_hops, i;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	BOOLEAN ok;
 | 
			
		||||
	CONN_ID con;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
@@ -56,18 +64,18 @@ GLOBAL BOOLEAN IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		if(( Req->argc != 2 ) && ( Req->argc != 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
		/* Ist dieser Server bei uns konfiguriert? */
 | 
			
		||||
		for( i = 0; i < Conf_Server_Count; i++ ) if( strcasecmp( Req->argv[0], Conf_Server[i].name ) == 0 ) break;
 | 
			
		||||
		if( i >= Conf_Server_Count )
 | 
			
		||||
		for( i = 0; i < MAX_SERVERS; i++ ) if( strcasecmp( Req->argv[0], Conf_Server[i].name ) == 0 ) break;
 | 
			
		||||
		if( i >= MAX_SERVERS )
 | 
			
		||||
		{
 | 
			
		||||
			/* Server ist nicht konfiguriert! */
 | 
			
		||||
			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 ) != 0 )
 | 
			
		||||
		if( strcmp( Client_Password( Client ), Conf_Server[i].pwd_in ) != 0 )
 | 
			
		||||
		{
 | 
			
		||||
			/* Falsches Passwort */
 | 
			
		||||
			Log( LOG_ERR, "Connection %d: Bad password for server \"%s\"!", Client_Conn( Client ), Req->argv[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;
 | 
			
		||||
		}
 | 
			
		||||
@@ -79,27 +87,48 @@ GLOBAL BOOLEAN IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		Client_SetID( Client, Req->argv[0] );
 | 
			
		||||
		Client_SetHops( Client, 1 );
 | 
			
		||||
		Client_SetInfo( Client, Req->argv[Req->argc - 1] );
 | 
			
		||||
		
 | 
			
		||||
		/* Meldet sich der Server bei uns an? */
 | 
			
		||||
		if( Req->argc == 2 )
 | 
			
		||||
 | 
			
		||||
		/* Meldet sich der Server bei uns an (d.h., bauen nicht wir
 | 
			
		||||
		 * selber die Verbindung zu einem anderen Server auf)? */
 | 
			
		||||
		con = Client_Conn( Client );
 | 
			
		||||
		if( Client_Token( Client ) != TOKEN_OUTBOUND )
 | 
			
		||||
		{
 | 
			
		||||
			/* Unseren SERVER- und PASS-Befehl senden */
 | 
			
		||||
			/* Eingehende Verbindung: Unseren SERVER- und PASS-Befehl senden */
 | 
			
		||||
			ok = TRUE;
 | 
			
		||||
			if( ! IRC_WriteStrClient( Client, "PASS %s "PASSSERVERADD, Conf_Server[i].pwd )) ok = FALSE;
 | 
			
		||||
			if( ! IRC_WriteStrClient( Client, "PASS %s %s", Conf_Server[i].pwd_out, NGIRCd_ProtoID )) ok = FALSE;
 | 
			
		||||
			else ok = IRC_WriteStrClient( Client, "SERVER %s 1 :%s", Conf_ServerName, Conf_ServerInfo );
 | 
			
		||||
			if( ! ok )
 | 
			
		||||
			{
 | 
			
		||||
				Conn_Close( Client_Conn( Client ), "Unexpected server behavior!", NULL, FALSE );
 | 
			
		||||
				Conn_Close( con, "Unexpected server behavior!", NULL, FALSE );
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
			Client_SetIntroducer( Client, Client );
 | 
			
		||||
			Client_SetToken( Client, 1 );
 | 
			
		||||
		}
 | 
			
		||||
		else  Client_SetToken( Client, atoi( Req->argv[1] ));
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* Ausgehende verbindung, SERVER und PASS wurden von uns bereits
 | 
			
		||||
			 * an die Gegenseite uerbermittelt */
 | 
			
		||||
			Client_SetToken( Client, atoi( Req->argv[1] ));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" registered (connection %d, 1 hop - direct link).", Client_ID( Client ), Client_Conn( Client ));
 | 
			
		||||
		Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" registered (connection %d, 1 hop - direct link).", Client_ID( Client ), con );
 | 
			
		||||
 | 
			
		||||
		Client_SetType( Client, CLIENT_SERVER );
 | 
			
		||||
		Conf_SetServer( i, con );
 | 
			
		||||
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
		/* Kompression initialisieren, wenn erforderlich */
 | 
			
		||||
		if( strchr( Client_Flags( Client ), 'Z' ))
 | 
			
		||||
		{
 | 
			
		||||
			if( ! Zip_InitConn( con ))
 | 
			
		||||
			{
 | 
			
		||||
				/* Fehler! */
 | 
			
		||||
				Conn_Close( con, "Can't inizialize compression (zlib)!", NULL, FALSE );
 | 
			
		||||
				return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		/* maximalen Hop Count ermitteln */
 | 
			
		||||
		max_hops = 0;
 | 
			
		||||
@@ -149,25 +178,54 @@ GLOBAL BOOLEAN IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		chan = Channel_First( );
 | 
			
		||||
		while( chan )
 | 
			
		||||
		{
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
			/* Send CHANINFO if the peer supports it */
 | 
			
		||||
			if( strchr( Client_Flags( Client ), 'C' ))
 | 
			
		||||
			{
 | 
			
		||||
				modes = Channel_Modes( chan );
 | 
			
		||||
				topic = Channel_Topic( chan );
 | 
			
		||||
 | 
			
		||||
				if( *modes || *topic )
 | 
			
		||||
				{
 | 
			
		||||
					/* send CHANINFO */
 | 
			
		||||
					if(( ! strchr( Channel_Modes( chan ), 'k' )) && ( ! strchr( Channel_Modes( chan ), 'l' )) && ( ! *topic ))
 | 
			
		||||
					{
 | 
			
		||||
						/* "CHANINFO <chan> +<modes>" */
 | 
			
		||||
						if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s", Channel_Name( chan ), modes )) return DISCONNECTED;
 | 
			
		||||
					}
 | 
			
		||||
					else if(( ! strchr( Channel_Modes( chan ), 'k' )) && ( ! strchr( Channel_Modes( chan ), 'l' )))
 | 
			
		||||
					{
 | 
			
		||||
						/* "CHANINFO <chan> +<modes> :<topic>" */
 | 
			
		||||
						if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s :%s", Channel_Name( chan ), modes, topic )) return DISCONNECTED;
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						/* "CHANINFO <chan> +<modes> <key> <limit> :<topic>" */
 | 
			
		||||
						if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s %s %ld :%s", Channel_Name( chan ), modes, strchr( Channel_Modes( chan ), 'k' ) ? Channel_Key( chan ) : "*", strchr( Channel_Modes( chan ), 'l' ) ? Channel_MaxUsers( chan ) : 0L, topic )) return DISCONNECTED;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
			/* alle Member suchen */
 | 
			
		||||
			cl2chan = Channel_FirstMember( chan );
 | 
			
		||||
			sprintf( str, "NJOIN %s :", Channel_Name( chan ));
 | 
			
		||||
			snprintf( str, sizeof( str ), "NJOIN %s :", Channel_Name( chan ));
 | 
			
		||||
			while( cl2chan )
 | 
			
		||||
			{
 | 
			
		||||
				cl = Channel_GetClient( cl2chan );
 | 
			
		||||
				assert( cl != NULL );
 | 
			
		||||
 | 
			
		||||
				/* Nick, ggf. mit Modes, anhaengen */
 | 
			
		||||
				if( str[strlen( str ) - 1] != ':' ) strcat( str, "," );
 | 
			
		||||
				if( strchr( Channel_UserModes( chan, cl ), 'v' )) strcat( str, "+" );
 | 
			
		||||
				if( strchr( Channel_UserModes( chan, cl ), 'o' )) strcat( str, "@" );
 | 
			
		||||
				strcat( str, Client_ID( cl ));
 | 
			
		||||
				if( str[strlen( str ) - 1] != ':' ) strlcat( str, ",", sizeof( str ));
 | 
			
		||||
				if( strchr( Channel_UserModes( chan, cl ), 'v' )) strlcat( str, "+", sizeof( str ));
 | 
			
		||||
				if( strchr( Channel_UserModes( chan, cl ), 'o' )) strlcat( str, "@", sizeof( str ));
 | 
			
		||||
				strlcat( str, Client_ID( cl ), sizeof( str ));
 | 
			
		||||
 | 
			
		||||
				if( strlen( str ) > ( LINE_LEN - CLIENT_NICK_LEN - 8 ))
 | 
			
		||||
				{
 | 
			
		||||
					/* Zeile senden */
 | 
			
		||||
					if( ! IRC_WriteStrClient( Client, str )) return DISCONNECTED;
 | 
			
		||||
					sprintf( str, "NJOIN %s :", Channel_Name( chan ));
 | 
			
		||||
					if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
 | 
			
		||||
					snprintf( str, sizeof( str ), "NJOIN %s :", Channel_Name( chan ));
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				cl2chan = Channel_NextMember( chan, cl2chan );
 | 
			
		||||
@@ -177,7 +235,7 @@ GLOBAL BOOLEAN IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
			if( str[strlen( str ) - 1] != ':')
 | 
			
		||||
			{
 | 
			
		||||
				/* Ja; Also senden ... */
 | 
			
		||||
				if( ! IRC_WriteStrClient( Client, str )) return DISCONNECTED;
 | 
			
		||||
				if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* naechsten Channel suchen */
 | 
			
		||||
@@ -220,7 +278,7 @@ GLOBAL BOOLEAN IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Log-Meldung zusammenbauen und ausgeben */
 | 
			
		||||
		if(( Client_Hops( c ) > 1 ) && ( Req->prefix[0] )) sprintf( str, "connected to %s, ", Client_ID( from ));
 | 
			
		||||
		if(( Client_Hops( c ) > 1 ) && ( Req->prefix[0] )) snprintf( str, sizeof( str ), "connected to %s, ", Client_ID( from ));
 | 
			
		||||
		else strcpy( str, "" );
 | 
			
		||||
		Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" registered (via %s, %s%d hop%s).", Client_ID( c ), Client_ID( Client ), str, Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
 | 
			
		||||
 | 
			
		||||
@@ -233,9 +291,10 @@ GLOBAL BOOLEAN IRC_SERVER( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
} /* IRC_SERVER */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_NJOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_NJOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CHAR *channame, *ptr, modes[8];
 | 
			
		||||
	CHAR nick_in[COMMAND_LEN], nick_out[COMMAND_LEN], *channame, *ptr, modes[8];
 | 
			
		||||
	BOOLEAN is_op, is_voiced;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
@@ -243,13 +302,14 @@ GLOBAL BOOLEAN IRC_NJOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Client_Type( Client ) != CLIENT_SERVER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTEREDSERVER_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	strlcpy( nick_in, Req->argv[1], sizeof( nick_in ));
 | 
			
		||||
	strcpy( nick_out, "" );
 | 
			
		||||
 | 
			
		||||
	channame = Req->argv[0];
 | 
			
		||||
	ptr = strtok( Req->argv[1], "," );
 | 
			
		||||
	ptr = strtok( nick_in, "," );
 | 
			
		||||
	while( ptr )
 | 
			
		||||
	{
 | 
			
		||||
		is_op = is_voiced = FALSE;
 | 
			
		||||
@@ -276,12 +336,17 @@ GLOBAL BOOLEAN IRC_NJOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
			IRC_WriteStrChannelPrefix( Client, chan, c, FALSE, "JOIN :%s", channame );
 | 
			
		||||
 | 
			
		||||
			/* Channel-User-Modes setzen */
 | 
			
		||||
			strcpy( modes, Channel_UserModes( chan, c ));
 | 
			
		||||
			strlcpy( modes, Channel_UserModes( chan, c ), sizeof( modes ));
 | 
			
		||||
			if( modes[0] )
 | 
			
		||||
			{
 | 
			
		||||
				/* Modes im Channel bekannt machen */
 | 
			
		||||
				IRC_WriteStrChannelPrefix( Client, chan, Client, FALSE, "MODE %s +%s %s", channame, modes, Client_ID( c ));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if( nick_out[0] != '\0' ) strlcat( nick_out, ",", sizeof( nick_out ));
 | 
			
		||||
			if( is_op ) 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 );
 | 
			
		||||
		
 | 
			
		||||
@@ -290,13 +355,14 @@ GLOBAL BOOLEAN IRC_NJOIN( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* an andere Server weiterleiten */
 | 
			
		||||
	IRC_WriteStrServersPrefix( Client, Client_ThisServer( ), "NJOIN %s :%s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
	if( nick_out[0] != '\0' ) IRC_WriteStrServersPrefix( Client, Client_ThisServer( ), "NJOIN %s :%s", Req->argv[0], nick_out );
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_NJOIN */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_SQUIT( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_SQUIT( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *target;
 | 
			
		||||
	CHAR msg[LINE_LEN + 64];
 | 
			
		||||
@@ -304,17 +370,11 @@ GLOBAL BOOLEAN IRC_SQUIT( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* SQUIT ist nur fuer Server erlaubt */
 | 
			
		||||
	if( Client_Type( Client ) != CLIENT_SERVER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	Log( LOG_DEBUG, "Got SQUIT from %s for \"%s\": \"%s\" ...", Client_ID( Client ), Req->argv[0], Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
	/* SQUIT an alle Server weiterleiten */
 | 
			
		||||
	IRC_WriteStrServers( Client, "SQUIT %s :%s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
	target = Client_Search( Req->argv[0] );
 | 
			
		||||
	if( ! target )
 | 
			
		||||
	{
 | 
			
		||||
@@ -326,9 +386,9 @@ GLOBAL BOOLEAN IRC_SQUIT( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	if( Req->argv[1][0] )
 | 
			
		||||
	{
 | 
			
		||||
		if( strlen( Req->argv[1] ) > LINE_LEN ) Req->argv[1][LINE_LEN] = '\0';
 | 
			
		||||
		sprintf( msg, "%s (SQUIT from %s).", Req->argv[1], Client_ID( Client ));
 | 
			
		||||
		snprintf( msg, sizeof( msg ), "%s (SQUIT from %s).", Req->argv[1], Client_ID( Client ));
 | 
			
		||||
	}
 | 
			
		||||
	else sprintf( msg, "Got SQUIT from %s.", Client_ID( Client ));
 | 
			
		||||
	else snprintf( msg, sizeof( msg ), "Got SQUIT from %s.", Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	if( Client_Conn( target ) > NONE )
 | 
			
		||||
	{
 | 
			
		||||
 
 | 
			
		||||
@@ -2,29 +2,25 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-server.h,v 1.2 2002/03/12 14:37:52 alex Exp $
 | 
			
		||||
 * $Id: irc-server.h,v 1.4 2002/12/12 12:23:43 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * irc-server.h: IRC-Befehle fuer Server-Links (Header)
 | 
			
		||||
 * IRC commands for server links (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __irc_server_h__
 | 
			
		||||
#define __irc_server_h__
 | 
			
		||||
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_SERVER( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_NJOIN( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_SQUIT( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_SERVER PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_NJOIN PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_SQUIT PARAMS((CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -2,36 +2,52 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-write.c,v 1.3 2002/03/25 17:13:07 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * irc-write.c: IRC-Texte und Befehle ueber Netzwerk versenden
 | 
			
		||||
 * Sending IRC commands over the network
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc-write.c,v 1.14.2.1 2003/11/07 20:51:11 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL CHAR *Get_Prefix( CLIENT *Target, CLIENT *Client );
 | 
			
		||||
#define SEND_TO_USER 1
 | 
			
		||||
#define SEND_TO_SERVER 2
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrClient( CLIENT *Client, CHAR *Format, ... )
 | 
			
		||||
LOCAL CHAR *Get_Prefix PARAMS(( CLIENT *Target, CLIENT *Client ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_WriteStrClient( CLIENT *Client, CHAR *Format, ... )
 | 
			
		||||
#else
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_WriteStrClient( Client, Format, va_alist )
 | 
			
		||||
CLIENT *Client;
 | 
			
		||||
CHAR *Format;
 | 
			
		||||
va_dcl
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	CHAR buffer[1000];
 | 
			
		||||
	BOOLEAN ok = CONNECTED;
 | 
			
		||||
@@ -40,18 +56,32 @@ GLOBAL BOOLEAN IRC_WriteStrClient( CLIENT *Client, CHAR *Format, ... )
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Format != NULL );
 | 
			
		||||
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
	va_start( ap, Format );
 | 
			
		||||
#else
 | 
			
		||||
	va_start( ap );
 | 
			
		||||
#endif
 | 
			
		||||
	vsnprintf( buffer, 1000, Format, ap );
 | 
			
		||||
	va_end( ap );
 | 
			
		||||
 | 
			
		||||
	/* an den Client selber */
 | 
			
		||||
	ok = IRC_WriteStrClientPrefix( Client, Client_ThisServer( ), buffer );
 | 
			
		||||
	ok = IRC_WriteStrClientPrefix( Client, Client_ThisServer( ), "%s", buffer );
 | 
			
		||||
 | 
			
		||||
	return ok;
 | 
			
		||||
} /* IRC_WriteStrClient */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, CHAR *Format, ... )
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, CHAR *Format, ... )
 | 
			
		||||
#else
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_WriteStrClientPrefix( Client, Prefix, Format, va_alist )
 | 
			
		||||
CLIENT *Client;
 | 
			
		||||
CLIENT *Prefix;
 | 
			
		||||
CHAR *Format;
 | 
			
		||||
va_dcl
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	/* Text an Clients, lokal bzw. remote, senden. */
 | 
			
		||||
 | 
			
		||||
@@ -62,7 +92,11 @@ GLOBAL BOOLEAN IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, CHAR *F
 | 
			
		||||
	assert( Format != NULL );
 | 
			
		||||
	assert( Prefix != NULL );
 | 
			
		||||
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
	va_start( ap, Format );
 | 
			
		||||
#else
 | 
			
		||||
	va_start( ap );
 | 
			
		||||
#endif
 | 
			
		||||
	vsnprintf( buffer, 1000, Format, ap );
 | 
			
		||||
	va_end( ap );
 | 
			
		||||
 | 
			
		||||
@@ -70,7 +104,18 @@ GLOBAL BOOLEAN IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, CHAR *F
 | 
			
		||||
} /* IRC_WriteStrClientPrefix */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrChannel( CLIENT *Client, CHANNEL *Chan, BOOLEAN Remote, CHAR *Format, ... )
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_WriteStrChannel( CLIENT *Client, CHANNEL *Chan, BOOLEAN Remote, CHAR *Format, ... )
 | 
			
		||||
#else
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_WriteStrChannel( Client, Chan, Remote, Format, va_alist )
 | 
			
		||||
CLIENT *Client;
 | 
			
		||||
CHANNEL *Chan;
 | 
			
		||||
BOOLEAN Remote;
 | 
			
		||||
CHAR *Format;
 | 
			
		||||
va_dcl
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	CHAR buffer[1000];
 | 
			
		||||
	va_list ap;
 | 
			
		||||
@@ -78,21 +123,37 @@ GLOBAL BOOLEAN IRC_WriteStrChannel( CLIENT *Client, CHANNEL *Chan, BOOLEAN Remot
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Format != NULL );
 | 
			
		||||
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
	va_start( ap, Format );
 | 
			
		||||
#else
 | 
			
		||||
	va_start( ap );
 | 
			
		||||
#endif
 | 
			
		||||
	vsnprintf( buffer, 1000, Format, ap );
 | 
			
		||||
	va_end( ap );
 | 
			
		||||
 | 
			
		||||
	return IRC_WriteStrChannelPrefix( Client, Chan, Client_ThisServer( ), Remote, buffer );
 | 
			
		||||
	return IRC_WriteStrChannelPrefix( Client, Chan, Client_ThisServer( ), Remote, "%s", buffer );
 | 
			
		||||
} /* IRC_WriteStrChannel */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrChannelPrefix( CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... )
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_WriteStrChannelPrefix( CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... )
 | 
			
		||||
#else
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_WriteStrChannelPrefix( Client, Chan, Prefix, Remote, Format, va_alist )
 | 
			
		||||
CLIENT *Client;
 | 
			
		||||
CHANNEL *Chan;
 | 
			
		||||
CLIENT *Prefix;
 | 
			
		||||
BOOLEAN Remote;
 | 
			
		||||
CHAR *Format;
 | 
			
		||||
va_dcl
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	BOOLEAN sock[MAX_CONNECTIONS], is_server[MAX_CONNECTIONS], ok = CONNECTED;
 | 
			
		||||
	BOOLEAN ok = CONNECTED;
 | 
			
		||||
	CHAR buffer[1000];
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	CONN_ID conn;
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	INT s, i;
 | 
			
		||||
	va_list ap;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
@@ -100,11 +161,15 @@ GLOBAL BOOLEAN IRC_WriteStrChannelPrefix( CLIENT *Client, CHANNEL *Chan, CLIENT
 | 
			
		||||
	assert( Prefix != NULL );
 | 
			
		||||
	assert( Format != NULL );
 | 
			
		||||
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
	va_start( ap, Format );
 | 
			
		||||
#else
 | 
			
		||||
	va_start( ap  );
 | 
			
		||||
#endif
 | 
			
		||||
	vsnprintf( buffer, 1000, Format, ap );
 | 
			
		||||
	va_end( ap );
 | 
			
		||||
 | 
			
		||||
	for( i = 0; i < MAX_CONNECTIONS; i++ ) sock[i] = FALSE;
 | 
			
		||||
	Conn_ClearFlags( );
 | 
			
		||||
 | 
			
		||||
	/* An alle Clients, die in den selben Channels sind.
 | 
			
		||||
	 * Dabei aber nur einmal je Remote-Server */
 | 
			
		||||
@@ -122,47 +187,101 @@ GLOBAL BOOLEAN IRC_WriteStrChannelPrefix( CLIENT *Client, CHANNEL *Chan, CLIENT
 | 
			
		||||
		if( c && ( c != Client ))
 | 
			
		||||
		{
 | 
			
		||||
			/* Ok, anderer Client */
 | 
			
		||||
			s = Client_Conn( c );
 | 
			
		||||
			assert( s >= 0 );
 | 
			
		||||
			assert( s < MAX_CONNECTIONS );
 | 
			
		||||
			sock[s] = TRUE;
 | 
			
		||||
			if( Client_Type( c ) == CLIENT_SERVER ) is_server[s] = TRUE;
 | 
			
		||||
			else is_server[s] = FALSE;
 | 
			
		||||
			conn = Client_Conn( c );
 | 
			
		||||
			if( Client_Type( c ) == CLIENT_SERVER )	Conn_SetFlag( conn, SEND_TO_SERVER );
 | 
			
		||||
			else Conn_SetFlag( conn, SEND_TO_USER );
 | 
			
		||||
		}
 | 
			
		||||
		cl2chan = Channel_NextMember( Chan, cl2chan );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Senden ... */
 | 
			
		||||
	for( i = 0; i < MAX_CONNECTIONS; i++ )
 | 
			
		||||
	/* Senden: alle Verbindungen durchgehen ... */
 | 
			
		||||
	conn = Conn_First( );
 | 
			
		||||
	while( conn != NONE )
 | 
			
		||||
	{
 | 
			
		||||
		if( sock[i] )
 | 
			
		||||
		{
 | 
			
		||||
			if( is_server[i] ) ok = Conn_WriteStr( i, ":%s %s", Client_ID( Prefix ), buffer );
 | 
			
		||||
			else ok = Conn_WriteStr( i, ":%s %s", Client_Mask( Prefix ), buffer );
 | 
			
		||||
			if( ! ok ) break;
 | 
			
		||||
		}
 | 
			
		||||
		/* muessen Daten ueber diese Verbindung verschickt werden? */
 | 
			
		||||
		if( Conn_Flag( conn ) == SEND_TO_SERVER) ok = Conn_WriteStr( conn, ":%s %s", Client_ID( Prefix ), buffer );
 | 
			
		||||
		else if( Conn_Flag( conn ) == SEND_TO_USER ) ok = Conn_WriteStr( conn, ":%s %s", Client_Mask( Prefix ), buffer );
 | 
			
		||||
		if( ! ok ) break;
 | 
			
		||||
 | 
			
		||||
		/* naechste Verbindung testen */
 | 
			
		||||
		conn = Conn_Next( conn );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ok;
 | 
			
		||||
} /* IRC_WriteStrChannelPrefix */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID IRC_WriteStrServers( CLIENT *ExceptOf, CHAR *Format, ... )
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
IRC_WriteStrServers( CLIENT *ExceptOf, CHAR *Format, ... )
 | 
			
		||||
#else
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
IRC_WriteStrServers( ExceptOf, Format, va_alist )
 | 
			
		||||
CLIENT *ExceptOf;
 | 
			
		||||
CHAR *Format;
 | 
			
		||||
va_dcl
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	CHAR buffer[1000];
 | 
			
		||||
	va_list ap;
 | 
			
		||||
 | 
			
		||||
	assert( Format != NULL );
 | 
			
		||||
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
	va_start( ap, Format );
 | 
			
		||||
#else
 | 
			
		||||
	va_start( ap );
 | 
			
		||||
#endif
 | 
			
		||||
	vsnprintf( buffer, 1000, Format, ap );
 | 
			
		||||
	va_end( ap );
 | 
			
		||||
 | 
			
		||||
	/* an den Client selber */
 | 
			
		||||
	return IRC_WriteStrServersPrefix( ExceptOf, Client_ThisServer( ), buffer );
 | 
			
		||||
	IRC_WriteStrServersPrefix( ExceptOf, Client_ThisServer( ), "%s", buffer );
 | 
			
		||||
} /* IRC_WriteStrServers */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID IRC_WriteStrServersPrefix( CLIENT *ExceptOf, CLIENT *Prefix, CHAR *Format, ... )
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
IRC_WriteStrServersPrefix( CLIENT *ExceptOf, CLIENT *Prefix, CHAR *Format, ... )
 | 
			
		||||
#else
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
IRC_WriteStrServersPrefix( ExceptOf, Prefix, Format, va_alist )
 | 
			
		||||
CLIENT *ExceptOf;
 | 
			
		||||
CLIENT *Prefix;
 | 
			
		||||
CHAR *Format;
 | 
			
		||||
va_dcl
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	CHAR buffer[1000];
 | 
			
		||||
	va_list ap;
 | 
			
		||||
 | 
			
		||||
	assert( Format != NULL );
 | 
			
		||||
	assert( Prefix != NULL );
 | 
			
		||||
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
	va_start( ap, Format );
 | 
			
		||||
#else
 | 
			
		||||
	va_start( ap );
 | 
			
		||||
#endif
 | 
			
		||||
	vsnprintf( buffer, 1000, Format, ap );
 | 
			
		||||
	va_end( ap );
 | 
			
		||||
 | 
			
		||||
	IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, '\0', "%s", buffer );
 | 
			
		||||
} /* IRC_WriteStrServersPrefix */
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
IRC_WriteStrServersPrefixFlag( CLIENT *ExceptOf, CLIENT *Prefix, CHAR Flag, CHAR *Format, ... )
 | 
			
		||||
#else
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
IRC_WriteStrServersPrefixFlag( ExceptOf, Prefix, Flag, Format, va_alist )
 | 
			
		||||
CLIENT *ExceptOf;
 | 
			
		||||
CLIENT *Prefix;
 | 
			
		||||
CHAR Flag;
 | 
			
		||||
CHAR *Format;
 | 
			
		||||
va_dcl
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	CHAR buffer[1000];
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
@@ -171,7 +290,11 @@ GLOBAL VOID IRC_WriteStrServersPrefix( CLIENT *ExceptOf, CLIENT *Prefix, CHAR *F
 | 
			
		||||
	assert( Format != NULL );
 | 
			
		||||
	assert( Prefix != NULL );
 | 
			
		||||
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
	va_start( ap, Format );
 | 
			
		||||
#else
 | 
			
		||||
	va_start( ap );
 | 
			
		||||
#endif
 | 
			
		||||
	vsnprintf( buffer, 1000, Format, ap );
 | 
			
		||||
	va_end( ap );
 | 
			
		||||
	
 | 
			
		||||
@@ -180,34 +303,49 @@ GLOBAL VOID IRC_WriteStrServersPrefix( CLIENT *ExceptOf, CLIENT *Prefix, CHAR *F
 | 
			
		||||
	{
 | 
			
		||||
		if(( Client_Type( c ) == CLIENT_SERVER ) && ( Client_Conn( c ) > NONE ) && ( c != Client_ThisServer( )) && ( c != ExceptOf ))
 | 
			
		||||
		{
 | 
			
		||||
			/* Ziel-Server gefunden */
 | 
			
		||||
			IRC_WriteStrClientPrefix( c, Prefix, buffer );
 | 
			
		||||
			/* Ziel-Server gefunden. Nun noch pruefen, ob Flags stimmen */
 | 
			
		||||
			if(( Flag == '\0' ) || ( strchr( Client_Flags( c ), Flag ) != NULL )) IRC_WriteStrClientPrefix( c, Prefix, "%s", buffer );
 | 
			
		||||
		}
 | 
			
		||||
		c = Client_Next( c );
 | 
			
		||||
	}
 | 
			
		||||
} /* IRC_WriteStrServersPrefix */
 | 
			
		||||
} /* IRC_WriteStrServersPrefixFlag */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrRelatedPrefix( CLIENT *Client, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... )
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_WriteStrRelatedPrefix( CLIENT *Client, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... )
 | 
			
		||||
#else
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_WriteStrRelatedPrefix( Client, Prefix, Remote, Format, va_alist )
 | 
			
		||||
CLIENT *Client;
 | 
			
		||||
CLIENT *Prefix;
 | 
			
		||||
BOOLEAN Remote;
 | 
			
		||||
CHAR *Format;
 | 
			
		||||
va_dcl
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	BOOLEAN sock[MAX_CONNECTIONS], is_server[MAX_CONNECTIONS], ok = CONNECTED;
 | 
			
		||||
	BOOLEAN ok = CONNECTED;
 | 
			
		||||
	CL2CHAN *chan_cl2chan, *cl2chan;
 | 
			
		||||
	CHAR buffer[1000];
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	CONN_ID conn;
 | 
			
		||||
	va_list ap;
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	INT i, s;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Prefix != NULL );
 | 
			
		||||
	assert( Format != NULL );
 | 
			
		||||
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
	va_start( ap, Format );
 | 
			
		||||
#else
 | 
			
		||||
	va_start( ap );
 | 
			
		||||
#endif
 | 
			
		||||
	vsnprintf( buffer, 1000, Format, ap );
 | 
			
		||||
	va_end( ap );
 | 
			
		||||
 | 
			
		||||
	/* initialisieren */
 | 
			
		||||
	for( i = 0; i < MAX_CONNECTIONS; i++ ) sock[i] = FALSE;
 | 
			
		||||
	Conn_ClearFlags( );
 | 
			
		||||
 | 
			
		||||
	/* An alle Clients, die in einem Channel mit dem "Ausloeser" sind,
 | 
			
		||||
	 * den Text schicken. An Remote-Server aber jeweils nur einmal. */
 | 
			
		||||
@@ -230,12 +368,9 @@ GLOBAL BOOLEAN IRC_WriteStrRelatedPrefix( CLIENT *Client, CLIENT *Prefix, BOOLEA
 | 
			
		||||
			if( c && ( c != Client ))
 | 
			
		||||
			{
 | 
			
		||||
				/* Ok, anderer Client */
 | 
			
		||||
				s = Client_Conn( c );
 | 
			
		||||
				assert( s >= 0 );
 | 
			
		||||
				assert( s < MAX_CONNECTIONS );
 | 
			
		||||
				sock[s] = TRUE;
 | 
			
		||||
				if( Client_Type( c ) == CLIENT_SERVER ) is_server[s] = TRUE;
 | 
			
		||||
				else is_server[s] = FALSE;
 | 
			
		||||
				conn = Client_Conn( c );
 | 
			
		||||
				if( Client_Type( c ) == CLIENT_SERVER ) Conn_SetFlag( conn, SEND_TO_SERVER );
 | 
			
		||||
				else Conn_SetFlag( conn, SEND_TO_USER );
 | 
			
		||||
			}
 | 
			
		||||
			cl2chan = Channel_NextMember( chan, cl2chan );
 | 
			
		||||
		}
 | 
			
		||||
@@ -244,21 +379,39 @@ GLOBAL BOOLEAN IRC_WriteStrRelatedPrefix( CLIENT *Client, CLIENT *Prefix, BOOLEA
 | 
			
		||||
		chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Senden ... */
 | 
			
		||||
	for( i = 0; i < MAX_CONNECTIONS; i++ )
 | 
			
		||||
	/* Senden: alle Verbindungen durchgehen ... */
 | 
			
		||||
	conn = Conn_First( );
 | 
			
		||||
	while( conn != NONE )
 | 
			
		||||
	{
 | 
			
		||||
		if( sock[i] )
 | 
			
		||||
		{
 | 
			
		||||
			if( is_server[i] ) ok = Conn_WriteStr( i, ":%s %s", Client_ID( Prefix ), buffer );
 | 
			
		||||
			else ok = Conn_WriteStr( i, ":%s %s", Client_Mask( Prefix ), buffer );
 | 
			
		||||
			if( ! ok ) break;
 | 
			
		||||
		}
 | 
			
		||||
		/* muessen ueber diese Verbindung Daten gesendet werden? */
 | 
			
		||||
		if( Conn_Flag( conn ) == SEND_TO_SERVER ) ok = Conn_WriteStr( conn, ":%s %s", Client_ID( Prefix ), buffer );
 | 
			
		||||
		else if( Conn_Flag( conn ) == SEND_TO_USER ) ok = Conn_WriteStr( conn, ":%s %s", Client_Mask( Prefix ), buffer );
 | 
			
		||||
		if( ! ok ) break;
 | 
			
		||||
 | 
			
		||||
		/* naechste Verbindung testen */
 | 
			
		||||
		conn = Conn_Next( conn );
 | 
			
		||||
	}
 | 
			
		||||
	return ok;
 | 
			
		||||
} /* IRC_WriteStrRelatedPrefix */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL CHAR *Get_Prefix( CLIENT *Target, CLIENT *Client )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
IRC_SetPenalty( CLIENT *Client, INT Seconds )
 | 
			
		||||
{
 | 
			
		||||
	CONN_ID c;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Seconds > 0 );
 | 
			
		||||
	
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) return;
 | 
			
		||||
	
 | 
			
		||||
	c = Client_Conn( Client );
 | 
			
		||||
	if( c > NONE ) Conn_SetPenalty( c, Seconds );		
 | 
			
		||||
} /* IRC_SetPenalty */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL CHAR *
 | 
			
		||||
Get_Prefix( CLIENT *Target, CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	assert( Target != NULL );
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 
 | 
			
		||||
@@ -2,35 +2,35 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc-write.h,v 1.2 2002/03/12 14:37:52 alex Exp $
 | 
			
		||||
 * $Id: irc-write.h,v 1.5.4.1 2003/11/07 20:51:11 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * irc-write.h: IRC-Texte und Befehle ueber Netzwerk versenden (Header)
 | 
			
		||||
 * Sending IRC commands over the network (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __irc_write_h__
 | 
			
		||||
#define __irc_write_h__
 | 
			
		||||
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrClient PARAMS(( CLIENT *Client, CHAR *Format, ... ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrClientPrefix PARAMS(( CLIENT *Client, CLIENT *Prefix, CHAR *Format, ... ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrClient( CLIENT *Client, CHAR *Format, ... );
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, CHAR *Format, ... );
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrChannel PARAMS(( CLIENT *Client, CHANNEL *Chan, BOOLEAN Remote, CHAR *Format, ... ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrChannelPrefix PARAMS(( CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrChannel( CLIENT *Client, CHANNEL *Chan, BOOLEAN Remote, CHAR *Format, ... );
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrChannelPrefix( CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... );
 | 
			
		||||
GLOBAL VOID IRC_WriteStrServers PARAMS(( CLIENT *ExceptOf, CHAR *Format, ... ));
 | 
			
		||||
GLOBAL VOID IRC_WriteStrServersPrefix PARAMS(( CLIENT *ExceptOf, CLIENT *Prefix, CHAR *Format, ... ));
 | 
			
		||||
GLOBAL VOID IRC_WriteStrServersPrefixFlag PARAMS(( CLIENT *ExceptOf, CLIENT *Prefix, CHAR Flag, CHAR *Format, ... ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID IRC_WriteStrServers( CLIENT *ExceptOf, CHAR *Format, ... );
 | 
			
		||||
GLOBAL VOID IRC_WriteStrServersPrefix( CLIENT *ExceptOf, CLIENT *Prefix, CHAR *Format, ... );
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrRelatedPrefix PARAMS(( CLIENT *Client, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_WriteStrRelatedPrefix( CLIENT *Client, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... );
 | 
			
		||||
GLOBAL VOID IRC_SetPenalty PARAMS(( CLIENT *Client, INT Seconds ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										887
									
								
								src/ngircd/irc.c
									
									
									
									
									
								
							
							
						
						
									
										887
									
								
								src/ngircd/irc.c
									
									
									
									
									
								
							@@ -1,58 +1,169 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc.c,v 1.89 2002/03/25 17:04:02 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * irc.c: IRC-Befehle
 | 
			
		||||
 * IRC commands
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: irc.c,v 1.120.2.2 2003/11/07 20:51:11 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "tool.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "irc.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_MOTD( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
LOCAL CHAR *Option_String PARAMS(( CONN_ID Idx ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_ERROR( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
	if( Req->argc < 1 ) Log( LOG_NOTICE, "Got ERROR from \"%s\"!", Client_Mask( Client ));
 | 
			
		||||
	else Log( LOG_NOTICE, "Got ERROR from \"%s\": %s!", Client_Mask( Client ), Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_ERROR */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_KILL( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *prefix, *c;
 | 
			
		||||
	CHAR reason[COMMAND_LEN];
 | 
			
		||||
	CONN_ID my_conn, conn;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Is the user an IRC operator? */
 | 
			
		||||
	if(( Client_Type( Client ) != CLIENT_SERVER ) && ( ! Client_OperByMe( Client ))) return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Bad number of parameters? */
 | 
			
		||||
	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( )) 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 ) 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 );
 | 
			
		||||
 | 
			
		||||
	/* Save ID of this connection */
 | 
			
		||||
	my_conn = Client_Conn( Client );
 | 
			
		||||
	
 | 
			
		||||
	/* Do we host such a client? */
 | 
			
		||||
	c = Client_Search( Req->argv[0] );
 | 
			
		||||
	if( c )
 | 
			
		||||
	{
 | 
			
		||||
		/* Yes, there is such a client -- but is it a valid user? */
 | 
			
		||||
		if( Client_Type( c ) == CLIENT_SERVER )
 | 
			
		||||
		{
 | 
			
		||||
			if( Client != Client_ThisServer( )) IRC_WriteStrClient( Client, ERR_CANTKILLSERVER_MSG, Client_ID( Client ));
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				/* Oops, I should kill another server!? */
 | 
			
		||||
				Log( LOG_ERR, "Can't KILL server \"%s\"!", Req->argv[0] );
 | 
			
		||||
				conn = Client_Conn( Client_NextHop( c ));
 | 
			
		||||
				assert( conn > NONE );
 | 
			
		||||
				Conn_Close( conn, NULL, "Nick collision for server!?", TRUE );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else if( Client_Type( c ) != CLIENT_USER  )
 | 
			
		||||
		{
 | 
			
		||||
			if( Client != Client_ThisServer( )) IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG, Client_ID( Client ));
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				/* Oops, what sould I close?? */
 | 
			
		||||
				Log( LOG_ERR, "Can't KILL \"%s\": invalid client type!", Req->argv[0] );
 | 
			
		||||
				conn = Client_Conn( Client_NextHop( c ));
 | 
			
		||||
				assert( conn > NONE );
 | 
			
		||||
				Conn_Close( conn, NULL, "Collision for invalid client type!?", TRUE );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* Kill user NOW! */
 | 
			
		||||
			conn = Client_Conn( c );
 | 
			
		||||
			Client_Destroy( c, NULL, reason, FALSE );
 | 
			
		||||
			if( conn != NONE ) Conn_Close( conn, NULL, reason, TRUE );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else Log( LOG_NOTICE, "Client with nick \"%s\" is unknown here.", Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
	/* Are we still connected or were we killed, too? */
 | 
			
		||||
	if(( my_conn > NONE ) && ( Client_GetFromConn( my_conn ))) return CONNECTED;
 | 
			
		||||
	else return DISCONNECTED;
 | 
			
		||||
} /* IRC_KILL */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_NOTICE( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *to, *from;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return CONNECTED;
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc != 0 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
	if( Req->argc != 2 ) return CONNECTED;
 | 
			
		||||
 | 
			
		||||
	return IRC_Show_MOTD( Client );
 | 
			
		||||
} /* IRC_MOTD */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	to = Client_Search( Req->argv[0] );
 | 
			
		||||
	if(( to ) && ( Client_Type( to ) == CLIENT_USER ))
 | 
			
		||||
	{
 | 
			
		||||
		/* Okay, Ziel ist ein User */
 | 
			
		||||
		return IRC_WriteStrClientPrefix( to, from, "NOTICE %s :%s", Client_ID( to ), Req->argv[1] );
 | 
			
		||||
	}
 | 
			
		||||
	else return CONNECTED;
 | 
			
		||||
} /* IRC_NOTICE */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_PRIVMSG( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_PRIVMSG( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *cl, *from;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
@@ -60,8 +171,6 @@ GLOBAL BOOLEAN IRC_PRIVMSG( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc == 0 ) return IRC_WriteStrClient( Client, ERR_NORECIPIENT_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
	if( Req->argc == 1 ) return IRC_WriteStrClient( Client, ERR_NOTEXTTOSEND_MSG, Client_ID( Client ));
 | 
			
		||||
@@ -74,6 +183,9 @@ GLOBAL BOOLEAN IRC_PRIVMSG( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
	cl = Client_Search( Req->argv[0] );
 | 
			
		||||
	if( cl )
 | 
			
		||||
	{
 | 
			
		||||
		/* Okay, Ziel ist ein Client. Aber ist es auch ein User? */
 | 
			
		||||
		if( Client_Type( cl ) != CLIENT_USER ) return IRC_WriteStrClient( from, ERR_NOSUCHNICK_MSG, Client_ID( from ), Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
		/* Okay, Ziel ist ein User */
 | 
			
		||||
		if(( Client_Type( Client ) != CLIENT_SERVER ) && ( strchr( Client_Modes( cl ), 'a' )))
 | 
			
		||||
		{
 | 
			
		||||
@@ -93,704 +205,109 @@ GLOBAL BOOLEAN IRC_PRIVMSG( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
} /* IRC_PRIVMSG */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_NOTICE( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *to, *from;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc != 2 ) return CONNECTED;
 | 
			
		||||
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	to = Client_Search( Req->argv[0] );
 | 
			
		||||
	if( to )
 | 
			
		||||
	{
 | 
			
		||||
		/* Okay, Ziel ist ein User */
 | 
			
		||||
		return IRC_WriteStrClientPrefix( to, from, "NOTICE %s :%s", Client_ID( to ), Req->argv[1] );
 | 
			
		||||
	}
 | 
			
		||||
	else return CONNECTED;
 | 
			
		||||
} /* IRC_NOTICE */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_NAMES( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CHAR rpl[COMMAND_LEN], *ptr;
 | 
			
		||||
	CLIENT *target, *from, *c;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* From aus Prefix ermitteln */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
	
 | 
			
		||||
	if( Req->argc == 2 )
 | 
			
		||||
	{
 | 
			
		||||
		/* an anderen Server forwarden */
 | 
			
		||||
		target = Client_Search( Req->argv[1] );
 | 
			
		||||
		if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
		if( target != Client_ThisServer( ))
 | 
			
		||||
		{
 | 
			
		||||
			/* Ok, anderer Server ist das Ziel: forwarden */
 | 
			
		||||
			return IRC_WriteStrClientPrefix( target, from, "NAMES %s :%s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( Req->argc > 0 )
 | 
			
		||||
	{
 | 
			
		||||
		/* bestimmte Channels durchgehen */
 | 
			
		||||
		ptr = strtok( Req->argv[0], "," );
 | 
			
		||||
		while( ptr )
 | 
			
		||||
		{
 | 
			
		||||
			chan = Channel_Search( ptr );
 | 
			
		||||
			if( chan )
 | 
			
		||||
			{
 | 
			
		||||
				/* Namen ausgeben */
 | 
			
		||||
				if( ! IRC_Send_NAMES( from, chan )) return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
			if( ! IRC_WriteStrClient( from, RPL_ENDOFNAMES_MSG, Client_ID( from ), ptr )) return DISCONNECTED;
 | 
			
		||||
			
 | 
			
		||||
			/* naechsten Namen ermitteln */
 | 
			
		||||
			ptr = strtok( NULL, "," );
 | 
			
		||||
		}
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* alle Channels durchgehen */
 | 
			
		||||
	chan = Channel_First( );
 | 
			
		||||
	while( chan )
 | 
			
		||||
	{
 | 
			
		||||
		/* Namen ausgeben */
 | 
			
		||||
		if( ! IRC_Send_NAMES( from, chan )) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
		/* naechster Channel */
 | 
			
		||||
		chan = Channel_Next( chan );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Nun noch alle Clients ausgeben, die in keinem Channel sind */
 | 
			
		||||
	c = Client_First( );
 | 
			
		||||
	sprintf( rpl, RPL_NAMREPLY_MSG, Client_ID( from ), "*", "*" );
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		if(( Client_Type( c ) == CLIENT_USER ) && ( Channel_FirstChannelOf( c ) == NULL ) && ( ! strchr( Client_Modes( c ), 'i' )))
 | 
			
		||||
		{
 | 
			
		||||
			/* Okay, das ist ein User: anhaengen */
 | 
			
		||||
			if( rpl[strlen( rpl ) - 1] != ':' ) strcat( rpl, " " );
 | 
			
		||||
			strcat( rpl, Client_ID( c ));
 | 
			
		||||
 | 
			
		||||
			if( strlen( rpl ) > ( LINE_LEN - CLIENT_NICK_LEN - 4 ))
 | 
			
		||||
			{
 | 
			
		||||
				/* Zeile wird zu lang: senden! */
 | 
			
		||||
				if( ! IRC_WriteStrClient( from, rpl )) return DISCONNECTED;
 | 
			
		||||
				sprintf( rpl, RPL_NAMREPLY_MSG, Client_ID( from ), "*", "*" );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* naechster Client */
 | 
			
		||||
		c = Client_Next( c );
 | 
			
		||||
	}
 | 
			
		||||
	if( rpl[strlen( rpl ) - 1] != ':')
 | 
			
		||||
	{
 | 
			
		||||
		/* es wurden User gefunden */
 | 
			
		||||
		if( ! IRC_WriteStrClient( from, rpl )) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return IRC_WriteStrClient( from, RPL_ENDOFNAMES_MSG, Client_ID( from ), "*" );
 | 
			
		||||
} /* IRC_NAMES */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_ISON( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CHAR rpl[COMMAND_LEN];
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	CHAR *ptr;
 | 
			
		||||
	INT i;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc < 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	strcpy( rpl, RPL_ISON_MSG );
 | 
			
		||||
	for( i = 0; i < Req->argc; i++ )
 | 
			
		||||
	{
 | 
			
		||||
		ptr = strtok( Req->argv[i], " " );
 | 
			
		||||
		while( ptr )
 | 
			
		||||
		{
 | 
			
		||||
			ngt_TrimStr( ptr );
 | 
			
		||||
			c = Client_Search( ptr );
 | 
			
		||||
			if( c && ( Client_Type( c ) == CLIENT_USER ))
 | 
			
		||||
			{
 | 
			
		||||
				/* Dieser Nick ist "online" */
 | 
			
		||||
				strcat( rpl, ptr );
 | 
			
		||||
				strcat( rpl, " " );
 | 
			
		||||
			}
 | 
			
		||||
			ptr = strtok( NULL, " " );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if( rpl[strlen( rpl ) - 1] == ' ' ) rpl[strlen( rpl ) - 1] = '\0';
 | 
			
		||||
 | 
			
		||||
	return IRC_WriteStrClient( Client, rpl, Client_ID( Client ) );
 | 
			
		||||
} /* IRC_ISON */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_WHOIS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_TRACE( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *from, *target, *c;
 | 
			
		||||
	CHAR str[LINE_LEN + 1], *ptr = NULL;
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc < 1 ) || ( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Client suchen */
 | 
			
		||||
	c = Client_Search( Req->argv[Req->argc - 1] );
 | 
			
		||||
	if(( ! c ) || ( Client_Type( c ) != CLIENT_USER )) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[Req->argc - 1] );
 | 
			
		||||
 | 
			
		||||
	/* Empfaenger des WHOIS suchen */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
	
 | 
			
		||||
	/* Forwarden an anderen Server? */
 | 
			
		||||
	if( Req->argc > 1 )
 | 
			
		||||
	{
 | 
			
		||||
		/* angegebenen Ziel-Server suchen */
 | 
			
		||||
		target = Client_Search( Req->argv[1] );
 | 
			
		||||
		if( ! target ) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[1] );
 | 
			
		||||
		ptr = Req->argv[1];
 | 
			
		||||
	}
 | 
			
		||||
	else target = Client_ThisServer( );
 | 
			
		||||
 | 
			
		||||
	assert( target != NULL );
 | 
			
		||||
	
 | 
			
		||||
	if(( Client_NextHop( target ) != Client_ThisServer( )) && ( Client_Type( Client_NextHop( target )) == CLIENT_SERVER )) return IRC_WriteStrClientPrefix( target, from, "WHOIS %s :%s", Req->argv[0], ptr );
 | 
			
		||||
	
 | 
			
		||||
	/* Nick, User und Name */
 | 
			
		||||
	if( ! IRC_WriteStrClient( from, RPL_WHOISUSER_MSG, Client_ID( from ), Client_ID( c ), Client_User( c ), Client_Hostname( c ), Client_Info( c ))) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	/* Server */
 | 
			
		||||
	if( ! IRC_WriteStrClient( from, RPL_WHOISSERVER_MSG, Client_ID( from ), Client_ID( c ), Client_ID( Client_Introducer( c )), Client_Info( Client_Introducer( c )))) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	/* Channels */
 | 
			
		||||
	sprintf( str, RPL_WHOISCHANNELS_MSG, Client_ID( from ), Client_ID( c ));
 | 
			
		||||
	cl2chan = Channel_FirstChannelOf( c );
 | 
			
		||||
	while( cl2chan )
 | 
			
		||||
	{
 | 
			
		||||
		chan = Channel_GetChannel( cl2chan );
 | 
			
		||||
		assert( chan != NULL );
 | 
			
		||||
		
 | 
			
		||||
		/* Channel-Name anhaengen */
 | 
			
		||||
		if( str[strlen( str ) - 1] != ':' ) strcat( str, " " );
 | 
			
		||||
		if( strchr( Channel_UserModes( chan, c ), 'o' )) strcat( str, "@" );
 | 
			
		||||
		else if( strchr( Channel_UserModes( chan, c ), 'v' )) strcat( str, "+" );
 | 
			
		||||
		strcat( str, Channel_Name( chan ));
 | 
			
		||||
 | 
			
		||||
		if( strlen( str ) > ( LINE_LEN - CHANNEL_NAME_LEN - 4 ))
 | 
			
		||||
		{
 | 
			
		||||
			/* Zeile wird zu lang: senden! */
 | 
			
		||||
			if( ! IRC_WriteStrClient( Client, str )) return DISCONNECTED;
 | 
			
		||||
			sprintf( str, RPL_WHOISCHANNELS_MSG, Client_ID( from ), Client_ID( c ));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* naechstes Mitglied suchen */
 | 
			
		||||
		cl2chan = Channel_NextChannelOf( c, cl2chan );
 | 
			
		||||
	}
 | 
			
		||||
	if( str[strlen( str ) - 1] != ':')
 | 
			
		||||
	{
 | 
			
		||||
		/* Es sind noch Daten da, die gesendet werden muessen */
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, str )) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* IRC-Operator? */
 | 
			
		||||
	if( Client_HasMode( c, 'o' ))
 | 
			
		||||
	{
 | 
			
		||||
		if( ! IRC_WriteStrClient( from, RPL_WHOISOPERATOR_MSG, Client_ID( from ), Client_ID( c ))) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Idle (nur lokale Clients) */
 | 
			
		||||
	if( Client_Conn( c ) > NONE )
 | 
			
		||||
	{
 | 
			
		||||
		if( ! IRC_WriteStrClient( from, RPL_WHOISIDLE_MSG, Client_ID( from ), Client_ID( c ), Conn_GetIdle( Client_Conn ( c )))) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Away? */
 | 
			
		||||
	if( Client_HasMode( c, 'a' ))
 | 
			
		||||
	{
 | 
			
		||||
		if( ! IRC_WriteStrClient( from, RPL_AWAY_MSG, Client_ID( from ), Client_ID( c ), Client_Away( c ))) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* End of Whois */
 | 
			
		||||
	return IRC_WriteStrClient( from, RPL_ENDOFWHOIS_MSG, Client_ID( from ), Client_ID( c ));
 | 
			
		||||
} /* IRC_WHOIS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_WHO( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	BOOLEAN ok, only_ops;
 | 
			
		||||
	CHAR flags[8], *ptr;
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	CHANNEL *chan;
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	only_ops = FALSE;
 | 
			
		||||
	chan = NULL;
 | 
			
		||||
 | 
			
		||||
	if( Req->argc == 2 )
 | 
			
		||||
	{
 | 
			
		||||
		/* Nur OPs anzeigen? */
 | 
			
		||||
		if( strcmp( Req->argv[1], "o" ) == 0 ) only_ops = TRUE;
 | 
			
		||||
#ifdef STRICT_RFC
 | 
			
		||||
		else return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if( Req->argc >= 1 )
 | 
			
		||||
	{
 | 
			
		||||
		/* wurde ein Channel oder Nick-Mask angegeben? */
 | 
			
		||||
		chan = Channel_Search( Req->argv[0] );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( chan )
 | 
			
		||||
	{
 | 
			
		||||
		/* User eines Channels ausgeben */
 | 
			
		||||
		if( ! IRC_Send_WHO( Client, chan, only_ops )) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c = Client_First( );
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		if(( Client_Type( c ) == CLIENT_USER ) && ( ! strchr( Client_Modes( c ), 'i' )))
 | 
			
		||||
		{
 | 
			
		||||
			ok = FALSE;
 | 
			
		||||
			if( Req->argc == 0 ) ok = TRUE;
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				if( strcasecmp( Req->argv[0], Client_ID( c )) == 0 ) ok = TRUE;
 | 
			
		||||
				else if( strcmp( Req->argv[0], "0" ) == 0 ) ok = TRUE;
 | 
			
		||||
			}
 | 
			
		||||
				
 | 
			
		||||
			if( ok && (( ! only_ops ) || ( strchr( Client_Modes( c ), 'o' ))))
 | 
			
		||||
			{
 | 
			
		||||
				/* Flags zusammenbasteln */
 | 
			
		||||
				strcpy( flags, "H" );
 | 
			
		||||
				if( strchr( Client_Modes( c ), 'o' )) strcat( flags, "*" );
 | 
			
		||||
 | 
			
		||||
				/* ausgeben */
 | 
			
		||||
				cl2chan = Channel_FirstChannelOf( c );
 | 
			
		||||
				if( cl2chan ) ptr = Channel_Name( Channel_GetChannel( cl2chan ));
 | 
			
		||||
				else ptr = "*";
 | 
			
		||||
				if( ! IRC_WriteStrClient( Client, RPL_WHOREPLY_MSG, Client_ID( Client ), ptr, Client_User( c ), Client_Hostname( c ), Client_ID( Client_Introducer( c )), Client_ID( c ), flags, Client_Hops( c ), Client_Info( c ))) return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* naechster Client */
 | 
			
		||||
		c = Client_Next( c );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( chan ) return IRC_WriteStrClient( Client, RPL_ENDOFWHO_MSG, Client_ID( Client ), Channel_Name( chan ));
 | 
			
		||||
	else if( Req->argc == 0 ) return IRC_WriteStrClient( Client, RPL_ENDOFWHO_MSG, Client_ID( Client ), "*" );
 | 
			
		||||
	else return IRC_WriteStrClient( Client, RPL_ENDOFWHO_MSG, Client_ID( Client ), Req->argv[0] );
 | 
			
		||||
} /* IRC_WHO */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_USERHOST( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CHAR rpl[COMMAND_LEN];
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
	INT max, i;
 | 
			
		||||
	CONN_ID idx, idx2;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
	/* Bad number of arguments? */
 | 
			
		||||
	if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NORECIPIENT_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc < 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	if( Req->argc > 5 ) max = 5;
 | 
			
		||||
	else max = Req->argc;
 | 
			
		||||
	
 | 
			
		||||
	strcpy( rpl, RPL_USERHOST_MSG );
 | 
			
		||||
	for( i = 0; i < max; i++ )
 | 
			
		||||
	{
 | 
			
		||||
		c = Client_Search( Req->argv[i] );
 | 
			
		||||
		if( c && ( Client_Type( c ) == CLIENT_USER ))
 | 
			
		||||
		{
 | 
			
		||||
			/* Dieser Nick ist "online" */
 | 
			
		||||
			strcat( rpl, Client_ID( c ));
 | 
			
		||||
			if( Client_HasMode( c, 'o' )) strcat( rpl, "*" );
 | 
			
		||||
			strcat( rpl, "=" );
 | 
			
		||||
			if( Client_HasMode( c, 'a' )) strcat( rpl, "-" );
 | 
			
		||||
			else strcat( rpl, "+" );
 | 
			
		||||
			strcat( rpl, Client_User( c ));
 | 
			
		||||
			strcat( rpl, "@" );
 | 
			
		||||
			strcat( rpl, Client_Hostname( c ));
 | 
			
		||||
			strcat( rpl, " " );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if( rpl[strlen( rpl ) - 1] == ' ' ) rpl[strlen( rpl ) - 1] = '\0';
 | 
			
		||||
 | 
			
		||||
	return IRC_WriteStrClient( Client, rpl, Client_ID( Client ) );
 | 
			
		||||
} /* IRC_USERHOST */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_ERROR( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Req->argc < 1 ) Log( LOG_NOTICE, "Got ERROR from \"%s\"!", Client_Mask( Client ));
 | 
			
		||||
	else Log( LOG_NOTICE, "Got ERROR from \"%s\": %s!", Client_Mask( Client ), Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_ERROR */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_LUSERS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *target, *from;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Absender ermitteln */
 | 
			
		||||
	/* Search sender */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
 | 
			
		||||
	/* An anderen Server forwarden? */
 | 
			
		||||
	if( Req->argc == 2 )
 | 
			
		||||
	{
 | 
			
		||||
		target = Client_Search( Req->argv[1] );
 | 
			
		||||
		if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[1] );
 | 
			
		||||
		else if( target != Client_ThisServer( )) return IRC_WriteStrClientPrefix( target, from, "LUSERS %s %s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Wer ist der Absender? */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
 | 
			
		||||
	else target = Client;
 | 
			
		||||
	if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
	
 | 
			
		||||
	IRC_Send_LUSERS( target );
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_LUSERS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_LINKS( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *target, *from, *c;
 | 
			
		||||
	CHAR *mask;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Server-Mask ermitteln */
 | 
			
		||||
	if( Req->argc > 0 ) mask = Req->argv[Req->argc - 1];
 | 
			
		||||
	else mask = "*";
 | 
			
		||||
 | 
			
		||||
	/* Absender ermitteln */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_Search( Req->prefix );
 | 
			
		||||
	else from = Client;
 | 
			
		||||
	if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
	
 | 
			
		||||
	/* An anderen Server forwarden? */
 | 
			
		||||
	if( Req->argc == 2 )
 | 
			
		||||
	{
 | 
			
		||||
		target = Client_Search( Req->argv[0] );
 | 
			
		||||
		if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] );
 | 
			
		||||
		else if( target != Client_ThisServer( )) return IRC_WriteStrClientPrefix( target, from, "LINKS %s %s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Wer ist der Absender? */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
 | 
			
		||||
	else target = Client;
 | 
			
		||||
	if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
	
 | 
			
		||||
	c = Client_First( );
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		if( Client_Type( c ) == CLIENT_SERVER )
 | 
			
		||||
		{
 | 
			
		||||
			if( ! IRC_WriteStrClient( target, RPL_LINKS_MSG, Client_ID( target ), Client_ID( c ), Client_ID( Client_TopServer( c ) ? Client_TopServer( c ) : Client_ThisServer( )), Client_Hops( c ), Client_Info( c ))) return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
		c = Client_Next( c );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return IRC_WriteStrClient( target, RPL_ENDOFLINKS_MSG, Client_ID( target ), mask );
 | 
			
		||||
} /* IRC_LINKS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_VERSION( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *target, *prefix;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc > 1 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Ziel suchen */
 | 
			
		||||
	/* Search target */
 | 
			
		||||
	if( Req->argc == 1 ) target = Client_Search( Req->argv[0] );
 | 
			
		||||
	else target = Client_ThisServer( );
 | 
			
		||||
 | 
			
		||||
	/* Prefix ermitteln */
 | 
			
		||||
	if( Client_Type( Client ) == CLIENT_SERVER ) prefix = Client_Search( Req->prefix );
 | 
			
		||||
	else prefix = Client;
 | 
			
		||||
	if( ! prefix ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->prefix );
 | 
			
		||||
	
 | 
			
		||||
	/* An anderen Server weiterleiten? */
 | 
			
		||||
	/* Forward command to other server? */
 | 
			
		||||
	if( target != Client_ThisServer( ))
 | 
			
		||||
	{
 | 
			
		||||
		if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[0] );
 | 
			
		||||
		if(( ! target ) || ( Client_Type( target ) != CLIENT_SERVER )) return IRC_WriteStrClient( from, ERR_NOSUCHSERVER_MSG, Client_ID( from ), Req->argv[0] );
 | 
			
		||||
 | 
			
		||||
		/* forwarden */
 | 
			
		||||
		IRC_WriteStrClientPrefix( target, prefix, "VERSION %s", Req->argv[0] );
 | 
			
		||||
		/* Send RPL_TRACELINK back to initiator */
 | 
			
		||||
		idx = Client_Conn( Client ); assert( idx > NONE );
 | 
			
		||||
		idx2 = Client_Conn( Client_NextHop( target )); assert( idx2 > NONE );
 | 
			
		||||
		if( ! IRC_WriteStrClient( from, RPL_TRACELINK_MSG, Client_ID( from ), PACKAGE_NAME, PACKAGE_VERSION, Client_ID( target ), Client_ID( Client_NextHop( target )), Option_String( idx2 ), time( NULL ) - Conn_StartTime( idx2 ), Conn_SendQ( idx ), Conn_SendQ( idx2 ))) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
		/* Forward command */
 | 
			
		||||
		IRC_WriteStrClientPrefix( target, from, "TRACE %s", Req->argv[0] );
 | 
			
		||||
		return CONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* mit Versionsinfo antworten */
 | 
			
		||||
	return IRC_WriteStrClient( Client, RPL_VERSION_MSG, Client_ID( prefix ), NGIRCd_DebugLevel, Conf_ServerName, NGIRCd_VersionAddition( ));
 | 
			
		||||
} /* IRC_VERSION */
 | 
			
		||||
	/* Infos about all connected servers */
 | 
			
		||||
	c = Client_First( );
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		if( Client_Conn( c ) > NONE )
 | 
			
		||||
		{
 | 
			
		||||
			/* Local client */
 | 
			
		||||
			if( Client_Type( c ) == CLIENT_SERVER )
 | 
			
		||||
			{
 | 
			
		||||
				/* Server link */
 | 
			
		||||
				if( ! IRC_WriteStrClient( from, RPL_TRACESERVER_MSG, Client_ID( from ), Client_ID( c ), Client_Mask( c ), Option_String( Client_Conn( c )))) return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
			if(( Client_Type( c ) == CLIENT_USER ) && ( strchr( Client_Modes( c ), 'o' )))
 | 
			
		||||
			{
 | 
			
		||||
				/* IRC Operator */
 | 
			
		||||
				if( ! IRC_WriteStrClient( from, RPL_TRACEOPERATOR_MSG, Client_ID( from ), Client_ID( c ))) return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		c = Client_Next( c );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Some information about us */
 | 
			
		||||
	if( ! IRC_WriteStrClient( from, RPL_TRACESERVER_MSG, Client_ID( from ), Conf_ServerName, Client_Mask( Client_ThisServer( )), Option_String( Client_Conn( Client )))) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	IRC_SetPenalty( Client, 3 );
 | 
			
		||||
	return IRC_WriteStrClient( from, RPL_TRACEEND_MSG, Client_ID( from ), Conf_ServerName, PACKAGE_NAME, PACKAGE_VERSION, NGIRCd_DebugLevel );
 | 
			
		||||
} /* IRC_TRACE */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_KILL( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
IRC_HELP( CLIENT *Client, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	CLIENT *prefix, *c;
 | 
			
		||||
	
 | 
			
		||||
	COMMAND *cmd;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Client_Type( Client ) != CLIENT_SERVER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
 | 
			
		||||
	/* Bad number of arguments? */
 | 
			
		||||
	if( Req->argc > 0 ) return IRC_WriteStrClient( Client, ERR_NORECIPIENT_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	/* Falsche Anzahl Parameter? */
 | 
			
		||||
	if(( Req->argc != 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
 | 
			
		||||
 | 
			
		||||
	prefix = Client_Search( Req->prefix );
 | 
			
		||||
	if( ! prefix )
 | 
			
		||||
	cmd = Parse_GetCommandStruct( );
 | 
			
		||||
	while( cmd->name )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_WARNING, "Got KILL with invalid prefix: \"%s\"!", Req->prefix );
 | 
			
		||||
		prefix = Client_ThisServer( );
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, "NOTICE %s :%s", Client_ID( Client ), cmd->name )) return DISCONNECTED;
 | 
			
		||||
		cmd++;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	Log( LOG_NOTICE, "Got KILL command from \"%s\" for \"%s\": %s", Client_Mask( prefix ), Req->argv[0], Req->argv[1] );
 | 
			
		||||
	
 | 
			
		||||
	/* andere Server benachrichtigen */
 | 
			
		||||
	IRC_WriteStrServersPrefix( Client, prefix, "KILL %s :%s", Req->argv[0], Req->argv[1] );
 | 
			
		||||
 | 
			
		||||
	/* haben wir selber einen solchen Client? */
 | 
			
		||||
	c = Client_Search( Req->argv[0] );
 | 
			
		||||
	if( c && ( Client_Conn( c ) != NONE )) Conn_Close( Client_Conn( c ), NULL, Req->argv[1], TRUE );
 | 
			
		||||
	
 | 
			
		||||
	IRC_SetPenalty( Client, 2 );
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_KILL */
 | 
			
		||||
} /* IRC_HELP */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_Show_MOTD( CLIENT *Client )
 | 
			
		||||
LOCAL CHAR *
 | 
			
		||||
Option_String( CONN_ID Idx )
 | 
			
		||||
{
 | 
			
		||||
	BOOLEAN ok;
 | 
			
		||||
	CHAR line[127];
 | 
			
		||||
	FILE *fd;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	STATIC CHAR option_txt[8];
 | 
			
		||||
	INT options;
 | 
			
		||||
 | 
			
		||||
	fd = fopen( Conf_MotdFile, "r" );
 | 
			
		||||
	if( ! fd )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_WARNING, "Can't read MOTD file \"%s\": %s", Conf_MotdFile, strerror( errno ));
 | 
			
		||||
		return IRC_WriteStrClient( Client, ERR_NOMOTD_MSG, Client_ID( Client ) );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	IRC_WriteStrClient( Client, RPL_MOTDSTART_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )));
 | 
			
		||||
	while( TRUE )
 | 
			
		||||
	{
 | 
			
		||||
		if( ! fgets( line, 126, fd )) break;
 | 
			
		||||
		if( line[strlen( line ) - 1] == '\n' ) line[strlen( line ) - 1] = '\0';
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, RPL_MOTD_MSG, Client_ID( Client ), line ))
 | 
			
		||||
		{
 | 
			
		||||
			fclose( fd );
 | 
			
		||||
			return FALSE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	ok = IRC_WriteStrClient( Client, RPL_ENDOFMOTD_MSG, Client_ID( Client ) );
 | 
			
		||||
	options = Conn_Options( Idx );
 | 
			
		||||
 | 
			
		||||
	fclose( fd );
 | 
			
		||||
	
 | 
			
		||||
	return ok;
 | 
			
		||||
} /* IRC_Show_MOTD */
 | 
			
		||||
	strcpy( option_txt, "F" );	/* No idea what this means but the original ircd sends it ... */
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
	if( options & CONN_ZIP ) strcat( option_txt, "z" );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_Send_NAMES( CLIENT *Client, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	BOOLEAN is_visible, is_member;
 | 
			
		||||
	CHAR str[LINE_LEN + 1];
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	CLIENT *cl;
 | 
			
		||||
	
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Channel_IsMemberOf( Chan, Client )) is_member = TRUE;
 | 
			
		||||
	else is_member = FALSE;
 | 
			
		||||
			 
 | 
			
		||||
	/* Alle Mitglieder suchen */
 | 
			
		||||
	sprintf( str, RPL_NAMREPLY_MSG, Client_ID( Client ), "=", Channel_Name( Chan ));
 | 
			
		||||
	cl2chan = Channel_FirstMember( Chan );
 | 
			
		||||
	while( cl2chan )
 | 
			
		||||
	{
 | 
			
		||||
		cl = Channel_GetClient( cl2chan );
 | 
			
		||||
 | 
			
		||||
		if( strchr( Client_Modes( cl ), 'i' )) is_visible = FALSE;
 | 
			
		||||
		else is_visible = TRUE;
 | 
			
		||||
 | 
			
		||||
		if( is_member || is_visible )
 | 
			
		||||
		{
 | 
			
		||||
			/* Nick anhaengen */
 | 
			
		||||
			if( str[strlen( str ) - 1] != ':' ) strcat( str, " " );
 | 
			
		||||
			if( strchr( Channel_UserModes( Chan, cl ), 'o' )) strcat( str, "@" );
 | 
			
		||||
			else if( strchr( Channel_UserModes( Chan, cl ), 'v' )) strcat( str, "+" );
 | 
			
		||||
			strcat( str, Client_ID( cl ));
 | 
			
		||||
	
 | 
			
		||||
			if( strlen( str ) > ( LINE_LEN - CLIENT_NICK_LEN - 4 ))
 | 
			
		||||
			{
 | 
			
		||||
				/* Zeile wird zu lang: senden! */
 | 
			
		||||
				if( ! IRC_WriteStrClient( Client, str )) return DISCONNECTED;
 | 
			
		||||
				sprintf( str, RPL_NAMREPLY_MSG, Client_ID( Client ), "=", Channel_Name( Chan ));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* naechstes Mitglied suchen */
 | 
			
		||||
		cl2chan = Channel_NextMember( Chan, cl2chan );
 | 
			
		||||
	}
 | 
			
		||||
	if( str[strlen( str ) - 1] != ':')
 | 
			
		||||
	{
 | 
			
		||||
		/* Es sind noch Daten da, die gesendet werden muessen */
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, str )) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_Send_NAMES */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_Send_WHO( CLIENT *Client, CHANNEL *Chan, BOOLEAN OnlyOps )
 | 
			
		||||
{
 | 
			
		||||
	BOOLEAN is_visible, is_member;
 | 
			
		||||
	CL2CHAN *cl2chan;
 | 
			
		||||
	CHAR flags[8];
 | 
			
		||||
	CLIENT *c;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Channel_IsMemberOf( Chan, Client )) is_member = TRUE;
 | 
			
		||||
	else is_member = FALSE;
 | 
			
		||||
 | 
			
		||||
	/* Alle Mitglieder suchen */
 | 
			
		||||
	cl2chan = Channel_FirstMember( Chan );
 | 
			
		||||
	while( cl2chan )
 | 
			
		||||
	{
 | 
			
		||||
		c = Channel_GetClient( cl2chan );
 | 
			
		||||
 | 
			
		||||
		if( strchr( Client_Modes( c ), 'i' )) is_visible = FALSE;
 | 
			
		||||
		else is_visible = TRUE;
 | 
			
		||||
 | 
			
		||||
		if( is_member || is_visible )
 | 
			
		||||
		{
 | 
			
		||||
			/* Flags zusammenbasteln */
 | 
			
		||||
			strcpy( flags, "H" );
 | 
			
		||||
			if( strchr( Client_Modes( c ), 'o' )) strcat( flags, "*" );
 | 
			
		||||
			if( strchr( Channel_UserModes( Chan, c ), 'o' )) strcat( flags, "@" );
 | 
			
		||||
			else if( strchr( Channel_UserModes( Chan, c ), 'v' )) strcat( flags, "+" );
 | 
			
		||||
			
 | 
			
		||||
			/* ausgeben */
 | 
			
		||||
			if(( ! OnlyOps ) || ( strchr( Client_Modes( c ), 'o' )))
 | 
			
		||||
			{
 | 
			
		||||
				if( ! IRC_WriteStrClient( Client, RPL_WHOREPLY_MSG, Client_ID( Client ), Channel_Name( Chan ), Client_User( c ), Client_Hostname( c ), Client_ID( Client_Introducer( c )), Client_ID( c ), flags, Client_Hops( c ), Client_Info( c ))) return DISCONNECTED;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* naechstes Mitglied suchen */
 | 
			
		||||
		cl2chan = Channel_NextMember( Chan, cl2chan );
 | 
			
		||||
	}
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_Send_WHO */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_Send_LUSERS( CLIENT *Client )
 | 
			
		||||
{
 | 
			
		||||
	INT cnt;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Users, Services und Serevr im Netz */
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_LUSERCLIENT_MSG, Client_ID( Client ), Client_UserCount( ), Client_ServiceCount( ), Client_ServerCount( ))) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	/* IRC-Operatoren im Netz */
 | 
			
		||||
	cnt = Client_OperCount( );
 | 
			
		||||
	if( cnt > 0 )
 | 
			
		||||
	{
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, RPL_LUSEROP_MSG, Client_ID( Client ), cnt )) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Unbekannt Verbindungen */
 | 
			
		||||
	cnt = Client_UnknownCount( );
 | 
			
		||||
	if( cnt > 0 )
 | 
			
		||||
	{
 | 
			
		||||
		if( ! IRC_WriteStrClient( Client, RPL_LUSERUNKNOWN_MSG, Client_ID( Client ), cnt )) return DISCONNECTED;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Channels im Netz */
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_LUSERCHANNELS_MSG, Client_ID( Client ), Channel_Count( ))) return DISCONNECTED;
 | 
			
		||||
 | 
			
		||||
	/* Channels im Netz */
 | 
			
		||||
	if( ! IRC_WriteStrClient( Client, RPL_LUSERME_MSG, Client_ID( Client ), Client_MyUserCount( ), Client_MyServiceCount( ), Client_MyServerCount( ))) return DISCONNECTED;
 | 
			
		||||
	
 | 
			
		||||
	return CONNECTED;
 | 
			
		||||
} /* IRC_Send_LUSERS */
 | 
			
		||||
	return option_txt;
 | 
			
		||||
} /* Option_String */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
@@ -2,48 +2,28 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: irc.h,v 1.30 2002/03/12 14:37:52 alex Exp $
 | 
			
		||||
 * $Id: irc.h,v 1.38 2003/01/15 13:49:20 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * irc.h: IRC-Befehle (Header)
 | 
			
		||||
 * IRC commands (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __irc_h__
 | 
			
		||||
#define __irc_h__
 | 
			
		||||
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_MOTD( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_LUSERS( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_LINKS( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_VERSION( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_PRIVMSG( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_NOTICE( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_NAMES( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_ISON( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_WHOIS( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_USERHOST( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_WHO( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_ERROR( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
GLOBAL BOOLEAN IRC_KILL( CLIENT *Client, REQUEST *Req );
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN IRC_Send_NAMES( CLIENT *Client, CHANNEL *Chan );
 | 
			
		||||
GLOBAL BOOLEAN IRC_Send_LUSERS( CLIENT *Client );
 | 
			
		||||
GLOBAL BOOLEAN IRC_Show_MOTD( CLIENT *Client );
 | 
			
		||||
GLOBAL BOOLEAN IRC_Send_WHO( CLIENT *Client, CHANNEL *Chan, BOOLEAN OnlyOps );
 | 
			
		||||
GLOBAL BOOLEAN IRC_ERROR PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_KILL PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_NOTICE PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_PRIVMSG PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_TRACE PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
GLOBAL BOOLEAN IRC_HELP PARAMS(( CLIENT *Client, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										442
									
								
								src/ngircd/lists.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										442
									
								
								src/ngircd/lists.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,442 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * Management of IRC lists: ban, invite, ...
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: lists.c,v 1.11 2002/12/26 16:25:43 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "match.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "lists.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define MASK_LEN 2*CLIENT_HOST_LEN
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct _C2C
 | 
			
		||||
{
 | 
			
		||||
	struct _C2C *next;
 | 
			
		||||
	CHAR mask[MASK_LEN];
 | 
			
		||||
	CHANNEL *channel;
 | 
			
		||||
	BOOLEAN onlyonce;
 | 
			
		||||
} C2C;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL C2C *My_Invites, *My_Bans;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL C2C *New_C2C PARAMS(( CHAR *Mask, CHANNEL *Chan, BOOLEAN OnlyOnce ));
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Check_List PARAMS(( C2C **Cl2Chan, CLIENT *Client, CHANNEL *Chan ));
 | 
			
		||||
LOCAL BOOLEAN Already_Registered PARAMS(( C2C *Cl2Chan, CHAR *Mask, CHANNEL *Chan ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Lists_Init( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Modul initialisieren */
 | 
			
		||||
 | 
			
		||||
	My_Invites = My_Bans = NULL;
 | 
			
		||||
} /* Lists_Init */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Lists_Exit( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Modul abmelden */
 | 
			
		||||
 | 
			
		||||
	C2C *c2c, *next;
 | 
			
		||||
 | 
			
		||||
	/* Invite-Lists freigeben */
 | 
			
		||||
	c2c = My_Invites;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		next = c2c->next;
 | 
			
		||||
		free( c2c );
 | 
			
		||||
		c2c = next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Ban-Lists freigeben */
 | 
			
		||||
	c2c = My_Bans;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		next = c2c->next;
 | 
			
		||||
		free( c2c );
 | 
			
		||||
		c2c = next;
 | 
			
		||||
	}
 | 
			
		||||
} /* Lists_Exit */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Lists_CheckInvited( CLIENT *Client, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	return Check_List( &My_Invites, Client, Chan );
 | 
			
		||||
} /* Lists_CheckInvited */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Lists_AddInvited( CLIENT *From, CHAR *Mask, CHANNEL *Chan, BOOLEAN OnlyOnce )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c;
 | 
			
		||||
 | 
			
		||||
	assert( Mask != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Already_Registered( My_Invites, Mask, Chan ))
 | 
			
		||||
	{
 | 
			
		||||
		/* Eintrag ist bereits vorhanden */
 | 
			
		||||
		IRC_WriteStrClient( From, RPL_INVITELIST_MSG, Client_ID( From ), Channel_Name( Chan ), Mask );
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	c2c = New_C2C( Mask, Chan, OnlyOnce );
 | 
			
		||||
	if( ! c2c )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_ERR, "Can't add new invite list entry!" );
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* verketten */
 | 
			
		||||
	c2c->next = My_Invites;
 | 
			
		||||
	My_Invites = c2c;
 | 
			
		||||
 | 
			
		||||
	Log( LOG_DEBUG, "Added \"%s\" to invite list for \"%s\".", Mask, Channel_Name( Chan ));
 | 
			
		||||
	return TRUE;
 | 
			
		||||
} /* Lists_AddInvited */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Lists_DelInvited( CHAR *Mask, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c, *last, *next;
 | 
			
		||||
 | 
			
		||||
	assert( Mask != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	last = NULL;
 | 
			
		||||
	c2c = My_Invites;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		next = c2c->next;
 | 
			
		||||
		if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 ))
 | 
			
		||||
		{
 | 
			
		||||
			/* dieser Eintrag muss geloescht werden */
 | 
			
		||||
			Log( LOG_DEBUG, "Deleted \"%s\" from invite list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
 | 
			
		||||
			if( last ) last->next = next;
 | 
			
		||||
			else My_Invites = next;
 | 
			
		||||
			free( c2c );
 | 
			
		||||
		}
 | 
			
		||||
		else last = c2c;
 | 
			
		||||
		c2c = next;
 | 
			
		||||
	}
 | 
			
		||||
} /* Lists_DelInvited */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Lists_ShowInvites( CLIENT *Client, CHANNEL *Channel )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Channel != NULL );
 | 
			
		||||
 | 
			
		||||
	c2c = My_Invites;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		if( c2c->channel == Channel )
 | 
			
		||||
		{
 | 
			
		||||
			/* Eintrag fuer Channel gefunden; ausgeben: */
 | 
			
		||||
			if( ! IRC_WriteStrClient( Client, RPL_INVITELIST_MSG, Client_ID( Client ), Channel_Name( Channel ), c2c->mask )) return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
		c2c = c2c->next;
 | 
			
		||||
	}
 | 
			
		||||
	return IRC_WriteStrClient( Client, RPL_ENDOFINVITELIST_MSG, Client_ID( Client ), Channel_Name( Channel ));
 | 
			
		||||
} /* Lists_ShowInvites */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Lists_CheckBanned( CLIENT *Client, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	return Check_List( &My_Bans, Client, Chan );
 | 
			
		||||
} /* Lists_CheckBanned */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Lists_AddBanned( CLIENT *From, CHAR *Mask, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c;
 | 
			
		||||
 | 
			
		||||
	assert( Mask != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	if( Already_Registered( My_Bans, Mask, Chan ))
 | 
			
		||||
	{
 | 
			
		||||
		/* Eintrag ist bereits vorhanden */
 | 
			
		||||
		IRC_WriteStrClient( From, RPL_BANLIST_MSG, Client_ID( From ), Channel_Name( Chan ), Mask );
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c2c = New_C2C( Mask, Chan, FALSE );
 | 
			
		||||
	if( ! c2c )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_ERR, "Can't add new ban list entry!" );
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* verketten */
 | 
			
		||||
	c2c->next = My_Bans;
 | 
			
		||||
	My_Bans = c2c;
 | 
			
		||||
 | 
			
		||||
	Log( LOG_DEBUG, "Added \"%s\" to ban list for \"%s\".", Mask, Channel_Name( Chan ));
 | 
			
		||||
	return TRUE;
 | 
			
		||||
} /* Lists_AddBanned */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Lists_DelBanned( CHAR *Mask, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c, *last, *next;
 | 
			
		||||
 | 
			
		||||
	assert( Mask != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	last = NULL;
 | 
			
		||||
	c2c = My_Bans;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		next = c2c->next;
 | 
			
		||||
		if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 ))
 | 
			
		||||
		{
 | 
			
		||||
			/* dieser Eintrag muss geloescht werden */
 | 
			
		||||
			Log( LOG_DEBUG, "Deleted \"%s\" from ban list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
 | 
			
		||||
			if( last ) last->next = next;
 | 
			
		||||
			else My_Bans = next;
 | 
			
		||||
			free( c2c );
 | 
			
		||||
		}
 | 
			
		||||
		else last = c2c;
 | 
			
		||||
		c2c = next;
 | 
			
		||||
	}
 | 
			
		||||
} /* Lists_DelBanned */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Lists_ShowBans( CLIENT *Client, CHANNEL *Channel )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c;
 | 
			
		||||
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Channel != NULL );
 | 
			
		||||
 | 
			
		||||
	c2c = My_Bans;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		if( c2c->channel == Channel )
 | 
			
		||||
		{
 | 
			
		||||
			/* Eintrag fuer Channel gefunden; ausgeben: */
 | 
			
		||||
			if( ! IRC_WriteStrClient( Client, RPL_BANLIST_MSG, Client_ID( Client ), Channel_Name( Channel ), c2c->mask )) return DISCONNECTED;
 | 
			
		||||
		}
 | 
			
		||||
		c2c = c2c->next;
 | 
			
		||||
	}
 | 
			
		||||
	return IRC_WriteStrClient( Client, RPL_ENDOFBANLIST_MSG, Client_ID( Client ), Channel_Name( Channel ));
 | 
			
		||||
} /* Lists_ShowBans */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Lists_DeleteChannel( CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	/* Channel wurde geloescht, Invite- und Ban-Lists aufraeumen */
 | 
			
		||||
 | 
			
		||||
	C2C *c2c, *last, *next;
 | 
			
		||||
 | 
			
		||||
	/* Invite-List */
 | 
			
		||||
	last = NULL;
 | 
			
		||||
	c2c = My_Invites;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		next = c2c->next;
 | 
			
		||||
		if( c2c->channel == Chan )
 | 
			
		||||
		{
 | 
			
		||||
			/* dieser Eintrag muss geloescht werden */
 | 
			
		||||
			Log( LOG_DEBUG, "Deleted \"%s\" from invite list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
 | 
			
		||||
			if( last ) last->next = next;
 | 
			
		||||
			else My_Invites = next;
 | 
			
		||||
			free( c2c );
 | 
			
		||||
		}
 | 
			
		||||
		else last = c2c;
 | 
			
		||||
		c2c = next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Ban-List */
 | 
			
		||||
	last = NULL;
 | 
			
		||||
	c2c = My_Bans;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		next = c2c->next;
 | 
			
		||||
		if( c2c->channel == Chan )
 | 
			
		||||
		{
 | 
			
		||||
			/* dieser Eintrag muss geloescht werden */
 | 
			
		||||
			Log( LOG_DEBUG, "Deleted \"%s\" from ban list for \"%s\"." , c2c->mask, Channel_Name( Chan ));
 | 
			
		||||
			if( last ) last->next = next;
 | 
			
		||||
			else My_Bans = next;
 | 
			
		||||
			free( c2c );
 | 
			
		||||
		}
 | 
			
		||||
		else last = c2c;
 | 
			
		||||
		c2c = next;
 | 
			
		||||
	}
 | 
			
		||||
} /* Lists_DeleteChannel */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
Lists_MakeMask( CHAR *Pattern )
 | 
			
		||||
{
 | 
			
		||||
	/* Hier wird aus einem "beliebigen" Pattern eine gueltige IRC-Mask erzeugt.
 | 
			
		||||
	 * Diese ist aber nur bis zum naechsten Aufruf von Lists_MakeMask() gueltig,
 | 
			
		||||
	 * da ein einziger globaler Puffer verwendet wird. ->Umkopieren!*/
 | 
			
		||||
 | 
			
		||||
	STATIC CHAR TheMask[MASK_LEN];
 | 
			
		||||
	CHAR *excl, *at;
 | 
			
		||||
 | 
			
		||||
	assert( Pattern != NULL );
 | 
			
		||||
 | 
			
		||||
	excl = strchr( Pattern, '!' );
 | 
			
		||||
	at = strchr( Pattern, '@' );
 | 
			
		||||
 | 
			
		||||
	if(( at ) && ( at < excl )) excl = NULL;
 | 
			
		||||
 | 
			
		||||
	if(( ! at ) && ( ! excl ))
 | 
			
		||||
	{
 | 
			
		||||
		/* weder ! noch @ vorhanden: als Nick annehmen */
 | 
			
		||||
		strlcpy( TheMask, Pattern, sizeof( TheMask ) - 5 );
 | 
			
		||||
		strlcat( TheMask, "!*@*", sizeof( TheMask ));
 | 
			
		||||
		return TheMask;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(( ! at ) && ( excl ))
 | 
			
		||||
	{
 | 
			
		||||
		/* Domain fehlt */
 | 
			
		||||
		strlcpy( TheMask, Pattern, sizeof( TheMask ) - 3 );
 | 
			
		||||
		strlcat( TheMask, "@*", sizeof( TheMask ));
 | 
			
		||||
		return TheMask;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if(( at ) && ( ! excl ))
 | 
			
		||||
	{
 | 
			
		||||
		/* User fehlt */
 | 
			
		||||
		*at = '\0'; at++;
 | 
			
		||||
		strlcpy( TheMask, Pattern, sizeof( TheMask ) - strlen( at ) - 4 );
 | 
			
		||||
		strlcat( TheMask, "!*@", sizeof( TheMask ));
 | 
			
		||||
		strlcat( TheMask, at, sizeof( TheMask ));
 | 
			
		||||
		return TheMask;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* alle Teile vorhanden */
 | 
			
		||||
	strlcpy( TheMask, Pattern, sizeof( TheMask ));
 | 
			
		||||
	return TheMask;
 | 
			
		||||
} /* Lists_MakeMask */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL C2C *
 | 
			
		||||
New_C2C( CHAR *Mask, CHANNEL *Chan, BOOLEAN OnlyOnce )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c;
 | 
			
		||||
	
 | 
			
		||||
	assert( Mask != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Speicher fuer Eintrag anfordern */
 | 
			
		||||
	c2c = malloc( sizeof( C2C ));
 | 
			
		||||
	if( ! c2c )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_EMERG, "Can't allocate memory! [New_C2C]" );
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	strlcpy( c2c->mask, Mask, sizeof( c2c->mask ));
 | 
			
		||||
	c2c->channel = Chan;
 | 
			
		||||
	c2c->onlyonce = OnlyOnce;
 | 
			
		||||
 | 
			
		||||
	return c2c;
 | 
			
		||||
} /* New_C2C */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN
 | 
			
		||||
Check_List( C2C **Cl2Chan, CLIENT *Client, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c, *last;
 | 
			
		||||
 | 
			
		||||
	assert( Cl2Chan != NULL );
 | 
			
		||||
	assert( Client != NULL );
 | 
			
		||||
	assert( Chan != NULL );
 | 
			
		||||
 | 
			
		||||
	c2c = *Cl2Chan;
 | 
			
		||||
	last = NULL;
 | 
			
		||||
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		if( c2c->channel == Chan )
 | 
			
		||||
		{
 | 
			
		||||
			/* Ok, richtiger Channel. Passt die Maske? */
 | 
			
		||||
			if( Match( c2c->mask, Client_Mask( Client )))
 | 
			
		||||
			{
 | 
			
		||||
				/* Treffer! */
 | 
			
		||||
				if( c2c->onlyonce )
 | 
			
		||||
				{
 | 
			
		||||
					/* Eintrag loeschen */
 | 
			
		||||
					Log( LOG_DEBUG, "Deleted \"%s\" from %s list for \"%s\".", c2c->mask, *Cl2Chan == My_Invites ? "invite" : "ban", Channel_Name( Chan ));
 | 
			
		||||
					if( last ) last->next = c2c->next;
 | 
			
		||||
					else *Cl2Chan = c2c->next;
 | 
			
		||||
					free( c2c );
 | 
			
		||||
				}
 | 
			
		||||
				return TRUE;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		last = c2c;
 | 
			
		||||
		c2c = c2c->next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return FALSE;
 | 
			
		||||
} /* Check_List */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN
 | 
			
		||||
Already_Registered( C2C *List, CHAR *Mask, CHANNEL *Chan )
 | 
			
		||||
{
 | 
			
		||||
	C2C *c2c;
 | 
			
		||||
 | 
			
		||||
	c2c = List;
 | 
			
		||||
	while( c2c )
 | 
			
		||||
	{
 | 
			
		||||
		if(( c2c->channel == Chan ) && ( strcasecmp( c2c->mask, Mask ) == 0 )) return TRUE;
 | 
			
		||||
		c2c = c2c->next;
 | 
			
		||||
	}
 | 
			
		||||
	return FALSE;
 | 
			
		||||
} /* Already_Registered */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										42
									
								
								src/ngircd/lists.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/ngircd/lists.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: lists.h,v 1.9 2002/12/12 12:23:43 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Management of IRC lists: ban, invite, ... (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __lists_h__
 | 
			
		||||
#define __lists_h__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Lists_Init PARAMS(( VOID ));
 | 
			
		||||
GLOBAL VOID Lists_Exit PARAMS(( VOID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Lists_CheckInvited PARAMS(( CLIENT *Client, CHANNEL *Chan ));
 | 
			
		||||
GLOBAL BOOLEAN Lists_AddInvited PARAMS(( CLIENT *From, CHAR *Mask, CHANNEL *Chan, BOOLEAN OnlyOnce ));
 | 
			
		||||
GLOBAL VOID Lists_DelInvited PARAMS(( CHAR *Mask, CHANNEL *Chan ));
 | 
			
		||||
GLOBAL BOOLEAN Lists_ShowInvites PARAMS(( CLIENT *Client, CHANNEL *Channel ));
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Lists_CheckBanned PARAMS(( CLIENT *Client, CHANNEL *Chan ));
 | 
			
		||||
GLOBAL BOOLEAN Lists_AddBanned PARAMS(( CLIENT *From, CHAR *Mask, CHANNEL *Chan ));
 | 
			
		||||
GLOBAL VOID Lists_DelBanned PARAMS(( CHAR *Mask, CHANNEL *Chan ));
 | 
			
		||||
GLOBAL BOOLEAN Lists_ShowBans PARAMS(( CLIENT *Client, CHANNEL *Channel ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Lists_DeleteChannel PARAMS(( CHANNEL *Chan ));
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *Lists_MakeMask PARAMS(( CHAR *Pattern ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
@@ -2,21 +2,20 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: log.c,v 1.32 2002/03/31 16:46:15 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * log.c: Logging-Funktionen
 | 
			
		||||
 * Logging functions
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: log.c,v 1.43 2003/03/31 15:54:21 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
@@ -31,8 +30,10 @@
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
@@ -43,14 +44,15 @@ LOCAL CHAR Error_File[FNAME_LEN];
 | 
			
		||||
LOCAL CHAR Init_Txt[127];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Wall_ServerNotice( CHAR *Msg );
 | 
			
		||||
LOCAL VOID Wall_ServerNotice PARAMS(( CHAR *Msg ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Log_Init( VOID )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Log_Init( VOID )
 | 
			
		||||
{
 | 
			
		||||
#ifdef USE_SYSLOG
 | 
			
		||||
	/* Syslog initialisieren */
 | 
			
		||||
	openlog( PACKAGE, LOG_CONS|LOG_PID, LOG_LOCAL5 );
 | 
			
		||||
	openlog( PACKAGE_NAME, LOG_CONS|LOG_PID, LOG_LOCAL5 );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Hello World! */
 | 
			
		||||
@@ -86,13 +88,14 @@ GLOBAL VOID Log_Init( VOID )
 | 
			
		||||
} /* Log_Init */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Log_InitErrorfile( VOID )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Log_InitErrorfile( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* "Error-Log" initialisieren: stderr in Datei umlenken. Dort
 | 
			
		||||
	 * landen z.B. alle Ausgaben von assert()-Aufrufen. */
 | 
			
		||||
 | 
			
		||||
	/* Dateiname zusammen bauen */
 | 
			
		||||
	sprintf( Error_File, ERROR_DIR"/"PACKAGE"-%ld.err", (INT32)getpid( ));
 | 
			
		||||
	sprintf( Error_File, "%s/%s-%ld.err", ERROR_DIR, PACKAGE_NAME, (LONG)getpid( ));
 | 
			
		||||
 | 
			
		||||
	/* stderr umlenken */
 | 
			
		||||
	fflush( stderr );
 | 
			
		||||
@@ -112,10 +115,12 @@ GLOBAL VOID Log_InitErrorfile( VOID )
 | 
			
		||||
} /* Log_InitErrfile */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Log_Exit( VOID )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Log_Exit( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Good Bye! */
 | 
			
		||||
	Log( LOG_NOTICE, PACKAGE" done.");
 | 
			
		||||
	if( NGIRCd_SignalRestart ) Log( LOG_NOTICE, "%s done (restarting).", PACKAGE_NAME );
 | 
			
		||||
	else Log( LOG_NOTICE, "%s done.", PACKAGE_NAME );
 | 
			
		||||
 | 
			
		||||
	/* Error-File (stderr) loeschen */
 | 
			
		||||
	if( unlink( Error_File ) != 0 ) Log( LOG_ERR, "Can't delete \"%s\": %s", Error_File, strerror( errno ));
 | 
			
		||||
@@ -127,7 +132,16 @@ GLOBAL VOID Log_Exit( VOID )
 | 
			
		||||
} /* Log_Exit */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Log( INT Level, CONST CHAR *Format, ... )
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Log( INT Level, CONST CHAR *Format, ... )
 | 
			
		||||
#else
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Log( Level, Format, va_alist )
 | 
			
		||||
INT Level;
 | 
			
		||||
CONST CHAR *Format;
 | 
			
		||||
va_dcl
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	/* Eintrag in Logfile(s) schreiben */
 | 
			
		||||
 | 
			
		||||
@@ -152,15 +166,27 @@ GLOBAL VOID Log( INT Level, CONST CHAR *Format, ... )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* String mit variablen Argumenten zusammenbauen ... */
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
	va_start( ap, Format );
 | 
			
		||||
#else
 | 
			
		||||
	va_start( ap );
 | 
			
		||||
#endif
 | 
			
		||||
	vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
 | 
			
		||||
	va_end( ap );
 | 
			
		||||
 | 
			
		||||
	if( NGIRCd_NoDaemon )
 | 
			
		||||
	{
 | 
			
		||||
		/* auf Konsole ausgeben */
 | 
			
		||||
		printf( "[%d] %s\n", Level, msg );
 | 
			
		||||
		fprintf( stdout, "[%d] %s\n", Level, msg );
 | 
			
		||||
		fflush( stdout );
 | 
			
		||||
	}
 | 
			
		||||
#ifdef USE_SYSLOG
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* Syslog */
 | 
			
		||||
		syslog( Level, "%s", msg );
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if( Level <= LOG_CRIT )
 | 
			
		||||
	{
 | 
			
		||||
@@ -169,11 +195,6 @@ GLOBAL VOID Log( INT Level, CONST CHAR *Format, ... )
 | 
			
		||||
		fflush( stderr );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef USE_SYSLOG
 | 
			
		||||
	/* Syslog */
 | 
			
		||||
	syslog( Level, msg );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if( snotice )
 | 
			
		||||
	{
 | 
			
		||||
		/* NOTICE an lokale User mit "s"-Mode */
 | 
			
		||||
@@ -182,15 +203,17 @@ GLOBAL VOID Log( INT Level, CONST CHAR *Format, ... )
 | 
			
		||||
} /* Log */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Log_Init_Resolver( VOID )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Log_Init_Resolver( VOID )
 | 
			
		||||
{
 | 
			
		||||
#ifdef USE_SYSLOG
 | 
			
		||||
	openlog( PACKAGE, LOG_CONS|LOG_PID, LOG_LOCAL5 );
 | 
			
		||||
	openlog( PACKAGE_NAME, LOG_CONS|LOG_PID, LOG_LOCAL5 );
 | 
			
		||||
#endif
 | 
			
		||||
} /* Log_Init_Resolver */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Log_Exit_Resolver( VOID )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Log_Exit_Resolver( VOID )
 | 
			
		||||
{
 | 
			
		||||
#ifdef USE_SYSLOG
 | 
			
		||||
	closelog( );
 | 
			
		||||
@@ -198,7 +221,16 @@ GLOBAL VOID Log_Exit_Resolver( VOID )
 | 
			
		||||
} /* Log_Exit_Resolver */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Log_Resolver( CONST INT Level, CONST CHAR *Format, ... )
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Log_Resolver( CONST INT Level, CONST CHAR *Format, ... )
 | 
			
		||||
#else
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Log_Resolver( Level, Format, va_alist )
 | 
			
		||||
CONST INT Level;
 | 
			
		||||
CONST CHAR *Format;
 | 
			
		||||
va_dcl
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	/* Eintrag des Resolver in Logfile(s) schreiben */
 | 
			
		||||
 | 
			
		||||
@@ -211,6 +243,8 @@ GLOBAL VOID Log_Resolver( CONST INT Level, CONST CHAR *Format, ... )
 | 
			
		||||
 | 
			
		||||
	assert( Format != NULL );
 | 
			
		||||
 | 
			
		||||
	if( NGIRCd_NoDaemon ) return;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
 | 
			
		||||
#else
 | 
			
		||||
@@ -218,7 +252,11 @@ GLOBAL VOID Log_Resolver( CONST INT Level, CONST CHAR *Format, ... )
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* String mit variablen Argumenten zusammenbauen ... */
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
	va_start( ap, Format );
 | 
			
		||||
#else
 | 
			
		||||
	va_start( ap );
 | 
			
		||||
#endif
 | 
			
		||||
	vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
 | 
			
		||||
	va_end( ap );
 | 
			
		||||
 | 
			
		||||
@@ -229,7 +267,8 @@ GLOBAL VOID Log_Resolver( CONST INT Level, CONST CHAR *Format, ... )
 | 
			
		||||
} /* Log_Resolver */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Wall_ServerNotice( CHAR *Msg )
 | 
			
		||||
LOCAL VOID
 | 
			
		||||
Wall_ServerNotice( CHAR *Msg )
 | 
			
		||||
{
 | 
			
		||||
	/* Server-Notice an entsprechende User verschicken */
 | 
			
		||||
 | 
			
		||||
@@ -240,7 +279,7 @@ LOCAL VOID Wall_ServerNotice( CHAR *Msg )
 | 
			
		||||
	c = Client_First( );
 | 
			
		||||
	while( c )
 | 
			
		||||
	{
 | 
			
		||||
		if(( Client_Conn( c ) > NONE ) && ( Client_HasMode( c, 's' ))) IRC_WriteStrClient( c, "NOTICE %s :%s", Client_ThisServer( ), Msg );
 | 
			
		||||
		if(( Client_Conn( c ) > NONE ) && ( Client_HasMode( c, 's' ))) IRC_WriteStrClient( c, "NOTICE %s :%s%s", Client_ThisServer( ), NOTICE_TXTPREFIX, Msg );
 | 
			
		||||
		c = Client_Next( c );
 | 
			
		||||
	}
 | 
			
		||||
} /* Wall_ServerNotice */
 | 
			
		||||
 
 | 
			
		||||
@@ -2,16 +2,15 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: log.h,v 1.11 2002/03/29 23:33:42 alex Exp $
 | 
			
		||||
 * $Id: log.h,v 1.13 2002/12/12 12:23:43 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * log.h: Logging-Funktionen (Header)
 | 
			
		||||
 * Logging functions (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -36,16 +35,16 @@
 | 
			
		||||
#define LOG_snotice 1024
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Log_Init( VOID );
 | 
			
		||||
GLOBAL VOID Log_Exit( VOID );
 | 
			
		||||
GLOBAL VOID Log_Init PARAMS((VOID ));
 | 
			
		||||
GLOBAL VOID Log_Exit PARAMS((VOID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Log_InitErrorfile( VOID );
 | 
			
		||||
GLOBAL VOID Log( INT Level, CONST CHAR *Format, ... );
 | 
			
		||||
GLOBAL VOID Log_InitErrorfile PARAMS((VOID ));
 | 
			
		||||
GLOBAL VOID Log PARAMS((INT Level, CONST CHAR *Format, ... ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Log_Init_Resolver( VOID );
 | 
			
		||||
GLOBAL VOID Log_Exit_Resolver( VOID );
 | 
			
		||||
GLOBAL VOID Log_Init_Resolver PARAMS((VOID ));
 | 
			
		||||
GLOBAL VOID Log_Exit_Resolver PARAMS((VOID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Log_Resolver( CONST INT Level, CONST CHAR *Format, ... );
 | 
			
		||||
GLOBAL VOID Log_Resolver PARAMS((CONST INT Level, CONST CHAR *Format, ... ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										253
									
								
								src/ngircd/match.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										253
									
								
								src/ngircd/match.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,253 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * Wildcard pattern matching
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: match.c,v 1.2 2002/12/12 12:24:18 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "match.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Die Pattern-Matching-Funkionen [Matche(), Matche_After_Star()] basieren
 | 
			
		||||
 * auf Versionen von J. Kercheval. Die Version 1.1 wurde am 12.03.1991 als
 | 
			
		||||
 * "public domain" freigegeben:
 | 
			
		||||
 * <http://www.snippets.org/snippets/portable/MATCH+C.php3>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL INT Matche PARAMS(( REGISTER CHAR *p, REGISTER CHAR *t ));
 | 
			
		||||
LOCAL INT Matche_After_Star PARAMS(( REGISTER CHAR *p, REGISTER CHAR *t ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define MATCH_PATTERN	6	/* bad pattern */
 | 
			
		||||
#define MATCH_LITERAL	5	/* match failure on literal match */
 | 
			
		||||
#define MATCH_RANGE	4	/* match failure on [..] construct */
 | 
			
		||||
#define MATCH_ABORT	3	/* premature end of text string */
 | 
			
		||||
#define MATCH_END	2	/* premature end of pattern string */
 | 
			
		||||
#define MATCH_VALID	1	/* valid match */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Match( CHAR *Pattern, CHAR *String )
 | 
			
		||||
{
 | 
			
		||||
	/* Pattern mit String vergleichen */
 | 
			
		||||
	if( Matche( Pattern, String ) == MATCH_VALID ) return TRUE;
 | 
			
		||||
	else return FALSE;
 | 
			
		||||
} /* Match */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL INT
 | 
			
		||||
Matche( REGISTER CHAR *p, REGISTER CHAR *t )
 | 
			
		||||
{
 | 
			
		||||
	REGISTER CHAR range_start, range_end;
 | 
			
		||||
	BOOLEAN invert;
 | 
			
		||||
	BOOLEAN member_match;
 | 
			
		||||
	BOOLEAN loop;
 | 
			
		||||
 | 
			
		||||
	for( ; *p; p++, t++ )
 | 
			
		||||
	{
 | 
			
		||||
		/* if this is the end of the text then this is the end of the match */
 | 
			
		||||
		if( ! *t )
 | 
			
		||||
		{
 | 
			
		||||
			return ( *p == '*' && *++p == '\0' ) ? MATCH_VALID : MATCH_ABORT;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* determine and react to pattern type */
 | 
			
		||||
		switch( *p )
 | 
			
		||||
		{
 | 
			
		||||
			case '?':	/* single any character match */
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case '*':	/* multiple any character match */
 | 
			
		||||
				return Matche_After_Star( p, t );
 | 
			
		||||
 | 
			
		||||
			case '[':	/* [..] construct, single member/exclusion character match */
 | 
			
		||||
				/* move to beginning of range */
 | 
			
		||||
				p++;
 | 
			
		||||
 | 
			
		||||
				/* check if this is a member match or exclusion match */
 | 
			
		||||
				invert = FALSE;
 | 
			
		||||
				if( *p == '!' || *p == '^' )
 | 
			
		||||
				{
 | 
			
		||||
					invert = TRUE;
 | 
			
		||||
					p++;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				/* if closing bracket here or at range start then we have a malformed pattern */
 | 
			
		||||
				if ( *p == ']' ) return MATCH_PATTERN;
 | 
			
		||||
 | 
			
		||||
				member_match = FALSE;
 | 
			
		||||
				loop = TRUE;
 | 
			
		||||
 | 
			
		||||
				while( loop )
 | 
			
		||||
				{
 | 
			
		||||
					/* if end of construct then loop is done */
 | 
			
		||||
					if( *p == ']' )
 | 
			
		||||
					{
 | 
			
		||||
						loop = FALSE;
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					/* matching a '!', '^', '-', '\' or a ']' */
 | 
			
		||||
					if( *p == '\\' ) range_start = range_end = *++p;
 | 
			
		||||
					else  range_start = range_end = *p;
 | 
			
		||||
 | 
			
		||||
					/* if end of pattern then bad pattern (Missing ']') */
 | 
			
		||||
					if( ! *p ) return MATCH_PATTERN;
 | 
			
		||||
 | 
			
		||||
					/* check for range bar */
 | 
			
		||||
					if( *++p == '-' )
 | 
			
		||||
					{
 | 
			
		||||
						/* get the range end */
 | 
			
		||||
						range_end = *++p;
 | 
			
		||||
 | 
			
		||||
						/* if end of pattern or construct then bad pattern */
 | 
			
		||||
						if( range_end == '\0' || range_end == ']' ) return MATCH_PATTERN;
 | 
			
		||||
 | 
			
		||||
						/* special character range end */
 | 
			
		||||
						if( range_end == '\\' )
 | 
			
		||||
						{
 | 
			
		||||
							range_end = *++p;
 | 
			
		||||
 | 
			
		||||
							/* if end of text then we have a bad pattern */
 | 
			
		||||
							if ( ! range_end ) return MATCH_PATTERN;
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						/* move just beyond this range */
 | 
			
		||||
						p++;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					/* if the text character is in range then match found. make sure the range
 | 
			
		||||
					 * letters have the proper relationship to one another before comparison */
 | 
			
		||||
					if( range_start < range_end )
 | 
			
		||||
					{
 | 
			
		||||
						if( *t >= range_start && *t <= range_end )
 | 
			
		||||
						{
 | 
			
		||||
							member_match = TRUE;
 | 
			
		||||
							loop = FALSE;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						if( *t >= range_end && *t <= range_start )
 | 
			
		||||
						{
 | 
			
		||||
							member_match = TRUE;
 | 
			
		||||
							loop = FALSE;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				/* if there was a match in an exclusion set then no match */
 | 
			
		||||
				/* if there was no match in a member set then no match */
 | 
			
		||||
				if(( invert && member_match ) || ! ( invert || member_match )) return MATCH_RANGE;
 | 
			
		||||
 | 
			
		||||
				/* if this is not an exclusion then skip the rest of the [...]
 | 
			
		||||
				 * construct that already matched. */
 | 
			
		||||
				if( member_match )
 | 
			
		||||
				{
 | 
			
		||||
					while( *p != ']' )
 | 
			
		||||
					{
 | 
			
		||||
						/* bad pattern (Missing ']') */
 | 
			
		||||
						if( ! *p ) return MATCH_PATTERN;
 | 
			
		||||
 | 
			
		||||
						/* skip exact match */
 | 
			
		||||
						if( *p == '\\' )
 | 
			
		||||
						{
 | 
			
		||||
							p++;
 | 
			
		||||
 | 
			
		||||
							/* if end of text then we have a bad pattern */
 | 
			
		||||
							if( ! *p ) return MATCH_PATTERN;
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						/* move to next pattern char */
 | 
			
		||||
						p++;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case '\\':	/* next character is quoted and must match exactly */
 | 
			
		||||
				/* move pattern pointer to quoted char and fall through */
 | 
			
		||||
				p++;
 | 
			
		||||
 | 
			
		||||
				/* if end of text then we have a bad pattern */
 | 
			
		||||
				if( ! *p ) return MATCH_PATTERN;
 | 
			
		||||
 | 
			
		||||
				/* must match this character exactly */
 | 
			
		||||
			default:
 | 
			
		||||
				if( *p != *t ) return MATCH_LITERAL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	/* if end of text not reached then the pattern fails */
 | 
			
		||||
 | 
			
		||||
	if( *t ) return MATCH_END;
 | 
			
		||||
	else return MATCH_VALID;
 | 
			
		||||
} /* Matche */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL INT
 | 
			
		||||
Matche_After_Star( REGISTER CHAR *p, REGISTER CHAR *t )
 | 
			
		||||
{
 | 
			
		||||
	REGISTER INT nextp, match = 0;
 | 
			
		||||
 | 
			
		||||
	/* pass over existing ? and * in pattern */
 | 
			
		||||
	while( *p == '?' || *p == '*' )
 | 
			
		||||
	{
 | 
			
		||||
		/* take one char for each ? and + */
 | 
			
		||||
		if (*p == '?')
 | 
			
		||||
		{
 | 
			
		||||
			/* if end of text then no match */
 | 
			
		||||
			if( ! *t++ ) return MATCH_ABORT;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* move to next char in pattern */
 | 
			
		||||
		p++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* if end of pattern we have matched regardless of text left */
 | 
			
		||||
	if( ! *p ) return MATCH_VALID;
 | 
			
		||||
 | 
			
		||||
	/* get the next character to match which must be a literal or '[' */
 | 
			
		||||
	nextp = *p;
 | 
			
		||||
	if( nextp == '\\' )
 | 
			
		||||
	{
 | 
			
		||||
		nextp = p[1];
 | 
			
		||||
 | 
			
		||||
		/* if end of text then we have a bad pattern */
 | 
			
		||||
		if( ! nextp ) return MATCH_PATTERN;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Continue until we run out of text or definite result seen */
 | 
			
		||||
	do
 | 
			
		||||
	{
 | 
			
		||||
		/* a precondition for matching is that the next character
 | 
			
		||||
		 * in the pattern match the next character in the text or that
 | 
			
		||||
		 * the next pattern char is the beginning of a range.  Increment
 | 
			
		||||
		 * text pointer as we go here */
 | 
			
		||||
		if( nextp == *t || nextp == '[' ) match = Matche( p, t );
 | 
			
		||||
 | 
			
		||||
		/* if the end of text is reached then no match */
 | 
			
		||||
		if( ! *t++ ) match = MATCH_ABORT;
 | 
			
		||||
	} while( match != MATCH_VALID && match != MATCH_ABORT && match != MATCH_PATTERN );
 | 
			
		||||
 | 
			
		||||
	/* return result */
 | 
			
		||||
	return match;
 | 
			
		||||
} /* Matche_After_Star */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										27
									
								
								src/ngircd/match.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/ngircd/match.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: match.h,v 1.2 2002/12/12 12:23:43 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Wildcard pattern matching (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __match_h__
 | 
			
		||||
#define __match_h__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Match PARAMS(( CHAR *Pattern, CHAR *String ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
@@ -1,17 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: messages.h,v 1.37 2002/03/12 22:08:24 alex Exp $
 | 
			
		||||
 * $Id: messages.h,v 1.64 2003/03/19 21:16:16 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * irc.h: IRC-Befehle (Header)
 | 
			
		||||
 * IRC numerics (Header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -19,181 +18,108 @@
 | 
			
		||||
#define __messages_h__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define RPL_WELCOME			"001"
 | 
			
		||||
#define RPL_WELCOME_MSG			RPL_WELCOME" %s :Welcome to the Internet Relay Network %s"
 | 
			
		||||
#define RPL_WELCOME_MSG			"001 %s :Welcome to the Internet Relay Network %s"
 | 
			
		||||
#define RPL_YOURHOST_MSG		"002 %s :Your host is %s, running version ngircd-%s (%s/%s/%s)"
 | 
			
		||||
#define RPL_CREATED_MSG			"003 %s :This server has been started %s"
 | 
			
		||||
#define RPL_MYINFO_MSG			"004 %s %s ngircd-%s %s %s"
 | 
			
		||||
#define RPL_ISUPPORT_MSG		"005 %s NICKLEN=%d TOPICLEN=%d AWAYLEN=%d MAXCHANNELS=%d :are supported on this server"
 | 
			
		||||
 | 
			
		||||
#define RPL_YOURHOST			"002"
 | 
			
		||||
#define RPL_YOURHOST_MSG		RPL_YOURHOST" %s :Your host is %s, running ngircd "VERSION"-"TARGET_CPU"/"TARGET_VENDOR"/"TARGET_OS
 | 
			
		||||
#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 :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_ENDOFSTATS_MSG		"219 %s %c :End of STATS report"
 | 
			
		||||
#define RPL_UMODEIS_MSG			"221 %s +%s"
 | 
			
		||||
#define RPL_LUSERCLIENT_MSG		"251 %s :There are %ld users and %ld services on %ld servers"
 | 
			
		||||
#define RPL_LUSEROP_MSG			"252 %s %ld :operator(s) online"
 | 
			
		||||
#define RPL_LUSERUNKNOWN_MSG		"253 %s %ld :unknown connection(s)"
 | 
			
		||||
#define RPL_LUSERCHANNELS_MSG		"254 %s %ld :channels formed"
 | 
			
		||||
#define RPL_LUSERME_MSG			"255 %s :I have %ld users, %ld services and %ld servers"
 | 
			
		||||
#define RPL_ADMINME_MSG			"256 %s %s :Administrative info"
 | 
			
		||||
#define RPL_ADMINLOC1_MSG		"257 %s :%s"
 | 
			
		||||
#define RPL_ADMINLOC2_MSG		"258 %s :%s"
 | 
			
		||||
#define RPL_ADMINEMAIL_MSG		"259 %s :%s"
 | 
			
		||||
#define RPL_TRACEEND_MSG		"262 %s %s %s-%s.%s :End of TRACE"
 | 
			
		||||
#define RPL_LOCALUSERS_MSG		"265 %s :Current local users: %ld, Max: %ld"
 | 
			
		||||
#define RPL_NETUSERS_MSG		"266 %s :Current global users: %ld, Max: %ld"
 | 
			
		||||
 | 
			
		||||
#define RPL_CREATED			"003"
 | 
			
		||||
#define RPL_CREATED_MSG			RPL_CREATED" %s :This server was started %s"
 | 
			
		||||
#define RPL_AWAY_MSG			"301 %s %s :%s"
 | 
			
		||||
#define RPL_USERHOST_MSG		"302 %s :"
 | 
			
		||||
#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_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"
 | 
			
		||||
#define RPL_WHOWASUSER_MSG		"314 %s %s %s %s * :%s"
 | 
			
		||||
#define RPL_ENDOFWHO_MSG		"315 %s %s :End of WHO list"
 | 
			
		||||
#define RPL_WHOISIDLE_MSG		"317 %s %s %ld :seconds idle"
 | 
			
		||||
#define RPL_ENDOFWHOIS_MSG		"318 %s %s :End of WHOIS list"
 | 
			
		||||
#define RPL_WHOISCHANNELS_MSG		"319 %s %s :"
 | 
			
		||||
#define RPL_LIST_MSG			"322 %s %s %ld :%s"
 | 
			
		||||
#define RPL_LISTEND_MSG			"323 %s :End of LIST"
 | 
			
		||||
#define RPL_CHANNELMODEIS_MSG		"324 %s %s +%s"
 | 
			
		||||
#define RPL_NOTOPIC_MSG			"331 %s %s :No topic is set"
 | 
			
		||||
#define RPL_TOPIC_MSG			"332 %s %s :%s"
 | 
			
		||||
#define RPL_INVITING_MSG		"341 %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_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 :"
 | 
			
		||||
#define RPL_LINKS_MSG			"364 %s %s %s :%d %s"
 | 
			
		||||
#define RPL_ENDOFLINKS_MSG		"365 %s %s :End of LINKS list"
 | 
			
		||||
#define RPL_ENDOFNAMES_MSG		"366 %s %s :End of NAMES list"
 | 
			
		||||
#define RPL_BANLIST_MSG			"367 %s %s %s"
 | 
			
		||||
#define RPL_ENDOFBANLIST_MSG		"368 %s %s :End of channel ban list"
 | 
			
		||||
#define RPL_ENDOFWHOWAS_MSG		"369 %s %s :End of WHOWAS list"
 | 
			
		||||
#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_YOUREOPER_MSG		"381 %s :You are now an IRC Operator"
 | 
			
		||||
#define RPL_YOURESERVICE_MSG		"383 %s :You are service %s"
 | 
			
		||||
#define RPL_TIME_MSG			"391 %s %s :%s"
 | 
			
		||||
 | 
			
		||||
#define RPL_MYINFO			"004"
 | 
			
		||||
#define RPL_MYINFO_MSG			RPL_MYINFO" %s :%s ngircd-"VERSION" "USERMODES" "CHANMODES
 | 
			
		||||
#define ERR_NOSUCHNICK_MSG		"401 %s %s :No such nick or channel name"
 | 
			
		||||
#define ERR_NOSUCHSERVER_MSG		"402 %s %s :No such server"
 | 
			
		||||
#define ERR_NOSUCHCHANNEL_MSG		"403 %s %s :No such channel"
 | 
			
		||||
#define ERR_CANNOTSENDTOCHAN_MSG	"404 %s %s :Cannot send to channel"
 | 
			
		||||
#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_NORECIPIENT_MSG		"411 %s :No receipient given (%s)"
 | 
			
		||||
#define ERR_NOTEXTTOSEND_MSG		"412 %s :No text to send"
 | 
			
		||||
#define ERR_UNKNOWNCOMMAND_MSG		"421 %s %s :Unknown command"
 | 
			
		||||
#define ERR_NOMOTD_MSG			"422 %s :MOTD file is missing"
 | 
			
		||||
#define ERR_ERRONEUSNICKNAME_MSG	"432 %s %s :Erroneous nickname"
 | 
			
		||||
#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_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_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_NOPRIVILEGES_MSG		"481 %s :Permission denied"
 | 
			
		||||
#define ERR_CHANOPRIVSNEEDED_MSG	"482 %s %s :You are not channel operator"
 | 
			
		||||
#define ERR_CANTKILLSERVER_MSG		"483 %s :You can't kill a server!"
 | 
			
		||||
#define ERR_RESTRICTED_MSG		"484 %s :Your connection is restricted"
 | 
			
		||||
#define ERR_NOOPERHOST_MSG		"491 %s :Not configured for your host"
 | 
			
		||||
 | 
			
		||||
#define RPL_UMODEIS			"211"
 | 
			
		||||
#define RPL_UMODEIS_MSG			RPL_UMODEIS" %s +%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 RPL_LUSERCLIENT			"251"
 | 
			
		||||
#define RPL_LUSERCLIENT_MSG		RPL_LUSERCLIENT" %s :There are %d users and %d services on %d servers"
 | 
			
		||||
 | 
			
		||||
#define RPL_LUSEROP			"252"
 | 
			
		||||
#define RPL_LUSEROP_MSG			RPL_LUSEROP" %s %d :operator(s) online"
 | 
			
		||||
 | 
			
		||||
#define RPL_LUSERUNKNOWN		"253"
 | 
			
		||||
#define	RPL_LUSERUNKNOWN_MSG		RPL_LUSERUNKNOWN" %s %d :unknown connection(s)"
 | 
			
		||||
 | 
			
		||||
#define RPL_LUSERCHANNELS		"254"
 | 
			
		||||
#define RPL_LUSERCHANNELS_MSG		RPL_LUSERCHANNELS" %s %d :channels formed"
 | 
			
		||||
 | 
			
		||||
#define RPL_LUSERME			"255"
 | 
			
		||||
#define	RPL_LUSERME_MSG			RPL_LUSERME" %s :I have %d users, %d services and %d servers"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define RPL_UNAWAY			"305"
 | 
			
		||||
#define RPL_UNAWAY_MSG			RPL_UNAWAY" %s :You are no longer marked as being away"
 | 
			
		||||
 | 
			
		||||
#define RPL_NOWAWAY			"306"
 | 
			
		||||
#define RPL_NOWAWAY_MSG			RPL_NOWAWAY" %s :You have been marked as being away"
 | 
			
		||||
 | 
			
		||||
#define RPL_MOTD			"372"
 | 
			
		||||
#define RPL_MOTD_MSG			RPL_MOTD" %s :- %s"
 | 
			
		||||
 | 
			
		||||
#define RPL_MOTDSTART			"375"
 | 
			
		||||
#define RPL_MOTDSTART_MSG		RPL_MOTDSTART" %s :- %s message of the day"
 | 
			
		||||
 | 
			
		||||
#define RPL_ENDOFMOTD			"376"
 | 
			
		||||
#define RPL_ENDOFMOTD_MSG		RPL_ENDOFMOTD" %s :End of MOTD command"
 | 
			
		||||
 | 
			
		||||
#define	RPL_AWAY			"301"
 | 
			
		||||
#define RPL_AWAY_MSG			RPL_AWAY" %s %s :%s"
 | 
			
		||||
 | 
			
		||||
#define RPL_USERHOST			"302"
 | 
			
		||||
#define RPL_USERHOST_MSG		RPL_USERHOST" %s :"
 | 
			
		||||
 | 
			
		||||
#define RPL_ISON			"303"
 | 
			
		||||
#define RPL_ISON_MSG			RPL_ISON" %s :"
 | 
			
		||||
 | 
			
		||||
#define RPL_WHOISUSER			"311"
 | 
			
		||||
#define RPL_WHOISUSER_MSG		RPL_WHOISUSER" %s %s %s %s * :%s"
 | 
			
		||||
 | 
			
		||||
#define RPL_WHOISSERVER			"312"
 | 
			
		||||
#define RPL_WHOISSERVER_MSG		RPL_WHOISSERVER" %s %s %s :%s"
 | 
			
		||||
 | 
			
		||||
#define RPL_WHOISOPERATOR		"313"
 | 
			
		||||
#define RPL_WHOISOPERATOR_MSG		RPL_WHOISOPERATOR" %s %s :is an IRC operator"
 | 
			
		||||
 | 
			
		||||
#define RPL_ENDOFWHO			"315"
 | 
			
		||||
#define RPL_ENDOFWHO_MSG		RPL_ENDOFWHO" %s %s :End of WHO list"
 | 
			
		||||
 | 
			
		||||
#define RPL_WHOISIDLE			"317"
 | 
			
		||||
#define RPL_WHOISIDLE_MSG		RPL_WHOISIDLE" %s %s %ld :seconds idle"
 | 
			
		||||
 | 
			
		||||
#define RPL_ENDOFWHOIS			"318"
 | 
			
		||||
#define RPL_ENDOFWHOIS_MSG		RPL_ENDOFWHOIS" %s %s :End of WHOIS list"
 | 
			
		||||
 | 
			
		||||
#define RPL_WHOISCHANNELS		"319"
 | 
			
		||||
#define RPL_WHOISCHANNELS_MSG		RPL_WHOISCHANNELS" %s %s :"
 | 
			
		||||
 | 
			
		||||
#define RPL_CHANNELMODEIS		"324"
 | 
			
		||||
#define RPL_CHANNELMODEIS_MSG		RPL_CHANNELMODEIS" %s %s +%s"
 | 
			
		||||
 | 
			
		||||
#define RPL_NOTOPIC			"331"
 | 
			
		||||
#define RPL_NOTOPIC_MSG			RPL_NOTOPIC" %s %s :No topic is set"
 | 
			
		||||
 | 
			
		||||
#define RPL_TOPIC			"332"
 | 
			
		||||
#define RPL_TOPIC_MSG			RPL_TOPIC" %s %s :%s"
 | 
			
		||||
 | 
			
		||||
#define RPL_VERSION			"351"
 | 
			
		||||
#define RPL_VERSION_MSG			RPL_VERSION" %s "PACKAGE"-"VERSION".%s %s :%s"
 | 
			
		||||
 | 
			
		||||
#define RPL_WHOREPLY			"352"
 | 
			
		||||
#define RPL_WHOREPLY_MSG		RPL_WHOREPLY" %s %s %s %s %s %s %s :%d %s"
 | 
			
		||||
 | 
			
		||||
#define RPL_NAMREPLY			"353"
 | 
			
		||||
#define RPL_NAMREPLY_MSG		RPL_NAMREPLY" %s %s %s :"
 | 
			
		||||
 | 
			
		||||
#define RPL_LINKS			"364"
 | 
			
		||||
#define RPL_LINKS_MSG			RPL_LINKS" %s %s %s :%d %s"
 | 
			
		||||
 | 
			
		||||
#define RPL_ENDOFLINKS			"365"
 | 
			
		||||
#define RPL_ENDOFLINKS_MSG		RPL_ENDOFLINKS" %s %s :End of LINKS list"
 | 
			
		||||
 | 
			
		||||
#define RPL_ENDOFNAMES			"366"
 | 
			
		||||
#define RPL_ENDOFNAMES_MSG		RPL_ENDOFNAMES" %s %s :End of NAMES list"
 | 
			
		||||
 | 
			
		||||
#define RPL_YOUREOPER			"381"
 | 
			
		||||
#define RPL_YOUREOPER_MSG		RPL_YOUREOPER" %s :You are now an IRC Operator"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define ERR_NOSUCHNICK			"401"
 | 
			
		||||
#define ERR_NOSUCHNICK_MSG		ERR_NOSUCHNICK" %s %s :No such nick or channel name"
 | 
			
		||||
 | 
			
		||||
#define ERR_NOSUCHSERVER		"402"
 | 
			
		||||
#define ERR_NOSUCHSERVER_MSG		ERR_NOSUCHSERVER" %s %s :No such server"
 | 
			
		||||
 | 
			
		||||
#define ERR_NOSUCHCHANNEL		"403"
 | 
			
		||||
#define ERR_NOSUCHCHANNEL_MSG		ERR_NOSUCHCHANNEL" %s %s :No such channel"
 | 
			
		||||
 | 
			
		||||
#define ERR_CANNOTSENDTOCHAN		"404"
 | 
			
		||||
#define ERR_CANNOTSENDTOCHAN_MSG	ERR_CANNOTSENDTOCHAN" %s %s :Cannot send to channel"
 | 
			
		||||
 | 
			
		||||
#define ERR_NOORIGIN			"409"
 | 
			
		||||
#define ERR_NOORIGIN_MSG		ERR_NOORIGIN" %s :No origin specified"
 | 
			
		||||
 | 
			
		||||
#define ERR_NORECIPIENT			"411"
 | 
			
		||||
#define ERR_NORECIPIENT_MSG		ERR_NORECIPIENT" %s :No receipient given (%s)"
 | 
			
		||||
 | 
			
		||||
#define ERR_NOTEXTTOSEND		"412"
 | 
			
		||||
#define ERR_NOTEXTTOSEND_MSG		ERR_NOTEXTTOSEND" %s :No text to send"
 | 
			
		||||
 | 
			
		||||
#define ERR_UNKNOWNCOMMAND		"421"
 | 
			
		||||
#define ERR_UNKNOWNCOMMAND_MSG		ERR_UNKNOWNCOMMAND" %s %s :Unknown command"
 | 
			
		||||
 | 
			
		||||
#define ERR_NOMOTD			"422"
 | 
			
		||||
#define ERR_NOMOTD_MSG			ERR_NOMOTD" %s :MOTD file is missing"
 | 
			
		||||
 | 
			
		||||
#define ERR_ERRONEUSNICKNAME		"432"
 | 
			
		||||
#define ERR_ERRONEUSNICKNAME_MSG	ERR_ERRONEUSNICKNAME" %s %s :Erroneous nickname"
 | 
			
		||||
 | 
			
		||||
#define ERR_NICKNAMEINUSE		"433"
 | 
			
		||||
#define ERR_NICKNAMEINUSE_MSG		ERR_NICKNAMEINUSE" %s %s :Nickname already in use"
 | 
			
		||||
 | 
			
		||||
#define ERR_NOTONCHANNEL		"442"
 | 
			
		||||
#define ERR_NOTONCHANNEL_MSG		ERR_NOTONCHANNEL" %s %s :You are not on that channel"
 | 
			
		||||
 | 
			
		||||
#define ERR_NOTREGISTERED		"451"
 | 
			
		||||
#define ERR_NOTREGISTERED_MSG		ERR_NOTREGISTERED" %s :Connection not registered"
 | 
			
		||||
#define ERR_NOTREGISTEREDSERVER_MSG	ERR_NOTREGISTERED" %s :Connection not registered as server link"
 | 
			
		||||
 | 
			
		||||
#define ERR_NEEDMOREPARAMS		"461"
 | 
			
		||||
#define ERR_NEEDMOREPARAMS_MSG		ERR_NEEDMOREPARAMS" %s %s :Syntax error"
 | 
			
		||||
 | 
			
		||||
#define ERR_ALREADYREGISTRED		"462"
 | 
			
		||||
#define ERR_ALREADYREGISTRED_MSG	ERR_ALREADYREGISTRED" %s :Connection already registered"
 | 
			
		||||
 | 
			
		||||
#define ERR_PASSWDMISMATCH		"464"
 | 
			
		||||
#define ERR_PASSWDMISMATCH_MSG		ERR_PASSWDMISMATCH" %s: Invalid password"
 | 
			
		||||
 | 
			
		||||
#define ERR_NOPRIVILEGES		"481"
 | 
			
		||||
#define ERR_NOPRIVILEGES_MSG		ERR_NOPRIVILEGES" %s :Permission denied"
 | 
			
		||||
 | 
			
		||||
#define ERR_CHANOPRIVSNEEDED		"482"
 | 
			
		||||
#define ERR_CHANOPRIVSNEEDED_MSG	ERR_CHANOPRIVSNEEDED" %s %s :You are not channel operator"
 | 
			
		||||
 | 
			
		||||
#define ERR_RESTRICTED			"484"
 | 
			
		||||
#define ERR_RESTRICTED_MSG		ERR_RESTRICTED" %s :Your connection is restricted"
 | 
			
		||||
 | 
			
		||||
#define ERR_NOOPERHOST			"491"
 | 
			
		||||
#define ERR_NOOPERHOST_MSG		ERR_NOOPERHOST" %s :Not configured for your host"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define ERR_UMODEUNKNOWNFLAG		"501"
 | 
			
		||||
#define ERR_UMODEUNKNOWNFLAG_MSG	ERR_UMODEUNKNOWNFLAG" %s :Unknown mode"
 | 
			
		||||
#define ERR_UMODEUNKNOWNFLAG2_MSG	ERR_UMODEUNKNOWNFLAG" %s :Unknown mode \"%c%c\""
 | 
			
		||||
 | 
			
		||||
#define ERR_USERSDONTMATCH		"502"
 | 
			
		||||
#define ERR_USERSDONTMATCH_MSG		ERR_USERSDONTMATCH" %s :Can't set/get mode for other users"
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
#define RPL_STATSLINKINFOZIP_MSG	"211 %s %s %d %ld %ld/%ld %ld %ld/%ld :%ld"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -1,72 +1,84 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: ngircd.c,v 1.41 2002/03/31 13:20:42 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * ngircd.c: Hier beginnt alles ;-)
 | 
			
		||||
 * Main program -- main()
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: ngircd.c,v 1.76.2.1 2003/07/18 20:50:05 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <pwd.h>
 | 
			
		||||
#include <grp.h>
 | 
			
		||||
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "conf.h"
 | 
			
		||||
#include "cvs-version.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "irc.h"
 | 
			
		||||
#include "lists.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
#include "irc.h"
 | 
			
		||||
 | 
			
		||||
#ifdef RENDEZVOUS
 | 
			
		||||
#include "rendezvous.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Initialize_Signal_Handler( VOID );
 | 
			
		||||
LOCAL VOID Signal_Handler( INT Signal );
 | 
			
		||||
LOCAL VOID Initialize_Signal_Handler PARAMS(( VOID ));
 | 
			
		||||
LOCAL VOID Signal_Handler PARAMS(( INT Signal ));
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Initialize_Listen_Ports( VOID );
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Show_Version( VOID );
 | 
			
		||||
LOCAL VOID Show_Help( VOID );
 | 
			
		||||
LOCAL VOID Show_Version PARAMS(( VOID ));
 | 
			
		||||
LOCAL VOID Show_Help PARAMS(( VOID ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL int main( int argc, const char *argv[] )
 | 
			
		||||
GLOBAL int
 | 
			
		||||
main( int argc, const char *argv[] )
 | 
			
		||||
{
 | 
			
		||||
	struct passwd *pwd;
 | 
			
		||||
	struct group *grp;
 | 
			
		||||
	BOOLEAN ok, configtest = FALSE;
 | 
			
		||||
	INT32 pid, n;
 | 
			
		||||
	LONG pid, n;
 | 
			
		||||
	INT i;
 | 
			
		||||
 | 
			
		||||
	NGIRCd_Restart = FALSE;
 | 
			
		||||
	NGIRCd_Quit = FALSE;
 | 
			
		||||
	NGIRCd_NoDaemon = FALSE;
 | 
			
		||||
	NGIRCd_Passive = FALSE;
 | 
			
		||||
	umask( 0077 );
 | 
			
		||||
 | 
			
		||||
	NGIRCd_SignalQuit = NGIRCd_SignalRestart = NGIRCd_SignalRehash = FALSE;
 | 
			
		||||
	NGIRCd_NoDaemon = NGIRCd_Passive = FALSE;
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	NGIRCd_Debug = FALSE;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SNIFFER
 | 
			
		||||
	NGIRCd_Sniffer = FALSE;
 | 
			
		||||
#endif
 | 
			
		||||
	strcpy( NGIRCd_ConfFile, CONFIG_FILE );
 | 
			
		||||
	strlcpy( NGIRCd_ConfFile, SYSCONFDIR, sizeof( NGIRCd_ConfFile ));
 | 
			
		||||
	strlcat( NGIRCd_ConfFile, CONFIG_FILE, sizeof( NGIRCd_ConfFile ));
 | 
			
		||||
 | 
			
		||||
	/* Kommandozeile parsen */
 | 
			
		||||
	for( i = 1; i < argc; i++ )
 | 
			
		||||
@@ -80,11 +92,10 @@ GLOBAL int main( int argc, const char *argv[] )
 | 
			
		||||
			{
 | 
			
		||||
				if( i + 1 < argc )
 | 
			
		||||
				{
 | 
			
		||||
					/* Ok, danach kommt noch ein Parameter */
 | 
			
		||||
					strncpy( NGIRCd_ConfFile, argv[i + 1], FNAME_LEN - 1 );
 | 
			
		||||
					NGIRCd_ConfFile[FNAME_LEN - 1] = '\0';
 | 
			
		||||
					/* Ok, there's an parameter left */
 | 
			
		||||
					strlcpy( NGIRCd_ConfFile, argv[i + 1], sizeof( NGIRCd_ConfFile ));
 | 
			
		||||
 | 
			
		||||
					/* zum uebernaechsten Parameter */
 | 
			
		||||
					/* next parameter */
 | 
			
		||||
					i++; ok = TRUE;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
@@ -133,7 +144,7 @@ GLOBAL int main( int argc, const char *argv[] )
 | 
			
		||||
		{
 | 
			
		||||
			/* Kurze Option */
 | 
			
		||||
			
 | 
			
		||||
			for( n = 1; n < (INT32)strlen( argv[i] ); n++ )
 | 
			
		||||
			for( n = 1; n < (LONG)strlen( argv[i] ); n++ )
 | 
			
		||||
			{
 | 
			
		||||
				ok = FALSE;
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
@@ -147,12 +158,11 @@ GLOBAL int main( int argc, const char *argv[] )
 | 
			
		||||
				{
 | 
			
		||||
					if(( ! argv[i][n + 1] ) && ( i + 1 < argc ))
 | 
			
		||||
					{
 | 
			
		||||
						/* Ok, danach kommt ein Leerzeichen */
 | 
			
		||||
						strncpy( NGIRCd_ConfFile, argv[i + 1], FNAME_LEN - 1 );
 | 
			
		||||
						NGIRCd_ConfFile[FNAME_LEN - 1] = '\0';
 | 
			
		||||
						/* Ok, next character is a blank */
 | 
			
		||||
						strlcpy( NGIRCd_ConfFile, argv[i + 1], sizeof( NGIRCd_ConfFile ));
 | 
			
		||||
 | 
			
		||||
						/* zum uebernaechsten Parameter */
 | 
			
		||||
						i++; n = strlen( argv[i] );
 | 
			
		||||
						/* go to the following parameter */
 | 
			
		||||
						i++; n = (LONG)strlen( argv[i] );
 | 
			
		||||
						ok = TRUE;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
@@ -176,8 +186,8 @@ GLOBAL int main( int argc, const char *argv[] )
 | 
			
		||||
 | 
			
		||||
				if( ! ok )
 | 
			
		||||
				{
 | 
			
		||||
					printf( PACKAGE": invalid option \"-%c\"!\n", argv[i][n] );
 | 
			
		||||
					puts( "Try \""PACKAGE" --help\" for more information." );
 | 
			
		||||
					printf( "%s: invalid option \"-%c\"!\n", PACKAGE_NAME, argv[i][n] );
 | 
			
		||||
					printf( "Try \"%s --help\" for more information.\n", PACKAGE_NAME );
 | 
			
		||||
					exit( 1 );
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
@@ -185,8 +195,8 @@ GLOBAL int main( int argc, const char *argv[] )
 | 
			
		||||
		}
 | 
			
		||||
		if( ! ok )
 | 
			
		||||
		{
 | 
			
		||||
			printf( PACKAGE": invalid option \"%s\"!\n", argv[i] );
 | 
			
		||||
			puts( "Try \""PACKAGE" --help\" for more information." );
 | 
			
		||||
			printf( "%s: invalid option \"%s\"!\n", PACKAGE_NAME, argv[i] );
 | 
			
		||||
			printf( "Try \"%s --help\" for more information.\n", PACKAGE_NAME );
 | 
			
		||||
			exit( 1 );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -197,7 +207,11 @@ GLOBAL int main( int argc, const char *argv[] )
 | 
			
		||||
	if( NGIRCd_Debug ) strcpy( NGIRCd_DebugLevel, "1" );
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef SNIFFER
 | 
			
		||||
	if( NGIRCd_Sniffer ) strcpy( NGIRCd_DebugLevel, "2" );
 | 
			
		||||
	if( NGIRCd_Sniffer )
 | 
			
		||||
	{
 | 
			
		||||
		NGIRCd_Debug = TRUE;
 | 
			
		||||
		strcpy( NGIRCd_DebugLevel, "2" );
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Soll nur die Konfigurations ueberprueft und ausgegeben werden? */
 | 
			
		||||
@@ -207,7 +221,7 @@ GLOBAL int main( int argc, const char *argv[] )
 | 
			
		||||
		exit( Conf_Test( ));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	while( ! NGIRCd_Quit )
 | 
			
		||||
	while( ! NGIRCd_SignalQuit )
 | 
			
		||||
	{
 | 
			
		||||
		/* In der Regel wird ein Sub-Prozess ge-fork()'t, der
 | 
			
		||||
		 * nicht mehr mit dem Terminal verbunden ist. Mit der
 | 
			
		||||
@@ -216,7 +230,7 @@ GLOBAL int main( int argc, const char *argv[] )
 | 
			
		||||
		if( ! NGIRCd_NoDaemon )
 | 
			
		||||
		{
 | 
			
		||||
			/* Daemon im Hintergrund erzeugen */
 | 
			
		||||
			pid = (INT32)fork( );
 | 
			
		||||
			pid = (LONG)fork( );
 | 
			
		||||
			if( pid > 0 )
 | 
			
		||||
			{
 | 
			
		||||
				/* "alter" Prozess */
 | 
			
		||||
@@ -225,7 +239,7 @@ GLOBAL int main( int argc, const char *argv[] )
 | 
			
		||||
			if( pid < 0 )
 | 
			
		||||
			{
 | 
			
		||||
				/* Fehler */
 | 
			
		||||
				printf( PACKAGE": Can't fork: %s!\nFatal error, exiting now ...", strerror( errno ));
 | 
			
		||||
				printf( "%s: Can't fork: %s!\nFatal error, exiting now ...\n", PACKAGE_NAME, strerror( errno ));
 | 
			
		||||
				exit( 1 );
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@@ -237,14 +251,20 @@ GLOBAL int main( int argc, const char *argv[] )
 | 
			
		||||
		/* Globale Variablen initialisieren */
 | 
			
		||||
		NGIRCd_Start = time( NULL );
 | 
			
		||||
		(VOID)strftime( NGIRCd_StartStr, 64, "%a %b %d %Y at %H:%M:%S (%Z)", localtime( &NGIRCd_Start ));
 | 
			
		||||
		NGIRCd_Restart = FALSE;
 | 
			
		||||
		NGIRCd_Quit = FALSE;
 | 
			
		||||
		NGIRCd_SignalRehash = FALSE;
 | 
			
		||||
		NGIRCd_SignalRestart = FALSE;
 | 
			
		||||
		NGIRCd_SignalQuit = FALSE;
 | 
			
		||||
 | 
			
		||||
		/* Module initialisieren */
 | 
			
		||||
		Log_Init( );
 | 
			
		||||
		Resolve_Init( );
 | 
			
		||||
		Conf_Init( );
 | 
			
		||||
		Lists_Init( );
 | 
			
		||||
		Channel_Init( );
 | 
			
		||||
		Client_Init( );
 | 
			
		||||
#ifdef RENDEZVOUS
 | 
			
		||||
		Rendezvous_Init( );
 | 
			
		||||
#endif
 | 
			
		||||
		Conn_Init( );
 | 
			
		||||
 | 
			
		||||
		/* Wenn als root ausgefuehrt und eine andere UID
 | 
			
		||||
@@ -262,28 +282,57 @@ GLOBAL int main( int argc, const char *argv[] )
 | 
			
		||||
				if( setuid( Conf_UID ) != 0 ) Log( LOG_ERR, "Can't change User-ID to %u: %s", Conf_UID, strerror( errno ));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		Log( LOG_INFO, "Running as user %ld, group %ld.", (INT32)getuid( ), (INT32)getgid( ));
 | 
			
		||||
		
 | 
			
		||||
		/* User, Gruppe und Prozess-ID des Daemon ausgeben */
 | 
			
		||||
		pwd = getpwuid( getuid( )); grp = getgrgid( getgid( ));
 | 
			
		||||
		Log( LOG_INFO, "Running as user %s(%ld), group %s(%ld), with PID %ld.", pwd ? pwd->pw_name : "unknown", (LONG)getuid( ), grp ? grp->gr_name : "unknown", (LONG)getgid( ), (LONG)getpid( ));
 | 
			
		||||
 | 
			
		||||
		/* stderr in "Error-File" umlenken */
 | 
			
		||||
		Log_InitErrorfile( );
 | 
			
		||||
 | 
			
		||||
		/* Signal-Handler initialisieren */
 | 
			
		||||
		Initialize_Signal_Handler( );
 | 
			
		||||
 | 
			
		||||
		/* Listen-Ports initialisieren */
 | 
			
		||||
		Initialize_Listen_Ports( );
 | 
			
		||||
		/* Protokoll- und Server-Identifikation erzeugen. Die vom ngIRCd
 | 
			
		||||
		 * beim PASS-Befehl verwendete Syntax sowie die erweiterten Flags
 | 
			
		||||
		 * sind in doc/Protocol.txt beschrieben. */
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
		sprintf( NGIRCd_ProtoID, "%s%s %s|%s:%s", PROTOVER, PROTOIRCPLUS, PACKAGE_NAME, PACKAGE_VERSION, IRCPLUSFLAGS );
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
		strcat( NGIRCd_ProtoID, "Z" );
 | 
			
		||||
#endif
 | 
			
		||||
		if( Conf_OperCanMode ) strcat( NGIRCd_ProtoID, "o" );
 | 
			
		||||
#else
 | 
			
		||||
		sprintf( NGIRCd_ProtoID, "%s%s %s|%s", PROTOVER, PROTOIRC, PACKAGE_NAME, PACKAGE_VERSION );
 | 
			
		||||
#endif
 | 
			
		||||
		strcat( NGIRCd_ProtoID, " P" );
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
		strcat( NGIRCd_ProtoID, "Z" );
 | 
			
		||||
#endif
 | 
			
		||||
		Log( LOG_DEBUG, "Protocol and server ID is \"%s\".", NGIRCd_ProtoID );
 | 
			
		||||
 | 
			
		||||
		/* Hauptschleife */
 | 
			
		||||
		while( TRUE )
 | 
			
		||||
		/* Vordefinierte Channels anlegen */
 | 
			
		||||
		Channel_InitPredefined( );
 | 
			
		||||
 | 
			
		||||
		/* Listen-Ports initialisieren */
 | 
			
		||||
		if( Conn_InitListeners( ) < 1 )
 | 
			
		||||
		{
 | 
			
		||||
			if( NGIRCd_Quit || NGIRCd_Restart ) break;
 | 
			
		||||
			Conn_Handler( 5 );
 | 
			
		||||
			Log( LOG_ALERT, "Server isn't listening on a single port!" );
 | 
			
		||||
			Log( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME );
 | 
			
		||||
			exit( 1 );
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		/* Hauptschleife */
 | 
			
		||||
		Conn_Handler( );
 | 
			
		||||
 | 
			
		||||
		/* Alles abmelden */
 | 
			
		||||
		Conn_Exit( );
 | 
			
		||||
#ifdef RENDEZVOUS
 | 
			
		||||
		Rendezvous_Exit( );
 | 
			
		||||
#endif
 | 
			
		||||
		Client_Exit( );
 | 
			
		||||
		Channel_Exit( );
 | 
			
		||||
		Conf_Exit( );
 | 
			
		||||
		Lists_Exit( );
 | 
			
		||||
		Log_Exit( );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -291,18 +340,24 @@ GLOBAL int main( int argc, const char *argv[] )
 | 
			
		||||
} /* main */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *NGIRCd_Version( VOID )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
NGIRCd_Version( VOID )
 | 
			
		||||
{
 | 
			
		||||
	STATIC CHAR version[126];
 | 
			
		||||
 | 
			
		||||
	sprintf( version, PACKAGE" version "VERSION"-%s", NGIRCd_VersionAddition( ));
 | 
			
		||||
	
 | 
			
		||||
#ifdef CVSDATE
 | 
			
		||||
	sprintf( version, "%s %s(%s)-%s", PACKAGE_NAME, PACKAGE_VERSION, CVSDATE, NGIRCd_VersionAddition( ));
 | 
			
		||||
#else
 | 
			
		||||
	sprintf( version, "%s %s-%s", PACKAGE_NAME, PACKAGE_VERSION, NGIRCd_VersionAddition( ));
 | 
			
		||||
#endif
 | 
			
		||||
	return version;
 | 
			
		||||
} /* NGIRCd_Version */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *NGIRCd_VersionAddition( VOID )
 | 
			
		||||
GLOBAL CHAR *
 | 
			
		||||
NGIRCd_VersionAddition( VOID )
 | 
			
		||||
{
 | 
			
		||||
	STATIC CHAR txt[64];
 | 
			
		||||
	STATIC CHAR txt[200];
 | 
			
		||||
 | 
			
		||||
	strcpy( txt, "" );
 | 
			
		||||
 | 
			
		||||
@@ -310,9 +365,17 @@ GLOBAL CHAR *NGIRCd_VersionAddition( VOID )
 | 
			
		||||
	if( txt[0] ) strcat( txt, "+" );
 | 
			
		||||
	strcat( txt, "SYSLOG" );
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef STRICT_RFC
 | 
			
		||||
#ifdef USE_ZLIB
 | 
			
		||||
	if( txt[0] ) strcat( txt, "+" );
 | 
			
		||||
	strcat( txt, "RFC" );
 | 
			
		||||
	strcat( txt, "ZLIB" );
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef USE_TCPWRAP
 | 
			
		||||
	if( txt[0] ) strcat( txt, "+" );
 | 
			
		||||
	strcat( txt, "TCPWRAP" );
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef RENDEZVOUS
 | 
			
		||||
	if( txt[0] ) strcat( txt, "+" );
 | 
			
		||||
	strcat( txt, "RENDEZVOUS" );
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	if( txt[0] ) strcat( txt, "+" );
 | 
			
		||||
@@ -322,15 +385,69 @@ GLOBAL CHAR *NGIRCd_VersionAddition( VOID )
 | 
			
		||||
	if( txt[0] ) strcat( txt, "+" );
 | 
			
		||||
	strcat( txt, "SNIFFER" );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if( txt[0] ) strcat( txt, "-" );
 | 
			
		||||
	strcat( txt, TARGET_CPU"/"TARGET_VENDOR"/"TARGET_OS );
 | 
			
		||||
#ifdef STRICT_RFC
 | 
			
		||||
	if( txt[0] ) strcat( txt, "+" );
 | 
			
		||||
	strcat( txt, "RFC" );
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
	if( txt[0] ) strcat( txt, "+" );
 | 
			
		||||
	strcat( txt, "IRCPLUS" );
 | 
			
		||||
#endif
 | 
			
		||||
	
 | 
			
		||||
	if( txt[0] ) strlcat( txt, "-", sizeof( txt ));
 | 
			
		||||
	strlcat( txt, TARGET_CPU, sizeof( txt ));
 | 
			
		||||
	strlcat( txt, "/", sizeof( txt ));
 | 
			
		||||
	strlcat( txt, TARGET_VENDOR, sizeof( txt ));
 | 
			
		||||
	strlcat( txt, "/", sizeof( txt ));
 | 
			
		||||
	strlcat( txt, TARGET_OS, sizeof( txt ));
 | 
			
		||||
 | 
			
		||||
	return txt;
 | 
			
		||||
} /* NGIRCd_VersionAddition */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Initialize_Signal_Handler( VOID )
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
NGIRCd_Rehash( VOID )
 | 
			
		||||
{
 | 
			
		||||
	CHAR old_name[CLIENT_ID_LEN];
 | 
			
		||||
 | 
			
		||||
	Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" );
 | 
			
		||||
	NGIRCd_SignalRehash = FALSE;
 | 
			
		||||
 | 
			
		||||
	/* Alle Listen-Sockets schliessen */
 | 
			
		||||
	Conn_ExitListeners( );
 | 
			
		||||
 | 
			
		||||
	/* Alten Server-Namen merken */
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	assert( sizeof( old_name ) == sizeof( Conf_ServerName ));
 | 
			
		||||
#endif
 | 
			
		||||
	strcpy( old_name, Conf_ServerName );
 | 
			
		||||
 | 
			
		||||
	/* Konfiguration neu lesen ... */
 | 
			
		||||
	Conf_Rehash( );
 | 
			
		||||
 | 
			
		||||
	/* Alten Server-Namen wiederherstellen: dieser
 | 
			
		||||
	 * kann nicht zur Laufzeit geaendert werden ... */
 | 
			
		||||
	if( strcmp( old_name, Conf_ServerName ) != 0 )
 | 
			
		||||
	{
 | 
			
		||||
		strcpy( Conf_ServerName, old_name );
 | 
			
		||||
		Log( LOG_ERR, "Can't change \"ServerName\" on runtime! Ignored new name." );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* neue pre-defined Channel anlegen: */
 | 
			
		||||
	Channel_InitPredefined( );
 | 
			
		||||
	
 | 
			
		||||
	/* Listen-Sockets neu anlegen: */
 | 
			
		||||
	Conn_InitListeners( );
 | 
			
		||||
 | 
			
		||||
	/* Sync configuration with established connections */
 | 
			
		||||
	Conn_SyncServerStruct( );
 | 
			
		||||
 | 
			
		||||
	Log( LOG_NOTICE|LOG_snotice, "Re-reading of configuration done." );
 | 
			
		||||
} /* NGIRCd_Rehash */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID
 | 
			
		||||
Initialize_Signal_Handler( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Signal-Handler initialisieren: einige Signale
 | 
			
		||||
	 * werden ignoriert, andere speziell behandelt. */
 | 
			
		||||
@@ -376,7 +493,8 @@ LOCAL VOID Initialize_Signal_Handler( VOID )
 | 
			
		||||
} /* Initialize_Signal_Handler */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Signal_Handler( INT Signal )
 | 
			
		||||
LOCAL VOID
 | 
			
		||||
Signal_Handler( INT Signal )
 | 
			
		||||
{
 | 
			
		||||
	/* Signal-Handler. Dieser wird aufgerufen, wenn eines der Signale eintrifft,
 | 
			
		||||
	 * fuer das wir uns registriert haben (vgl. Initialize_Signal_Handler). Die
 | 
			
		||||
@@ -388,66 +506,44 @@ LOCAL VOID Signal_Handler( INT Signal )
 | 
			
		||||
		case SIGINT:
 | 
			
		||||
		case SIGQUIT:
 | 
			
		||||
			/* wir soll(t)en uns wohl beenden ... */
 | 
			
		||||
			if( Signal == SIGTERM ) Log( LOG_WARNING, "Got TERM signal, terminating now ..." );
 | 
			
		||||
			else if( Signal == SIGINT ) Log( LOG_WARNING, "Got INT signal, terminating now ..." );
 | 
			
		||||
			else if( Signal == SIGQUIT ) Log( LOG_WARNING, "Got QUIT signal, terminating now ..." );
 | 
			
		||||
			NGIRCd_Quit = TRUE;
 | 
			
		||||
			NGIRCd_SignalQuit = TRUE;
 | 
			
		||||
			break;
 | 
			
		||||
		case SIGHUP:
 | 
			
		||||
			/* neu starten */
 | 
			
		||||
			Log( LOG_WARNING, "Got HUP signal, restarting now ..." );
 | 
			
		||||
			NGIRCd_Restart = TRUE;
 | 
			
		||||
			/* Konfiguration neu einlesen: */
 | 
			
		||||
			NGIRCd_SignalRehash = TRUE;
 | 
			
		||||
			break;
 | 
			
		||||
		case SIGCHLD:
 | 
			
		||||
			/* Child-Prozess wurde beendet. Zombies vermeiden: */
 | 
			
		||||
			while( waitpid( -1, NULL, WNOHANG ) > 0);
 | 
			
		||||
			break;
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
		default:
 | 
			
		||||
			/* unbekanntes bzw. unbehandeltes Signal */
 | 
			
		||||
			Log( LOG_NOTICE, "Got signal %d! Ignored.", Signal );
 | 
			
		||||
			Log( LOG_DEBUG, "Got signal %d! Ignored.", Signal );
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
} /* Signal_Handler */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Initialize_Listen_Ports( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Ports, auf denen der Server Verbindungen entgegennehmen
 | 
			
		||||
	 * soll, initialisieren */
 | 
			
		||||
	
 | 
			
		||||
	UINT created, i;
 | 
			
		||||
 | 
			
		||||
	created = 0;
 | 
			
		||||
	for( i = 0; i < Conf_ListenPorts_Count; i++ )
 | 
			
		||||
	{
 | 
			
		||||
		if( Conn_NewListener( Conf_ListenPorts[i] )) created++;
 | 
			
		||||
		else Log( LOG_ERR, "Can't listen on port %u!", Conf_ListenPorts[i] );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( created < 1 )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_ALERT, "Server isn't listening on a single port!" );
 | 
			
		||||
		Log( LOG_ALERT, PACKAGE" exiting due to fatal errors!" );
 | 
			
		||||
		exit( 1 );
 | 
			
		||||
	}
 | 
			
		||||
} /* Initialize_Listen_Ports */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Show_Version( VOID )
 | 
			
		||||
LOCAL VOID
 | 
			
		||||
Show_Version( VOID )
 | 
			
		||||
{
 | 
			
		||||
	puts( NGIRCd_Version( ));
 | 
			
		||||
	puts( "Copyright (c)2001,2002 by Alexander Barton (alex@barton.de).\n" );
 | 
			
		||||
	puts( "Copyright (c)2001-2003 by Alexander Barton (<alex@barton.de>)." );
 | 
			
		||||
	puts( "Homepage: <http://arthur.ath.cx/~alex/ngircd/>\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." );
 | 
			
		||||
} /* Show_Version */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Show_Help( VOID )
 | 
			
		||||
LOCAL VOID
 | 
			
		||||
Show_Help( VOID )
 | 
			
		||||
{
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	puts( "  -d, --debug        log extra debug messages" );
 | 
			
		||||
#endif
 | 
			
		||||
	puts( "  -f, --config <f>   use file <f> as configuration file" );
 | 
			
		||||
        puts( "  -n, --nodaemon     don't fork and don't detatch from controlling terminal" );
 | 
			
		||||
        puts( "  -n, --nodaemon     don't fork and don't detach from controlling terminal" );
 | 
			
		||||
        puts( "  -p, --passive      disable automatic connections to other servers" );
 | 
			
		||||
#ifdef SNIFFER
 | 
			
		||||
	puts( "  -s, --sniffer      enable network sniffer and display all IRC traffic" );
 | 
			
		||||
 
 | 
			
		||||
@@ -2,16 +2,15 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: ngircd.h,v 1.12 2002/03/27 16:40:31 alex Exp $
 | 
			
		||||
 * $Id: ngircd.h,v 1.19 2002/12/26 16:48:14 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * ngircd.h: Prototypen aus dem "Haupt-Modul"
 | 
			
		||||
 * Prototypes of the "main module".
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -38,15 +37,21 @@ GLOBAL BOOLEAN NGIRCd_NoDaemon;		/* nicht im Hintergrund laufen */
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN NGIRCd_Passive;		/* nicht zu anderen Servern connecten */
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN NGIRCd_Quit;		/* TRUE: ngIRCd beenden */
 | 
			
		||||
GLOBAL BOOLEAN NGIRCd_Restart;		/* TRUE: neu starten */
 | 
			
		||||
GLOBAL BOOLEAN NGIRCd_SignalQuit;	/* TRUE: quit server*/
 | 
			
		||||
GLOBAL BOOLEAN NGIRCd_SignalRestart;	/* TRUE: restart server */
 | 
			
		||||
GLOBAL BOOLEAN NGIRCd_SignalRehash;	/* TRUE: reload configuration */
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR NGIRCd_DebugLevel[2];	/* Debug-Level fuer IRC_VERSION() */
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR NGIRCd_ConfFile[FNAME_LEN];	/* Konfigurationsdatei */
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *NGIRCd_Version( VOID );
 | 
			
		||||
GLOBAL CHAR *NGIRCd_VersionAddition( VOID );
 | 
			
		||||
GLOBAL CHAR NGIRCd_ProtoID[COMMAND_LEN];/* Protokoll- und Server-Identifikation */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *NGIRCd_Version PARAMS((VOID ));
 | 
			
		||||
GLOBAL CHAR *NGIRCd_VersionAddition PARAMS((VOID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID NGIRCd_Rehash PARAMS(( VOID ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -2,21 +2,20 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: parse.c,v 1.31 2002/03/25 17:13:46 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * parse.c: Parsen der Client-Anfragen
 | 
			
		||||
 * IRC command parser and validator
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: parse.c,v 1.59 2003/01/15 13:49:20 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
@@ -24,16 +23,10 @@
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "ngircd.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "irc.h"
 | 
			
		||||
#include "irc-channel.h"
 | 
			
		||||
#include "irc-login.h"
 | 
			
		||||
#include "irc-mode.h"
 | 
			
		||||
#include "irc-oper.h"
 | 
			
		||||
#include "irc-server.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
#include "conn-func.h"
 | 
			
		||||
#include "client.h"
 | 
			
		||||
#include "channel.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
#include "messages.h"
 | 
			
		||||
#include "tool.h"
 | 
			
		||||
@@ -41,19 +34,89 @@
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "parse.h"
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include "irc.h"
 | 
			
		||||
#include "irc-channel.h"
 | 
			
		||||
#include "irc-info.h"
 | 
			
		||||
#include "irc-login.h"
 | 
			
		||||
#include "irc-mode.h"
 | 
			
		||||
#include "irc-op.h"
 | 
			
		||||
#include "irc-oper.h"
 | 
			
		||||
#include "irc-server.h"
 | 
			
		||||
#include "irc-write.h"
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Init_Request( REQUEST *Req );
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Parse_Error( CONN_ID Idx, CHAR *Error );
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Validate_Prefix( REQUEST *Req );
 | 
			
		||||
LOCAL BOOLEAN Validate_Command( REQUEST *Req );
 | 
			
		||||
LOCAL BOOLEAN Validate_Args( REQUEST *Req );
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *Req );
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
 | 
			
		||||
COMMAND My_Commands[] =
 | 
			
		||||
{
 | 
			
		||||
	{ "ADMIN", IRC_ADMIN, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "AWAY", IRC_AWAY, CLIENT_USER, 0, 0, 0 },
 | 
			
		||||
	{ "CONNECT", IRC_CONNECT, CLIENT_USER, 0, 0, 0 },
 | 
			
		||||
	{ "DIE", IRC_DIE, CLIENT_USER, 0, 0, 0 },
 | 
			
		||||
	{ "DISCONNECT", IRC_DISCONNECT, CLIENT_USER, 0, 0, 0 },
 | 
			
		||||
	{ "ERROR", IRC_ERROR, 0xFFFF, 0, 0, 0 },
 | 
			
		||||
	{ "HELP", IRC_HELP, CLIENT_USER, 0, 0, 0 },
 | 
			
		||||
	{ "INVITE", IRC_INVITE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "ISON", IRC_ISON, CLIENT_USER, 0, 0, 0 },
 | 
			
		||||
	{ "JOIN", IRC_JOIN, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "KICK", IRC_KICK, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "KILL", IRC_KILL, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "LINKS", IRC_LINKS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "LIST", IRC_LIST, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "LUSERS", IRC_LUSERS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "MODE", IRC_MODE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "MOTD", IRC_MOTD, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "NAMES", IRC_NAMES, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "NICK", IRC_NICK, 0xFFFF, 0, 0, 0 },
 | 
			
		||||
	{ "NJOIN", IRC_NJOIN, CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "NOTICE", IRC_NOTICE, 0xFFFF, 0, 0, 0 },
 | 
			
		||||
	{ "OPER", IRC_OPER, CLIENT_USER, 0, 0, 0 },
 | 
			
		||||
	{ "PART", IRC_PART, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "PASS", IRC_PASS, 0xFFFF, 0, 0, 0 },
 | 
			
		||||
	{ "PING", IRC_PING, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "PONG", IRC_PONG, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "PRIVMSG", IRC_PRIVMSG, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "QUIT", IRC_QUIT, 0xFFFF, 0, 0, 0 },
 | 
			
		||||
	{ "REHASH", IRC_REHASH, CLIENT_USER, 0, 0, 0 },
 | 
			
		||||
	{ "RESTART", IRC_RESTART, CLIENT_USER, 0, 0, 0 },
 | 
			
		||||
	{ "SERVER", IRC_SERVER, 0xFFFF, 0, 0, 0 },
 | 
			
		||||
	{ "SQUIT", IRC_SQUIT, CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "STATS", IRC_STATS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "TIME", IRC_TIME, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "TOPIC", IRC_TOPIC, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "TRACE", IRC_TRACE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "USER", IRC_USER, 0xFFFF, 0, 0, 0 },
 | 
			
		||||
	{ "USERHOST", IRC_USERHOST, CLIENT_USER, 0, 0, 0 },
 | 
			
		||||
	{ "VERSION", IRC_VERSION, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "WHO", IRC_WHO, CLIENT_USER, 0, 0, 0 },
 | 
			
		||||
	{ "WHOIS", IRC_WHOIS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
	{ "WHOWAS", IRC_WHOWAS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
#ifdef IRCPLUS
 | 
			
		||||
	{ "CHANINFO", IRC_CHANINFO, CLIENT_SERVER, 0, 0, 0 },
 | 
			
		||||
#endif
 | 
			
		||||
	{ NULL, NULL, 0x0, 0, 0, 0 } /* Ende-Marke */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Init_Request PARAMS(( REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Validate_Prefix PARAMS(( CONN_ID Idx, REQUEST *Req, BOOLEAN *Closed ));
 | 
			
		||||
LOCAL BOOLEAN Validate_Command PARAMS(( CONN_ID Idx, REQUEST *Req, BOOLEAN *Closed ));
 | 
			
		||||
LOCAL BOOLEAN Validate_Args PARAMS(( CONN_ID Idx, REQUEST *Req, BOOLEAN *Closed ));
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Handle_Request PARAMS(( CONN_ID Idx, REQUEST *Req ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL COMMAND *
 | 
			
		||||
Parse_GetCommandStruct( VOID )
 | 
			
		||||
{
 | 
			
		||||
	return My_Commands;
 | 
			
		||||
} /* Parse_GetCommandStruct */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN
 | 
			
		||||
Parse_Request( CONN_ID Idx, CHAR *Request )
 | 
			
		||||
{
 | 
			
		||||
	/* Client-Request parsen. Bei einem schwerwiegenden Fehler wird
 | 
			
		||||
	 * die Verbindung geschlossen und FALSE geliefert.
 | 
			
		||||
@@ -61,6 +124,7 @@ GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
 | 
			
		||||
 | 
			
		||||
	REQUEST req;
 | 
			
		||||
	CHAR *start, *ptr;
 | 
			
		||||
	BOOLEAN closed;
 | 
			
		||||
 | 
			
		||||
	assert( Idx >= 0 );
 | 
			
		||||
	assert( Request != NULL );
 | 
			
		||||
@@ -68,7 +132,7 @@ GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
 | 
			
		||||
#ifdef SNIFFER
 | 
			
		||||
	if( NGIRCd_Sniffer ) Log( LOG_DEBUG, " <- connection %d: '%s'.", Idx, Request );
 | 
			
		||||
#endif
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	Init_Request( &req );
 | 
			
		||||
 | 
			
		||||
	/* Fuehrendes und folgendes "Geraffel" verwerfen */
 | 
			
		||||
@@ -80,7 +144,11 @@ GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
 | 
			
		||||
		/* Prefix vorhanden */
 | 
			
		||||
		req.prefix = Request + 1;
 | 
			
		||||
		ptr = strchr( Request, ' ' );
 | 
			
		||||
		if( ! ptr ) return Parse_Error( Idx, "Prefix without command!?" );
 | 
			
		||||
		if( ! ptr )
 | 
			
		||||
		{
 | 
			
		||||
			Log( LOG_DEBUG, "Connection %d: Parse error: prefix without command!?", Idx );
 | 
			
		||||
			return Conn_WriteStr( Idx, "ERROR :Prefix without command!?" );
 | 
			
		||||
		}
 | 
			
		||||
		*ptr = '\0';
 | 
			
		||||
#ifndef STRICT_RFC
 | 
			
		||||
		/* multiple Leerzeichen als Trenner zwischen
 | 
			
		||||
@@ -91,8 +159,6 @@ GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
 | 
			
		||||
	}
 | 
			
		||||
	else start = Request;
 | 
			
		||||
 | 
			
		||||
	if( ! Validate_Prefix( &req )) return Parse_Error( Idx, "Invalid prefix");
 | 
			
		||||
 | 
			
		||||
	/* Befehl */
 | 
			
		||||
	ptr = strchr( start, ' ' );
 | 
			
		||||
	if( ptr )
 | 
			
		||||
@@ -100,14 +166,12 @@ GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
 | 
			
		||||
		*ptr = '\0';
 | 
			
		||||
#ifndef STRICT_RFC
 | 
			
		||||
		/* multiple Leerzeichen als Trenner vor
 | 
			
		||||
		*Parametertrennern ignorieren */
 | 
			
		||||
		 * Parametern ignorieren */
 | 
			
		||||
		while( *(ptr + 1) == ' ' ) ptr++;
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
	req.command = start;
 | 
			
		||||
 | 
			
		||||
	if( ! Validate_Command( &req )) return Parse_Error( Idx, "Invalid command" );
 | 
			
		||||
 | 
			
		||||
	/* Argumente, Parameter */
 | 
			
		||||
	if( ptr )
 | 
			
		||||
	{
 | 
			
		||||
@@ -135,29 +199,33 @@ GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
 | 
			
		||||
#endif
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			req.argc++;
 | 
			
		||||
 | 
			
		||||
			if( start[0] == ':' ) break;
 | 
			
		||||
			if( req.argc > 14 ) break;
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			if( ptr ) start = ptr + 1;
 | 
			
		||||
			else start = NULL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if( ! Validate_Args( &req )) return Parse_Error( Idx, "Invalid argument(s)" );
 | 
			
		||||
 | 
			
		||||
	/* Daten validieren */
 | 
			
		||||
	if( ! Validate_Prefix( Idx, &req, &closed )) return ! closed;
 | 
			
		||||
	if( ! Validate_Command( Idx, &req, &closed )) return ! closed;
 | 
			
		||||
	if( ! Validate_Args( Idx, &req, &closed )) return ! closed;
 | 
			
		||||
 | 
			
		||||
	return Handle_Request( Idx, &req );
 | 
			
		||||
} /* Parse_Request */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Init_Request( REQUEST *Req )
 | 
			
		||||
LOCAL VOID
 | 
			
		||||
Init_Request( REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	/* Neue Request-Struktur initialisieren */
 | 
			
		||||
 | 
			
		||||
	INT i;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	Req->prefix = NULL;
 | 
			
		||||
@@ -167,48 +235,91 @@ LOCAL VOID Init_Request( REQUEST *Req )
 | 
			
		||||
} /* Init_Request */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Parse_Error( CONN_ID Idx, CHAR *Error )
 | 
			
		||||
LOCAL BOOLEAN
 | 
			
		||||
Validate_Prefix( CONN_ID Idx, REQUEST *Req, BOOLEAN *Closed )
 | 
			
		||||
{
 | 
			
		||||
	/* Fehler beim Parsen. Fehlermeldung an den Client schicken.
 | 
			
		||||
	 * TRUE: Connection wurde durch diese Funktion nicht geschlossen,
 | 
			
		||||
	 * FALSE: Connection wurde terminiert. */
 | 
			
		||||
	
 | 
			
		||||
	CLIENT *client, *c;
 | 
			
		||||
 | 
			
		||||
	assert( Idx >= 0 );
 | 
			
		||||
	assert( Error != NULL );
 | 
			
		||||
 | 
			
		||||
	Log( LOG_DEBUG, "Connection %d: Parse error: %s", Idx, Error );
 | 
			
		||||
	return Conn_WriteStr( Idx, "ERROR :Parse error: %s", Error );
 | 
			
		||||
} /* Parse_Error */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Validate_Prefix( REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
 | 
			
		||||
	*Closed = FALSE;
 | 
			
		||||
 | 
			
		||||
	/* ist ueberhaupt ein Prefix vorhanden? */
 | 
			
		||||
	if( ! Req->prefix ) return TRUE;
 | 
			
		||||
 | 
			
		||||
	/* Client-Struktur der Connection ermitteln */
 | 
			
		||||
	client = Client_GetFromConn( Idx );
 | 
			
		||||
	assert( client != NULL );
 | 
			
		||||
 | 
			
		||||
	/* nur validieren, wenn bereits registrierte Verbindung */
 | 
			
		||||
	if(( Client_Type( client ) != CLIENT_USER ) && ( Client_Type( client ) != CLIENT_SERVER ) && ( Client_Type( client ) != CLIENT_SERVICE ))
 | 
			
		||||
	{
 | 
			
		||||
		/* noch nicht registrierte Verbindung.
 | 
			
		||||
		 * Das Prefix wird ignoriert. */
 | 
			
		||||
		Req->prefix = NULL;
 | 
			
		||||
		return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* pruefen, ob der im Prefix angegebene Client bekannt ist */
 | 
			
		||||
	c = Client_Search( Req->prefix );
 | 
			
		||||
	if( ! c )
 | 
			
		||||
	{
 | 
			
		||||
		/* im Prefix angegebener Client ist nicht bekannt */
 | 
			
		||||
		Log( LOG_ERR, "Invalid prefix \"%s\", client not known (connection %d, command %s)!?", Req->prefix, Idx, Req->command );
 | 
			
		||||
		if( ! Conn_WriteStr( Idx, "ERROR :Invalid prefix \"%s\", client not known!?", Req->prefix )) *Closed = TRUE;
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* pruefen, ob der Client mit dem angegebenen Prefix in Richtung
 | 
			
		||||
	 * des Senders liegt, d.h. sicherstellen, dass das Prefix nicht
 | 
			
		||||
	 * gefaelscht ist */
 | 
			
		||||
	if( Client_NextHop( c ) != client )
 | 
			
		||||
	{
 | 
			
		||||
		/* das angegebene Prefix ist aus dieser Richtung, also
 | 
			
		||||
		 * aus der gegebenen Connection, ungueltig! */
 | 
			
		||||
		Log( LOG_ERR, "Spoofed prefix \"%s\" from \"%s\" (connection %d, command %s)!", Req->prefix, Client_Mask( Client_GetFromConn( Idx )), Idx, Req->command );
 | 
			
		||||
		Conn_Close( Idx, NULL, "Spoofed prefix", TRUE );
 | 
			
		||||
		*Closed = TRUE;
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
} /* Validate_Prefix */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Validate_Command( REQUEST *Req )
 | 
			
		||||
LOCAL BOOLEAN
 | 
			
		||||
Validate_Command( CONN_ID Idx, REQUEST *Req, BOOLEAN *Closed )
 | 
			
		||||
{
 | 
			
		||||
	assert( Idx >= 0 );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
	*Closed = FALSE;
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
} /* Validate_Comman */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Validate_Args( REQUEST *Req )
 | 
			
		||||
LOCAL BOOLEAN
 | 
			
		||||
Validate_Args( CONN_ID Idx, REQUEST *Req, BOOLEAN *Closed )
 | 
			
		||||
{
 | 
			
		||||
	assert( Idx >= 0 );
 | 
			
		||||
	assert( Req != NULL );
 | 
			
		||||
	*Closed = FALSE;
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
} /* Validate_Args */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *Req )
 | 
			
		||||
LOCAL BOOLEAN
 | 
			
		||||
Handle_Request( CONN_ID Idx, REQUEST *Req )
 | 
			
		||||
{
 | 
			
		||||
	/* Client-Request verarbeiten. Bei einem schwerwiegenden Fehler
 | 
			
		||||
	 * wird die Verbindung geschlossen und FALSE geliefert. */
 | 
			
		||||
 | 
			
		||||
	CLIENT *client, *target, *prefix;
 | 
			
		||||
	CHAR str[LINE_LEN];
 | 
			
		||||
	BOOLEAN result;
 | 
			
		||||
	COMMAND *cmd;
 | 
			
		||||
	INT i;
 | 
			
		||||
 | 
			
		||||
	assert( Idx >= 0 );
 | 
			
		||||
@@ -218,86 +329,87 @@ LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *Req )
 | 
			
		||||
	client = Client_GetFromConn( Idx );
 | 
			
		||||
	assert( client != NULL );
 | 
			
		||||
 | 
			
		||||
	/* Statuscode, der geforwarded werden muss? */
 | 
			
		||||
	if(( strlen( Req->command ) == 3 ) && ( atoi( Req->command ) > 100 ))
 | 
			
		||||
	/* Statuscode? */
 | 
			
		||||
	if(( Client_Type( client ) == CLIENT_SERVER ) && ( strlen( Req->command ) == 3 ) && ( atoi( Req->command ) > 100 ))
 | 
			
		||||
	{
 | 
			
		||||
		/* Befehl ist ein Statuscode */
 | 
			
		||||
		/* Command is a status code from an other server */
 | 
			
		||||
 | 
			
		||||
		/* Zielserver ermitteln */
 | 
			
		||||
		if(( Client_Type( client ) == CLIENT_SERVER ) && ( Req->argc > 0 )) target = Client_Search( Req->argv[0] );
 | 
			
		||||
		/* Determine target */
 | 
			
		||||
		if( Req->argc > 0 ) target = Client_Search( Req->argv[0] );
 | 
			
		||||
		else target = NULL;
 | 
			
		||||
		if( ! target )
 | 
			
		||||
		{
 | 
			
		||||
			if( Req->argc > 0 ) Log( LOG_WARNING, "Unknown target for status code: \"%s\"", Req->argv[0] );
 | 
			
		||||
			else Log( LOG_WARNING, "Unknown target for status code!" );
 | 
			
		||||
			/* Status code without target!? */
 | 
			
		||||
			if( Req->argc > 0 ) Log( LOG_WARNING, "Unknown target for status code %s: \"%s\"", Req->command, Req->argv[0] );
 | 
			
		||||
			else Log( LOG_WARNING, "Unknown target for status code %s!", Req->command );
 | 
			
		||||
			return TRUE;
 | 
			
		||||
		}
 | 
			
		||||
		if( target == Client_ThisServer( ))
 | 
			
		||||
		{
 | 
			
		||||
			/* This server is the target, ignore it */
 | 
			
		||||
			Log( LOG_DEBUG, "Ignored status code %s from \"%s\".", Req->command, Client_ID( client ));
 | 
			
		||||
			return TRUE;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Quell-Client ermitteln */
 | 
			
		||||
		/* Determine source */
 | 
			
		||||
		if( ! Req->prefix[0] )
 | 
			
		||||
		{
 | 
			
		||||
			Log( LOG_WARNING, "Got status code without prefix!?" );
 | 
			
		||||
			/* Oops, no prefix!? */
 | 
			
		||||
			Log( LOG_WARNING, "Got status code %s from \"%s\" without prefix!?", Req->command, Client_ID( client ));
 | 
			
		||||
			return TRUE;
 | 
			
		||||
		}
 | 
			
		||||
		else prefix = Client_Search( Req->prefix );
 | 
			
		||||
		if( ! prefix )
 | 
			
		||||
		{
 | 
			
		||||
			Log( LOG_WARNING, "Got status code from unknown source: \"%s\"", Req->prefix );
 | 
			
		||||
			/* Oops, unknown prefix!? */
 | 
			
		||||
			Log( LOG_WARNING, "Got status code %s from unknown source: \"%s\"", Req->command, Req->prefix );
 | 
			
		||||
			return TRUE;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Statuscode weiterleiten */
 | 
			
		||||
		strcpy( str, Req->command );
 | 
			
		||||
		/* Forward status code */
 | 
			
		||||
		strlcpy( str, Req->command, sizeof( str ));
 | 
			
		||||
		for( i = 0; i < Req->argc; i++ )
 | 
			
		||||
		{
 | 
			
		||||
			if( i < Req->argc - 1 ) strcat( str, " " );
 | 
			
		||||
			else strcat( str, " :" );
 | 
			
		||||
			strcat( str, Req->argv[i] );
 | 
			
		||||
			if( i < Req->argc - 1 ) strlcat( str, " ", sizeof( str ));
 | 
			
		||||
			else strlcat( str, " :", sizeof( str ));
 | 
			
		||||
			strlcat( str, Req->argv[i], sizeof( str ));
 | 
			
		||||
		}
 | 
			
		||||
		return IRC_WriteStrClientPrefix( target, prefix, str );
 | 
			
		||||
		return IRC_WriteStrClientPrefix( target, prefix, "%s", str );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( strcasecmp( Req->command, "PASS" ) == 0 ) return IRC_PASS( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "NICK" ) == 0 ) return IRC_NICK( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "USER" ) == 0 ) return IRC_USER( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "SERVER" ) == 0 ) return IRC_SERVER( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "NJOIN" ) == 0 ) return IRC_NJOIN( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "QUIT" ) == 0 ) return IRC_QUIT( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "SQUIT" ) == 0 ) return IRC_SQUIT( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "PING" ) == 0 ) return IRC_PING( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "PONG" ) == 0 ) return IRC_PONG( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "MOTD" ) == 0 ) return IRC_MOTD( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "PRIVMSG" ) == 0 ) return IRC_PRIVMSG( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "NOTICE" ) == 0 ) return IRC_NOTICE( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "MODE" ) == 0 ) return IRC_MODE( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "NAMES" ) == 0 ) return IRC_NAMES( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "ISON" ) == 0 ) return IRC_ISON( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "WHOIS" ) == 0 ) return IRC_WHOIS( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "USERHOST" ) == 0 ) return IRC_USERHOST( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "OPER" ) == 0 ) return IRC_OPER( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "DIE" ) == 0 ) return IRC_DIE( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "RESTART" ) == 0 ) return IRC_RESTART( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "ERROR" ) == 0 ) return IRC_ERROR( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "LUSERS" ) == 0 ) return IRC_LUSERS( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "LINKS" ) == 0 ) return IRC_LINKS( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "JOIN" ) == 0 ) return IRC_JOIN( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "PART" ) == 0 ) return IRC_PART( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "VERSION" ) == 0 ) return IRC_VERSION( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "KILL" ) == 0 ) return IRC_KILL( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "AWAY" ) == 0 ) return IRC_AWAY( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "TOPIC" ) == 0 ) return IRC_TOPIC( client, Req );
 | 
			
		||||
	else if( strcasecmp( Req->command, "WHO" ) == 0 ) return IRC_WHO( client, Req );
 | 
			
		||||
	cmd = My_Commands;
 | 
			
		||||
	while( cmd->name )
 | 
			
		||||
	{
 | 
			
		||||
		/* Befehl suchen */
 | 
			
		||||
		if( strcasecmp( Req->command, cmd->name ) != 0 )
 | 
			
		||||
		{
 | 
			
		||||
			cmd++; continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if( Client_Type( client ) & cmd->type )
 | 
			
		||||
		{
 | 
			
		||||
			/* Command is allowed for this client: call it and count produced bytes */
 | 
			
		||||
			Conn_ResetWCounter( );
 | 
			
		||||
			result = (cmd->function)( client, Req );
 | 
			
		||||
			cmd->bytes += Conn_WCounter( );
 | 
			
		||||
 | 
			
		||||
			/* Adjust counters */
 | 
			
		||||
			if( Client_Type( client ) != CLIENT_SERVER ) cmd->lcount++;
 | 
			
		||||
			else cmd->rcount++;
 | 
			
		||||
 | 
			
		||||
			return result;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			/* Befehl ist fuer diesen Client-Typ nicht erlaubt! */
 | 
			
		||||
			return IRC_WriteStrClient( client, ERR_NOTREGISTERED_MSG, Client_ID( client ));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* Unbekannter Befehl */
 | 
			
		||||
	if( Client_Type( client ) != CLIENT_SERVER ) IRC_WriteStrClient( client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( client ), Req->command );
 | 
			
		||||
	Log( LOG_DEBUG, "Connection %d: Unknown command \"%s\", %d %s,%s prefix.", Client_Conn( client ), Req->command, Req->argc, Req->argc == 1 ? "parameter" : "parameters", Req->prefix ? "" : " no" );
 | 
			
		||||
 | 
			
		||||
	return TRUE;
 | 
			
		||||
	if( Client_Type( client ) != CLIENT_SERVER ) return IRC_WriteStrClient( client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( client ), Req->command );
 | 
			
		||||
	else return TRUE;
 | 
			
		||||
} /* Handle_Request */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,24 +2,21 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: parse.h,v 1.6 2002/03/12 14:37:52 alex Exp $
 | 
			
		||||
 * $Id: parse.h,v 1.10 2003/01/03 22:03:51 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * parse.h: Parsen der Client-Anfragen (Header)
 | 
			
		||||
 * IRC command parser and validator (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __parse_h__
 | 
			
		||||
#define __parse_h__
 | 
			
		||||
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct _REQUEST			/* vgl. RFC 2812, 2.3 */
 | 
			
		||||
{
 | 
			
		||||
@@ -30,7 +27,19 @@ typedef struct _REQUEST			/* vgl. RFC 2812, 2.3 */
 | 
			
		||||
} REQUEST;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request );
 | 
			
		||||
typedef struct _COMMAND
 | 
			
		||||
{
 | 
			
		||||
	CHAR *name;		/* command name */
 | 
			
		||||
	BOOLEAN (*function) PARAMS(( CLIENT *Client, REQUEST *Request ));
 | 
			
		||||
	CLIENT_TYPE type;	/* valid client types (bit mask) */
 | 
			
		||||
	LONG lcount, rcount;	/* number of local and remote calls */
 | 
			
		||||
	LONG bytes;		/* number of bytes created */
 | 
			
		||||
} COMMAND;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Parse_Request PARAMS((CONN_ID Idx, CHAR *Request ));
 | 
			
		||||
 | 
			
		||||
GLOBAL COMMAND *Parse_GetCommandStruct PARAMS(( VOID ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										229
									
								
								src/ngircd/rendezvous.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										229
									
								
								src/ngircd/rendezvous.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,229 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * Rendezvous service registration (using Mach Ports, e.g. Mac OS X)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
#ifdef RENDEZVOUS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: rendezvous.c,v 1.2 2003/03/27 01:24:32 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_MACH_PORT_H
 | 
			
		||||
#include "mach/port.h"
 | 
			
		||||
#include "mach/message.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_DNSSERVICEDISCOVERY_DNSSERVICEDISCOVERY_H
 | 
			
		||||
#include <DNSServiceDiscovery/DNSServiceDiscovery.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "rendezvous.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct _service
 | 
			
		||||
{
 | 
			
		||||
	dns_service_discovery_ref Discovery_Ref;
 | 
			
		||||
	mach_port_t Mach_Port;
 | 
			
		||||
	CHAR Desc[CLIENT_ID_LEN];
 | 
			
		||||
} SERVICE;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrCode, VOID *Context );
 | 
			
		||||
LOCAL VOID Unregister( INT Idx );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define MAX_RENDEZVOUS 1000
 | 
			
		||||
#define MAX_MACH_MSG_SIZE 512
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL SERVICE My_Rendezvous[MAX_RENDEZVOUS];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Rendezvous_Init( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Initialize structures */
 | 
			
		||||
 | 
			
		||||
	INT i;
 | 
			
		||||
 | 
			
		||||
	for( i = 0; i < MAX_RENDEZVOUS; i++ )
 | 
			
		||||
	{
 | 
			
		||||
		My_Rendezvous[i].Discovery_Ref = 0;
 | 
			
		||||
		My_Rendezvous[i].Mach_Port = 0;
 | 
			
		||||
	}
 | 
			
		||||
} /* Rendezvous_Init */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Rendezvous_Exit( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Clean up & exit module */
 | 
			
		||||
 | 
			
		||||
	INT i;
 | 
			
		||||
 | 
			
		||||
	for( i = 0; i < MAX_RENDEZVOUS; i++ )
 | 
			
		||||
	{
 | 
			
		||||
		if( My_Rendezvous[i].Discovery_Ref ) Unregister( i );
 | 
			
		||||
	}
 | 
			
		||||
} /* Rendezvous_Exit */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Rendezvous_Register( CHAR *Name, CHAR *Type, UINT Port )
 | 
			
		||||
{
 | 
			
		||||
	/* Register new service */
 | 
			
		||||
 | 
			
		||||
	INT i;
 | 
			
		||||
 | 
			
		||||
	/* Search free port structure */
 | 
			
		||||
	for( i = 0; i < MAX_RENDEZVOUS; i++ ) if( ! My_Rendezvous[i].Discovery_Ref ) break;
 | 
			
		||||
	if( i >= MAX_RENDEZVOUS )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_ERR, "Can't register \"%s\" with Rendezvous: limit (%d) reached!", Name, MAX_RENDEZVOUS );
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
	strlcpy( My_Rendezvous[i].Desc, Name, sizeof( My_Rendezvous[i].Desc ));
 | 
			
		||||
	
 | 
			
		||||
	/* Register new service */
 | 
			
		||||
	My_Rendezvous[i].Discovery_Ref = DNSServiceRegistrationCreate( Name, Type, "", htonl( Port ), "", Registration_Reply_Handler, My_Rendezvous[i].Desc );
 | 
			
		||||
	if( ! My_Rendezvous[i].Discovery_Ref )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_ERR, "Can't register \"%s\" with Rendezvous: can't register service!", My_Rendezvous[i].Desc );
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/* Get and save the corresponding Mach Port */
 | 
			
		||||
	My_Rendezvous[i].Mach_Port = DNSServiceDiscoveryMachPort( My_Rendezvous[i].Discovery_Ref );
 | 
			
		||||
	if( ! My_Rendezvous[i].Mach_Port )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_ERR, "Can't register \"%s\" with Rendezvous: got no Mach Port!", My_Rendezvous[i].Desc );
 | 
			
		||||
		/* Here we actually leek a descriptor :-( */
 | 
			
		||||
		My_Rendezvous[i].Discovery_Ref = 0;
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log( LOG_DEBUG, "Rendezvous: Registering \"%s\" ...", My_Rendezvous[i].Desc );
 | 
			
		||||
	return TRUE;
 | 
			
		||||
} /* Rendezvous_Register */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Rendezvous_Unregister( CHAR *Name )
 | 
			
		||||
{
 | 
			
		||||
	/* Unregister service from rendezvous */
 | 
			
		||||
 | 
			
		||||
	INT i;
 | 
			
		||||
	BOOLEAN ok;
 | 
			
		||||
 | 
			
		||||
	ok = FALSE;
 | 
			
		||||
	for( i = 0; i < MAX_RENDEZVOUS; i++ )
 | 
			
		||||
	{
 | 
			
		||||
		if( strcmp( Name, My_Rendezvous[i].Desc ) == 0 )
 | 
			
		||||
		{
 | 
			
		||||
			Unregister( i );
 | 
			
		||||
			ok = TRUE;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ok;
 | 
			
		||||
} /* Rendezvous_Unregister */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Rendezvous_UnregisterListeners( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Unregister all our listening sockets from Rendezvous */
 | 
			
		||||
 | 
			
		||||
	INT i;
 | 
			
		||||
 | 
			
		||||
	for( i = 0; i < MAX_RENDEZVOUS; i++ )
 | 
			
		||||
	{
 | 
			
		||||
		if( My_Rendezvous[i].Discovery_Ref ) Unregister( i );
 | 
			
		||||
	}
 | 
			
		||||
} /* Rendezvous_UnregisterListeners */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Rendezvous_Handler( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Handle all Rendezvous stuff; this function must be called
 | 
			
		||||
	 * periodically from the run loop of the main program */
 | 
			
		||||
 | 
			
		||||
	INT i;
 | 
			
		||||
	CHAR buffer[MAX_MACH_MSG_SIZE];
 | 
			
		||||
	mach_msg_return_t result;
 | 
			
		||||
	mach_msg_header_t *msg;
 | 
			
		||||
 | 
			
		||||
	for( i = 0; i < MAX_RENDEZVOUS; i++ )
 | 
			
		||||
	{
 | 
			
		||||
		if( ! My_Rendezvous[i].Discovery_Ref ) continue;
 | 
			
		||||
 | 
			
		||||
		/* Read message from Mach Port */
 | 
			
		||||
		msg = (mach_msg_header_t *)buffer;
 | 
			
		||||
		result = mach_msg( msg, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0, MAX_MACH_MSG_SIZE, My_Rendezvous[i].Mach_Port, 1, 0 );
 | 
			
		||||
 | 
			
		||||
		/* Handle message */
 | 
			
		||||
		if( result == MACH_MSG_SUCCESS ) DNSServiceDiscovery_handleReply( msg );
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
		else if( result != MACH_RCV_TIMED_OUT ) Log( LOG_DEBUG, "mach_msg(): %ld", (LONG)result );
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
} /* Rendezvous_Handler */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Registration_Reply_Handler( DNSServiceRegistrationReplyErrorType ErrCode, VOID *Context )
 | 
			
		||||
{
 | 
			
		||||
	CHAR txt[50];
 | 
			
		||||
 | 
			
		||||
	if( ErrCode == kDNSServiceDiscoveryNoError )
 | 
			
		||||
	{
 | 
			
		||||
		/* Success! */
 | 
			
		||||
		Log( LOG_INFO, "Successfully registered \"%s\" with Rendezvous.", Context ? Context : "NULL" );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch( ErrCode )
 | 
			
		||||
	{
 | 
			
		||||
		case kDNSServiceDiscoveryAlreadyRegistered:
 | 
			
		||||
			strcpy( txt, "name already registered!" );
 | 
			
		||||
			break;
 | 
			
		||||
		case kDNSServiceDiscoveryNameConflict:
 | 
			
		||||
			strcpy( txt, "name conflict!" );
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			sprintf( txt, "error code %ld!", (LONG)ErrCode );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log( LOG_INFO, "Can't register \"%s\" with Rendezvous: %s", Context ? Context : "NULL", txt );
 | 
			
		||||
} /* Registration_Reply_Handler */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Unregister( INT Idx )
 | 
			
		||||
{
 | 
			
		||||
	/* Unregister service */
 | 
			
		||||
 | 
			
		||||
	DNSServiceDiscoveryDeallocate( My_Rendezvous[Idx].Discovery_Ref );
 | 
			
		||||
	Log( LOG_INFO, "Unregistered \"%s\" from Rendezvous.", My_Rendezvous[Idx].Desc );
 | 
			
		||||
	My_Rendezvous[Idx].Discovery_Ref = 0;
 | 
			
		||||
} /* Unregister */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif	/* RENDEZVOUS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										39
									
								
								src/ngircd/rendezvous.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/ngircd/rendezvous.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: rendezvous.h,v 1.1 2003/02/23 12:02:26 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * "Rendezvous" functions (Header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef RENDEZVOUS
 | 
			
		||||
 | 
			
		||||
#ifndef __rdezvous_h__
 | 
			
		||||
#define __rdezvous_h__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Rendezvous_Init( VOID );
 | 
			
		||||
GLOBAL VOID Rendezvous_Exit( VOID );
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Rendezvous_Register( CHAR *Name, CHAR *Type, UINT Port );
 | 
			
		||||
 | 
			
		||||
GLOBAL BOOLEAN Rendezvous_Unregister( CHAR *Name );
 | 
			
		||||
GLOBAL VOID Rendezvous_UnregisterListeners( VOID );
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Rendezvous_Handler( VOID );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif	/* __rdezvous_h__ */
 | 
			
		||||
 | 
			
		||||
#endif	/* RENDEZVOUS */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										265
									
								
								src/ngircd/resolve.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										265
									
								
								src/ngircd/resolve.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,265 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * Asynchronous resolver
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: resolve.c,v 1.6 2003/04/21 10:52:51 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
 | 
			
		||||
#include "conn.h"
 | 
			
		||||
#include "defines.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
#include "resolve.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID Do_ResolveAddr PARAMS(( struct sockaddr_in *Addr, INT w_fd ));
 | 
			
		||||
LOCAL VOID Do_ResolveName PARAMS(( CHAR *Host, INT w_fd ));
 | 
			
		||||
 | 
			
		||||
#ifdef h_errno
 | 
			
		||||
LOCAL CHAR *Get_Error PARAMS(( INT H_Error ));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID
 | 
			
		||||
Resolve_Init( VOID )
 | 
			
		||||
{
 | 
			
		||||
	/* Modul initialisieren */
 | 
			
		||||
 | 
			
		||||
	FD_ZERO( &Resolver_FDs );
 | 
			
		||||
} /* Resolve_Init */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL RES_STAT *
 | 
			
		||||
Resolve_Addr( struct sockaddr_in *Addr )
 | 
			
		||||
{
 | 
			
		||||
	/* IP (asyncron!) aufloesen. Bei Fehler, z.B. wenn der
 | 
			
		||||
	 * Child-Prozess nicht erzeugt werden kann, wird NULL geliefert.
 | 
			
		||||
	 * Der Host kann dann nicht aufgeloest werden. */
 | 
			
		||||
 | 
			
		||||
	RES_STAT *s;
 | 
			
		||||
	INT pid;
 | 
			
		||||
 | 
			
		||||
	/* Speicher anfordern */
 | 
			
		||||
	s = malloc( sizeof( RES_STAT ));
 | 
			
		||||
	if( ! s )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_EMERG, "Resolver: Can't allocate memory! [Resolve_Addr]" );
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Pipe fuer Antwort initialisieren */
 | 
			
		||||
	if( pipe( s->pipe ) != 0 )
 | 
			
		||||
	{
 | 
			
		||||
		free( s );
 | 
			
		||||
		Log( LOG_ALERT, "Resolver: Can't create output pipe: %s!", strerror( errno ));
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Sub-Prozess erzeugen */
 | 
			
		||||
	pid = fork( );
 | 
			
		||||
	if( pid > 0 )
 | 
			
		||||
	{
 | 
			
		||||
		/* Haupt-Prozess */
 | 
			
		||||
		Log( LOG_DEBUG, "Resolver for %s created (PID %d).", inet_ntoa( Addr->sin_addr ), pid );
 | 
			
		||||
		FD_SET( s->pipe[0], &Resolver_FDs );
 | 
			
		||||
		if( s->pipe[0] > Conn_MaxFD ) Conn_MaxFD = s->pipe[0];
 | 
			
		||||
		s->pid = pid;
 | 
			
		||||
		return s;
 | 
			
		||||
	}
 | 
			
		||||
	else if( pid == 0 )
 | 
			
		||||
	{
 | 
			
		||||
		/* Sub-Prozess */
 | 
			
		||||
		Log_Init_Resolver( );
 | 
			
		||||
		Do_ResolveAddr( Addr, s->pipe[1] );
 | 
			
		||||
		Log_Exit_Resolver( );
 | 
			
		||||
		exit( 0 );
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* Fehler */
 | 
			
		||||
		free( s );
 | 
			
		||||
		Log( LOG_CRIT, "Resolver: Can't fork: %s!", strerror( errno ));
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
} /* Resolve_Addr */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL RES_STAT *
 | 
			
		||||
Resolve_Name( CHAR *Host )
 | 
			
		||||
{
 | 
			
		||||
	/* Hostnamen (asyncron!) aufloesen. Bei Fehler, z.B. wenn der
 | 
			
		||||
	 * Child-Prozess nicht erzeugt werden kann, wird NULL geliefert.
 | 
			
		||||
	 * Der Host kann dann nicht aufgeloest werden. */
 | 
			
		||||
 | 
			
		||||
	RES_STAT *s;
 | 
			
		||||
	INT pid;
 | 
			
		||||
 | 
			
		||||
	/* Speicher anfordern */
 | 
			
		||||
	s = malloc( sizeof( RES_STAT ));
 | 
			
		||||
	if( ! s )
 | 
			
		||||
	{
 | 
			
		||||
		Log( LOG_EMERG, "Resolver: Can't allocate memory! [Resolve_Name]" );
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Pipe fuer Antwort initialisieren */
 | 
			
		||||
	if( pipe( s->pipe ) != 0 )
 | 
			
		||||
	{
 | 
			
		||||
		free( s );
 | 
			
		||||
		Log( LOG_ALERT, "Resolver: Can't create output pipe: %s!", strerror( errno ));
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Sub-Prozess erzeugen */
 | 
			
		||||
	pid = fork( );
 | 
			
		||||
	if( pid > 0 )
 | 
			
		||||
	{
 | 
			
		||||
		/* Haupt-Prozess */
 | 
			
		||||
		Log( LOG_DEBUG, "Resolver for \"%s\" created (PID %d).", Host, pid );
 | 
			
		||||
		FD_SET( s->pipe[0], &Resolver_FDs );
 | 
			
		||||
		if( s->pipe[0] > Conn_MaxFD ) Conn_MaxFD = s->pipe[0];
 | 
			
		||||
		s->pid = pid;
 | 
			
		||||
		return s;
 | 
			
		||||
	}
 | 
			
		||||
	else if( pid == 0 )
 | 
			
		||||
	{
 | 
			
		||||
		/* Sub-Prozess */
 | 
			
		||||
		Log_Init_Resolver( );
 | 
			
		||||
		Do_ResolveName( Host, s->pipe[1] );
 | 
			
		||||
		Log_Exit_Resolver( );
 | 
			
		||||
		exit( 0 );
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		/* Fehler */
 | 
			
		||||
		free( s );
 | 
			
		||||
		Log( LOG_CRIT, "Resolver: Can't fork: %s!", strerror( errno ));
 | 
			
		||||
		return NULL;
 | 
			
		||||
	}
 | 
			
		||||
} /* Resolve_Name */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID
 | 
			
		||||
Do_ResolveAddr( struct sockaddr_in *Addr, INT w_fd )
 | 
			
		||||
{
 | 
			
		||||
	/* Resolver Sub-Prozess: IP aufloesen und Ergebnis in Pipe schreiben. */
 | 
			
		||||
 | 
			
		||||
	CHAR hostname[HOST_LEN];
 | 
			
		||||
	struct hostent *h;
 | 
			
		||||
 | 
			
		||||
	Log_Resolver( LOG_DEBUG, "Now resolving %s ...", inet_ntoa( Addr->sin_addr ));
 | 
			
		||||
 | 
			
		||||
	/* Namen aufloesen */
 | 
			
		||||
	h = gethostbyaddr( (CHAR *)&Addr->sin_addr, sizeof( Addr->sin_addr ), AF_INET );
 | 
			
		||||
	if( h ) strlcpy( hostname, h->h_name, sizeof( hostname ));
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
#ifdef h_errno
 | 
			
		||||
		Log_Resolver( LOG_WARNING, "Can't resolve address \"%s\": %s!", inet_ntoa( Addr->sin_addr ), Get_Error( h_errno ));
 | 
			
		||||
#else
 | 
			
		||||
		Log_Resolver( LOG_WARNING, "Can't resolve address \"%s\"!", inet_ntoa( Addr->sin_addr ));
 | 
			
		||||
#endif	
 | 
			
		||||
		strlcpy( hostname, inet_ntoa( Addr->sin_addr ), sizeof( hostname ));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Antwort an Parent schreiben */
 | 
			
		||||
	if( (size_t)write( w_fd, hostname, strlen( hostname ) + 1 ) != (size_t)( strlen( hostname ) + 1 ))
 | 
			
		||||
	{
 | 
			
		||||
		Log_Resolver( LOG_CRIT, "Resolver: Can't write to parent: %s!", strerror( errno ));
 | 
			
		||||
		close( w_fd );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log_Resolver( LOG_DEBUG, "Ok, translated %s to \"%s\".", inet_ntoa( Addr->sin_addr ), hostname );
 | 
			
		||||
} /* Do_ResolveAddr */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID
 | 
			
		||||
Do_ResolveName( CHAR *Host, INT w_fd )
 | 
			
		||||
{
 | 
			
		||||
	/* Resolver Sub-Prozess: Name aufloesen und Ergebnis in Pipe schreiben. */
 | 
			
		||||
 | 
			
		||||
	CHAR ip[16];
 | 
			
		||||
	struct hostent *h;
 | 
			
		||||
	struct in_addr *addr;
 | 
			
		||||
 | 
			
		||||
	Log_Resolver( LOG_DEBUG, "Now resolving \"%s\" ...", Host );
 | 
			
		||||
 | 
			
		||||
	/* Namen aufloesen */
 | 
			
		||||
	h = gethostbyname( Host );
 | 
			
		||||
	if( h )
 | 
			
		||||
	{
 | 
			
		||||
		addr = (struct in_addr *)h->h_addr;
 | 
			
		||||
		strlcpy( ip, inet_ntoa( *addr ), sizeof( ip ));
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
#ifdef h_errno
 | 
			
		||||
		Log_Resolver( LOG_WARNING, "Can't resolve \"%s\": %s!", Host, Get_Error( h_errno ));
 | 
			
		||||
#else
 | 
			
		||||
		Log_Resolver( LOG_WARNING, "Can't resolve \"%s\"!", Host );
 | 
			
		||||
#endif
 | 
			
		||||
		strcpy( ip, "" );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Antwort an Parent schreiben */
 | 
			
		||||
	if( (size_t)write( w_fd, ip, strlen( ip ) + 1 ) != (size_t)( strlen( ip ) + 1 ))
 | 
			
		||||
	{
 | 
			
		||||
		Log_Resolver( LOG_CRIT, "Resolver: Can't write to parent: %s!", strerror( errno ));
 | 
			
		||||
		close( w_fd );
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if( ip[0] ) Log_Resolver( LOG_DEBUG, "Ok, translated \"%s\" to %s.", Host, ip );
 | 
			
		||||
} /* Do_ResolveName */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef h_errno
 | 
			
		||||
 | 
			
		||||
LOCAL CHAR *
 | 
			
		||||
Get_Error( INT H_Error )
 | 
			
		||||
{
 | 
			
		||||
	/* Fehlerbeschreibung fuer H_Error liefern */
 | 
			
		||||
 | 
			
		||||
	switch( H_Error )
 | 
			
		||||
	{
 | 
			
		||||
		case HOST_NOT_FOUND:
 | 
			
		||||
			return "host not found";
 | 
			
		||||
		case NO_DATA:
 | 
			
		||||
			return "name valid but no IP address defined";
 | 
			
		||||
		case NO_RECOVERY:
 | 
			
		||||
			return "name server error";
 | 
			
		||||
		case TRY_AGAIN:
 | 
			
		||||
			return "name server temporary not available";
 | 
			
		||||
		default:
 | 
			
		||||
			return "unknown error";
 | 
			
		||||
	}
 | 
			
		||||
} /* Get_Error */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										47
									
								
								src/ngircd/resolve.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/ngircd/resolve.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: resolve.h,v 1.5 2003/04/21 10:53:10 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * Asynchronous resolver (header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __resolve_h__
 | 
			
		||||
#define __resolve_h__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_SYS_SELECT_H
 | 
			
		||||
#	include <sys/select.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct _Res_Stat
 | 
			
		||||
{
 | 
			
		||||
	INT pid;			/* PID des Child-Prozess */
 | 
			
		||||
	INT pipe[2];			/* Pipe fuer IPC */
 | 
			
		||||
} RES_STAT;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL fd_set Resolver_FDs;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID Resolve_Init PARAMS(( VOID ));
 | 
			
		||||
 | 
			
		||||
GLOBAL RES_STAT *Resolve_Addr PARAMS(( struct sockaddr_in *Addr ));
 | 
			
		||||
GLOBAL RES_STAT *Resolve_Name PARAMS(( CHAR *Host ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
@@ -1,30 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: tool.h,v 1.7 2002/03/22 00:17:27 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * log.h: Hilfsfunktionen (Header)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef __tool_h__
 | 
			
		||||
#define __tool_h__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL VOID ngt_TrimStr( CHAR *String );
 | 
			
		||||
 | 
			
		||||
GLOBAL CHAR *ngt_LowerStr( CHAR *String );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
@@ -9,13 +9,23 @@
 | 
			
		||||
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
 | 
			
		||||
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile.am,v 1.2 2002/03/15 15:41:55 alex Exp $
 | 
			
		||||
# $Id: Makefile.am,v 1.7 2003/01/03 22:04:14 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
AUTOMAKE_OPTIONS = ansi2knr
 | 
			
		||||
 | 
			
		||||
noinst_LIBRARIES = libngportab.a
 | 
			
		||||
 | 
			
		||||
libngportab_a_SOURCES = strlcpy.c vsnprintf.c
 | 
			
		||||
 | 
			
		||||
check_PROGRAMS = portabtest
 | 
			
		||||
 | 
			
		||||
portabtest_SOURCES = portabtest.c
 | 
			
		||||
 | 
			
		||||
portabtest_LDFLAGS = -L.
 | 
			
		||||
 | 
			
		||||
portabtest_LDADD = -lngportab
 | 
			
		||||
 | 
			
		||||
noinst_HEADERS = imp.h exp.h portab.h
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								src/portab/ansi2knr.1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/portab/ansi2knr.1
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
.TH ANSI2KNR 1 "19 Jan 1996"
 | 
			
		||||
.SH NAME
 | 
			
		||||
ansi2knr \- convert ANSI C to Kernighan & Ritchie C
 | 
			
		||||
.SH SYNOPSIS
 | 
			
		||||
.I ansi2knr
 | 
			
		||||
[--varargs] input_file [output_file]
 | 
			
		||||
.SH DESCRIPTION
 | 
			
		||||
If no output_file is supplied, output goes to stdout.
 | 
			
		||||
.br
 | 
			
		||||
There are no error messages.
 | 
			
		||||
.sp
 | 
			
		||||
.I ansi2knr
 | 
			
		||||
recognizes function definitions by seeing a non-keyword identifier at the left
 | 
			
		||||
margin, followed by a left parenthesis, with a right parenthesis as the last
 | 
			
		||||
character on the line, and with a left brace as the first token on the
 | 
			
		||||
following line (ignoring possible intervening comments).  It will recognize a
 | 
			
		||||
multi-line header provided that no intervening line ends with a left or right
 | 
			
		||||
brace or a semicolon.  These algorithms ignore whitespace and comments, except
 | 
			
		||||
that the function name must be the first thing on the line.
 | 
			
		||||
.sp
 | 
			
		||||
The following constructs will confuse it:
 | 
			
		||||
.br
 | 
			
		||||
     - Any other construct that starts at the left margin and follows the
 | 
			
		||||
above syntax (such as a macro or function call).
 | 
			
		||||
.br
 | 
			
		||||
     - Some macros that tinker with the syntax of the function header.
 | 
			
		||||
.sp
 | 
			
		||||
The --varargs switch is obsolete, and is recognized only for
 | 
			
		||||
backwards compatibility.  The present version of
 | 
			
		||||
.I ansi2knr
 | 
			
		||||
will always attempt to convert a ... argument to va_alist and va_dcl.
 | 
			
		||||
.SH AUTHOR
 | 
			
		||||
L. Peter Deutsch <ghost@aladdin.com> wrote the original ansi2knr and
 | 
			
		||||
continues to maintain the current version; most of the code in the current
 | 
			
		||||
version is his work.  ansi2knr also includes contributions by Francois
 | 
			
		||||
Pinard <pinard@iro.umontreal.ca> and Jim Avera <jima@netcom.com>.
 | 
			
		||||
							
								
								
									
										738
									
								
								src/portab/ansi2knr.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										738
									
								
								src/portab/ansi2knr.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,738 @@
 | 
			
		||||
/* Copyright (C) 1989, 2000 Aladdin Enterprises.  All rights reserved. */
 | 
			
		||||
 | 
			
		||||
/* Convert ANSI C function definitions to K&R ("traditional C") syntax */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
ansi2knr is distributed in the hope that it will be useful, but WITHOUT ANY
 | 
			
		||||
WARRANTY.  No author or distributor accepts responsibility to anyone for the
 | 
			
		||||
consequences of using it or for whether it serves any particular purpose or
 | 
			
		||||
works at all, unless he says so in writing.  Refer to the GNU General Public
 | 
			
		||||
License (the "GPL") for full details.
 | 
			
		||||
 | 
			
		||||
Everyone is granted permission to copy, modify and redistribute ansi2knr,
 | 
			
		||||
but only under the conditions described in the GPL.  A copy of this license
 | 
			
		||||
is supposed to have been given to you along with ansi2knr so you can know
 | 
			
		||||
your rights and responsibilities.  It should be in a file named COPYLEFT,
 | 
			
		||||
or, if there is no file named COPYLEFT, a file named COPYING.  Among other
 | 
			
		||||
things, the copyright notice and this notice must be preserved on all
 | 
			
		||||
copies.
 | 
			
		||||
 | 
			
		||||
We explicitly state here what we believe is already implied by the GPL: if
 | 
			
		||||
the ansi2knr program is distributed as a separate set of sources and a
 | 
			
		||||
separate executable file which are aggregated on a storage medium together
 | 
			
		||||
with another program, this in itself does not bring the other program under
 | 
			
		||||
the GPL, nor does the mere fact that such a program or the procedures for
 | 
			
		||||
constructing it invoke the ansi2knr executable bring any other part of the
 | 
			
		||||
program under the GPL.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Usage:
 | 
			
		||||
	ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]
 | 
			
		||||
 * --filename provides the file name for the #line directive in the output,
 | 
			
		||||
 * overriding input_file (if present).
 | 
			
		||||
 * If no input_file is supplied, input is read from stdin.
 | 
			
		||||
 * If no output_file is supplied, output goes to stdout.
 | 
			
		||||
 * There are no error messages.
 | 
			
		||||
 *
 | 
			
		||||
 * ansi2knr recognizes function definitions by seeing a non-keyword
 | 
			
		||||
 * identifier at the left margin, followed by a left parenthesis, with a
 | 
			
		||||
 * right parenthesis as the last character on the line, and with a left
 | 
			
		||||
 * brace as the first token on the following line (ignoring possible
 | 
			
		||||
 * intervening comments and/or preprocessor directives), except that a line
 | 
			
		||||
 * consisting of only
 | 
			
		||||
 *	identifier1(identifier2)
 | 
			
		||||
 * will not be considered a function definition unless identifier2 is
 | 
			
		||||
 * the word "void", and a line consisting of
 | 
			
		||||
 *	identifier1(identifier2, <<arbitrary>>)
 | 
			
		||||
 * will not be considered a function definition.
 | 
			
		||||
 * ansi2knr will recognize a multi-line header provided that no intervening
 | 
			
		||||
 * line ends with a left or right brace or a semicolon.  These algorithms
 | 
			
		||||
 * ignore whitespace, comments, and preprocessor directives, except that
 | 
			
		||||
 * the function name must be the first thing on the line.  The following
 | 
			
		||||
 * constructs will confuse it:
 | 
			
		||||
 *	- Any other construct that starts at the left margin and
 | 
			
		||||
 *	    follows the above syntax (such as a macro or function call).
 | 
			
		||||
 *	- Some macros that tinker with the syntax of function headers.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The original and principal author of ansi2knr is L. Peter Deutsch
 | 
			
		||||
 * <ghost@aladdin.com>.  Other authors are noted in the change history
 | 
			
		||||
 * that follows (in reverse chronological order):
 | 
			
		||||
 | 
			
		||||
	lpd 2000-04-12 backs out Eggert's changes because of bugs:
 | 
			
		||||
	- concatlits didn't declare the type of its bufend argument;
 | 
			
		||||
	- concatlits didn't't recognize when it was inside a comment;
 | 
			
		||||
	- scanstring could scan backward past the beginning of the string; when
 | 
			
		||||
	- the check for \ + newline in scanstring was unnecessary.
 | 
			
		||||
 | 
			
		||||
	2000-03-05  Paul Eggert  <eggert@twinsun.com>
 | 
			
		||||
 | 
			
		||||
	Add support for concatenated string literals.
 | 
			
		||||
	* ansi2knr.c (concatlits): New decl.
 | 
			
		||||
	(main): Invoke concatlits to concatenate string literals.
 | 
			
		||||
	(scanstring): Handle backslash-newline correctly.  Work with
 | 
			
		||||
	character constants.  Fix bug when scanning backwards through
 | 
			
		||||
	backslash-quote.  Check for unterminated strings.
 | 
			
		||||
	(convert1): Parse character constants, too.
 | 
			
		||||
	(appendline, concatlits): New functions.
 | 
			
		||||
	* ansi2knr.1: Document this.
 | 
			
		||||
 | 
			
		||||
	lpd 1999-08-17 added code to allow preprocessor directives
 | 
			
		||||
		wherever comments are allowed
 | 
			
		||||
	lpd 1999-04-12 added minor fixes from Pavel Roskin
 | 
			
		||||
		<pavel_roskin@geocities.com> for clean compilation with
 | 
			
		||||
		gcc -W -Wall
 | 
			
		||||
	lpd 1999-03-22 added hack to recognize lines consisting of
 | 
			
		||||
		identifier1(identifier2, xxx) as *not* being procedures
 | 
			
		||||
	lpd 1999-02-03 made indentation of preprocessor commands consistent
 | 
			
		||||
	lpd 1999-01-28 fixed two bugs: a '/' in an argument list caused an
 | 
			
		||||
		endless loop; quoted strings within an argument list
 | 
			
		||||
		confused the parser
 | 
			
		||||
	lpd 1999-01-24 added a check for write errors on the output,
 | 
			
		||||
		suggested by Jim Meyering <meyering@ascend.com>
 | 
			
		||||
	lpd 1998-11-09 added further hack to recognize identifier(void)
 | 
			
		||||
		as being a procedure
 | 
			
		||||
	lpd 1998-10-23 added hack to recognize lines consisting of
 | 
			
		||||
		identifier1(identifier2) as *not* being procedures
 | 
			
		||||
	lpd 1997-12-08 made input_file optional; only closes input and/or
 | 
			
		||||
		output file if not stdin or stdout respectively; prints
 | 
			
		||||
		usage message on stderr rather than stdout; adds
 | 
			
		||||
		--filename switch (changes suggested by
 | 
			
		||||
		<ceder@lysator.liu.se>)
 | 
			
		||||
	lpd 1996-01-21 added code to cope with not HAVE_CONFIG_H and with
 | 
			
		||||
		compilers that don't understand void, as suggested by
 | 
			
		||||
		Tom Lane
 | 
			
		||||
	lpd 1996-01-15 changed to require that the first non-comment token
 | 
			
		||||
		on the line following a function header be a left brace,
 | 
			
		||||
		to reduce sensitivity to macros, as suggested by Tom Lane
 | 
			
		||||
		<tgl@sss.pgh.pa.us>
 | 
			
		||||
	lpd 1995-06-22 removed #ifndefs whose sole purpose was to define
 | 
			
		||||
		undefined preprocessor symbols as 0; changed all #ifdefs
 | 
			
		||||
		for configuration symbols to #ifs
 | 
			
		||||
	lpd 1995-04-05 changed copyright notice to make it clear that
 | 
			
		||||
		including ansi2knr in a program does not bring the entire
 | 
			
		||||
		program under the GPL
 | 
			
		||||
	lpd 1994-12-18 added conditionals for systems where ctype macros
 | 
			
		||||
		don't handle 8-bit characters properly, suggested by
 | 
			
		||||
		Francois Pinard <pinard@iro.umontreal.ca>;
 | 
			
		||||
		removed --varargs switch (this is now the default)
 | 
			
		||||
	lpd 1994-10-10 removed CONFIG_BROKETS conditional
 | 
			
		||||
	lpd 1994-07-16 added some conditionals to help GNU `configure',
 | 
			
		||||
		suggested by Francois Pinard <pinard@iro.umontreal.ca>;
 | 
			
		||||
		properly erase prototype args in function parameters,
 | 
			
		||||
		contributed by Jim Avera <jima@netcom.com>;
 | 
			
		||||
		correct error in writeblanks (it shouldn't erase EOLs)
 | 
			
		||||
	lpd 1989-xx-xx original version
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* Most of the conditionals here are to make ansi2knr work with */
 | 
			
		||||
/* or without the GNU configure machinery. */
 | 
			
		||||
 | 
			
		||||
#if HAVE_CONFIG_H
 | 
			
		||||
# include <config.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
 | 
			
		||||
#if HAVE_CONFIG_H
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
   For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
 | 
			
		||||
   This will define HAVE_CONFIG_H and so, activate the following lines.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
# if STDC_HEADERS || HAVE_STRING_H
 | 
			
		||||
#  include <string.h>
 | 
			
		||||
# else
 | 
			
		||||
#  include <strings.h>
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
#else /* not HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
/* Otherwise do it the hard way */
 | 
			
		||||
 | 
			
		||||
# ifdef BSD
 | 
			
		||||
#  include <strings.h>
 | 
			
		||||
# else
 | 
			
		||||
#  ifdef VMS
 | 
			
		||||
    extern int strlen(), strncmp();
 | 
			
		||||
#  else
 | 
			
		||||
#   include <string.h>
 | 
			
		||||
#  endif
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
#endif /* not HAVE_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
#if STDC_HEADERS
 | 
			
		||||
# include <stdlib.h>
 | 
			
		||||
#else
 | 
			
		||||
/*
 | 
			
		||||
   malloc and free should be declared in stdlib.h,
 | 
			
		||||
   but if you've got a K&R compiler, they probably aren't.
 | 
			
		||||
 */
 | 
			
		||||
# ifdef MSDOS
 | 
			
		||||
#  include <malloc.h>
 | 
			
		||||
# else
 | 
			
		||||
#  ifdef VMS
 | 
			
		||||
     extern char *malloc();
 | 
			
		||||
     extern void free();
 | 
			
		||||
#  else
 | 
			
		||||
     extern char *malloc();
 | 
			
		||||
     extern int free();
 | 
			
		||||
#  endif
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Define NULL (for *very* old compilers). */
 | 
			
		||||
#ifndef NULL
 | 
			
		||||
# define NULL (0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The ctype macros don't always handle 8-bit characters correctly.
 | 
			
		||||
 * Compensate for this here.
 | 
			
		||||
 */
 | 
			
		||||
#ifdef isascii
 | 
			
		||||
# undef HAVE_ISASCII		/* just in case */
 | 
			
		||||
# define HAVE_ISASCII 1
 | 
			
		||||
#else
 | 
			
		||||
#endif
 | 
			
		||||
#if STDC_HEADERS || !HAVE_ISASCII
 | 
			
		||||
# define is_ascii(c) 1
 | 
			
		||||
#else
 | 
			
		||||
# define is_ascii(c) isascii(c)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define is_space(c) (is_ascii(c) && isspace(c))
 | 
			
		||||
#define is_alpha(c) (is_ascii(c) && isalpha(c))
 | 
			
		||||
#define is_alnum(c) (is_ascii(c) && isalnum(c))
 | 
			
		||||
 | 
			
		||||
/* Scanning macros */
 | 
			
		||||
#define isidchar(ch) (is_alnum(ch) || (ch) == '_')
 | 
			
		||||
#define isidfirstchar(ch) (is_alpha(ch) || (ch) == '_')
 | 
			
		||||
 | 
			
		||||
/* Forward references */
 | 
			
		||||
char *ppdirforward();
 | 
			
		||||
char *ppdirbackward();
 | 
			
		||||
char *skipspace();
 | 
			
		||||
char *scanstring();
 | 
			
		||||
int writeblanks();
 | 
			
		||||
int test1();
 | 
			
		||||
int convert1();
 | 
			
		||||
 | 
			
		||||
/* The main program */
 | 
			
		||||
int
 | 
			
		||||
main(argc, argv)
 | 
			
		||||
    int argc;
 | 
			
		||||
    char *argv[];
 | 
			
		||||
{	FILE *in = stdin;
 | 
			
		||||
	FILE *out = stdout;
 | 
			
		||||
	char *filename = 0;
 | 
			
		||||
	char *program_name = argv[0];
 | 
			
		||||
	char *output_name = 0;
 | 
			
		||||
#define bufsize 5000			/* arbitrary size */
 | 
			
		||||
	char *buf;
 | 
			
		||||
	char *line;
 | 
			
		||||
	char *more;
 | 
			
		||||
	char *usage =
 | 
			
		||||
	  "Usage: ansi2knr [--filename FILENAME] [INPUT_FILE [OUTPUT_FILE]]\n";
 | 
			
		||||
	/*
 | 
			
		||||
	 * In previous versions, ansi2knr recognized a --varargs switch.
 | 
			
		||||
	 * If this switch was supplied, ansi2knr would attempt to convert
 | 
			
		||||
	 * a ... argument to va_alist and va_dcl; if this switch was not
 | 
			
		||||
	 * supplied, ansi2knr would simply drop any such arguments.
 | 
			
		||||
	 * Now, ansi2knr always does this conversion, and we only
 | 
			
		||||
	 * check for this switch for backward compatibility.
 | 
			
		||||
	 */
 | 
			
		||||
	int convert_varargs = 1;
 | 
			
		||||
	int output_error;
 | 
			
		||||
 | 
			
		||||
	while ( argc > 1 && argv[1][0] == '-' ) {
 | 
			
		||||
	  if ( !strcmp(argv[1], "--varargs") ) {
 | 
			
		||||
	    convert_varargs = 1;
 | 
			
		||||
	    argc--;
 | 
			
		||||
	    argv++;
 | 
			
		||||
	    continue;
 | 
			
		||||
	  }
 | 
			
		||||
	  if ( !strcmp(argv[1], "--filename") && argc > 2 ) {
 | 
			
		||||
	    filename = argv[2];
 | 
			
		||||
	    argc -= 2;
 | 
			
		||||
	    argv += 2;
 | 
			
		||||
	    continue;
 | 
			
		||||
	  }
 | 
			
		||||
	  fprintf(stderr, "%s: Unrecognized switch: %s\n", program_name,
 | 
			
		||||
		  argv[1]);
 | 
			
		||||
	  fprintf(stderr, usage);
 | 
			
		||||
	  exit(1);
 | 
			
		||||
	}
 | 
			
		||||
	switch ( argc )
 | 
			
		||||
	   {
 | 
			
		||||
	default:
 | 
			
		||||
		fprintf(stderr, usage);
 | 
			
		||||
		exit(0);
 | 
			
		||||
	case 3:
 | 
			
		||||
		output_name = argv[2];
 | 
			
		||||
		out = fopen(output_name, "w");
 | 
			
		||||
		if ( out == NULL ) {
 | 
			
		||||
		  fprintf(stderr, "%s: Cannot open output file %s\n",
 | 
			
		||||
			  program_name, output_name);
 | 
			
		||||
		  exit(1);
 | 
			
		||||
		}
 | 
			
		||||
		/* falls through */
 | 
			
		||||
	case 2:
 | 
			
		||||
		in = fopen(argv[1], "r");
 | 
			
		||||
		if ( in == NULL ) {
 | 
			
		||||
		  fprintf(stderr, "%s: Cannot open input file %s\n",
 | 
			
		||||
			  program_name, argv[1]);
 | 
			
		||||
		  exit(1);
 | 
			
		||||
		}
 | 
			
		||||
		if ( filename == 0 )
 | 
			
		||||
		  filename = argv[1];
 | 
			
		||||
		/* falls through */
 | 
			
		||||
	case 1:
 | 
			
		||||
		break;
 | 
			
		||||
	   }
 | 
			
		||||
	if ( filename )
 | 
			
		||||
	  fprintf(out, "#line 1 \"%s\"\n", filename);
 | 
			
		||||
	buf = malloc(bufsize);
 | 
			
		||||
	if ( buf == NULL )
 | 
			
		||||
	   {
 | 
			
		||||
		fprintf(stderr, "Unable to allocate read buffer!\n");
 | 
			
		||||
		exit(1);
 | 
			
		||||
	   }
 | 
			
		||||
	line = buf;
 | 
			
		||||
	while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
 | 
			
		||||
	   {
 | 
			
		||||
test:		line += strlen(line);
 | 
			
		||||
		switch ( test1(buf) )
 | 
			
		||||
		   {
 | 
			
		||||
		case 2:			/* a function header */
 | 
			
		||||
			convert1(buf, out, 1, convert_varargs);
 | 
			
		||||
			break;
 | 
			
		||||
		case 1:			/* a function */
 | 
			
		||||
			/* Check for a { at the start of the next line. */
 | 
			
		||||
			more = ++line;
 | 
			
		||||
f:			if ( line >= buf + (bufsize - 1) ) /* overflow check */
 | 
			
		||||
			  goto wl;
 | 
			
		||||
			if ( fgets(line, (unsigned)(buf + bufsize - line), in) == NULL )
 | 
			
		||||
			  goto wl;
 | 
			
		||||
			switch ( *skipspace(ppdirforward(more), 1) )
 | 
			
		||||
			  {
 | 
			
		||||
			  case '{':
 | 
			
		||||
			    /* Definitely a function header. */
 | 
			
		||||
			    convert1(buf, out, 0, convert_varargs);
 | 
			
		||||
			    fputs(more, out);
 | 
			
		||||
			    break;
 | 
			
		||||
			  case 0:
 | 
			
		||||
			    /* The next line was blank or a comment: */
 | 
			
		||||
			    /* keep scanning for a non-comment. */
 | 
			
		||||
			    line += strlen(line);
 | 
			
		||||
			    goto f;
 | 
			
		||||
			  default:
 | 
			
		||||
			    /* buf isn't a function header, but */
 | 
			
		||||
			    /* more might be. */
 | 
			
		||||
			    fputs(buf, out);
 | 
			
		||||
			    strcpy(buf, more);
 | 
			
		||||
			    line = buf;
 | 
			
		||||
			    goto test;
 | 
			
		||||
			  }
 | 
			
		||||
			break;
 | 
			
		||||
		case -1:		/* maybe the start of a function */
 | 
			
		||||
			if ( line != buf + (bufsize - 1) ) /* overflow check */
 | 
			
		||||
			  continue;
 | 
			
		||||
			/* falls through */
 | 
			
		||||
		default:		/* not a function */
 | 
			
		||||
wl:			fputs(buf, out);
 | 
			
		||||
			break;
 | 
			
		||||
		   }
 | 
			
		||||
		line = buf;
 | 
			
		||||
	   }
 | 
			
		||||
	if ( line != buf )
 | 
			
		||||
	  fputs(buf, out);
 | 
			
		||||
	free(buf);
 | 
			
		||||
	if ( output_name ) {
 | 
			
		||||
	  output_error = ferror(out);
 | 
			
		||||
	  output_error |= fclose(out);
 | 
			
		||||
	} else {		/* out == stdout */
 | 
			
		||||
	  fflush(out);
 | 
			
		||||
	  output_error = ferror(out);
 | 
			
		||||
	}
 | 
			
		||||
	if ( output_error ) {
 | 
			
		||||
	  fprintf(stderr, "%s: error writing to %s\n", program_name,
 | 
			
		||||
		  (output_name ? output_name : "stdout"));
 | 
			
		||||
	  exit(1);
 | 
			
		||||
	}
 | 
			
		||||
	if ( in != stdin )
 | 
			
		||||
	  fclose(in);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Skip forward or backward over one or more preprocessor directives.
 | 
			
		||||
 */
 | 
			
		||||
char *
 | 
			
		||||
ppdirforward(p)
 | 
			
		||||
    char *p;
 | 
			
		||||
{
 | 
			
		||||
    for (; *p == '#'; ++p) {
 | 
			
		||||
	for (; *p != '\r' && *p != '\n'; ++p)
 | 
			
		||||
	    if (*p == 0)
 | 
			
		||||
		return p;
 | 
			
		||||
	if (*p == '\r' && p[1] == '\n')
 | 
			
		||||
	    ++p;
 | 
			
		||||
    }
 | 
			
		||||
    return p;
 | 
			
		||||
}
 | 
			
		||||
char *
 | 
			
		||||
ppdirbackward(p, limit)
 | 
			
		||||
    char *p;
 | 
			
		||||
    char *limit;
 | 
			
		||||
{
 | 
			
		||||
    char *np = p;
 | 
			
		||||
 | 
			
		||||
    for (;; p = --np) {
 | 
			
		||||
	if (*np == '\n' && np[-1] == '\r')
 | 
			
		||||
	    --np;
 | 
			
		||||
	for (; np > limit && np[-1] != '\r' && np[-1] != '\n'; --np)
 | 
			
		||||
	    if (np[-1] == 0)
 | 
			
		||||
		return np;
 | 
			
		||||
	if (*np != '#')
 | 
			
		||||
	    return p;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Skip over whitespace, comments, and preprocessor directives,
 | 
			
		||||
 * in either direction.
 | 
			
		||||
 */
 | 
			
		||||
char *
 | 
			
		||||
skipspace(p, dir)
 | 
			
		||||
    char *p;
 | 
			
		||||
    int dir;			/* 1 for forward, -1 for backward */
 | 
			
		||||
{
 | 
			
		||||
    for ( ; ; ) {
 | 
			
		||||
	while ( is_space(*p) )
 | 
			
		||||
	    p += dir;
 | 
			
		||||
	if ( !(*p == '/' && p[dir] == '*') )
 | 
			
		||||
	    break;
 | 
			
		||||
	p += dir;  p += dir;
 | 
			
		||||
	while ( !(*p == '*' && p[dir] == '/') ) {
 | 
			
		||||
	    if ( *p == 0 )
 | 
			
		||||
		return p;	/* multi-line comment?? */
 | 
			
		||||
	    p += dir;
 | 
			
		||||
	}
 | 
			
		||||
	p += dir;  p += dir;
 | 
			
		||||
    }
 | 
			
		||||
    return p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Scan over a quoted string, in either direction. */
 | 
			
		||||
char *
 | 
			
		||||
scanstring(p, dir)
 | 
			
		||||
    char *p;
 | 
			
		||||
    int dir;
 | 
			
		||||
{
 | 
			
		||||
    for (p += dir; ; p += dir)
 | 
			
		||||
	if (*p == '"' && p[-dir] != '\\')
 | 
			
		||||
	    return p + dir;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Write blanks over part of a string.
 | 
			
		||||
 * Don't overwrite end-of-line characters.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
writeblanks(start, end)
 | 
			
		||||
    char *start;
 | 
			
		||||
    char *end;
 | 
			
		||||
{	char *p;
 | 
			
		||||
	for ( p = start; p < end; p++ )
 | 
			
		||||
	  if ( *p != '\r' && *p != '\n' )
 | 
			
		||||
	    *p = ' ';
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Test whether the string in buf is a function definition.
 | 
			
		||||
 * The string may contain and/or end with a newline.
 | 
			
		||||
 * Return as follows:
 | 
			
		||||
 *	0 - definitely not a function definition;
 | 
			
		||||
 *	1 - definitely a function definition;
 | 
			
		||||
 *	2 - definitely a function prototype (NOT USED);
 | 
			
		||||
 *	-1 - may be the beginning of a function definition,
 | 
			
		||||
 *		append another line and look again.
 | 
			
		||||
 * The reason we don't attempt to convert function prototypes is that
 | 
			
		||||
 * Ghostscript's declaration-generating macros look too much like
 | 
			
		||||
 * prototypes, and confuse the algorithms.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
test1(buf)
 | 
			
		||||
    char *buf;
 | 
			
		||||
{	char *p = buf;
 | 
			
		||||
	char *bend;
 | 
			
		||||
	char *endfn;
 | 
			
		||||
	int contin;
 | 
			
		||||
 | 
			
		||||
	if ( !isidfirstchar(*p) )
 | 
			
		||||
	  return 0;		/* no name at left margin */
 | 
			
		||||
	bend = skipspace(ppdirbackward(buf + strlen(buf) - 1, buf), -1);
 | 
			
		||||
	switch ( *bend )
 | 
			
		||||
	   {
 | 
			
		||||
	   case ';': contin = 0 /*2*/; break;
 | 
			
		||||
	   case ')': contin = 1; break;
 | 
			
		||||
	   case '{': return 0;		/* not a function */
 | 
			
		||||
	   case '}': return 0;		/* not a function */
 | 
			
		||||
	   default: contin = -1;
 | 
			
		||||
	   }
 | 
			
		||||
	while ( isidchar(*p) )
 | 
			
		||||
	  p++;
 | 
			
		||||
	endfn = p;
 | 
			
		||||
	p = skipspace(p, 1);
 | 
			
		||||
	if ( *p++ != '(' )
 | 
			
		||||
	  return 0;		/* not a function */
 | 
			
		||||
	p = skipspace(p, 1);
 | 
			
		||||
	if ( *p == ')' )
 | 
			
		||||
	  return 0;		/* no parameters */
 | 
			
		||||
	/* Check that the apparent function name isn't a keyword. */
 | 
			
		||||
	/* We only need to check for keywords that could be followed */
 | 
			
		||||
	/* by a left parenthesis (which, unfortunately, is most of them). */
 | 
			
		||||
	   {	static char *words[] =
 | 
			
		||||
		   {	"asm", "auto", "case", "char", "const", "double",
 | 
			
		||||
			"extern", "float", "for", "if", "int", "long",
 | 
			
		||||
			"register", "return", "short", "signed", "sizeof",
 | 
			
		||||
			"static", "switch", "typedef", "unsigned",
 | 
			
		||||
			"void", "volatile", "while", 0
 | 
			
		||||
		   };
 | 
			
		||||
		char **key = words;
 | 
			
		||||
		char *kp;
 | 
			
		||||
		unsigned len = endfn - buf;
 | 
			
		||||
 | 
			
		||||
		while ( (kp = *key) != 0 )
 | 
			
		||||
		   {	if ( strlen(kp) == len && !strncmp(kp, buf, len) )
 | 
			
		||||
			  return 0;	/* name is a keyword */
 | 
			
		||||
			key++;
 | 
			
		||||
		   }
 | 
			
		||||
	   }
 | 
			
		||||
	   {
 | 
			
		||||
	       char *id = p;
 | 
			
		||||
	       int len;
 | 
			
		||||
	       /*
 | 
			
		||||
		* Check for identifier1(identifier2) and not
 | 
			
		||||
		* identifier1(void), or identifier1(identifier2, xxxx).
 | 
			
		||||
		*/
 | 
			
		||||
 | 
			
		||||
	       while ( isidchar(*p) )
 | 
			
		||||
		   p++;
 | 
			
		||||
	       len = p - id;
 | 
			
		||||
	       p = skipspace(p, 1);
 | 
			
		||||
	       if (*p == ',' ||
 | 
			
		||||
		   (*p == ')' && (len != 4 || strncmp(id, "void", 4)))
 | 
			
		||||
		   )
 | 
			
		||||
		   return 0;	/* not a function */
 | 
			
		||||
	   }
 | 
			
		||||
	/*
 | 
			
		||||
	 * If the last significant character was a ), we need to count
 | 
			
		||||
	 * parentheses, because it might be part of a formal parameter
 | 
			
		||||
	 * that is a procedure.
 | 
			
		||||
	 */
 | 
			
		||||
	if (contin > 0) {
 | 
			
		||||
	    int level = 0;
 | 
			
		||||
 | 
			
		||||
	    for (p = skipspace(buf, 1); *p; p = skipspace(p + 1, 1))
 | 
			
		||||
		level += (*p == '(' ? 1 : *p == ')' ? -1 : 0);
 | 
			
		||||
	    if (level > 0)
 | 
			
		||||
		contin = -1;
 | 
			
		||||
	}
 | 
			
		||||
	return contin;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Convert a recognized function definition or header to K&R syntax. */
 | 
			
		||||
int
 | 
			
		||||
convert1(buf, out, header, convert_varargs)
 | 
			
		||||
    char *buf;
 | 
			
		||||
    FILE *out;
 | 
			
		||||
    int header;			/* Boolean */
 | 
			
		||||
    int convert_varargs;	/* Boolean */
 | 
			
		||||
{	char *endfn;
 | 
			
		||||
	char *p;
 | 
			
		||||
	/*
 | 
			
		||||
	 * The breaks table contains pointers to the beginning and end
 | 
			
		||||
	 * of each argument.
 | 
			
		||||
	 */
 | 
			
		||||
	char **breaks;
 | 
			
		||||
	unsigned num_breaks = 2;	/* for testing */
 | 
			
		||||
	char **btop;
 | 
			
		||||
	char **bp;
 | 
			
		||||
	char **ap;
 | 
			
		||||
	char *vararg = 0;
 | 
			
		||||
 | 
			
		||||
	/* Pre-ANSI implementations don't agree on whether strchr */
 | 
			
		||||
	/* is called strchr or index, so we open-code it here. */
 | 
			
		||||
	for ( endfn = buf; *(endfn++) != '('; )
 | 
			
		||||
	  ;
 | 
			
		||||
top:	p = endfn;
 | 
			
		||||
	breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
 | 
			
		||||
	if ( breaks == NULL )
 | 
			
		||||
	   {	/* Couldn't allocate break table, give up */
 | 
			
		||||
		fprintf(stderr, "Unable to allocate break table!\n");
 | 
			
		||||
		fputs(buf, out);
 | 
			
		||||
		return -1;
 | 
			
		||||
	   }
 | 
			
		||||
	btop = breaks + num_breaks * 2 - 2;
 | 
			
		||||
	bp = breaks;
 | 
			
		||||
	/* Parse the argument list */
 | 
			
		||||
	do
 | 
			
		||||
	   {	int level = 0;
 | 
			
		||||
		char *lp = NULL;
 | 
			
		||||
		char *rp = NULL;
 | 
			
		||||
		char *end = NULL;
 | 
			
		||||
 | 
			
		||||
		if ( bp >= btop )
 | 
			
		||||
		   {	/* Filled up break table. */
 | 
			
		||||
			/* Allocate a bigger one and start over. */
 | 
			
		||||
			free((char *)breaks);
 | 
			
		||||
			num_breaks <<= 1;
 | 
			
		||||
			goto top;
 | 
			
		||||
		   }
 | 
			
		||||
		*bp++ = p;
 | 
			
		||||
		/* Find the end of the argument */
 | 
			
		||||
		for ( ; end == NULL; p++ )
 | 
			
		||||
		   {	switch(*p)
 | 
			
		||||
			   {
 | 
			
		||||
			   case ',':
 | 
			
		||||
				if ( !level ) end = p;
 | 
			
		||||
				break;
 | 
			
		||||
			   case '(':
 | 
			
		||||
				if ( !level ) lp = p;
 | 
			
		||||
				level++;
 | 
			
		||||
				break;
 | 
			
		||||
			   case ')':
 | 
			
		||||
				if ( --level < 0 ) end = p;
 | 
			
		||||
				else rp = p;
 | 
			
		||||
				break;
 | 
			
		||||
			   case '/':
 | 
			
		||||
				if (p[1] == '*')
 | 
			
		||||
				    p = skipspace(p, 1) - 1;
 | 
			
		||||
				break;
 | 
			
		||||
			   case '"':
 | 
			
		||||
			       p = scanstring(p, 1) - 1;
 | 
			
		||||
			       break;
 | 
			
		||||
			   default:
 | 
			
		||||
				;
 | 
			
		||||
			   }
 | 
			
		||||
		   }
 | 
			
		||||
		/* Erase any embedded prototype parameters. */
 | 
			
		||||
		if ( lp && rp )
 | 
			
		||||
		  writeblanks(lp + 1, rp);
 | 
			
		||||
		p--;			/* back up over terminator */
 | 
			
		||||
		/* Find the name being declared. */
 | 
			
		||||
		/* This is complicated because of procedure and */
 | 
			
		||||
		/* array modifiers. */
 | 
			
		||||
		for ( ; ; )
 | 
			
		||||
		   {	p = skipspace(p - 1, -1);
 | 
			
		||||
			switch ( *p )
 | 
			
		||||
			   {
 | 
			
		||||
			   case ']':	/* skip array dimension(s) */
 | 
			
		||||
			   case ')':	/* skip procedure args OR name */
 | 
			
		||||
			   {	int level = 1;
 | 
			
		||||
				while ( level )
 | 
			
		||||
				 switch ( *--p )
 | 
			
		||||
				   {
 | 
			
		||||
				   case ']': case ')':
 | 
			
		||||
				       level++;
 | 
			
		||||
				       break;
 | 
			
		||||
				   case '[': case '(':
 | 
			
		||||
				       level--;
 | 
			
		||||
				       break;
 | 
			
		||||
				   case '/':
 | 
			
		||||
				       if (p > buf && p[-1] == '*')
 | 
			
		||||
					   p = skipspace(p, -1) + 1;
 | 
			
		||||
				       break;
 | 
			
		||||
				   case '"':
 | 
			
		||||
				       p = scanstring(p, -1) + 1;
 | 
			
		||||
				       break;
 | 
			
		||||
				   default: ;
 | 
			
		||||
				   }
 | 
			
		||||
			   }
 | 
			
		||||
				if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
 | 
			
		||||
				   {	/* We found the name being declared */
 | 
			
		||||
					while ( !isidfirstchar(*p) )
 | 
			
		||||
					  p = skipspace(p, 1) + 1;
 | 
			
		||||
					goto found;
 | 
			
		||||
				   }
 | 
			
		||||
				break;
 | 
			
		||||
			   default:
 | 
			
		||||
				goto found;
 | 
			
		||||
			   }
 | 
			
		||||
		   }
 | 
			
		||||
found:		if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
 | 
			
		||||
		  {	if ( convert_varargs )
 | 
			
		||||
			  {	*bp++ = "va_alist";
 | 
			
		||||
				vararg = p-2;
 | 
			
		||||
			  }
 | 
			
		||||
			else
 | 
			
		||||
			  {	p++;
 | 
			
		||||
				if ( bp == breaks + 1 )	/* sole argument */
 | 
			
		||||
				  writeblanks(breaks[0], p);
 | 
			
		||||
				else
 | 
			
		||||
				  writeblanks(bp[-1] - 1, p);
 | 
			
		||||
				bp--;
 | 
			
		||||
			  }
 | 
			
		||||
		   }
 | 
			
		||||
		else
 | 
			
		||||
		   {	while ( isidchar(*p) ) p--;
 | 
			
		||||
			*bp++ = p+1;
 | 
			
		||||
		   }
 | 
			
		||||
		p = end;
 | 
			
		||||
	   }
 | 
			
		||||
	while ( *p++ == ',' );
 | 
			
		||||
	*bp = p;
 | 
			
		||||
	/* Make a special check for 'void' arglist */
 | 
			
		||||
	if ( bp == breaks+2 )
 | 
			
		||||
	   {	p = skipspace(breaks[0], 1);
 | 
			
		||||
		if ( !strncmp(p, "void", 4) )
 | 
			
		||||
		   {	p = skipspace(p+4, 1);
 | 
			
		||||
			if ( p == breaks[2] - 1 )
 | 
			
		||||
			   {	bp = breaks;	/* yup, pretend arglist is empty */
 | 
			
		||||
				writeblanks(breaks[0], p + 1);
 | 
			
		||||
			   }
 | 
			
		||||
		   }
 | 
			
		||||
	   }
 | 
			
		||||
	/* Put out the function name and left parenthesis. */
 | 
			
		||||
	p = buf;
 | 
			
		||||
	while ( p != endfn ) putc(*p, out), p++;
 | 
			
		||||
	/* Put out the declaration. */
 | 
			
		||||
	if ( header )
 | 
			
		||||
	  {	fputs(");", out);
 | 
			
		||||
		for ( p = breaks[0]; *p; p++ )
 | 
			
		||||
		  if ( *p == '\r' || *p == '\n' )
 | 
			
		||||
		    putc(*p, out);
 | 
			
		||||
	  }
 | 
			
		||||
	else
 | 
			
		||||
	  {	for ( ap = breaks+1; ap < bp; ap += 2 )
 | 
			
		||||
		  {	p = *ap;
 | 
			
		||||
			while ( isidchar(*p) )
 | 
			
		||||
			  putc(*p, out), p++;
 | 
			
		||||
			if ( ap < bp - 1 )
 | 
			
		||||
			  fputs(", ", out);
 | 
			
		||||
		  }
 | 
			
		||||
		fputs(")  ", out);
 | 
			
		||||
		/* Put out the argument declarations */
 | 
			
		||||
		for ( ap = breaks+2; ap <= bp; ap += 2 )
 | 
			
		||||
		  (*ap)[-1] = ';';
 | 
			
		||||
		if ( vararg != 0 )
 | 
			
		||||
		  {	*vararg = 0;
 | 
			
		||||
			fputs(breaks[0], out);		/* any prior args */
 | 
			
		||||
			fputs("va_dcl", out);		/* the final arg */
 | 
			
		||||
			fputs(bp[0], out);
 | 
			
		||||
		  }
 | 
			
		||||
		else
 | 
			
		||||
		  fputs(breaks[0], out);
 | 
			
		||||
	  }
 | 
			
		||||
	free((char *)breaks);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,17 +1,16 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 * Copyright (c)2001-2003 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: portab.h,v 1.3 2002/03/25 19:13:19 alex Exp $
 | 
			
		||||
 * $Id: portab.h,v 1.15 2003/03/31 19:01:02 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * portab.h: "Portabilitaets-Definitionen"
 | 
			
		||||
 * Portability functions and declarations (header for libngbportab).
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -21,22 +20,55 @@
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_SYS_TYPES_H
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Keywords */
 | 
			
		||||
 | 
			
		||||
/* compiler features */
 | 
			
		||||
 | 
			
		||||
#ifdef __GNUC__
 | 
			
		||||
# define PUNUSED(x) __attribute__ ((unused)) x
 | 
			
		||||
# define UNUSED     __attribute__ ((unused))
 | 
			
		||||
#else
 | 
			
		||||
# define PUNUSED(x) x
 | 
			
		||||
# define UNUSED
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef PARAMS
 | 
			
		||||
# if PROTOTYPES
 | 
			
		||||
#  define PARAMS(args) args
 | 
			
		||||
# else
 | 
			
		||||
#  define PARAMS(args) ()
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* keywords */
 | 
			
		||||
 | 
			
		||||
#define EXTERN extern
 | 
			
		||||
#define STATIC static
 | 
			
		||||
#define LOCAL static
 | 
			
		||||
#define CONST const
 | 
			
		||||
#define REGISTER register
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Datatentypen */
 | 
			
		||||
/* datatypes */
 | 
			
		||||
 | 
			
		||||
#ifndef PROTOTYPES
 | 
			
		||||
# ifndef signed
 | 
			
		||||
#  define signed
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef void VOID;
 | 
			
		||||
typedef void POINTER;
 | 
			
		||||
 | 
			
		||||
typedef signed int INT;
 | 
			
		||||
typedef unsigned int UINT;
 | 
			
		||||
typedef signed long LONG;
 | 
			
		||||
typedef unsigned long ULONG;
 | 
			
		||||
 | 
			
		||||
typedef signed char INT8;
 | 
			
		||||
typedef unsigned char UINT8;
 | 
			
		||||
typedef signed short INT16;
 | 
			
		||||
@@ -44,6 +76,7 @@ typedef unsigned short UINT16;
 | 
			
		||||
typedef signed long INT32;
 | 
			
		||||
typedef unsigned long UINT32;
 | 
			
		||||
 | 
			
		||||
typedef double DOUBLE;
 | 
			
		||||
typedef float FLOAT;
 | 
			
		||||
 | 
			
		||||
typedef char CHAR;
 | 
			
		||||
@@ -57,7 +90,11 @@ typedef UINT8 BOOLEAN;
 | 
			
		||||
#define FALSE (BOOLEAN)0
 | 
			
		||||
 | 
			
		||||
#undef NULL
 | 
			
		||||
#define NULL (VOID *)0
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
# define NULL (VOID *)0
 | 
			
		||||
#else
 | 
			
		||||
# define NULL 0L
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#undef GLOBAL
 | 
			
		||||
#define GLOBAL
 | 
			
		||||
@@ -71,22 +108,7 @@ typedef UINT8 BOOLEAN;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* configure-Optionen */
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_socklen_t
 | 
			
		||||
#define socklen_t int			/* u.a. fuer Mac OS X */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_INET_ATON
 | 
			
		||||
#define inet_aton( opt, bind ) 0	/* Dummy fuer inet_aton() */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if OS_UNIX_AUX
 | 
			
		||||
#define _POSIX_SOURCE			/* muss unter A/UX definiert sein */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Konstanten */
 | 
			
		||||
/* target constants  */
 | 
			
		||||
 | 
			
		||||
#ifndef TARGET_OS
 | 
			
		||||
#define TARGET_OS "unknown"
 | 
			
		||||
@@ -101,6 +123,38 @@ typedef UINT8 BOOLEAN;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* configure options */
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_socklen_t
 | 
			
		||||
#define socklen_t int			/* u.a. fuer Mac OS X */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_SNPRINTF
 | 
			
		||||
EXTERN INT snprintf PARAMS(( CHAR *str, size_t count, CONST CHAR *fmt, ... ));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_STRLCAT
 | 
			
		||||
EXTERN size_t strlcat PARAMS(( CHAR *dst, CONST CHAR *src, size_t size ));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_STRLCPY
 | 
			
		||||
EXTERN size_t strlcpy PARAMS(( CHAR *dst, CONST CHAR *src, size_t size ));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_VSNPRINTF
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
EXTERN INT vsnprintf PARAMS(( CHAR *str, size_t count, CONST CHAR *fmt, va_list args ));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef PACKAGE_NAME
 | 
			
		||||
#define PACKAGE_NAME PACKAGE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef PACKAGE_VERSION
 | 
			
		||||
#define PACKAGE_VERSION VERSION
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2,60 +2,65 @@
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
 * der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
 * 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.
 | 
			
		||||
 *
 | 
			
		||||
 * $Id: portabtest.c,v 1.3 2002/03/12 21:47:40 alex Exp $
 | 
			
		||||
 *
 | 
			
		||||
 * portabtest.c: Testprogramm fuer portab.h
 | 
			
		||||
 * test program for portab.h and friends ;-)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: portabtest.c,v 1.11 2003/01/04 10:40:01 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN portab_check_types( VOID );
 | 
			
		||||
LOCAL VOID Panic PARAMS (( CHAR *Reason, INT Code ));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GLOBAL INT main( VOID )
 | 
			
		||||
GLOBAL int
 | 
			
		||||
main( VOID )
 | 
			
		||||
{
 | 
			
		||||
	INT ret = 0;
 | 
			
		||||
	/* validate datatypes */
 | 
			
		||||
	if( FALSE != 0 ) Panic( "FALSE", 1 );
 | 
			
		||||
	if( TRUE != 1 ) Panic( "TRUE", 1 );
 | 
			
		||||
	if( sizeof( INT8 ) != 1 ) Panic( "INT8", 1 );
 | 
			
		||||
	if( sizeof( UINT8 ) != 1 ) Panic( "UINT8", 1 );
 | 
			
		||||
	if( sizeof( INT16 ) != 2 ) Panic( "INT16", 1 );
 | 
			
		||||
	if( sizeof( UINT16 ) != 2 ) Panic( "UINT16", 1 );
 | 
			
		||||
	if( sizeof( INT32 ) != 4 ) Panic( "INT32", 1 );
 | 
			
		||||
	if( sizeof( UINT32 ) != 4 ) Panic( "UINT32", 1 );
 | 
			
		||||
 | 
			
		||||
	printf( "- datatypes: ");
 | 
			
		||||
	if( ! portab_check_types( ))
 | 
			
		||||
	{
 | 
			
		||||
		puts( "FAILED!" );
 | 
			
		||||
		ret = 1;
 | 
			
		||||
	}
 | 
			
		||||
	else puts( "ok." );
 | 
			
		||||
 | 
			
		||||
	puts( "- system type: "TARGET_CPU"/"TARGET_VENDOR"/"TARGET_OS );
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
} /* main */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL BOOLEAN portab_check_types( VOID )
 | 
			
		||||
{
 | 
			
		||||
	if( FALSE != 0 ) return 0;
 | 
			
		||||
	if( TRUE != 1 ) return 0;
 | 
			
		||||
	if( sizeof( INT8 ) != 1 ) return 0;
 | 
			
		||||
	if( sizeof( UINT8 ) != 1 ) return 0;
 | 
			
		||||
	if( sizeof( INT16 ) != 2 ) return 0;
 | 
			
		||||
	if( sizeof( UINT16 ) != 2 ) return 0;
 | 
			
		||||
	if( sizeof( INT32 ) != 4 ) return 0;
 | 
			
		||||
	if( sizeof( UINT32 ) != 4 ) return 0;
 | 
			
		||||
	return 1;
 | 
			
		||||
#ifdef PROTOTYPES
 | 
			
		||||
	/* check functions */
 | 
			
		||||
	if( ! snprintf ) Panic( "snprintf", 2 );
 | 
			
		||||
	if( ! vsnprintf ) Panic( "vsnprintf", 2 );
 | 
			
		||||
	if( ! strlcpy ) Panic( "strlcpy", 2 );
 | 
			
		||||
	if( ! strlcat ) Panic( "strlcat", 2 );
 | 
			
		||||
#endif
 | 
			
		||||
	
 | 
			
		||||
	/* ok, no error */
 | 
			
		||||
	return 0;
 | 
			
		||||
} /* portab_check_types */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
LOCAL VOID
 | 
			
		||||
Panic( CHAR *Reason, INT Code )
 | 
			
		||||
{
 | 
			
		||||
	/* Oops, something failed!? */
 | 
			
		||||
	fprintf( stderr, "Oops, test for %s failed!?", Reason );
 | 
			
		||||
	exit( Code );
 | 
			
		||||
} /* Panic */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										75
									
								
								src/portab/strlcpy.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/portab/strlcpy.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * strlcpy() and strlcat() replacement functions.
 | 
			
		||||
 * See <http://www.openbsd.org/papers/strlcpy-paper.ps> for details.
 | 
			
		||||
 *
 | 
			
		||||
 * Code partially borrowed from compat.c of rsync, written by Andrew
 | 
			
		||||
 * Tridgell (1998) and Martin Pool (2002):
 | 
			
		||||
 * <http://samba.anu.edu.au/rsync/doxygen/head/lib_2compat_8c.html>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: strlcpy.c,v 1.2 2002/12/26 14:34:11 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_STRLCAT
 | 
			
		||||
 | 
			
		||||
GLOBAL size_t
 | 
			
		||||
strlcat( CHAR *dst, CONST CHAR *src, size_t size )
 | 
			
		||||
{
 | 
			
		||||
	/* Like strncat() but does not 0 fill the buffer and
 | 
			
		||||
	 * always null terminates. */
 | 
			
		||||
 | 
			
		||||
	size_t len1 = strlen( dst );
 | 
			
		||||
	size_t len2 = strlen( src );
 | 
			
		||||
	size_t ret = len1 + len2;
 | 
			
		||||
	
 | 
			
		||||
	if( len1 + len2 >= size ) len2 = size - ( len1 + 1 );
 | 
			
		||||
	if( len2 > 0 )
 | 
			
		||||
	{
 | 
			
		||||
		memcpy( dst + len1, src, len2 );
 | 
			
		||||
		dst[len1 + len2] = 0;
 | 
			
		||||
	}
 | 
			
		||||
	return ret;
 | 
			
		||||
} /* strlcat */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_STRLCPY
 | 
			
		||||
 | 
			
		||||
GLOBAL size_t
 | 
			
		||||
strlcpy( CHAR *dst, CONST CHAR *src, size_t size )
 | 
			
		||||
{
 | 
			
		||||
	/* Like strncpy but does not 0 fill the buffer and
 | 
			
		||||
	 * always null terminates. */
 | 
			
		||||
 | 
			
		||||
	size_t len = strlen( src );
 | 
			
		||||
 | 
			
		||||
	if( size <= 0 ) return len;
 | 
			
		||||
	if( len >= size ) len = size - 1;
 | 
			
		||||
	memcpy( dst, src, len );
 | 
			
		||||
	dst[len] = 0;
 | 
			
		||||
	return len;
 | 
			
		||||
} /* strlcpy */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										927
									
								
								src/portab/vsnprintf.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										927
									
								
								src/portab/vsnprintf.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,927 @@
 | 
			
		||||
/*
 | 
			
		||||
 * ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
 * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * Please read the file COPYING, README and AUTHORS for more information.
 | 
			
		||||
 *
 | 
			
		||||
 * snprintf() and vsnprintf() replacement functions
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "portab.h"
 | 
			
		||||
 | 
			
		||||
static char UNUSED id[] = "$Id: vsnprintf.c,v 1.5 2003/04/21 10:53:38 alex Exp $";
 | 
			
		||||
 | 
			
		||||
#include "imp.h"
 | 
			
		||||
 | 
			
		||||
#include "exp.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * snprintf.c: Copyright Patrick Powell 1995
 | 
			
		||||
 * This code is based on code written by Patrick Powell (papowell@astart.com)
 | 
			
		||||
 * It may be used for any purpose as long as this notice remains intact
 | 
			
		||||
 * on all source code distributions
 | 
			
		||||
 *
 | 
			
		||||
 * Original: Patrick Powell Tue Apr 11 09:48:21 PDT 1995
 | 
			
		||||
 * A bombproof version of doprnt (dopr) included.
 | 
			
		||||
 * Sigh. This sort of thing is always nasty do deal with. Note that
 | 
			
		||||
 * the version here does not include floating point...
 | 
			
		||||
 *
 | 
			
		||||
 * snprintf() is used instead of sprintf() as it does limit checks
 | 
			
		||||
 * for string length. This covers a nasty loophole.
 | 
			
		||||
 *
 | 
			
		||||
 * The other functions are there to prevent NULL pointers from
 | 
			
		||||
 * causing nast effects.
 | 
			
		||||
 *
 | 
			
		||||
 * More Recently:
 | 
			
		||||
 *  Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
 | 
			
		||||
 *  This was ugly. It is still ugly. I opted out of floating point
 | 
			
		||||
 *  numbers, but the formatter understands just about everything
 | 
			
		||||
 *  from the normal C string format, at least as far as I can tell from
 | 
			
		||||
 *  the Solaris 2.5 printf(3S) man page.
 | 
			
		||||
 *
 | 
			
		||||
 * Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
 | 
			
		||||
 *  Ok, added some minimal floating point support, which means this
 | 
			
		||||
 *  probably requires libm on most operating systems. Don't yet
 | 
			
		||||
 *  support the exponent (e,E) and sigfig (g,G). Also, fmtint()
 | 
			
		||||
 *  was pretty badly broken, it just wasn't being exercised in ways
 | 
			
		||||
 *  which showed it, so that's been fixed. Also, formated the code
 | 
			
		||||
 *  to mutt conventions, and removed dead code left over from the
 | 
			
		||||
 *  original. Also, there is now a builtin-test, just compile with:
 | 
			
		||||
 *    gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
 | 
			
		||||
 *  and run snprintf for results.
 | 
			
		||||
 * 
 | 
			
		||||
 * Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
 | 
			
		||||
 *  The PGP code was using unsigned hexadecimal formats. 
 | 
			
		||||
 *  Unfortunately, unsigned formats simply didn't work.
 | 
			
		||||
 *
 | 
			
		||||
 * Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
 | 
			
		||||
 *  The original code assumed that both snprintf() and vsnprintf() were
 | 
			
		||||
 *  missing. Some systems only have snprintf() but not vsnprintf(), so
 | 
			
		||||
 *  the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
 | 
			
		||||
 *
 | 
			
		||||
 * Andrew Tridgell <tridge@samba.org>, October 1998
 | 
			
		||||
 *  fixed handling of %.0f
 | 
			
		||||
 *  added test for HAVE_LONG_DOUBLE
 | 
			
		||||
 *
 | 
			
		||||
 * tridge@samba.org, idra@samba.org, April 2001
 | 
			
		||||
 *  got rid of fcvt code (twas buggy and made testing harder)
 | 
			
		||||
 *  added C99 semantics
 | 
			
		||||
 *
 | 
			
		||||
 * Alexander Barton, <alex@barton.de>, 2002-05-19
 | 
			
		||||
 *  removed [v]asprintf() and C99 tests: not needed by ngIRCd.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_STRING_H
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef HAVE_STRINGS_H
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef HAVE_CTYPE_H
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#ifdef HAVE_STDLIB_H
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF)
 | 
			
		||||
/* only include stdio.h if we are not re-defining snprintf or vsnprintf */
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
/* make the compiler happy with an empty file */
 | 
			
		||||
void dummy_snprintf PARAMS(( void ));
 | 
			
		||||
void dummy_snprintf PARAMS(( void )) { }
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_LONG_DOUBLE
 | 
			
		||||
#define LDOUBLE long double
 | 
			
		||||
#else
 | 
			
		||||
#define LDOUBLE double
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_LONG_LONG
 | 
			
		||||
#define LLONG long long
 | 
			
		||||
#else
 | 
			
		||||
#define LLONG long
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static size_t dopr(char *buffer, size_t maxlen, const char *format, 
 | 
			
		||||
		   va_list args);
 | 
			
		||||
static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
 | 
			
		||||
		    char *value, int flags, int min, int max);
 | 
			
		||||
static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
 | 
			
		||||
		    long value, int base, int min, int max, int flags);
 | 
			
		||||
static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
 | 
			
		||||
		   LDOUBLE fvalue, int min, int max, int flags);
 | 
			
		||||
static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * dopr(): poor man's version of doprintf
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* format read states */
 | 
			
		||||
#define DP_S_DEFAULT 0
 | 
			
		||||
#define DP_S_FLAGS   1
 | 
			
		||||
#define DP_S_MIN     2
 | 
			
		||||
#define DP_S_DOT     3
 | 
			
		||||
#define DP_S_MAX     4
 | 
			
		||||
#define DP_S_MOD     5
 | 
			
		||||
#define DP_S_CONV    6
 | 
			
		||||
#define DP_S_DONE    7
 | 
			
		||||
 | 
			
		||||
/* format flags - Bits */
 | 
			
		||||
#define DP_F_MINUS      (1 << 0)
 | 
			
		||||
#define DP_F_PLUS       (1 << 1)
 | 
			
		||||
#define DP_F_SPACE      (1 << 2)
 | 
			
		||||
#define DP_F_NUM	(1 << 3)
 | 
			
		||||
#define DP_F_ZERO       (1 << 4)
 | 
			
		||||
#define DP_F_UP	 (1 << 5)
 | 
			
		||||
#define DP_F_UNSIGNED   (1 << 6)
 | 
			
		||||
 | 
			
		||||
/* Conversion Flags */
 | 
			
		||||
#define DP_C_SHORT   1
 | 
			
		||||
#define DP_C_LONG    2
 | 
			
		||||
#define DP_C_LDOUBLE 3
 | 
			
		||||
#define DP_C_LLONG   4
 | 
			
		||||
 | 
			
		||||
#define char_to_int(p) ((p)- '0')
 | 
			
		||||
#ifndef MAX
 | 
			
		||||
#define MAX(p,q) (((p) >= (q)) ? (p) : (q))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args)
 | 
			
		||||
{
 | 
			
		||||
	char ch;
 | 
			
		||||
	LLONG value;
 | 
			
		||||
	LDOUBLE fvalue;
 | 
			
		||||
	char *strvalue;
 | 
			
		||||
	int min;
 | 
			
		||||
	int max;
 | 
			
		||||
	int state;
 | 
			
		||||
	int flags;
 | 
			
		||||
	int cflags;
 | 
			
		||||
	size_t currlen;
 | 
			
		||||
	
 | 
			
		||||
	state = DP_S_DEFAULT;
 | 
			
		||||
	currlen = flags = cflags = min = 0;
 | 
			
		||||
	max = -1;
 | 
			
		||||
	ch = *format++;
 | 
			
		||||
	
 | 
			
		||||
	while (state != DP_S_DONE) {
 | 
			
		||||
		if (ch == '\0') 
 | 
			
		||||
			state = DP_S_DONE;
 | 
			
		||||
 | 
			
		||||
		switch(state) {
 | 
			
		||||
		case DP_S_DEFAULT:
 | 
			
		||||
			if (ch == '%') 
 | 
			
		||||
				state = DP_S_FLAGS;
 | 
			
		||||
			else 
 | 
			
		||||
				dopr_outch (buffer, &currlen, maxlen, ch);
 | 
			
		||||
			ch = *format++;
 | 
			
		||||
			break;
 | 
			
		||||
		case DP_S_FLAGS:
 | 
			
		||||
			switch (ch) {
 | 
			
		||||
			case '-':
 | 
			
		||||
				flags |= DP_F_MINUS;
 | 
			
		||||
				ch = *format++;
 | 
			
		||||
				break;
 | 
			
		||||
			case '+':
 | 
			
		||||
				flags |= DP_F_PLUS;
 | 
			
		||||
				ch = *format++;
 | 
			
		||||
				break;
 | 
			
		||||
			case ' ':
 | 
			
		||||
				flags |= DP_F_SPACE;
 | 
			
		||||
				ch = *format++;
 | 
			
		||||
				break;
 | 
			
		||||
			case '#':
 | 
			
		||||
				flags |= DP_F_NUM;
 | 
			
		||||
				ch = *format++;
 | 
			
		||||
				break;
 | 
			
		||||
			case '0':
 | 
			
		||||
				flags |= DP_F_ZERO;
 | 
			
		||||
				ch = *format++;
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				state = DP_S_MIN;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case DP_S_MIN:
 | 
			
		||||
			if (isdigit((unsigned char)ch)) {
 | 
			
		||||
				min = 10*min + char_to_int (ch);
 | 
			
		||||
				ch = *format++;
 | 
			
		||||
			} else if (ch == '*') {
 | 
			
		||||
				min = va_arg (args, int);
 | 
			
		||||
				ch = *format++;
 | 
			
		||||
				state = DP_S_DOT;
 | 
			
		||||
			} else {
 | 
			
		||||
				state = DP_S_DOT;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case DP_S_DOT:
 | 
			
		||||
			if (ch == '.') {
 | 
			
		||||
				state = DP_S_MAX;
 | 
			
		||||
				ch = *format++;
 | 
			
		||||
			} else { 
 | 
			
		||||
				state = DP_S_MOD;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case DP_S_MAX:
 | 
			
		||||
			if (isdigit((unsigned char)ch)) {
 | 
			
		||||
				if (max < 0)
 | 
			
		||||
					max = 0;
 | 
			
		||||
				max = 10*max + char_to_int (ch);
 | 
			
		||||
				ch = *format++;
 | 
			
		||||
			} else if (ch == '*') {
 | 
			
		||||
				max = va_arg (args, int);
 | 
			
		||||
				ch = *format++;
 | 
			
		||||
				state = DP_S_MOD;
 | 
			
		||||
			} else {
 | 
			
		||||
				state = DP_S_MOD;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		case DP_S_MOD:
 | 
			
		||||
			switch (ch) {
 | 
			
		||||
			case 'h':
 | 
			
		||||
				cflags = DP_C_SHORT;
 | 
			
		||||
				ch = *format++;
 | 
			
		||||
				break;
 | 
			
		||||
			case 'l':
 | 
			
		||||
				cflags = DP_C_LONG;
 | 
			
		||||
				ch = *format++;
 | 
			
		||||
				if (ch == 'l') {	/* It's a long long */
 | 
			
		||||
					cflags = DP_C_LLONG;
 | 
			
		||||
					ch = *format++;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case 'L':
 | 
			
		||||
				cflags = DP_C_LDOUBLE;
 | 
			
		||||
				ch = *format++;
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			state = DP_S_CONV;
 | 
			
		||||
			break;
 | 
			
		||||
		case DP_S_CONV:
 | 
			
		||||
			switch (ch) {
 | 
			
		||||
			case 'd':
 | 
			
		||||
			case 'i':
 | 
			
		||||
				if (cflags == DP_C_SHORT) 
 | 
			
		||||
					value = va_arg (args, int);
 | 
			
		||||
				else if (cflags == DP_C_LONG)
 | 
			
		||||
					value = va_arg (args, long int);
 | 
			
		||||
				else if (cflags == DP_C_LLONG)
 | 
			
		||||
					value = va_arg (args, LLONG);
 | 
			
		||||
				else
 | 
			
		||||
					value = va_arg (args, int);
 | 
			
		||||
				fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
 | 
			
		||||
				break;
 | 
			
		||||
			case 'o':
 | 
			
		||||
				flags |= DP_F_UNSIGNED;
 | 
			
		||||
				if (cflags == DP_C_SHORT)
 | 
			
		||||
					value = va_arg (args, unsigned int);
 | 
			
		||||
				else if (cflags == DP_C_LONG)
 | 
			
		||||
					value = (long)va_arg (args, unsigned long int);
 | 
			
		||||
				else if (cflags == DP_C_LLONG)
 | 
			
		||||
					value = (long)va_arg (args, unsigned LLONG);
 | 
			
		||||
				else
 | 
			
		||||
					value = (long)va_arg (args, unsigned int);
 | 
			
		||||
				fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
 | 
			
		||||
				break;
 | 
			
		||||
			case 'u':
 | 
			
		||||
				flags |= DP_F_UNSIGNED;
 | 
			
		||||
				if (cflags == DP_C_SHORT)
 | 
			
		||||
					value = va_arg (args, unsigned int);
 | 
			
		||||
				else if (cflags == DP_C_LONG)
 | 
			
		||||
					value = (long)va_arg (args, unsigned long int);
 | 
			
		||||
				else if (cflags == DP_C_LLONG)
 | 
			
		||||
					value = (LLONG)va_arg (args, unsigned LLONG);
 | 
			
		||||
				else
 | 
			
		||||
					value = (long)va_arg (args, unsigned int);
 | 
			
		||||
				fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
 | 
			
		||||
				break;
 | 
			
		||||
			case 'X':
 | 
			
		||||
				flags |= DP_F_UP;
 | 
			
		||||
			case 'x':
 | 
			
		||||
				flags |= DP_F_UNSIGNED;
 | 
			
		||||
				if (cflags == DP_C_SHORT)
 | 
			
		||||
					value = va_arg (args, unsigned int);
 | 
			
		||||
				else if (cflags == DP_C_LONG)
 | 
			
		||||
					value = (long)va_arg (args, unsigned long int);
 | 
			
		||||
				else if (cflags == DP_C_LLONG)
 | 
			
		||||
					value = (LLONG)va_arg (args, unsigned LLONG);
 | 
			
		||||
				else
 | 
			
		||||
					value = (long)va_arg (args, unsigned int);
 | 
			
		||||
				fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
 | 
			
		||||
				break;
 | 
			
		||||
			case 'f':
 | 
			
		||||
				if (cflags == DP_C_LDOUBLE)
 | 
			
		||||
					fvalue = va_arg (args, LDOUBLE);
 | 
			
		||||
				else
 | 
			
		||||
					fvalue = va_arg (args, double);
 | 
			
		||||
				/* um, floating point? */
 | 
			
		||||
				fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
 | 
			
		||||
				break;
 | 
			
		||||
			case 'E':
 | 
			
		||||
				flags |= DP_F_UP;
 | 
			
		||||
			case 'e':
 | 
			
		||||
				if (cflags == DP_C_LDOUBLE)
 | 
			
		||||
					fvalue = va_arg (args, LDOUBLE);
 | 
			
		||||
				else
 | 
			
		||||
					fvalue = va_arg (args, double);
 | 
			
		||||
				break;
 | 
			
		||||
			case 'G':
 | 
			
		||||
				flags |= DP_F_UP;
 | 
			
		||||
			case 'g':
 | 
			
		||||
				if (cflags == DP_C_LDOUBLE)
 | 
			
		||||
					fvalue = va_arg (args, LDOUBLE);
 | 
			
		||||
				else
 | 
			
		||||
					fvalue = va_arg (args, double);
 | 
			
		||||
				break;
 | 
			
		||||
			case 'c':
 | 
			
		||||
				dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
 | 
			
		||||
				break;
 | 
			
		||||
			case 's':
 | 
			
		||||
				strvalue = va_arg (args, char *);
 | 
			
		||||
				if (max == -1) {
 | 
			
		||||
					max = strlen(strvalue);
 | 
			
		||||
				}
 | 
			
		||||
				if (min > 0 && max >= 0 && min > max) max = min;
 | 
			
		||||
				fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
 | 
			
		||||
				break;
 | 
			
		||||
			case 'p':
 | 
			
		||||
				strvalue = va_arg (args, void *);
 | 
			
		||||
				fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
 | 
			
		||||
				break;
 | 
			
		||||
			case 'n':
 | 
			
		||||
				if (cflags == DP_C_SHORT) {
 | 
			
		||||
					short int *num;
 | 
			
		||||
					num = va_arg (args, short int *);
 | 
			
		||||
					*num = currlen;
 | 
			
		||||
				} else if (cflags == DP_C_LONG) {
 | 
			
		||||
					long int *num;
 | 
			
		||||
					num = va_arg (args, long int *);
 | 
			
		||||
					*num = (long int)currlen;
 | 
			
		||||
				} else if (cflags == DP_C_LLONG) {
 | 
			
		||||
					LLONG *num;
 | 
			
		||||
					num = va_arg (args, LLONG *);
 | 
			
		||||
					*num = (LLONG)currlen;
 | 
			
		||||
				} else {
 | 
			
		||||
					int *num;
 | 
			
		||||
					num = va_arg (args, int *);
 | 
			
		||||
					*num = currlen;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			case '%':
 | 
			
		||||
				dopr_outch (buffer, &currlen, maxlen, ch);
 | 
			
		||||
				break;
 | 
			
		||||
			case 'w':
 | 
			
		||||
				/* not supported yet, treat as next char */
 | 
			
		||||
				ch = *format++;
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				/* Unknown, skip */
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			ch = *format++;
 | 
			
		||||
			state = DP_S_DEFAULT;
 | 
			
		||||
			flags = cflags = min = 0;
 | 
			
		||||
			max = -1;
 | 
			
		||||
			break;
 | 
			
		||||
		case DP_S_DONE:
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			/* hmm? */
 | 
			
		||||
			break; /* some picky compilers need this */
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (maxlen != 0) {
 | 
			
		||||
		if (currlen < maxlen - 1) 
 | 
			
		||||
			buffer[currlen] = '\0';
 | 
			
		||||
		else if (maxlen > 0) 
 | 
			
		||||
			buffer[maxlen - 1] = '\0';
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return currlen;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
 | 
			
		||||
		    char *value, int flags, int min, int max)
 | 
			
		||||
{
 | 
			
		||||
	int padlen, strln;     /* amount to pad */
 | 
			
		||||
	int cnt = 0;
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_SNPRINTF
 | 
			
		||||
	printf("fmtstr min=%d max=%d s=[%s]\n", min, max, value);
 | 
			
		||||
#endif
 | 
			
		||||
	if (value == 0) {
 | 
			
		||||
		value = "<NULL>";
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (strln = 0; value[strln]; ++strln); /* strlen */
 | 
			
		||||
	padlen = min - strln;
 | 
			
		||||
	if (padlen < 0) 
 | 
			
		||||
		padlen = 0;
 | 
			
		||||
	if (flags & DP_F_MINUS) 
 | 
			
		||||
		padlen = -padlen; /* Left Justify */
 | 
			
		||||
	
 | 
			
		||||
	while ((padlen > 0) && (cnt < max)) {
 | 
			
		||||
		dopr_outch (buffer, currlen, maxlen, ' ');
 | 
			
		||||
		--padlen;
 | 
			
		||||
		++cnt;
 | 
			
		||||
	}
 | 
			
		||||
	while (*value && (cnt < max)) {
 | 
			
		||||
		dopr_outch (buffer, currlen, maxlen, *value++);
 | 
			
		||||
		++cnt;
 | 
			
		||||
	}
 | 
			
		||||
	while ((padlen < 0) && (cnt < max)) {
 | 
			
		||||
		dopr_outch (buffer, currlen, maxlen, ' ');
 | 
			
		||||
		++padlen;
 | 
			
		||||
		++cnt;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
 | 
			
		||||
 | 
			
		||||
static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
 | 
			
		||||
		    long value, int base, int min, int max, int flags)
 | 
			
		||||
{
 | 
			
		||||
	int signvalue = 0;
 | 
			
		||||
	unsigned long uvalue;
 | 
			
		||||
	char convert[20];
 | 
			
		||||
	int place = 0;
 | 
			
		||||
	int spadlen = 0; /* amount to space pad */
 | 
			
		||||
	int zpadlen = 0; /* amount to zero pad */
 | 
			
		||||
	int caps = 0;
 | 
			
		||||
	
 | 
			
		||||
	if (max < 0)
 | 
			
		||||
		max = 0;
 | 
			
		||||
	
 | 
			
		||||
	uvalue = value;
 | 
			
		||||
	
 | 
			
		||||
	if(!(flags & DP_F_UNSIGNED)) {
 | 
			
		||||
		if( value < 0 ) {
 | 
			
		||||
			signvalue = '-';
 | 
			
		||||
			uvalue = -value;
 | 
			
		||||
		} else {
 | 
			
		||||
			if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
 | 
			
		||||
				signvalue = '+';
 | 
			
		||||
			else if (flags & DP_F_SPACE)
 | 
			
		||||
				signvalue = ' ';
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
  
 | 
			
		||||
	if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		convert[place++] =
 | 
			
		||||
			(caps? "0123456789ABCDEF":"0123456789abcdef")
 | 
			
		||||
			[uvalue % (unsigned)base  ];
 | 
			
		||||
		uvalue = (uvalue / (unsigned)base );
 | 
			
		||||
	} while(uvalue && (place < 20));
 | 
			
		||||
	if (place == 20) place--;
 | 
			
		||||
	convert[place] = 0;
 | 
			
		||||
 | 
			
		||||
	zpadlen = max - place;
 | 
			
		||||
	spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
 | 
			
		||||
	if (zpadlen < 0) zpadlen = 0;
 | 
			
		||||
	if (spadlen < 0) spadlen = 0;
 | 
			
		||||
	if (flags & DP_F_ZERO) {
 | 
			
		||||
		zpadlen = MAX(zpadlen, spadlen);
 | 
			
		||||
		spadlen = 0;
 | 
			
		||||
	}
 | 
			
		||||
	if (flags & DP_F_MINUS) 
 | 
			
		||||
		spadlen = -spadlen; /* Left Justifty */
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_SNPRINTF
 | 
			
		||||
	printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
 | 
			
		||||
	       zpadlen, spadlen, min, max, place);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* Spaces */
 | 
			
		||||
	while (spadlen > 0) {
 | 
			
		||||
		dopr_outch (buffer, currlen, maxlen, ' ');
 | 
			
		||||
		--spadlen;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Sign */
 | 
			
		||||
	if (signvalue) 
 | 
			
		||||
		dopr_outch (buffer, currlen, maxlen, signvalue);
 | 
			
		||||
 | 
			
		||||
	/* Zeros */
 | 
			
		||||
	if (zpadlen > 0) {
 | 
			
		||||
		while (zpadlen > 0) {
 | 
			
		||||
			dopr_outch (buffer, currlen, maxlen, '0');
 | 
			
		||||
			--zpadlen;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Digits */
 | 
			
		||||
	while (place > 0) 
 | 
			
		||||
		dopr_outch (buffer, currlen, maxlen, convert[--place]);
 | 
			
		||||
  
 | 
			
		||||
	/* Left Justified spaces */
 | 
			
		||||
	while (spadlen < 0) {
 | 
			
		||||
		dopr_outch (buffer, currlen, maxlen, ' ');
 | 
			
		||||
		++spadlen;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static LDOUBLE abs_val(LDOUBLE value)
 | 
			
		||||
{
 | 
			
		||||
	LDOUBLE result = value;
 | 
			
		||||
 | 
			
		||||
	if (value < 0)
 | 
			
		||||
		result = -value;
 | 
			
		||||
	
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static LDOUBLE POW10(int exp)
 | 
			
		||||
{
 | 
			
		||||
	LDOUBLE result = 1;
 | 
			
		||||
	
 | 
			
		||||
	while (exp) {
 | 
			
		||||
		result *= 10;
 | 
			
		||||
		exp--;
 | 
			
		||||
	}
 | 
			
		||||
  
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static LLONG ROUND(LDOUBLE value)
 | 
			
		||||
{
 | 
			
		||||
	LLONG intpart;
 | 
			
		||||
 | 
			
		||||
	intpart = (LLONG)value;
 | 
			
		||||
	value = value - intpart;
 | 
			
		||||
	if (value >= 0.5) intpart++;
 | 
			
		||||
	
 | 
			
		||||
	return intpart;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* a replacement for modf that doesn't need the math library. Should
 | 
			
		||||
   be portable, but slow */
 | 
			
		||||
static double my_modf(double x0, double *iptr)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	long l;
 | 
			
		||||
	double x = x0;
 | 
			
		||||
	double f = 1.0;
 | 
			
		||||
 | 
			
		||||
	for (i=0;i<100;i++) {
 | 
			
		||||
		l = (long)x;
 | 
			
		||||
		if (l <= (x+1) && l >= (x-1)) break;
 | 
			
		||||
		x *= 0.1;
 | 
			
		||||
		f *= 10.0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (i == 100) {
 | 
			
		||||
		/* yikes! the number is beyond what we can handle. What do we do? */
 | 
			
		||||
		(*iptr) = 0;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (i != 0) {
 | 
			
		||||
		double i2;
 | 
			
		||||
		double ret;
 | 
			
		||||
 | 
			
		||||
		ret = my_modf(x0-l*f, &i2);
 | 
			
		||||
		(*iptr) = l*f + i2;
 | 
			
		||||
		return ret;
 | 
			
		||||
	} 
 | 
			
		||||
 | 
			
		||||
	(*iptr) = l;
 | 
			
		||||
	return x - (*iptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
 | 
			
		||||
		   LDOUBLE fvalue, int min, int max, int flags)
 | 
			
		||||
{
 | 
			
		||||
	int signvalue = 0;
 | 
			
		||||
	double ufvalue;
 | 
			
		||||
	char iconvert[311];
 | 
			
		||||
	char fconvert[311];
 | 
			
		||||
	int iplace = 0;
 | 
			
		||||
	int fplace = 0;
 | 
			
		||||
	int padlen = 0; /* amount to pad */
 | 
			
		||||
	int zpadlen = 0; 
 | 
			
		||||
	int caps = 0;
 | 
			
		||||
	int index;
 | 
			
		||||
	double intpart;
 | 
			
		||||
	double fracpart;
 | 
			
		||||
	double temp;
 | 
			
		||||
  
 | 
			
		||||
	/* 
 | 
			
		||||
	 * AIX manpage says the default is 0, but Solaris says the default
 | 
			
		||||
	 * is 6, and sprintf on AIX defaults to 6
 | 
			
		||||
	 */
 | 
			
		||||
	if (max < 0)
 | 
			
		||||
		max = 6;
 | 
			
		||||
 | 
			
		||||
	ufvalue = abs_val (fvalue);
 | 
			
		||||
 | 
			
		||||
	if (fvalue < 0) {
 | 
			
		||||
		signvalue = '-';
 | 
			
		||||
	} else {
 | 
			
		||||
		if (flags & DP_F_PLUS) { /* Do a sign (+/i) */
 | 
			
		||||
			signvalue = '+';
 | 
			
		||||
		} else {
 | 
			
		||||
			if (flags & DP_F_SPACE)
 | 
			
		||||
				signvalue = ' ';
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
	if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
	if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* 
 | 
			
		||||
	 * Sorry, we only support 16 digits past the decimal because of our 
 | 
			
		||||
	 * conversion method
 | 
			
		||||
	 */
 | 
			
		||||
	if (max > 16)
 | 
			
		||||
		max = 16;
 | 
			
		||||
 | 
			
		||||
	/* We "cheat" by converting the fractional part to integer by
 | 
			
		||||
	 * multiplying by a factor of 10
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	temp = ufvalue;
 | 
			
		||||
	my_modf(temp, &intpart);
 | 
			
		||||
 | 
			
		||||
	fracpart = ROUND((POW10(max)) * (ufvalue - intpart));
 | 
			
		||||
	
 | 
			
		||||
	if (fracpart >= POW10(max)) {
 | 
			
		||||
		intpart++;
 | 
			
		||||
		fracpart -= POW10(max);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	/* Convert integer part */
 | 
			
		||||
	do {
 | 
			
		||||
		temp = intpart;
 | 
			
		||||
		my_modf(intpart*0.1, &intpart);
 | 
			
		||||
		temp = temp*0.1;
 | 
			
		||||
		index = (int) ((temp -intpart +0.05)* 10.0);
 | 
			
		||||
		/* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */
 | 
			
		||||
		/* printf ("%llf, %f, %x\n", temp, intpart, index); */
 | 
			
		||||
		iconvert[iplace++] =
 | 
			
		||||
			(caps? "0123456789ABCDEF":"0123456789abcdef")[index];
 | 
			
		||||
	} while (intpart && (iplace < 311));
 | 
			
		||||
	if (iplace == 311) iplace--;
 | 
			
		||||
	iconvert[iplace] = 0;
 | 
			
		||||
 | 
			
		||||
	/* Convert fractional part */
 | 
			
		||||
	if (fracpart)
 | 
			
		||||
	{
 | 
			
		||||
		do {
 | 
			
		||||
			temp = fracpart;
 | 
			
		||||
			my_modf(fracpart*0.1, &fracpart);
 | 
			
		||||
			temp = temp*0.1;
 | 
			
		||||
			index = (int) ((temp -fracpart +0.05)* 10.0);
 | 
			
		||||
			/* index = (int) ((((temp/10) -fracpart) +0.05) *10); */
 | 
			
		||||
			/* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */
 | 
			
		||||
			fconvert[fplace++] =
 | 
			
		||||
			(caps? "0123456789ABCDEF":"0123456789abcdef")[index];
 | 
			
		||||
		} while(fracpart && (fplace < 311));
 | 
			
		||||
		if (fplace == 311) fplace--;
 | 
			
		||||
	}
 | 
			
		||||
	fconvert[fplace] = 0;
 | 
			
		||||
  
 | 
			
		||||
	/* -1 for decimal point, another -1 if we are printing a sign */
 | 
			
		||||
	padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 
 | 
			
		||||
	zpadlen = max - fplace;
 | 
			
		||||
	if (zpadlen < 0) zpadlen = 0;
 | 
			
		||||
	if (padlen < 0) 
 | 
			
		||||
		padlen = 0;
 | 
			
		||||
	if (flags & DP_F_MINUS) 
 | 
			
		||||
		padlen = -padlen; /* Left Justifty */
 | 
			
		||||
	
 | 
			
		||||
	if ((flags & DP_F_ZERO) && (padlen > 0)) {
 | 
			
		||||
		if (signvalue) {
 | 
			
		||||
			dopr_outch (buffer, currlen, maxlen, signvalue);
 | 
			
		||||
			--padlen;
 | 
			
		||||
			signvalue = 0;
 | 
			
		||||
		}
 | 
			
		||||
		while (padlen > 0) {
 | 
			
		||||
			dopr_outch (buffer, currlen, maxlen, '0');
 | 
			
		||||
			--padlen;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	while (padlen > 0) {
 | 
			
		||||
		dopr_outch (buffer, currlen, maxlen, ' ');
 | 
			
		||||
		--padlen;
 | 
			
		||||
	}
 | 
			
		||||
	if (signvalue) 
 | 
			
		||||
		dopr_outch (buffer, currlen, maxlen, signvalue);
 | 
			
		||||
	
 | 
			
		||||
	while (iplace > 0) 
 | 
			
		||||
		dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG_SNPRINTF
 | 
			
		||||
	printf("fmtfp: fplace=%d zpadlen=%d\n", fplace, zpadlen);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Decimal point.  This should probably use locale to find the correct
 | 
			
		||||
	 * char to print out.
 | 
			
		||||
	 */
 | 
			
		||||
	if (max > 0) {
 | 
			
		||||
		dopr_outch (buffer, currlen, maxlen, '.');
 | 
			
		||||
		
 | 
			
		||||
		while (fplace > 0) 
 | 
			
		||||
			dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	while (zpadlen > 0) {
 | 
			
		||||
		dopr_outch (buffer, currlen, maxlen, '0');
 | 
			
		||||
		--zpadlen;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	while (padlen < 0) {
 | 
			
		||||
		dopr_outch (buffer, currlen, maxlen, ' ');
 | 
			
		||||
		++padlen;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
 | 
			
		||||
{
 | 
			
		||||
	if (*currlen < maxlen) {
 | 
			
		||||
		buffer[(*currlen)] = c;
 | 
			
		||||
	}
 | 
			
		||||
	(*currlen)++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !defined(HAVE_VSNPRINTF)
 | 
			
		||||
int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
 | 
			
		||||
{
 | 
			
		||||
	return dopr(str, count, fmt, args);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if !defined(HAVE_SNPRINTF)
 | 
			
		||||
int snprintf(char *str,size_t count,const char *fmt,...)
 | 
			
		||||
{
 | 
			
		||||
	size_t ret;
 | 
			
		||||
	va_list ap;
 | 
			
		||||
    
 | 
			
		||||
	va_start(ap, fmt);
 | 
			
		||||
	ret = vsnprintf(str, count, fmt, ap);
 | 
			
		||||
	va_end(ap);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef TEST_SNPRINTF
 | 
			
		||||
int sprintf(char *str,const char *fmt,...);
 | 
			
		||||
int main (void)
 | 
			
		||||
{
 | 
			
		||||
	char buf1[1024];
 | 
			
		||||
	char buf2[1024];
 | 
			
		||||
	char *fp_fmt[] = {
 | 
			
		||||
		"%1.1f",
 | 
			
		||||
		"%-1.5f",
 | 
			
		||||
		"%1.5f",
 | 
			
		||||
		"%123.9f",
 | 
			
		||||
		"%10.5f",
 | 
			
		||||
		"% 10.5f",
 | 
			
		||||
		"%+22.9f",
 | 
			
		||||
		"%+4.9f",
 | 
			
		||||
		"%01.3f",
 | 
			
		||||
		"%4f",
 | 
			
		||||
		"%3.1f",
 | 
			
		||||
		"%3.2f",
 | 
			
		||||
		"%.0f",
 | 
			
		||||
		"%f",
 | 
			
		||||
		"-16.16f",
 | 
			
		||||
		NULL
 | 
			
		||||
	};
 | 
			
		||||
	double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 
 | 
			
		||||
			     0.9996, 1.996, 4.136,  0};
 | 
			
		||||
	char *int_fmt[] = {
 | 
			
		||||
		"%-1.5d",
 | 
			
		||||
		"%1.5d",
 | 
			
		||||
		"%123.9d",
 | 
			
		||||
		"%5.5d",
 | 
			
		||||
		"%10.5d",
 | 
			
		||||
		"% 10.5d",
 | 
			
		||||
		"%+22.33d",
 | 
			
		||||
		"%01.3d",
 | 
			
		||||
		"%4d",
 | 
			
		||||
		"%d",
 | 
			
		||||
		NULL
 | 
			
		||||
	};
 | 
			
		||||
	long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
 | 
			
		||||
	char *str_fmt[] = {
 | 
			
		||||
		"10.5s",
 | 
			
		||||
		"5.10s",
 | 
			
		||||
		"10.1s",
 | 
			
		||||
		"0.10s",
 | 
			
		||||
		"10.0s",
 | 
			
		||||
		"1.10s",
 | 
			
		||||
		"%s",
 | 
			
		||||
		"%.1s",
 | 
			
		||||
		"%.10s",
 | 
			
		||||
		"%10s",
 | 
			
		||||
		NULL
 | 
			
		||||
	};
 | 
			
		||||
	char *str_vals[] = {"hello", "a", "", "a longer string", NULL};
 | 
			
		||||
	int x, y;
 | 
			
		||||
	int fail = 0;
 | 
			
		||||
	int num = 0;
 | 
			
		||||
 | 
			
		||||
	printf ("Testing snprintf format codes against system sprintf...\n");
 | 
			
		||||
 | 
			
		||||
	for (x = 0; fp_fmt[x] ; x++) {
 | 
			
		||||
		for (y = 0; fp_nums[y] != 0 ; y++) {
 | 
			
		||||
			int l1 = snprintf(NULL, 0, fp_fmt[x], fp_nums[y]);
 | 
			
		||||
			int l2 = snprintf(buf1, sizeof(buf1), fp_fmt[x], fp_nums[y]);
 | 
			
		||||
			sprintf (buf2, fp_fmt[x], fp_nums[y]);
 | 
			
		||||
			if (strcmp (buf1, buf2)) {
 | 
			
		||||
				printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", 
 | 
			
		||||
				       fp_fmt[x], buf1, buf2);
 | 
			
		||||
				fail++;
 | 
			
		||||
			}
 | 
			
		||||
			if (l1 != l2) {
 | 
			
		||||
				printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, fp_fmt[x]);
 | 
			
		||||
				fail++;
 | 
			
		||||
			}
 | 
			
		||||
			num++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (x = 0; int_fmt[x] ; x++) {
 | 
			
		||||
		for (y = 0; int_nums[y] != 0 ; y++) {
 | 
			
		||||
			int l1 = snprintf(NULL, 0, int_fmt[x], int_nums[y]);
 | 
			
		||||
			int l2 = snprintf(buf1, sizeof(buf1), int_fmt[x], int_nums[y]);
 | 
			
		||||
			sprintf (buf2, int_fmt[x], int_nums[y]);
 | 
			
		||||
			if (strcmp (buf1, buf2)) {
 | 
			
		||||
				printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", 
 | 
			
		||||
				       int_fmt[x], buf1, buf2);
 | 
			
		||||
				fail++;
 | 
			
		||||
			}
 | 
			
		||||
			if (l1 != l2) {
 | 
			
		||||
				printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, int_fmt[x]);
 | 
			
		||||
				fail++;
 | 
			
		||||
			}
 | 
			
		||||
			num++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (x = 0; str_fmt[x] ; x++) {
 | 
			
		||||
		for (y = 0; str_vals[y] != 0 ; y++) {
 | 
			
		||||
			int l1 = snprintf(NULL, 0, str_fmt[x], str_vals[y]);
 | 
			
		||||
			int l2 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]);
 | 
			
		||||
			sprintf (buf2, str_fmt[x], str_vals[y]);
 | 
			
		||||
			if (strcmp (buf1, buf2)) {
 | 
			
		||||
				printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", 
 | 
			
		||||
				       str_fmt[x], buf1, buf2);
 | 
			
		||||
				fail++;
 | 
			
		||||
			}
 | 
			
		||||
			if (l1 != l2) {
 | 
			
		||||
				printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, str_fmt[x]);
 | 
			
		||||
				fail++;
 | 
			
		||||
			}
 | 
			
		||||
			num++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	printf ("%d tests failed out of %d.\n", fail, num);
 | 
			
		||||
 | 
			
		||||
	printf("seeing how many digits we support\n");
 | 
			
		||||
	{
 | 
			
		||||
		double v0 = 0.12345678901234567890123456789012345678901;
 | 
			
		||||
		for (x=0; x<100; x++) {
 | 
			
		||||
			snprintf(buf1, sizeof(buf1), "%1.1f", v0*pow(10, x));
 | 
			
		||||
			sprintf(buf2,		"%1.1f", v0*pow(10, x));
 | 
			
		||||
			if (strcmp(buf1, buf2)) {
 | 
			
		||||
				printf("we seem to support %d digits\n", x-1);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif /* SNPRINTF_TEST */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* -eof- */
 | 
			
		||||
							
								
								
									
										55
									
								
								src/testsuite/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/testsuite/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
#
 | 
			
		||||
# ngIRCd -- The Next Generation IRC Daemon
 | 
			
		||||
# Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
 | 
			
		||||
#
 | 
			
		||||
# Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen
 | 
			
		||||
# der GNU General Public License (GPL), wie von der Free Software Foundation
 | 
			
		||||
# 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.
 | 
			
		||||
#
 | 
			
		||||
# $Id: Makefile.am,v 1.9 2002/11/10 14:28:06 alex Exp $
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
AUTOMAKE_OPTIONS = ../portab/ansi2knr
 | 
			
		||||
 | 
			
		||||
INCLUDES = -I$(srcdir)/../portab
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = \
 | 
			
		||||
	getpid.sh \
 | 
			
		||||
	start-server.sh stop-server.sh tests.sh stress-server.sh \
 | 
			
		||||
	connect-test.e channel-test.e mode-test.e \
 | 
			
		||||
	stress-A.e stress-B.e check-idle.e \
 | 
			
		||||
	ngircd-test.conf
 | 
			
		||||
 | 
			
		||||
clean-local:
 | 
			
		||||
	rm -rf logs tests *-test ngircd-test.log ngircd-test.motd \
 | 
			
		||||
	 T-ngircd procs.tmp 
 | 
			
		||||
 | 
			
		||||
maintainer-clean-local:
 | 
			
		||||
	rm -f Makefile Makefile.in
 | 
			
		||||
 | 
			
		||||
check_SCRIPTS = ngircd-TEST-Binary tests.sh
 | 
			
		||||
 | 
			
		||||
ngircd-TEST-Binary:
 | 
			
		||||
	cp ../ngircd/ngircd T-ngircd
 | 
			
		||||
	[ -f getpid.sh ] || ln -s $(srcdir)/getpid.sh .
 | 
			
		||||
 | 
			
		||||
connect-test: tests.sh
 | 
			
		||||
	ln -s $(srcdir)/tests.sh connect-test
 | 
			
		||||
 | 
			
		||||
channel-test: tests.sh
 | 
			
		||||
	ln -s $(srcdir)/tests.sh channel-test
 | 
			
		||||
 | 
			
		||||
mode-test: tests.sh
 | 
			
		||||
	ln -s $(srcdir)/tests.sh mode-test
 | 
			
		||||
 | 
			
		||||
TESTS = start-server.sh \
 | 
			
		||||
	connect-test \
 | 
			
		||||
	channel-test \
 | 
			
		||||
	mode-test \
 | 
			
		||||
	stress-server.sh \
 | 
			
		||||
	stop-server.sh
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
							
								
								
									
										74
									
								
								src/testsuite/channel-test.e
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/testsuite/channel-test.e
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
# $Id: channel-test.e,v 1.2 2002/09/09 21:26:00 alex Exp $
 | 
			
		||||
 | 
			
		||||
spawn telnet localhost 6789
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"Connected"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "nick nick\r"
 | 
			
		||||
send "user user . . :User\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"376"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "join #channel\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	":nick!~user@* JOIN :#channel"
 | 
			
		||||
}
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"366"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "topic #channel :Test-Topic\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	":nick!~user@* TOPIC #channel :Test-Topic"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "who #channel\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"352 nick #channel ~user * nick H@ :0 User"
 | 
			
		||||
}
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"315 nick #channel"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "names #channel\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"353 nick = #channel :@nick"
 | 
			
		||||
}
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"366 nick #channel"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "list\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"322 nick #channel 1 :Test-Topic"
 | 
			
		||||
}
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"323 nick :End of LIST"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "part #channel\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	":nick!~user@* PART #channel :nick"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "quit\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"Connection closed"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
							
								
								
									
										31
									
								
								src/testsuite/check-idle.e
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/testsuite/check-idle.e
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
# $Id: check-idle.e,v 1.1 2002/09/09 22:56:07 alex Exp $
 | 
			
		||||
 | 
			
		||||
spawn telnet localhost 6789
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"Connected"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "nick IdleTest\r"
 | 
			
		||||
send "user idle . . :Idle-Test\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"376"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "lusers\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"251 IdleTest :There are 1 users and 0 services on 1 servers" { set r 0 }
 | 
			
		||||
	"251 IdleTest :There are" { set r 99 }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "quit\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"Connection closed"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
exit $r
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
							
								
								
									
										21
									
								
								src/testsuite/connect-test.e
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/testsuite/connect-test.e
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
# $Id: connect-test.e,v 1.1 2002/09/09 10:16:24 alex Exp $
 | 
			
		||||
 | 
			
		||||
spawn telnet localhost 6789
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"Connected"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "oper\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"451"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "quit\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"Connection closed"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
							
								
								
									
										39
									
								
								src/testsuite/getpid.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										39
									
								
								src/testsuite/getpid.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,39 @@
 | 
			
		||||
#!/bin/sh
 | 
			
		||||
# ngIRCd Test Suite
 | 
			
		||||
# $Id: getpid.sh,v 1.2.4.2 2003/11/07 20:51:11 alex Exp $
 | 
			
		||||
 | 
			
		||||
# did we get a name?
 | 
			
		||||
[ $# -ne 1 ] && exit 1
 | 
			
		||||
 | 
			
		||||
# detect flags for "ps" and "head"
 | 
			
		||||
if [ `uname` = "FreeBSD" ]; then
 | 
			
		||||
  PS_FLAGS="-a"; PS_PIDCOL="1"; HEAD_FLAGS="-n 1"
 | 
			
		||||
elif [ `uname` = "A/UX" ]; then
 | 
			
		||||
  PS_FLAGS="-ae"; PS_PIDCOL="1"; HEAD_FLAGS="-1"
 | 
			
		||||
elif [ `uname` = "GNU" ]; then
 | 
			
		||||
  PS_FLAGS="-ax"; PS_PIDCOL="2"; HEAD_FLAGS="-n 1"
 | 
			
		||||
else
 | 
			
		||||
  PS_FLAGS="-f"; PS_PIDCOL="2"; HEAD_FLAGS="-n 1"
 | 
			
		||||
  ps $PS_FLAGS > /dev/null 2>&1
 | 
			
		||||
  if [ $? -ne 0 ]; then PS_FLAGS="a"; PS_PIDCOL="1"; fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# debug output
 | 
			
		||||
#echo "$0: PS_FLAGS=$PS_FLAGS"
 | 
			
		||||
#echo "$0: PS_PIDCOL=$PS_PIDCOL"
 | 
			
		||||
#echo "$0: HEAD_FLAGS=$HEAD_FLAGS"
 | 
			
		||||
 | 
			
		||||
# search PID
 | 
			
		||||
ps $PS_FLAGS > procs.tmp
 | 
			
		||||
cat procs.tmp | grep -v "$0" | grep "$1" | awk "{print \$$PS_PIDCOL}" | sort -n > pids.tmp
 | 
			
		||||
pid=`head $HEAD_FLAGS pids.tmp`
 | 
			
		||||
rm -rf procs.tmp pids.tmp
 | 
			
		||||
 | 
			
		||||
# validate PID
 | 
			
		||||
[ "$pid" -gt 1 ] > /dev/null 2>&1
 | 
			
		||||
[ $? -ne 0 ] && exit 1
 | 
			
		||||
 | 
			
		||||
echo $pid
 | 
			
		||||
exit 0
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
							
								
								
									
										108
									
								
								src/testsuite/mode-test.e
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								src/testsuite/mode-test.e
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
# $Id: mode-test.e,v 1.4 2002/12/15 15:52:34 alex Exp $
 | 
			
		||||
 | 
			
		||||
spawn telnet localhost 6789
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"Connected"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "nick nick\r"
 | 
			
		||||
send "user user . . :User\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"376"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "mode nick +i\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	":nick!~user@* MODE nick +i"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "mode nick\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"221 nick +i"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "mode nick -i\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	":nick!~user@* MODE nick -i"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "oper TestOp 123\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"MODE nick :+o"
 | 
			
		||||
}
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"381 nick"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "mode nick\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"221 nick +o"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "join #channel\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	":nick!~user@* JOIN :#channel"
 | 
			
		||||
}
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"366"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "mode #channel +tn\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	":nick!~user@* MODE #channel +tn"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "mode #channel\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"324 nick #channel +tn"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "mode #channel +v nick\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	":nick!~user@* MODE #channel +v nick"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "mode #channel +I nick1\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	":nick!~user@* MODE #channel +I nick1!*@*"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "mode #channel +b nick2@domain\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	":nick!~user@* MODE #channel +b nick2!*@domain"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "mode #channel +I nick3!user\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	":nick!~user@* MODE #channel +I nick3!user@*"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "mode #channel -vo nick nick\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	":nick!~user@* MODE #channel -vo nick nick"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
send "quit\r"
 | 
			
		||||
expect {
 | 
			
		||||
	timeout { exit 1 }
 | 
			
		||||
	"Connection closed"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
							
								
								
									
										15
									
								
								src/testsuite/ngircd-test.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/testsuite/ngircd-test.conf
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
# $Id: ngircd-test.conf,v 1.3.4.1 2003/11/07 20:51:11 alex Exp $
 | 
			
		||||
 | 
			
		||||
[Global]
 | 
			
		||||
	Name = ngircd.test.server
 | 
			
		||||
	Info = ngIRCd Test-Server
 | 
			
		||||
	Ports = 6789
 | 
			
		||||
	MotdFile = ngircd-test.motd
 | 
			
		||||
	AdminEMail = admin@irc.server
 | 
			
		||||
	MaxConnectionsIP = 0
 | 
			
		||||
 | 
			
		||||
[Operator]
 | 
			
		||||
	Name = TestOp
 | 
			
		||||
	Password = 123
 | 
			
		||||
 | 
			
		||||
# -eof-
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user