mirror of
https://github.com/osmarks/ngircd.git
synced 2025-10-25 19:17:38 +00:00
Compare commits
747 Commits
rel-0-1-0
...
branch-0-6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4726e36efc | ||
|
|
3105bd9fff | ||
|
|
cb8ed9d5da | ||
|
|
a156641afd | ||
|
|
78752bbff8 | ||
|
|
90e6ec3f89 | ||
|
|
9810da343c | ||
|
|
e8b99f4d3a | ||
|
|
84efd5e969 | ||
|
|
33927ee854 | ||
|
|
3d46fc6036 | ||
|
|
ac587adc69 | ||
|
|
2688829ddd | ||
|
|
4294dd8043 | ||
|
|
6b9ce1cb72 | ||
|
|
72a4c0489f | ||
|
|
60a4085c38 | ||
|
|
5206ab302d | ||
|
|
635afd660d | ||
|
|
5b3d89312e | ||
|
|
f7c1242979 | ||
|
|
822d3d12c8 | ||
|
|
7de53b1903 | ||
|
|
9e3def72e0 | ||
|
|
3da58202e6 | ||
|
|
ec016a89e2 | ||
|
|
1bcc64721f | ||
|
|
939ec25f72 | ||
|
|
1f7024cb36 | ||
|
|
c2fcc98a55 | ||
|
|
fe06c3200e | ||
|
|
dd7ff82b8f | ||
|
|
f84cd22fe1 | ||
|
|
3544d1bc40 | ||
|
|
6c88184b58 | ||
|
|
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 | ||
|
|
b58ab32b9f | ||
|
|
85aad86906 | ||
|
|
d79b2f0a35 | ||
|
|
c5eaea7161 | ||
|
|
e506ae44e0 | ||
|
|
bebf0383d0 | ||
|
|
1c99b8377f | ||
|
|
c9e8d4bbad | ||
|
|
d68fb7a320 | ||
|
|
7efefd30f1 | ||
|
|
fe06f6e990 | ||
|
|
3d74a9c323 | ||
|
|
1c2d0ae5de | ||
|
|
07c3e62e11 | ||
|
|
773d886df6 | ||
|
|
d47f88427d | ||
|
|
95d55c56c6 | ||
|
|
4cdc98154c | ||
|
|
d4a9ceae75 | ||
|
|
6fbb2b7a67 | ||
|
|
1c00ddffec | ||
|
|
f4b23bfc96 | ||
|
|
72accd4ee5 | ||
|
|
d7ecb84847 | ||
|
|
da8da1ce7d | ||
|
|
20a2ffef88 | ||
|
|
6b58ab8427 | ||
|
|
e9b98fefc6 | ||
|
|
95be386e9d | ||
|
|
a89dc54690 | ||
|
|
e8668cf593 | ||
|
|
bdf53a6d29 | ||
|
|
d09dfb3e36 | ||
|
|
f86083a057 | ||
|
|
bcc5138518 | ||
|
|
e39925af9b | ||
|
|
d58fe2f185 | ||
|
|
b79ba679a1 | ||
|
|
8d79f26721 | ||
|
|
95a4b1b158 | ||
|
|
c0ef984273 | ||
|
|
a323186926 | ||
|
|
117c1df65a | ||
|
|
d4fca86ae8 | ||
|
|
bc4ed22635 | ||
|
|
c74083645a | ||
|
|
0ac6151be9 | ||
|
|
b5c16c228b | ||
|
|
cec0e2a4d7 | ||
|
|
0e38d10bcd | ||
|
|
7bb2c6b012 | ||
|
|
281d8e454d | ||
|
|
8e5a56cea7 | ||
|
|
0df6a76103 | ||
|
|
fdf23efef4 | ||
|
|
d7d2ab3d7f | ||
|
|
b9a2c4a8ec | ||
|
|
69f683070a | ||
|
|
31015c8306 | ||
|
|
b422b11865 | ||
|
|
8a45b177ce | ||
|
|
28c5a21fa0 | ||
|
|
239727b411 | ||
|
|
34d5434478 | ||
|
|
03c3f3c990 | ||
|
|
9146fa2534 | ||
|
|
882c91280e | ||
|
|
e298b83b92 | ||
|
|
c46f623d6f | ||
|
|
27d131a177 | ||
|
|
7049b60af4 | ||
|
|
7633e2f8c3 | ||
|
|
ca33cbda05 | ||
|
|
d18ca0b85d | ||
|
|
fbfb343176 | ||
|
|
f7a0ff1f65 | ||
|
|
50ec7a56a4 | ||
|
|
92793d3114 | ||
|
|
9fc7e66f66 | ||
|
|
590f2a3f0c | ||
|
|
221058009c | ||
|
|
5fa05dcea8 | ||
|
|
dce77559fa | ||
|
|
df09e7afd3 | ||
|
|
2464556a7d | ||
|
|
a8aab6bfdd | ||
|
|
23add79c3e | ||
|
|
e6faca1337 | ||
|
|
d67d94ea04 | ||
|
|
0777bca325 | ||
|
|
0903e7763c | ||
|
|
89f9522e22 | ||
|
|
965855756b | ||
|
|
5bd4734a88 | ||
|
|
37c7087c6f | ||
|
|
317941d840 | ||
|
|
652a003ef5 | ||
|
|
81889df4b7 | ||
|
|
0e092b3f06 | ||
|
|
2006b6195e | ||
|
|
fe2bc90e45 | ||
|
|
10aa35cc91 | ||
|
|
c68c092ce3 | ||
|
|
0a13ff41ea | ||
|
|
ae6ab2c3e0 | ||
|
|
b3a64f5e08 | ||
|
|
802a17b11d | ||
|
|
2b6309719f | ||
|
|
5562f411c4 | ||
|
|
a1a3e67de6 | ||
|
|
7de4683506 | ||
|
|
360bddd600 | ||
|
|
9d5551ba6d | ||
|
|
14aba7c1b2 | ||
|
|
10363b398e | ||
|
|
2ee05c9a68 | ||
|
|
8dd92fbcd8 | ||
|
|
e7214c151f | ||
|
|
829f741ccd | ||
|
|
6878d25d04 | ||
|
|
250ef1ab55 | ||
|
|
7b8b542396 | ||
|
|
5457e0788a | ||
|
|
09da2c9afd | ||
|
|
7157d93651 | ||
|
|
0370c4843f | ||
|
|
a3ee1a9a26 | ||
|
|
cbce54e0fc | ||
|
|
5facc989c5 | ||
|
|
02f394f0ce | ||
|
|
6da91c34b4 | ||
|
|
40f07f2f5c | ||
|
|
ef7f7a90f4 | ||
|
|
c23199d971 | ||
|
|
b56eb4d8d4 | ||
|
|
d022c1bf4e | ||
|
|
fc186d77c1 | ||
|
|
ff54198f43 | ||
|
|
a22a3d5f29 | ||
|
|
070da48826 | ||
|
|
9780ed1f21 | ||
|
|
d59f029043 | ||
|
|
d58e22a3ea | ||
|
|
8975c7a204 | ||
|
|
52548bd3e3 | ||
|
|
caf41e5bba | ||
|
|
3c01ac4e33 | ||
|
|
949977e878 | ||
|
|
83177581e4 | ||
|
|
18d881876d | ||
|
|
c48501245e | ||
|
|
b53b5728a6 | ||
|
|
cd6e40493c | ||
|
|
82da6d2ff1 | ||
|
|
f99a8ed18f | ||
|
|
a7bbcef6e0 | ||
|
|
c147ebef0d | ||
|
|
153aa0aac8 | ||
|
|
28d5898617 | ||
|
|
140d1aa505 | ||
|
|
d360137d94 | ||
|
|
805096d173 | ||
|
|
70e3c6b50a | ||
|
|
b181f1bd3c | ||
|
|
1575e30d77 | ||
|
|
e4754c3447 | ||
|
|
180095be32 | ||
|
|
93a52dfab8 | ||
|
|
08d43d5f67 | ||
|
|
1ff2fceb22 | ||
|
|
8c956d5989 | ||
|
|
6817e293c5 | ||
|
|
67295c48ca | ||
|
|
b7a6bf27cc | ||
|
|
abe6a2c107 | ||
|
|
c90cf7c9ed | ||
|
|
ed1dac585d | ||
|
|
a809fe36c7 | ||
|
|
62266a8d46 | ||
|
|
498e6e0d22 | ||
|
|
5d306a1dc9 | ||
|
|
aaa682fb24 | ||
|
|
6f955d2a34 | ||
|
|
8465653c6e | ||
|
|
2a69ee905a | ||
|
|
3c233aa9c5 | ||
|
|
0253bcc8af | ||
|
|
367657fd36 | ||
|
|
944352717a | ||
|
|
1b30228caa | ||
|
|
9919f38dae | ||
|
|
2617d21336 | ||
|
|
c66702c6d4 | ||
|
|
eea1a88b24 | ||
|
|
d1382fab5c | ||
|
|
fcb47ae64b | ||
|
|
1fe8355fcf | ||
|
|
26ffbc7850 | ||
|
|
b0482db966 | ||
|
|
0470cdfdcc | ||
|
|
b80fc259d8 | ||
|
|
efe152336c | ||
|
|
3fbbfe44ed | ||
|
|
5a8a789511 | ||
|
|
458174ffb0 | ||
|
|
00529c8fbd | ||
|
|
71fa0781d4 | ||
|
|
8fdb46361d | ||
|
|
3232c7d245 | ||
|
|
2c0a42e935 | ||
|
|
a233adfbd8 | ||
|
|
9f3a9df24a | ||
|
|
44b396d9a5 | ||
|
|
25e1e8b690 | ||
|
|
b60f369266 | ||
|
|
1b1b718e7e | ||
|
|
ce2738c984 | ||
|
|
bec7783ec9 | ||
|
|
db7ea9c4b3 | ||
|
|
2d87beed3d | ||
|
|
05a493e1d0 | ||
|
|
825711973a | ||
|
|
621a3ca102 | ||
|
|
57f36fc883 | ||
|
|
213fa0994f | ||
|
|
b10d05f2d2 | ||
|
|
645aeacf0a | ||
|
|
70ac29b253 | ||
|
|
f3f121b8f8 | ||
|
|
f908e78118 | ||
|
|
e1a1e7ecf4 | ||
|
|
6610d6e4ba | ||
|
|
207937da2a | ||
|
|
84a2f8ab26 | ||
|
|
5ef9ff5b2d | ||
|
|
617cdf068e | ||
|
|
d2d6dcbb1f | ||
|
|
0595f42fbe | ||
|
|
b9f005af75 | ||
|
|
2184b3615b | ||
|
|
d72c55a09d | ||
|
|
4da8fc54ac | ||
|
|
5c48cbff1d | ||
|
|
f29ae5ae0e | ||
|
|
175b20bbb5 | ||
|
|
33944e8cdb | ||
|
|
40c9f5c332 | ||
|
|
f53914b17a | ||
|
|
6e9ec92974 |
2
COPYING
2
COPYING
@@ -2,7 +2,7 @@
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
323
ChangeLog
323
ChangeLog
@@ -1,15 +1,329 @@
|
||||
|
||||
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 --
|
||||
|
||||
|
||||
ngIRCd 0.6.x
|
||||
|
||||
- Conn_Close() now handles recurisive calls for the same link correctly.
|
||||
|
||||
ngIRCd 0.6.1, 2002-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 syncronized 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 Unterstuetzung von Masks).
|
||||
- Der AWAY-Mode wurde nicht ueber mehrere Server-Links weitergegeben.
|
||||
- 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.
|
||||
- In Nicknames wird das Zeichen "-" nun als zulaessig erkannt.
|
||||
- die Beispiel-Konfigurationsdatei (doc/sample-ngircd.conf) wird als
|
||||
ngircd.conf installiert, wenn noch keine "echte" Konfigurationsdatei
|
||||
vorhanden ist.
|
||||
- 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
|
||||
einer Gruppe eine Verbindung aufgebaut, klappt es beim ersten Server
|
||||
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).
|
||||
- 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 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
|
||||
|
||||
- bekommt der Server ein HUP-Signal, so startet er neu -- genau so, wie
|
||||
er auf den IRC-Befehl RESTART reagiert.
|
||||
- FAQ um Hinweise auf den Bugtracker erweitert.
|
||||
- neuer Kommandozeilen-Schalter "--passive" (-p): wird er angegeben, so
|
||||
verbindet sich der ngIRCd nicht mehr automatisch zu anderen Servern.
|
||||
Zum Debuggen manchmal ganz praktisch :-)
|
||||
- direkt nach dem Start schreibt der ngIRCd nun die aktiven Kommando-
|
||||
zeilenschalter in's Logfile (Passive, Debug, Sniffer ...).
|
||||
- das Signal-Flag SA_RESTART wird nur noch gesetzt, wenn es auf dem
|
||||
jeweiligen System auch definiert ist.
|
||||
- bei ausgehenden Verbindungen wird nun der Ziel-Port protokolliert.
|
||||
- neue Befehle VERSION und KILL implementiert.
|
||||
- make-Target "check" (und "distcheck") mit Sinn erfuellt :-)
|
||||
(die Tests sind aber bisher nicht all zu tiefgehend ...)
|
||||
- Durch einen Ueberlauf konnte die Idle-Time bei WHOIS negativ werden ...
|
||||
- Anpassungen an A/UX: gehoert nun auch zu den unterstuetzten Platformen.
|
||||
- WHOIS wird nicht mehr automatisch an den "Original-Server" weiterge-
|
||||
leitet: war eh nicht RFC-konform und machte mit Clients Probleme.
|
||||
- an User wird nun immer ein "komplettes" Prefix (mit Host-Mask) ver-
|
||||
schickt, Server bekommen nach wie vor kurze: das "Original" hat bei
|
||||
bestimmten Befehlen (PRIVMSG) ansonsten evtl. Probleme ...
|
||||
- NAMES korrigiert und vollstaendig implementiert.
|
||||
- SQUIT wird auf jeden Fall geforwarded, zudem besseres Logging.
|
||||
- Ist ein Nick bei der User-Registrierung bereits belegt, nimmt der
|
||||
Server nun korrekt weitere NICK-Befehle an und verwendet diese.
|
||||
- PRIVMSG beachtet nun die Channel-Modes "n" und "m".
|
||||
- AWAY implementiert. PRIVMSG, MODE, USERHOST und WHOIS angepasst.
|
||||
- der ngIRCd unterstuetzt nun Channel-Topics (TOPIC-Befehl).
|
||||
- ausgehende Server-Verbindungen werden nun asyncron connectiert und
|
||||
blockieren nicht mehr den ganzen Server, wenn die Gegenseite nicht
|
||||
erreicht werden kann (bis zum Timeout konnten Minuten vergehen!).
|
||||
- Wert der Konfigurations-Variable "ConnectRetry" wird besser beachtet.
|
||||
- Channel- und Nicknames werden nun ordentlich validiert.
|
||||
|
||||
ngIRCd 0.2.1, 17.02.2002
|
||||
|
||||
- NICK korrigiert: es werden nun auch alle "betroffenen" User informiert.
|
||||
- configure-Script erweitert, u.a. bessere Anpassung an BeOS: dort wird
|
||||
nun die "libbe" zum ngIRCd gelinkt, somit funktioniert auch syslog.
|
||||
- Fehlerhafte bzw. noch nicht verstandene Modes werden nun ausfuehrlicher
|
||||
an den Client geliefert.
|
||||
|
||||
ngIRCd 0.2.0, 15.02.2002
|
||||
|
||||
- Nicknames und Channel-Namen werden etwas besser auf Gueltigkeit ueber-
|
||||
prueft; ist aber nach wie vor noch nicht ausreichend.
|
||||
- NJOINS von Servern wurden nicht an andere Server weitergeleitet.
|
||||
- Begonnen Channel-Modes und User-Channel-Modes zu implementieren: der
|
||||
Server versteht an User-Modes o und v, beachtet letzteres allerdings
|
||||
noch nirgends. Bekannte (aber nicht beachtete!) Channel-Modes sind
|
||||
bisher a, m, n, p, q, s und t. Diese Modes werden von Usern ange-
|
||||
nommen, von anderen Servern werden auch unbekannte Modes uebernommen.
|
||||
- Benutzer von connectierenden Servern wurden nicht in den Channels ange-
|
||||
kuendigt, es wurden nur die internen Strukturen angepasst.
|
||||
- Nach dem Connect eines Users werden LUSERS-Informationen angezeigt.
|
||||
|
||||
ngIRCd 0.1.0, 29.01.2002
|
||||
|
||||
- User-Modes bei User-Registrierungen von andere Servern (NICK-Befehl)
|
||||
@@ -34,7 +348,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
|
||||
@@ -81,4 +394,4 @@ ngIRCd 0.0.1, 31.12.2001
|
||||
|
||||
|
||||
--
|
||||
$Id: ChangeLog,v 1.13 2002/01/29 00:17:39 alex Exp $
|
||||
$Id: ChangeLog,v 1.147.2.14 2003/03/09 20:16:57 alex Exp $
|
||||
|
||||
115
INSTALL
115
INSTALL
@@ -8,28 +8,53 @@
|
||||
der GNU General Public License.
|
||||
|
||||
-- INSTALL / Installation --
|
||||
|
||||
Ilja Osthoff, <ilja@glide.ath.cx>
|
||||
|
||||
|
||||
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.
|
||||
+-----------------------------------------------------------------------+
|
||||
| Please note: English translations of some of the german documentation |
|
||||
| files can be found in the directory "doc/en" -- please have a look! |
|
||||
+-----------------------------------------------------------------------+
|
||||
|
||||
|
||||
I. Quick Start
|
||||
~~~~~~~~~~~~~~
|
||||
0. Update von frueheren Versionen
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In der Regel sind folgende Schritte ausreichend:
|
||||
Unterschiede zu Version 0.5.x
|
||||
|
||||
1) ./autogen.sh [nur erforderlich, wenn ueber CVS bezogen]
|
||||
2) ./configure
|
||||
3) make
|
||||
- Ab Version 0.6.0 werden asyncrone Passwoerter zur Identifikation anderer
|
||||
Server, die Variable "Password" in [Server]-Abschnitten wird nicht mehr
|
||||
unterstuetzt. Passwoerter fuer Server-Server-Links werden nun mit den
|
||||
Variablen "MyPassword" und "PeerPassword" angegeben.
|
||||
|
||||
- Neue Konfigurationsvariablen, Sektion [Global]: MaxConnections, MaxJoins
|
||||
(vgl. auch Beispiel-Konfiguration "doc/sample-ngircd.conf"!)
|
||||
|
||||
|
||||
zu 1) autogen.sh:
|
||||
I. Standard-Installation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
ngIRCd ist fuer UNIXoide-Systeme konzipiert worden, das bedeutet, dass die
|
||||
Installation auf einem modernen UNIX-aehnlichen System kein Problem dar-
|
||||
stellen sollte. Das System muss nur von GNU automake und GNU autoconf
|
||||
("configure") unterstuetzt werden.
|
||||
|
||||
Die Standard-Installation sieht so aus:
|
||||
|
||||
1) tar xzf ngircd-<Version>.tar.gz
|
||||
2) cd ngircd-<Version>
|
||||
3) ./autogen.sh [nur erforderlich, wenn ueber CVS bezogen]
|
||||
4) ./configure
|
||||
5) make
|
||||
6) make install
|
||||
|
||||
|
||||
zu 3): "autogen.sh"
|
||||
|
||||
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
|
||||
in tar.gz-Archiven der Fall, jedoch immer, wenn der Source-Code ueber CVS
|
||||
bezogen wurde.
|
||||
|
||||
Dieser Absatz ist also eigentlich ausschliesslich fuer Entwickler interessant.
|
||||
@@ -42,7 +67,7 @@ Versionen!) benoetigt.
|
||||
(nochmal: "Endanwender" mussen diesen Schritt i.d.R. nicht ausfuehren!)
|
||||
|
||||
|
||||
zu 2) ./configure:
|
||||
zu 4): "./configure"
|
||||
|
||||
Mit dem configure-Script wird ngIRCd, wie GNU Software meistens, an das
|
||||
lokale System angepasst und die erforderlichen Makefile's erzeugt.
|
||||
@@ -52,10 +77,22 @@ erkennen und entsprechend reagieren. Sollte dies einmal nicht der Fall sein,
|
||||
so zeigt "./configure --help" moegliche Optionen.
|
||||
|
||||
|
||||
zu 3) make:
|
||||
zu 5): "make"
|
||||
|
||||
Der make-Befehl bearbeitet die vom configure-Script erzeugten Makefile's und
|
||||
uebersetzt die comBase-Library und die Testprogramme.
|
||||
uebersetzt den ngIRCd.
|
||||
|
||||
|
||||
zu 6): "make install"
|
||||
|
||||
Mit "make install" wird der Server und ggf. eine Beispiels-Konfiguration
|
||||
im System installiert; hierzu sind in der Regel root-Rechte erforderlich.
|
||||
Eine bereits vorhandene Konfigurationsdatei wird nie ueberschrieben.
|
||||
|
||||
Folgende Dateien werden installiert:
|
||||
|
||||
- /usr/local/sbin/ngircd: ausfuehrbarer Server
|
||||
- /usr/local/etc/ngircd.conf: Beispiel-Konfiguration, wenn nicht vorhanden
|
||||
|
||||
|
||||
II. Nuetzliche make-Targets
|
||||
@@ -73,3 +110,53 @@ nuetzlichen Targets:
|
||||
- maintainer-clean: alle automat. erzeugten Dateien loeschen.
|
||||
Naechster Schritt: -> ./autogen.sh
|
||||
|
||||
|
||||
|
||||
III. Konfigurationsdatei ngircd.conf
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In der Konfigurationsdatei werden Kommentare durch "#" oder durch ";"
|
||||
eingeleitet. Dieses dient nur der besseren Lesbarkeit.
|
||||
|
||||
Die Datei ist in drei Abschnitte unterteilt: [Global], [Operator] und
|
||||
[Server]. Im [Global]-Teil werden die grundlegenden Einstellungen vor-
|
||||
genommen, z.B. der Server-Name und die Ports, auf denen er Verbindungen
|
||||
annehmen soll. In [Operator]-Abschnitten werden Server-Operatoren fest-
|
||||
gelegt und unter [Server] werden die Einstellungen fuer die Verbindung
|
||||
mit anderen Servern konfiguriert.
|
||||
|
||||
Die Bedeutung der einzelnen Variablen ist in der Beispiel-Konfiguration
|
||||
"doc/sample-ngircd.conf" erklaert, die bei "make install" auch als
|
||||
"ngircd.conf" in /usr/local/etc installiert wird, wenn dort noch keine
|
||||
Konfigurationsdatei vorhanden ist.
|
||||
|
||||
|
||||
IV. Kommandozeilen-Optionen
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Folgende Parameter koennen dem ngIRCd u.a. uebergeben werden:
|
||||
|
||||
-f, --config <file>
|
||||
Der Daemon wird angewiesen, statt der Standard-Konfigurationsdatei
|
||||
/usr/local/etc/ngircd.conf die Datei <file> einzulesen.
|
||||
|
||||
-n, --nodaemon
|
||||
ngIRCd soll im Fordergrund laufen; alle Meldungen werden zusaetzlich
|
||||
zum Syslog auch auf der Konsole ausgegeben.
|
||||
|
||||
-p, --passive
|
||||
Verbindungen zu anderen Servern (wie in der Konfigurationsdatei in
|
||||
[Server]-Abschnitten definiert) werden nicht automatisch hergestellt.
|
||||
|
||||
--configtest
|
||||
Die Konfigurationsdatei wird eingelesen, ueberprueft und so aus-
|
||||
gegeben, wie sie vom ngIRCd interpretiert wurde. Danach beendet
|
||||
sich der Server wieder.
|
||||
|
||||
Mit dem Parameter "--help" werden alle unterstuetzten Parameter angezeigt,
|
||||
mit "--version" die Versionsnummer. Bei beiden Parametern beendet sich der
|
||||
Server nach der Ausgabe wieder.
|
||||
|
||||
|
||||
--
|
||||
$Id: INSTALL,v 1.9 2002/12/18 12:19:07 alex Exp $
|
||||
|
||||
@@ -9,18 +9,7 @@
|
||||
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
#
|
||||
# $Id: Makefile.am,v 1.3 2002/01/02 02:40:15 alex Exp $
|
||||
#
|
||||
# $Log: Makefile.am,v $
|
||||
# Revision 1.3 2002/01/02 02:40:15 alex
|
||||
# - Copyright-Texte ergaenzt und aktualisiert,
|
||||
# - fehlende Dateien in Projekt aufgenommen.
|
||||
#
|
||||
# Revision 1.2 2001/12/31 16:02:12 alex
|
||||
# - Projektdateien von Mac OS X werden nun auch in die Distribution aufgenommen.
|
||||
#
|
||||
# Revision 1.1 2001/12/12 17:21:58 alex
|
||||
# - Projektdatei fuer den Mac OS X Project Builder erstellt.
|
||||
# $Id: Makefile.am,v 1.4 2002/03/12 14:37:51 alex Exp $
|
||||
#
|
||||
|
||||
SUBDIRS = ngircd.pbproj
|
||||
|
||||
@@ -9,15 +9,7 @@
|
||||
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
#
|
||||
# $Id: Makefile.am,v 1.2 2002/01/02 02:40:15 alex Exp $
|
||||
#
|
||||
# $Log: Makefile.am,v $
|
||||
# Revision 1.2 2002/01/02 02:40:15 alex
|
||||
# - Copyright-Texte ergaenzt und aktualisiert,
|
||||
# - fehlende Dateien in Projekt aufgenommen.
|
||||
#
|
||||
# Revision 1.1 2001/12/31 16:02:12 alex
|
||||
# - Projektdateien von Mac OS X werden nun auch in die Distribution aufgenommen.
|
||||
# $Id: Makefile.am,v 1.3 2002/03/12 14:37:51 alex Exp $
|
||||
#
|
||||
|
||||
EXTRA_DIST = project.pbxproj
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 34;
|
||||
objectVersion = 38;
|
||||
objects = {
|
||||
014CEA520018CE5811CA2923 = {
|
||||
buildRules = (
|
||||
@@ -59,24 +59,27 @@
|
||||
projectDirPath = "";
|
||||
targets = (
|
||||
08FB779FFE84155DC02AAC07,
|
||||
F538241E024F89BC01A85B04,
|
||||
F5BEF13002A129DC01A85B03,
|
||||
);
|
||||
};
|
||||
08FB7794FE84155DC02AAC07 = {
|
||||
children = (
|
||||
1AB674ADFE9D54B511CA2CBB,
|
||||
F51F791401DFD0DE01D13771,
|
||||
F56D8B9E01E0BFA00155ADA7,
|
||||
F5D3536103892A8A01A85B04,
|
||||
F51F791401DFD0DE01D13771,
|
||||
F520AF150335F1B801A85B04,
|
||||
F52162B301C7B904012300F4,
|
||||
F52162C201C7B904012300F4,
|
||||
F52162C301C7B904012300F4,
|
||||
F52162C401C7B904012300F4,
|
||||
F52162C501C7B904012300F4,
|
||||
F52162CB01C7B904012300F4,
|
||||
F52162C601C7B904012300F4,
|
||||
F52162C701C7B904012300F4,
|
||||
F52162C801C7B904012300F4,
|
||||
F52162C901C7B904012300F4,
|
||||
F52162CA01C7B904012300F4,
|
||||
F52162CB01C7B904012300F4,
|
||||
F52162C801C7B904012300F4,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = ngircd;
|
||||
@@ -91,16 +94,18 @@
|
||||
);
|
||||
buildSettings = {
|
||||
FRAMEWORK_SEARCH_PATHS = "";
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
HEADER_SEARCH_PATHS = "";
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
LIBRARY_SEARCH_PATHS = "";
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
OPTIMIZATION_CFLAGS = "-O2";
|
||||
OTHER_CFLAGS = "-DSYSCONFDIR=\\\\\\\"/usr/local/etc\\\\\\\"";
|
||||
OTHER_LDFLAGS = "-lz";
|
||||
OTHER_REZFLAGS = "";
|
||||
PRODUCT_NAME = ngircd;
|
||||
REZ_EXECUTABLE = YES;
|
||||
SECTORDER_FLAGS = "";
|
||||
WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
|
||||
WARNING_CFLAGS = "-Wall";
|
||||
};
|
||||
dependencies = (
|
||||
);
|
||||
@@ -114,8 +119,6 @@
|
||||
08FB77A0FE84155DC02AAC07 = {
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F52162CC01C7B904012300F4,
|
||||
F52162CD01C7B904012300F4,
|
||||
F52162CE01C7B904012300F4,
|
||||
F52162CF01C7B904012300F4,
|
||||
F52162D001C7B904012300F4,
|
||||
@@ -128,9 +131,25 @@
|
||||
F576ABFC01D5E77301A85B03,
|
||||
F576ABFF01D61D7401A85B03,
|
||||
F51F791301DFC95301D13771,
|
||||
F51DBB15022D95E801A85B04,
|
||||
F51DBB19022D995501A85B04,
|
||||
F51DBB1D022D9D8F01A85B04,
|
||||
F57C88870232853501A85B04,
|
||||
F57C888B0232884501A85B04,
|
||||
F57C888F02328D7201A85B04,
|
||||
F5F18138023EC63701A85B04,
|
||||
F5F18139023EC63701A85B04,
|
||||
F5F1813A023EC63701A85B04,
|
||||
F55047BC0240F6E501A85B04,
|
||||
F51044550297AC170173DE11,
|
||||
F5BEF12A02A0EFE201A85B03,
|
||||
F5BEF12E02A1169C01A85B03,
|
||||
F5BEF13302A12AFE01A85B03,
|
||||
F5E9448502C9F49D01A85B04,
|
||||
F5D5CC9403990FED0155B873,
|
||||
);
|
||||
isa = PBXHeadersBuildPhase;
|
||||
name = Headers;
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
08FB77A1FE84155DC02AAC07 = {
|
||||
buildActionMask = 2147483647;
|
||||
@@ -144,23 +163,36 @@
|
||||
F51D180701C8FDD001E11C2E,
|
||||
F576ABFD01D5E77301A85B03,
|
||||
F5263AEE01E263D201CE8F8F,
|
||||
F51DBB16022D95E801A85B04,
|
||||
F51DBB1A022D995501A85B04,
|
||||
F51DBB1E022D9D8F01A85B04,
|
||||
F57C88880232853501A85B04,
|
||||
F57C888C0232884501A85B04,
|
||||
F57C889002328D7201A85B04,
|
||||
F55047BD0240F6E501A85B04,
|
||||
F51044560297B5D40173DE11,
|
||||
F5BEF12B02A0EFE201A85B03,
|
||||
F5BEF12F02A1169C01A85B03,
|
||||
F5BEF13502A24F1001A85B03,
|
||||
F5E9448602C9F49D01A85B04,
|
||||
F5D5CC9603990FFA0155B873,
|
||||
);
|
||||
isa = PBXSourcesBuildPhase;
|
||||
name = Sources;
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
08FB77A3FE84155DC02AAC07 = {
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
name = "Frameworks & Libraries";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
08FB77A5FE84155DC02AAC07 = {
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
isa = PBXRezBuildPhase;
|
||||
name = "ResourceManager Resources";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
//080
|
||||
//081
|
||||
@@ -175,6 +207,7 @@
|
||||
1AB674ADFE9D54B511CA2CBB = {
|
||||
children = (
|
||||
034768E8FF38A79811DB9C8B,
|
||||
F538241D024F89BC01A85B04,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = Products;
|
||||
@@ -190,6 +223,30 @@
|
||||
//F52
|
||||
//F53
|
||||
//F54
|
||||
F51044520297ABF80173DE11 = {
|
||||
isa = PBXFileReference;
|
||||
name = vsnprintf.c;
|
||||
path = /Users/alex/Develop/ngircd/src/portab/vsnprintf.c;
|
||||
refType = 0;
|
||||
};
|
||||
F51044540297AC170173DE11 = {
|
||||
isa = PBXFileReference;
|
||||
name = splint.h;
|
||||
path = portab/splint.h;
|
||||
refType = 4;
|
||||
};
|
||||
F51044550297AC170173DE11 = {
|
||||
fileRef = F51044540297AC170173DE11;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F51044560297B5D40173DE11 = {
|
||||
fileRef = F51044520297ABF80173DE11;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F51D17FC01C8F5B701E11C2E = {
|
||||
isa = PBXFileReference;
|
||||
name = client.c;
|
||||
@@ -256,6 +313,72 @@
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F51DBB13022D95E801A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-write.c";
|
||||
refType = 4;
|
||||
};
|
||||
F51DBB14022D95E801A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-write.h";
|
||||
refType = 4;
|
||||
};
|
||||
F51DBB15022D95E801A85B04 = {
|
||||
fileRef = F51DBB14022D95E801A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F51DBB16022D95E801A85B04 = {
|
||||
fileRef = F51DBB13022D95E801A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F51DBB17022D995501A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-mode.c";
|
||||
refType = 4;
|
||||
};
|
||||
F51DBB18022D995501A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-mode.h";
|
||||
refType = 4;
|
||||
};
|
||||
F51DBB19022D995501A85B04 = {
|
||||
fileRef = F51DBB18022D995501A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F51DBB1A022D995501A85B04 = {
|
||||
fileRef = F51DBB17022D995501A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F51DBB1B022D9D8F01A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-login.c";
|
||||
refType = 4;
|
||||
};
|
||||
F51DBB1C022D9D8F01A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-login.h";
|
||||
refType = 4;
|
||||
};
|
||||
F51DBB1D022D9D8F01A85B04 = {
|
||||
fileRef = F51DBB1C022D9D8F01A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F51DBB1E022D9D8F01A85B04 = {
|
||||
fileRef = F51DBB1B022D9D8F01A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F51F791201DFC95301D13771 = {
|
||||
isa = PBXFileReference;
|
||||
name = defines.h;
|
||||
@@ -270,8 +393,13 @@
|
||||
};
|
||||
F51F791401DFD0DE01D13771 = {
|
||||
children = (
|
||||
F5E9447B02C9EE0E01A85B04,
|
||||
F5263AEF01E2A9B801CE8F8F,
|
||||
F51F791501DFD0DE01D13771,
|
||||
F5E9447D02C9EE2801A85B04,
|
||||
F5B565290325412B01A85B04,
|
||||
F5E9447E02C9EE2801A85B04,
|
||||
F5E9447F02C9EE2801A85B04,
|
||||
F51F791601DFD0DE01D13771,
|
||||
F51F791701DFD0DE01D13771,
|
||||
);
|
||||
@@ -295,11 +423,137 @@
|
||||
path = "sample-ngircd.conf";
|
||||
refType = 4;
|
||||
};
|
||||
F520AEA80335E29001A85B04 = {
|
||||
children = (
|
||||
F520AEA90335E29001A85B04,
|
||||
F520AEAA0335E29001A85B04,
|
||||
F520AEAC0335E29001A85B04,
|
||||
F520AEAD0335E29001A85B04,
|
||||
F520AEAE0335E29001A85B04,
|
||||
F520AECA0335E29001A85B04,
|
||||
F520AECC0335E29001A85B04,
|
||||
F520AECD0335E29001A85B04,
|
||||
F520AED00335E29001A85B04,
|
||||
F520AED40335E29001A85B04,
|
||||
F520AED50335E29001A85B04,
|
||||
F520AED60335E29001A85B04,
|
||||
F520AED70335E29001A85B04,
|
||||
F520AED80335E29001A85B04,
|
||||
F520AF0C0335E29001A85B04,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = testsuite;
|
||||
path = /Users/alex/Develop/ngircd/src/testsuite;
|
||||
refType = 0;
|
||||
};
|
||||
F520AEA90335E29001A85B04 = {
|
||||
isa = PBXExecutableFileReference;
|
||||
path = "channel-test";
|
||||
refType = 4;
|
||||
};
|
||||
F520AEAA0335E29001A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "channel-test.e";
|
||||
refType = 4;
|
||||
};
|
||||
F520AEAC0335E29001A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "check-idle.e";
|
||||
refType = 4;
|
||||
};
|
||||
F520AEAD0335E29001A85B04 = {
|
||||
isa = PBXExecutableFileReference;
|
||||
path = "connect-test";
|
||||
refType = 4;
|
||||
};
|
||||
F520AEAE0335E29001A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "connect-test.e";
|
||||
refType = 4;
|
||||
};
|
||||
F520AECA0335E29001A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = Makefile.am;
|
||||
refType = 4;
|
||||
};
|
||||
F520AECC0335E29001A85B04 = {
|
||||
isa = PBXExecutableFileReference;
|
||||
path = "mode-test";
|
||||
refType = 4;
|
||||
};
|
||||
F520AECD0335E29001A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "mode-test.e";
|
||||
refType = 4;
|
||||
};
|
||||
F520AED00335E29001A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "ngircd-test.conf";
|
||||
refType = 4;
|
||||
};
|
||||
F520AED40335E29001A85B04 = {
|
||||
isa = PBXExecutableFileReference;
|
||||
path = "start-server.sh";
|
||||
refType = 4;
|
||||
};
|
||||
F520AED50335E29001A85B04 = {
|
||||
isa = PBXExecutableFileReference;
|
||||
path = "stop-server.sh";
|
||||
refType = 4;
|
||||
};
|
||||
F520AED60335E29001A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "stress-A.e";
|
||||
refType = 4;
|
||||
};
|
||||
F520AED70335E29001A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "stress-B.e";
|
||||
refType = 4;
|
||||
};
|
||||
F520AED80335E29001A85B04 = {
|
||||
isa = PBXExecutableFileReference;
|
||||
path = "stress-server.sh";
|
||||
refType = 4;
|
||||
};
|
||||
F520AF0C0335E29001A85B04 = {
|
||||
isa = PBXExecutableFileReference;
|
||||
path = tests.sh;
|
||||
refType = 4;
|
||||
};
|
||||
F520AF150335F1B801A85B04 = {
|
||||
children = (
|
||||
F520AF180335F1B801A85B04,
|
||||
F520AF1A0335F1B801A85B04,
|
||||
F520AF1B0335F1B801A85B04,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = man;
|
||||
path = /Users/alex/Develop/ngircd/man;
|
||||
refType = 0;
|
||||
};
|
||||
F520AF180335F1B801A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = Makefile.am;
|
||||
refType = 4;
|
||||
};
|
||||
F520AF1A0335F1B801A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = ngircd.8;
|
||||
refType = 4;
|
||||
};
|
||||
F520AF1B0335F1B801A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = ngircd.conf.5;
|
||||
refType = 4;
|
||||
};
|
||||
F52162B301C7B904012300F4 = {
|
||||
children = (
|
||||
F52162B801C7B904012300F4,
|
||||
F52162D801C7BAAE012300F4,
|
||||
F52162B901C7B904012300F4,
|
||||
F5F18132023EC61E01A85B04,
|
||||
F520AEA80335E29001A85B04,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = src;
|
||||
@@ -314,7 +568,6 @@
|
||||
F52162B901C7B904012300F4 = {
|
||||
children = (
|
||||
F52162BD01C7B904012300F4,
|
||||
F52162BA01C7B904012300F4,
|
||||
F52162BE01C7B904012300F4,
|
||||
F52162BF01C7B904012300F4,
|
||||
F51D180001C8FDD001E11C2E,
|
||||
@@ -325,12 +578,36 @@
|
||||
F52162E301C7C77B012300F4,
|
||||
F52162DA01C7BCDC012300F4,
|
||||
F52162DB01C7BCDC012300F4,
|
||||
F55047BA0240F6E501A85B04,
|
||||
F55047BB0240F6E501A85B04,
|
||||
F51D180201C8FDD001E11C2E,
|
||||
F51D180301C8FDD001E11C2E,
|
||||
F57C888D02328D7201A85B04,
|
||||
F57C888E02328D7201A85B04,
|
||||
F5D5CC9503990FFA0155B873,
|
||||
F5D5CC9303990FED0155B873,
|
||||
F51DBB1B022D9D8F01A85B04,
|
||||
F51DBB1C022D9D8F01A85B04,
|
||||
F51DBB17022D995501A85B04,
|
||||
F51DBB18022D995501A85B04,
|
||||
F5BEF12C02A1169C01A85B03,
|
||||
F5BEF12D02A1169C01A85B03,
|
||||
F57C88850232853501A85B04,
|
||||
F57C88860232853501A85B04,
|
||||
F57C88890232884501A85B04,
|
||||
F57C888A0232884501A85B04,
|
||||
F51DBB13022D95E801A85B04,
|
||||
F51DBB14022D95E801A85B04,
|
||||
F5BEF12802A0EFE201A85B03,
|
||||
F5BEF12902A0EFE201A85B03,
|
||||
F52162BB01C7B904012300F4,
|
||||
F52162BC01C7B904012300F4,
|
||||
F5E9448402C9F49D01A85B04,
|
||||
F5E9448302C9F49D01A85B04,
|
||||
F576ABFA01D5E77301A85B03,
|
||||
F576ABFB01D5E77301A85B03,
|
||||
F5BEF13102A12AFE01A85B03,
|
||||
F5BEF13202A12AFE01A85B03,
|
||||
F52162C001C7B904012300F4,
|
||||
F52162C101C7B904012300F4,
|
||||
F51F791201DFC95301D13771,
|
||||
@@ -340,11 +617,6 @@
|
||||
path = ngircd;
|
||||
refType = 4;
|
||||
};
|
||||
F52162BA01C7B904012300F4 = {
|
||||
isa = PBXFileReference;
|
||||
path = global.h;
|
||||
refType = 4;
|
||||
};
|
||||
F52162BB01C7B904012300F4 = {
|
||||
isa = PBXFileReference;
|
||||
path = log.c;
|
||||
@@ -380,12 +652,6 @@
|
||||
path = tool.h;
|
||||
refType = 4;
|
||||
};
|
||||
F52162C201C7B904012300F4 = {
|
||||
isa = PBXFileReference;
|
||||
name = acconfig.h;
|
||||
path = ../acconfig.h;
|
||||
refType = 2;
|
||||
};
|
||||
F52162C301C7B904012300F4 = {
|
||||
isa = PBXExecutableFileReference;
|
||||
name = autogen.sh;
|
||||
@@ -440,18 +706,6 @@
|
||||
path = ../README;
|
||||
refType = 2;
|
||||
};
|
||||
F52162CC01C7B904012300F4 = {
|
||||
fileRef = F52162C201C7B904012300F4;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F52162CD01C7B904012300F4 = {
|
||||
fileRef = F52162BA01C7B904012300F4;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F52162CE01C7B904012300F4 = {
|
||||
fileRef = F52162BC01C7B904012300F4;
|
||||
isa = PBXBuildFile;
|
||||
@@ -560,6 +814,116 @@
|
||||
path = ../doc/Makefile.am;
|
||||
refType = 2;
|
||||
};
|
||||
F538241D024F89BC01A85B04 = {
|
||||
isa = PBXExecutableFileReference;
|
||||
path = portabtest;
|
||||
refType = 3;
|
||||
};
|
||||
F538241E024F89BC01A85B04 = {
|
||||
buildPhases = (
|
||||
F538241F024F89BC01A85B04,
|
||||
F5382423024F89BC01A85B04,
|
||||
F5382425024F89BC01A85B04,
|
||||
F5382426024F89BC01A85B04,
|
||||
);
|
||||
buildSettings = {
|
||||
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
|
||||
OPTIMIZATION_CFLAGS = "-O2";
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_REZFLAGS = "";
|
||||
PRODUCT_NAME = portabtest;
|
||||
REZ_EXECUTABLE = YES;
|
||||
SECTORDER_FLAGS = "";
|
||||
WARNING_CFLAGS = "-Wall";
|
||||
};
|
||||
dependencies = (
|
||||
);
|
||||
isa = PBXToolTarget;
|
||||
name = portabtest;
|
||||
productInstallPath = /usr/local/bin;
|
||||
productName = portabtest;
|
||||
productReference = F538241D024F89BC01A85B04;
|
||||
shouldUseHeadermap = 0;
|
||||
};
|
||||
F538241F024F89BC01A85B04 = {
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F5382420024F89BC01A85B04,
|
||||
F5382421024F89BC01A85B04,
|
||||
F5382422024F89BC01A85B04,
|
||||
);
|
||||
isa = PBXHeadersBuildPhase;
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F5382420024F89BC01A85B04 = {
|
||||
fileRef = F5F18134023EC63701A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5382421024F89BC01A85B04 = {
|
||||
fileRef = F5F18135023EC63701A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5382422024F89BC01A85B04 = {
|
||||
fileRef = F5F18136023EC63701A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5382423024F89BC01A85B04 = {
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F5382424024F89BC01A85B04,
|
||||
);
|
||||
isa = PBXSourcesBuildPhase;
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F5382424024F89BC01A85B04 = {
|
||||
fileRef = F5F18137023EC63701A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5382425024F89BC01A85B04 = {
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F5382426024F89BC01A85B04 = {
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
isa = PBXRezBuildPhase;
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F55047BA0240F6E501A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = hash.c;
|
||||
refType = 4;
|
||||
};
|
||||
F55047BB0240F6E501A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = hash.h;
|
||||
refType = 4;
|
||||
};
|
||||
F55047BC0240F6E501A85B04 = {
|
||||
fileRef = F55047BB0240F6E501A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F55047BD0240F6E501A85B04 = {
|
||||
fileRef = F55047BA0240F6E501A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F56D8B9E01E0BFA00155ADA7 = {
|
||||
children = (
|
||||
F56D8B9F01E0BFA00155ADA7,
|
||||
@@ -622,6 +986,347 @@
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F57C88850232853501A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-oper.c";
|
||||
refType = 4;
|
||||
};
|
||||
F57C88860232853501A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-oper.h";
|
||||
refType = 4;
|
||||
};
|
||||
F57C88870232853501A85B04 = {
|
||||
fileRef = F57C88860232853501A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F57C88880232853501A85B04 = {
|
||||
fileRef = F57C88850232853501A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F57C88890232884501A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-server.c";
|
||||
refType = 4;
|
||||
};
|
||||
F57C888A0232884501A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-server.h";
|
||||
refType = 4;
|
||||
};
|
||||
F57C888B0232884501A85B04 = {
|
||||
fileRef = F57C888A0232884501A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F57C888C0232884501A85B04 = {
|
||||
fileRef = F57C88890232884501A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F57C888D02328D7201A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-channel.c";
|
||||
refType = 4;
|
||||
};
|
||||
F57C888E02328D7201A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-channel.h";
|
||||
refType = 4;
|
||||
};
|
||||
F57C888F02328D7201A85B04 = {
|
||||
fileRef = F57C888E02328D7201A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F57C889002328D7201A85B04 = {
|
||||
fileRef = F57C888D02328D7201A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5B565290325412B01A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
name = Protocol.txt;
|
||||
path = ../doc/Protocol.txt;
|
||||
refType = 2;
|
||||
};
|
||||
F5BEF12802A0EFE201A85B03 = {
|
||||
isa = PBXFileReference;
|
||||
name = lists.c;
|
||||
path = /Users/alex/Develop/ngircd/src/ngircd/lists.c;
|
||||
refType = 0;
|
||||
};
|
||||
F5BEF12902A0EFE201A85B03 = {
|
||||
isa = PBXFileReference;
|
||||
name = lists.h;
|
||||
path = /Users/alex/Develop/ngircd/src/ngircd/lists.h;
|
||||
refType = 0;
|
||||
};
|
||||
F5BEF12A02A0EFE201A85B03 = {
|
||||
fileRef = F5BEF12902A0EFE201A85B03;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5BEF12B02A0EFE201A85B03 = {
|
||||
fileRef = F5BEF12802A0EFE201A85B03;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5BEF12C02A1169C01A85B03 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-op.c";
|
||||
refType = 4;
|
||||
};
|
||||
F5BEF12D02A1169C01A85B03 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-op.h";
|
||||
refType = 4;
|
||||
};
|
||||
F5BEF12E02A1169C01A85B03 = {
|
||||
fileRef = F5BEF12D02A1169C01A85B03;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5BEF12F02A1169C01A85B03 = {
|
||||
fileRef = F5BEF12C02A1169C01A85B03;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5BEF13002A129DC01A85B03 = {
|
||||
buildArgumentsString = $ACTION;
|
||||
buildPhases = (
|
||||
);
|
||||
buildSettings = {
|
||||
OTHER_CFLAGS = "";
|
||||
OTHER_LDFLAGS = "";
|
||||
OTHER_REZFLAGS = "";
|
||||
PRODUCT_NAME = "ngIRCd Makefile";
|
||||
SECTORDER_FLAGS = "";
|
||||
WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
|
||||
};
|
||||
buildToolPath = /usr/bin/gnumake;
|
||||
dependencies = (
|
||||
);
|
||||
isa = PBXLegacyTarget;
|
||||
name = "ngIRCd Makefile";
|
||||
productName = "ngIRCd Makefile";
|
||||
settingsToExpand = 6;
|
||||
settingsToPassInEnvironment = 287;
|
||||
settingsToPassOnCommandLine = 280;
|
||||
shouldUseHeadermap = 0;
|
||||
};
|
||||
F5BEF13102A12AFE01A85B03 = {
|
||||
isa = PBXFileReference;
|
||||
path = resolve.c;
|
||||
refType = 4;
|
||||
};
|
||||
F5BEF13202A12AFE01A85B03 = {
|
||||
isa = PBXFileReference;
|
||||
path = resolve.h;
|
||||
refType = 4;
|
||||
};
|
||||
F5BEF13302A12AFE01A85B03 = {
|
||||
fileRef = F5BEF13202A12AFE01A85B03;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5BEF13502A24F1001A85B03 = {
|
||||
fileRef = F5BEF13102A12AFE01A85B03;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5D3536103892A8A01A85B04 = {
|
||||
children = (
|
||||
F5D3536203892AD201A85B04,
|
||||
F5D3536303892AD201A85B04,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = contrib;
|
||||
refType = 4;
|
||||
};
|
||||
F5D3536203892AD201A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
name = Makefile.am;
|
||||
path = /Users/alex/Develop/ngircd/contrib/Makefile.am;
|
||||
refType = 0;
|
||||
};
|
||||
F5D3536303892AD201A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
name = ngircd.spec;
|
||||
path = /Users/alex/Develop/ngircd/contrib/ngircd.spec;
|
||||
refType = 0;
|
||||
};
|
||||
F5D3536403892AFE01A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
name = "sample-ngircd.conf";
|
||||
path = "en/sample-ngircd.conf";
|
||||
refType = 4;
|
||||
};
|
||||
F5D5CC9303990FED0155B873 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-info.h";
|
||||
refType = 4;
|
||||
};
|
||||
F5D5CC9403990FED0155B873 = {
|
||||
fileRef = F5D5CC9303990FED0155B873;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5D5CC9503990FFA0155B873 = {
|
||||
isa = PBXFileReference;
|
||||
path = "irc-info.c";
|
||||
refType = 4;
|
||||
};
|
||||
F5D5CC9603990FFA0155B873 = {
|
||||
fileRef = F5D5CC9503990FFA0155B873;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5E9447B02C9EE0E01A85B04 = {
|
||||
children = (
|
||||
F5E9448002C9EE4901A85B04,
|
||||
F5E9448202C9EE4901A85B04,
|
||||
F5E9448102C9EE4901A85B04,
|
||||
F5D3536403892AFE01A85B04,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = en;
|
||||
refType = 4;
|
||||
};
|
||||
F5E9447D02C9EE2801A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = FAQ.txt;
|
||||
refType = 4;
|
||||
};
|
||||
F5E9447E02C9EE2801A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "README-AUX.txt";
|
||||
refType = 4;
|
||||
};
|
||||
F5E9447F02C9EE2801A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = "README-BeOS.txt";
|
||||
refType = 4;
|
||||
};
|
||||
F5E9448002C9EE4901A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
name = Makefile.am;
|
||||
path = en/Makefile.am;
|
||||
refType = 4;
|
||||
};
|
||||
F5E9448102C9EE4901A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
name = INSTALL;
|
||||
path = en/INSTALL;
|
||||
refType = 4;
|
||||
};
|
||||
F5E9448202C9EE4901A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
name = README;
|
||||
path = en/README;
|
||||
refType = 4;
|
||||
};
|
||||
F5E9448302C9F49D01A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = match.h;
|
||||
refType = 4;
|
||||
};
|
||||
F5E9448402C9F49D01A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
path = match.c;
|
||||
refType = 4;
|
||||
};
|
||||
F5E9448502C9F49D01A85B04 = {
|
||||
fileRef = F5E9448302C9F49D01A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5E9448602C9F49D01A85B04 = {
|
||||
fileRef = F5E9448402C9F49D01A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5F18132023EC61E01A85B04 = {
|
||||
children = (
|
||||
F5F18133023EC63701A85B04,
|
||||
F5F18134023EC63701A85B04,
|
||||
F5F18135023EC63701A85B04,
|
||||
F5F18136023EC63701A85B04,
|
||||
F5F18137023EC63701A85B04,
|
||||
F51044540297AC170173DE11,
|
||||
F51044520297ABF80173DE11,
|
||||
);
|
||||
isa = PBXGroup;
|
||||
name = portab;
|
||||
path = /Users/alex/Develop/ngircd/src;
|
||||
refType = 0;
|
||||
};
|
||||
F5F18133023EC63701A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
name = Makefile.am;
|
||||
path = portab/Makefile.am;
|
||||
refType = 4;
|
||||
};
|
||||
F5F18134023EC63701A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
name = exp.h;
|
||||
path = portab/exp.h;
|
||||
refType = 4;
|
||||
};
|
||||
F5F18135023EC63701A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
name = imp.h;
|
||||
path = portab/imp.h;
|
||||
refType = 4;
|
||||
};
|
||||
F5F18136023EC63701A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
name = portab.h;
|
||||
path = portab/portab.h;
|
||||
refType = 4;
|
||||
};
|
||||
F5F18137023EC63701A85B04 = {
|
||||
isa = PBXFileReference;
|
||||
name = portabtest.c;
|
||||
path = portab/portabtest.c;
|
||||
refType = 4;
|
||||
};
|
||||
F5F18138023EC63701A85B04 = {
|
||||
fileRef = F5F18134023EC63701A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5F18139023EC63701A85B04 = {
|
||||
fileRef = F5F18135023EC63701A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5F1813A023EC63701A85B04 = {
|
||||
fileRef = F5F18136023EC63701A85B04;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
};
|
||||
rootObject = 08FB7793FE84155DC02AAC07;
|
||||
}
|
||||
|
||||
29
Makefile.am
29
Makefile.am
@@ -9,34 +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.5 2002/01/02 02:52:09 alex Exp $
|
||||
#
|
||||
# $Log: Makefile.am,v $
|
||||
# Revision 1.5 2002/01/02 02:52:09 alex
|
||||
# - Copyright-Texte angepasst ;-)
|
||||
#
|
||||
# Revision 1.4 2001/12/31 02:20:20 alex
|
||||
# - Unterverzeichnis "doc" aufgenommen.
|
||||
#
|
||||
# Revision 1.3 2001/12/30 19:24:28 alex
|
||||
# - acconfig.h in die "noinst_HEADERS" aufgenommen.
|
||||
#
|
||||
# Revision 1.2 2001/12/12 17:21:58 alex
|
||||
# - Projektdatei fuer den Mac OS X Project Builder erstellt.
|
||||
#
|
||||
# Revision 1.1.1.1 2001/12/11 21:53:04 alex
|
||||
# Imported sources to CVS.
|
||||
# $Id: Makefile.am,v 1.10 2002/10/01 09:57:08 alex Exp $
|
||||
#
|
||||
|
||||
AUTOMAKE_OPTIONS = gnu
|
||||
|
||||
SUBDIRS = doc MacOSX src
|
||||
|
||||
noinst_HEADERS = acconfig.h
|
||||
SUBDIRS = doc MacOSX src man contrib
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -rf autom4te.cache
|
||||
rm -f Makefile.in Makefile aclocal.m4 configure
|
||||
rm -f mkinstalldirs missing depcomp install-sh
|
||||
rm -f config.log
|
||||
|
||||
lint:
|
||||
make -C src/ngircd lint
|
||||
|
||||
rpm: distcheck
|
||||
rpm -ta ngircd-*.tar.gz
|
||||
|
||||
# -eof-
|
||||
|
||||
98
NEWS
98
NEWS
@@ -10,6 +10,102 @@
|
||||
-- NEWS / Neuigkeiten --
|
||||
|
||||
|
||||
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.
|
||||
- Server-Gruppen implementiert: es wird immer nur zu einem Server in
|
||||
einer Gruppe eine Verbindung aufgebaut, klappt es beim ersten Server
|
||||
nicht, so wird der naechste probiert.
|
||||
- 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.
|
||||
- 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.
|
||||
|
||||
ngIRCd 0.3.0, 02.03.2002
|
||||
|
||||
- bekommt der Server ein HUP-Signal, so startet er neu -- genau so, wie
|
||||
er auf den IRC-Befehl RESTART reagiert.
|
||||
- neuer Kommandozeilen-Schalter "--passive" (-p): wird er angegeben, so
|
||||
verbindet sich der ngIRCd nicht mehr automatisch zu anderen Servern.
|
||||
Zum Debuggen manchmal ganz praktisch :-)
|
||||
- neue Befehle VERSION und KILL implementiert. NAMES korrigiert.
|
||||
- Anpassungen an A/UX: gehoert nun auch zu den unterstuetzten Platformen.
|
||||
- AWAY (und der User-Mode 'a') ist nun implementiert.
|
||||
- der ngIRCd unterstuetzt nun Channel-Topics (TOPIC-Befehl).
|
||||
- Channel- und Nicknames werden nun ordentlich validiert.
|
||||
|
||||
ngIRCd 0.2.0, 15.02.2002
|
||||
|
||||
- Begonnen Channel-Modes und User-Channel-Modes zu implementieren: der
|
||||
Server versteht an User-Modes o und v, beachtet letzteres allerdings
|
||||
noch nirgends. Bekannte (aber nicht beachtete!) Channel-Modes sind
|
||||
bisher a, m, n, p, q, s und t. Diese Modes werden von Usern ange-
|
||||
nommen, von anderen Servern werden auch unbekannte Modes uebernommen.
|
||||
- Nach dem Connect eines Users werden LUSERS-Informationen angezeigt.
|
||||
|
||||
ngIRCd 0.1.0, 29.01.2002
|
||||
|
||||
- Channels implementiert, bisher jedoch noch ohne Channel-Modes, d.h.
|
||||
@@ -43,4 +139,4 @@ ngIRCd 0.0.1, 31.12.2001
|
||||
|
||||
|
||||
--
|
||||
$Id: NEWS,v 1.6 2002/01/29 00:17:39 alex Exp $
|
||||
$Id: NEWS,v 1.45.2.2 2002/12/24 13:53:54 alex Exp $
|
||||
|
||||
110
README
110
README
@@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
ngIRCd - Next Generation IRC Server
|
||||
|
||||
(c)2001,2002 by Alexander Barton,
|
||||
@@ -8,38 +8,98 @@
|
||||
der GNU General Public License.
|
||||
|
||||
-- README / Liesmich --
|
||||
|
||||
Ilja Osthoff, <ilja@glide.ath.cx>
|
||||
|
||||
|
||||
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.
|
||||
+-----------------------------------------------------------------------+
|
||||
| Please note: English translations of some of the german documentation |
|
||||
| files can be found in the directory "doc/en" -- please have a look! |
|
||||
+-----------------------------------------------------------------------+
|
||||
|
||||
Zur Zeit befindet sich ngIRCd noch in Entwicklung, vieles ist noch nicht
|
||||
implementiert bzw. nur "halbherzig": Channels gibt es noch nicht, genau so
|
||||
wenig wie Server-Links. Das private Chatten (PRIVMSG) mit den Client-Befehlen
|
||||
/msg und /query sollte hingegen funktionieren, ein wenig praktische Funk-
|
||||
tionalitaet ist also tatsaechlich schon vorhanden ;-)
|
||||
|
||||
I. Einfuehrung
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
ngIRCd ist ein Open-Source-Server fuer den Internet Relay Chat (IRC), der
|
||||
unter der GNU General Public License (http://www.gnu.org/licenses/gpl.html)
|
||||
entwickelt wird. ngIRCd steht fuer "next generation IRC daemon", er ist von
|
||||
Grund auf neu geschrieben, also nicht wie die meisten anderen IRCd's vom
|
||||
Urvater, dem Daemon des IRCNet abgeleitet.
|
||||
|
||||
|
||||
II. Status
|
||||
~~~~~~~~~~~
|
||||
|
||||
Zur Zeit befindet sich der ngIRCd noch in Entwicklung, manche Features sind
|
||||
noch nicht implementiert, andere nur teilweise.
|
||||
|
||||
Bisher (mehr oder wenig vollstaendig) implementierte IRC-Befehle:
|
||||
|
||||
DIE, ERROR, ISON, JOIN, LINKS, LUSERS, MODE, MOTD, NAMES, NICK, NOTICE, NJOIN,
|
||||
OPER, PART, PASS, PING, PONG, PRIVMSG, QUIT, RESTART, SERVER, SQUIT, USER,
|
||||
USERHOST, 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/>.
|
||||
|
||||
[ ... more to come ... ]
|
||||
ADMIN, AWAY, CHANINFO, CONNECT, DIE, ERROR, INVITE, ISON, JOIN, KICK, KILL,
|
||||
LINKS, LIST, LUSERS, MODE, MOTD, NAMES, NICK, NJOIN, NOTICE, OPER, PART,
|
||||
PASS, PING, PONG, PRIVMSG, QUIT, RESTART, SERVER, SQUIT, TIME, TOPIC,
|
||||
USERHOST, USER, VERSION, WHO, WHOIS.
|
||||
|
||||
|
||||
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 ,-)
|
||||
III. Features (oder: warum gerade ngIRCd?)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- keine Probleme mit Servern, deren IP-Adresse dynamisch ist,
|
||||
- einfache, uebersichtliche Konfigurationsdatei,
|
||||
- frei verfuegbarer C-Quellcode.
|
||||
- ngIRCd wird aktiv weiterentwickelt.
|
||||
- unterstuetzte Plattformen (getestete Version): AIX (3.2.5), A/UX (3.0.1),
|
||||
FreeBSD/i386 (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), Windows mit Cygwin.
|
||||
|
||||
|
||||
IV. Dokumentation
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Im Paket enthalten ist u.a.:
|
||||
|
||||
- README: das Dokument, das Du gerade liest :-)
|
||||
- INSTALL: Hinweise zur Installation des ngIRCd
|
||||
- NEWS: sagt der Name schon :-)
|
||||
- ChangeLog: die komplette History des ngIRCd
|
||||
- doc/FAQ.txt: haeufige Fragen und Antworten zum ngIRCd
|
||||
- doc/CVS.txt: Hinweise zum CVS-System
|
||||
- doc/RFC.txt: Infos ueber die RFC's
|
||||
- doc/sample-ngircd.conf: Beispiel-Konfigurationsdatei
|
||||
- doc/README-AUX.txt: Installationshinweise fuer A/UX
|
||||
- doc/README-BeOS.txt: dito fuer BeOS
|
||||
|
||||
- doc/en/: englischsprachige Dokumentation
|
||||
|
||||
|
||||
V. Bezugsquellen
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Die Homepage des ngIRCd ist: <http://arthur.ath.cx/~alex/ngircd>; dort
|
||||
findest du immer die neusten Informationen ueber den ngIRCd und die aktuellen
|
||||
freigegebenen ("stabilen") Releases.
|
||||
|
||||
Falls du dich fuer die aktuellen Entwicklungs-Versionen (die jedoch nicht
|
||||
immer "stabil" sind) interessierst, dann lese bitte den Punkt "CVS" auf der
|
||||
Homepage und die Datei "doc/CVS.txt", die die Verwendung des "Concurrent
|
||||
Versioning System" (CVS) beschreibt.
|
||||
|
||||
|
||||
VI. Bugs
|
||||
~~~~~~~~
|
||||
|
||||
Wenn du im ngIRCd Bugs finden solltest (so was soll ja auch vorkommen :-),
|
||||
dann lege bitte einen Bug-Report ueber diese URL an:
|
||||
|
||||
<http://arthur.ath.cx/~alex/ngircd/#bugs>
|
||||
|
||||
Dort kannst du dich auch ueber bekannte Fehler informieren.
|
||||
|
||||
Falls du noch Anregungen, Kritik, Patches etc. pp. zum ngIRCd hast, dann
|
||||
bitte einfach eine Mail an <alex@barton.de> oder <alex@arthur.ath.cx>
|
||||
schreiben.
|
||||
|
||||
|
||||
--
|
||||
$Id: README,v 1.4 2002/01/29 00:17:39 alex Exp $
|
||||
$Id: README,v 1.14 2002/11/24 18:48:59 alex Exp $
|
||||
|
||||
49
acconfig.h
49
acconfig.h
@@ -1,49 +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: acconfig.h,v 1.7 2002/01/02 02:52:09 alex Exp $
|
||||
*
|
||||
* $Log: acconfig.h,v $
|
||||
* Revision 1.7 2002/01/02 02:52:09 alex
|
||||
* - Copyright-Texte angepasst ;-)
|
||||
*
|
||||
* Revision 1.6 2001/12/31 02:21:00 alex
|
||||
* - "doc"-Unterverzeichnis aufgenommen.
|
||||
*
|
||||
* Revision 1.5 2001/12/29 03:04:35 alex
|
||||
* - neue configure-Option "--enable-strict-rfc", #define STRICT_RFC.
|
||||
*
|
||||
* Revision 1.4 2001/12/27 01:44:49 alex
|
||||
* - die Verwendung von syslog kann nun abgeschaltet werden.
|
||||
*
|
||||
* Revision 1.3 2001/12/25 22:01:47 alex
|
||||
* - neue configure-Option "--enable-sniffer".
|
||||
*
|
||||
* Revision 1.2 2001/12/21 23:54:15 alex
|
||||
* - zusaetzliche Debug-Ausgaben koennen eingeschaltet werden.
|
||||
*
|
||||
* Revision 1.1 2001/12/12 01:58:52 alex
|
||||
* - Test auf socklen_t verbessert.
|
||||
*/
|
||||
|
||||
|
||||
#undef HAVE_socklen_t
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
#undef SNIFFER
|
||||
|
||||
#undef USE_SYSLOG
|
||||
|
||||
#undef STRICT_RFC
|
||||
|
||||
|
||||
/* -eof- */
|
||||
@@ -1,13 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $Id: autogen.sh,v 1.2 2001/12/12 01:58:17 alex Exp $
|
||||
#
|
||||
# $Log: autogen.sh,v $
|
||||
# Revision 1.2 2001/12/12 01:58:17 alex
|
||||
# - fuer fehlende Dateien werden nun "nur noch" symbolische Links erzeugt.
|
||||
#
|
||||
# Revision 1.1.1.1 2001/12/11 21:53:04 alex
|
||||
# Imported sources to CVS.
|
||||
# $Id: autogen.sh,v 1.3 2002/03/12 14:37:51 alex Exp $
|
||||
#
|
||||
|
||||
if [ -f configure ]; then
|
||||
|
||||
1321
config.guess
vendored
Normal file
1321
config.guess
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1443
config.sub
vendored
Normal file
1443
config.sub
vendored
Normal file
File diff suppressed because it is too large
Load Diff
286
configure.in
286
configure.in
@@ -1,97 +1,42 @@
|
||||
#
|
||||
# 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.22 2002/01/29 00:24:17 alex Exp $
|
||||
#
|
||||
# $Log: configure.in,v $
|
||||
# Revision 1.22 2002/01/29 00:24:17 alex
|
||||
# - Version 0.0.1
|
||||
#
|
||||
# Revision 1.21 2002/01/16 23:06:16 alex
|
||||
# - Version auf 0.0.4-pre im CVS angehoben.
|
||||
#
|
||||
# Revision 1.20 2002/01/16 22:55:45 alex
|
||||
# - Version 0.0.3
|
||||
#
|
||||
# Revision 1.19 2002/01/06 16:21:09 alex
|
||||
# - CVS-Version auf "0.0.3-pre" angehoben.
|
||||
#
|
||||
# Revision 1.18 2002/01/06 16:09:37 alex
|
||||
# - Version 0.0.2
|
||||
#
|
||||
# Revision 1.17 2002/01/05 15:53:20 alex
|
||||
# - Test auf Header "arpa/inet.h" und Funktion inet_aton() hinzugefuegt (BeOS).
|
||||
#
|
||||
# Revision 1.16 2002/01/02 13:41:36 alex
|
||||
# - CFLAGS wird nur noch gesetzt, wenn der GCC verwendet wird.
|
||||
#
|
||||
# Revision 1.15 2002/01/02 02:52:09 alex
|
||||
# - Copyright-Texte angepasst ;-)
|
||||
#
|
||||
# Revision 1.14 2001/12/31 16:11:13 alex
|
||||
# - CVS-Version auf "0.0.2-pre" angehoben.
|
||||
#
|
||||
# Revision 1.13 2001/12/31 16:02:30 alex
|
||||
# - Version 0.0.1
|
||||
#
|
||||
# Revision 1.12 2001/12/31 02:21:00 alex
|
||||
# - "doc"-Unterverzeichnis aufgenommen.
|
||||
#
|
||||
# Revision 1.11 2001/12/29 03:04:06 alex
|
||||
# - neue configure-Option "--enable-strict-rfc".
|
||||
#
|
||||
# Revision 1.10 2001/12/27 16:25:36 alex
|
||||
# - neue configure-Option "--with-portab=DIR".
|
||||
#
|
||||
# Revision 1.9 2001/12/27 02:08:38 alex
|
||||
# - da fehlte an zwei Stellen ein AC_MSG_ERROR ... ups!
|
||||
#
|
||||
# Revision 1.8 2001/12/27 01:44:49 alex
|
||||
# - die Verwendung von syslog kann nun abgeschaltet werden.
|
||||
#
|
||||
# Revision 1.7 2001/12/27 00:37:07 alex
|
||||
# - Erkennung der "portab header" geaendert, CFLAGS werden nun anders gesetzt.
|
||||
#
|
||||
# Revision 1.6 2001/12/25 22:01:47 alex
|
||||
# - neue configure-Option "--enable-sniffer".
|
||||
#
|
||||
# Revision 1.5 2001/12/21 23:54:26 alex
|
||||
# - zusaetzliche Debug-Ausgaben koennen eingeschaltet werden.
|
||||
#
|
||||
# Revision 1.4 2001/12/12 17:21:58 alex
|
||||
# - Projektdatei fuer den Mac OS X Project Builder erstellt.
|
||||
#
|
||||
# Revision 1.3 2001/12/12 01:58:53 alex
|
||||
# - Test auf socklen_t verbessert.
|
||||
#
|
||||
# Revision 1.2 2001/12/11 22:04:21 alex
|
||||
# - Test auf stdint.h (HAVE_STDINT_H) hinzugefuegt.
|
||||
#
|
||||
# Revision 1.1.1.1 2001/12/11 21:53:04 alex
|
||||
# Imported sources to CVS.
|
||||
# $Id: configure.in,v 1.69.2.6 2003/03/09 22:33:19 alex Exp $
|
||||
#
|
||||
|
||||
# -- Initialisierung --
|
||||
|
||||
AC_INIT
|
||||
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
|
||||
AM_INIT_AUTOMAKE(ngircd,0.1.0)
|
||||
AC_PREREQ(2.50)
|
||||
AC_CANONICAL_TARGET
|
||||
AC_CONFIG_SRCDIR(src/config.h.in)
|
||||
AM_INIT_AUTOMAKE(ngircd,0.6.x-CVS)
|
||||
AM_CONFIG_HEADER(src/config.h)
|
||||
|
||||
# -- Variablen --
|
||||
# -- Templates fuer config.h --
|
||||
|
||||
AH_TEMPLATE([DEBUG], [Define if debug-mode should be enabled])
|
||||
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([IRCPLUS], [Define if IRC+ protocol should be used])
|
||||
|
||||
AH_TEMPLATE([TARGET_OS], [Target operating system name])
|
||||
AH_TEMPLATE([TARGET_VENDOR], [Target system vendor])
|
||||
AH_TEMPLATE([TARGET_CPU], [Target CPU name])
|
||||
|
||||
# -- C Compiler --
|
||||
|
||||
AC_PROG_CC
|
||||
AC_LANG_C
|
||||
|
||||
# -- Hilfsprogramme --
|
||||
|
||||
@@ -101,43 +46,41 @@ AC_PROG_LN_S
|
||||
AC_PROG_MAKE_SET
|
||||
AC_PROG_RANLIB
|
||||
|
||||
# -- Compiler Features --
|
||||
|
||||
AC_LANG_C
|
||||
|
||||
AM_C_PROTOTYPES
|
||||
AC_C_CONST
|
||||
|
||||
# -- Defines --
|
||||
|
||||
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
|
||||
|
||||
if test `uname` = "HP-UX"; then
|
||||
# unter HP-UX 11.11 muss _XOPEN_SOURCE_EXTENDED definiert sein.
|
||||
AC_MSG_RESULT([detected HP-UX, defining _XOPEN_SOURCE_EXTENDED])
|
||||
CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED"
|
||||
fi
|
||||
|
||||
# -- Header --
|
||||
|
||||
AC_HEADER_STDC
|
||||
|
||||
AC_HEADER_TIME
|
||||
|
||||
AC_ARG_WITH(portab,
|
||||
[ --with-portab=DIR search the "portab headers" in DIR],
|
||||
[ if test "x$withval" != "xno"; then
|
||||
CFLAGS="$CFLAGS -I${withval}"
|
||||
if test -f ${withval}/portab.h; then
|
||||
AC_MSG_RESULT([searching "portab headers" in ${withval}...])
|
||||
else
|
||||
AC_MSG_ERROR([${withval}/portab.h not found!])
|
||||
fi
|
||||
else
|
||||
AC_MSG_ERROR([Can't disable Alex \"portability headers\"!])
|
||||
fi
|
||||
],
|
||||
[ AC_CHECK_HEADER(portab.h,[
|
||||
AC_CHECK_HEADER(imp.h,,AC_MSG_ERROR([Alex \"portability headers\" (portab.h an friends) not found!]))
|
||||
AC_CHECK_HEADER(exp.h,,AC_MSG_ERROR([Alex \"portability headers\" (portab.h an friends) not found!]))
|
||||
],[
|
||||
AC_CHECK_HEADER(/usr/local/include/portab.h,,AC_MSG_ERROR([Alex \"portability headers\" (portab.h an friends) not found!]))
|
||||
AC_CHECK_HEADER(/usr/local/include/imp.h,,AC_MSG_ERROR([Alex \"portability headers\" (portab.h an friends) not found!]))
|
||||
AC_CHECK_HEADER(/usr/local/include/exp.h,,AC_MSG_ERROR([Alex \"portability headers\" (portab.h an friends) not found!]))
|
||||
CFLAGS="$CFLAGS -I/usr/local/include"
|
||||
])
|
||||
]
|
||||
)
|
||||
AC_HEADER_SYS_WAIT
|
||||
|
||||
AC_CHECK_HEADERS([ \
|
||||
errno.h fcntl.h netinet/in.h string.h \
|
||||
sys/socket.h sys/time.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)
|
||||
AC_CHECK_HEADERS(arpa/inet.h ctype.h malloc.h stdint.h sys/select.h varargs.h)
|
||||
|
||||
# -- Datentypen --
|
||||
|
||||
@@ -154,47 +97,80 @@ 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([ \
|
||||
gethostname inet_ntoa memmove memset select \
|
||||
socket strcasecmp strchr strerror strstr waitpid \
|
||||
bind gethostbyaddr gethostbyname gethostname inet_ntoa memmove \
|
||||
memset select setsockopt socket strcasecmp strchr strerror \
|
||||
strstr waitpid \
|
||||
],,AC_MSG_ERROR([required function missing!]))
|
||||
|
||||
AC_CHECK_FUNCS(inet_aton)
|
||||
|
||||
# -- Libraries --
|
||||
AC_CHECK_FUNCS(inet_aton isdigit sigaction snprintf vsnprintf)
|
||||
|
||||
# -- Konfigurationsoptionen --
|
||||
|
||||
x_syslog_on=no
|
||||
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_MSG_ERROR([Can't enable syslog: syslog.h not found!]))
|
||||
else
|
||||
AC_MSG_RESULT([disabling syslog])
|
||||
AC_CHECK_HEADER(syslog.h, x_syslog_on=yes,
|
||||
AC_MSG_ERROR([Can't enable syslog: syslog.h not found!])
|
||||
)
|
||||
fi
|
||||
],
|
||||
[ AC_CHECK_HEADER(syslog.h,AC_DEFINE(USE_SYSLOG, 1))
|
||||
]
|
||||
[ AC_CHECK_HEADER(syslog.h, x_syslog_on=yes) ]
|
||||
)
|
||||
if test "$x_syslog_on" = "yes"; then
|
||||
AC_DEFINE(USE_SYSLOG, 1)
|
||||
AC_CHECK_LIB(be,syslog)
|
||||
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_zlib_on=no
|
||||
AC_ARG_ENABLE(zlib,
|
||||
[ --disable-zlib disable zlib compression (autodetected by default)],
|
||||
[ if test "$enableval" = "yes"; then
|
||||
AC_CHECK_HEADER(zlib.h, x_zlib_on=yes,
|
||||
AC_MSG_ERROR([Can't enable zlib: zlib.h not found!])
|
||||
)
|
||||
fi
|
||||
],
|
||||
[ AC_CHECK_HEADER(zlib.h, x_zlib_on=yes) ]
|
||||
)
|
||||
if test "$x_zlib_on" = "yes"; then
|
||||
AC_DEFINE(USE_ZLIB, 1)
|
||||
AC_CHECK_LIB(z,deflate)
|
||||
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
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
@@ -204,24 +180,78 @@ AC_ARG_ENABLE(debug,
|
||||
)
|
||||
if test "$x_debug_on" = "yes"; then
|
||||
AC_DEFINE(DEBUG, 1)
|
||||
AC_MSG_RESULT([enabling additional debug output])
|
||||
fi
|
||||
|
||||
# -- Variablen II --
|
||||
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" )
|
||||
AC_DEFINE_UNQUOTED(TARGET_VENDOR, "$target_vendor" )
|
||||
AC_DEFINE_UNQUOTED(TARGET_OS, "$target_os" )
|
||||
|
||||
# -- Variablen --
|
||||
|
||||
if test "$GCC" = "yes"; then
|
||||
CFLAGS="-Wall $CFLAGS"
|
||||
fi
|
||||
|
||||
# -- Ausgabe --
|
||||
the_CFLAGS="$CFLAGS"
|
||||
|
||||
CFLAGS="$CFLAGS -DSYSCONFDIR='\"\$(sysconfdir)\"'"
|
||||
|
||||
# -- Ausgabe der Dateien --
|
||||
|
||||
AC_OUTPUT([ \
|
||||
Makefile \
|
||||
doc/Makefile \
|
||||
doc/en/Makefile \
|
||||
MacOSX/Makefile \
|
||||
MacOSX/ngircd.pbproj/Makefile \
|
||||
src/Makefile \
|
||||
src/portab/Makefile \
|
||||
src/ngircd/Makefile \
|
||||
src/testsuite/Makefile \
|
||||
man/Makefile \
|
||||
contrib/Makefile \
|
||||
])
|
||||
|
||||
# -- Ergebnis --
|
||||
|
||||
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}`
|
||||
|
||||
echo " host: ${host}"
|
||||
echo " compiler: ${CC}"
|
||||
echo " compiler flags: ${the_CFLAGS}"
|
||||
echo " preprocessor flags: ${CPPFLAGS}"
|
||||
echo " linker flags: ${LDFLAGS}"
|
||||
echo " libraries: ${LIBS}"
|
||||
echo
|
||||
echo " 'ngircd' binary: $S"
|
||||
echo " configuration file: $C"
|
||||
echo " manual pages: $M"
|
||||
echo
|
||||
|
||||
echo $ECHO_N " active options: $ECHO_C"
|
||||
test "$x_syslog_on" = "yes" && echo $ECHO_N "Syslog $ECHO_C"
|
||||
test "$x_zlib_on" = "yes" && echo $ECHO_N "zLib $ECHO_C"
|
||||
test "$x_debug_on" = "yes" && echo $ECHO_N "Debug $ECHO_C"
|
||||
test "$x_sniffer_on" = "yes" && echo $ECHO_N "Sniffer $ECHO_C"
|
||||
test "$x_strict_rfc_on" = "yes" && echo $ECHO_N "Strict-RFC $ECHO_C"
|
||||
test "$x_ircplus_on" = "yes" && echo $ECHO_N "IRC+ $ECHO_C"
|
||||
echo; 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.6.1
|
||||
%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/
|
||||
49
doc/CVS.txt
49
doc/CVS.txt
@@ -14,12 +14,51 @@ Die Sourcen des ngIRCd werden mit dem "Concurrent Versions System" (CVS)
|
||||
verwaltet. Somit koennen ohne Probleme mehrere Leute gleichzeitig die Sourcen
|
||||
bearbeitet.
|
||||
|
||||
Dieser Text soll in Zukunft die Grundlagen beschreiben. Tut er aber leider
|
||||
noch nicht, also frage einfach Alex direkt (siehe AUTHORS-Text), wenn du
|
||||
daran interessiert bist, Zugriff auf den Quellcode via CVS zu bekommen!
|
||||
|
||||
[ ... more to come ... ]
|
||||
I. Anonymer "Nur-Lesen"-Zugang
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Anonymer Zugriff auf die CVS-Repository von ngIRCd ist im "nur-lesen"-Modus
|
||||
moeglich. Dazu sind folgende Schritte noetig:
|
||||
|
||||
Beim CVS-Server anmelden
|
||||
|
||||
$ 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:
|
||||
|
||||
$ 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.
|
||||
|
||||
Dieses ist der "Arbeitsordner", alle CVS-Befehle werden in Zukunft aus
|
||||
diesem Ordner bzw. einem Unterordner davon ausgefuehrt.
|
||||
|
||||
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!
|
||||
|
||||
CVS-Tree aktualisieren:
|
||||
|
||||
$ cvs update
|
||||
|
||||
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 ;-))
|
||||
|
||||
|
||||
III. Schreibzugriff
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
Wer Schreibzugriff auf die CVS-Repository wuenscht, der moege sich bitte
|
||||
mit Alex Barton, <alex@barton.de> in Verbindung setzen.
|
||||
|
||||
|
||||
--
|
||||
$Id: CVS.txt,v 1.4 2002/01/23 18:20:04 alex Exp $
|
||||
$Id: CVS.txt,v 1.5 2002/02/15 15:15:22 alex Exp $
|
||||
|
||||
17
doc/FAQ.txt
17
doc/FAQ.txt
@@ -42,5 +42,20 @@ A: Auf dem System ist eine zu alte Version von GNU autoconf installiert.
|
||||
mit dem Befehl "rpm -e autoconf").
|
||||
|
||||
|
||||
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: 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/>
|
||||
|
||||
|
||||
--
|
||||
$Id: FAQ.txt,v 1.1 2002/01/23 14:05:20 alex Exp $
|
||||
$Id: FAQ.txt,v 1.2 2002/02/19 20:05:02 alex Exp $
|
||||
|
||||
@@ -9,22 +9,21 @@
|
||||
# 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.3 2002/01/02 02:40:31 alex Exp $
|
||||
#
|
||||
# $Log: Makefile.am,v $
|
||||
# Revision 1.3 2002/01/02 02:40:31 alex
|
||||
# - Copyright-Text ergaenzt.
|
||||
#
|
||||
# Revision 1.2 2001/12/31 02:45:24 alex
|
||||
# - nun werden alle generierten Dateien bei "maintainer-clean" geloescht.
|
||||
#
|
||||
# Revision 1.1 2001/12/31 02:22:29 alex
|
||||
# - Makefile.am fuer das "doc"-Verzeichnis begonnen.
|
||||
# $Id: Makefile.am,v 1.10 2002/09/16 10:35:06 alex Exp $
|
||||
#
|
||||
|
||||
EXTRA_DIST = CVS.txt RFC.txt sample-ngircd.conf
|
||||
SUBDIRS = en
|
||||
|
||||
EXTRA_DIST = CVS.txt FAQ.txt Protocol.txt README-AUX.txt \
|
||||
README-BeOS.txt RFC.txt sample-ngircd.conf
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile Makefile.in
|
||||
|
||||
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
|
||||
|
||||
# -eof-
|
||||
|
||||
115
doc/Protocol.txt
Normal file
115
doc/Protocol.txt
Normal file
@@ -0,0 +1,115 @@
|
||||
|
||||
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.
|
||||
|
||||
-- Protocol.txt --
|
||||
|
||||
|
||||
I. Kompatibilitaet
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Der ngIRCd haelt sich an das IRC-Protokoll Version 2.10, wie es in den RFCs
|
||||
1459 und 2810-2813 beschrieben ist. Diese (und ggf. weitere fuer den ngIRCd
|
||||
relevante) RFCs sind in RFC.txt aufgefuehrt.
|
||||
|
||||
Leider verhaelt sich aber schon der "Originalserver" nicht immer genau so,
|
||||
wie es in den RFCs beschrieben ist. Da der ngIRCd aber ein Ersatz fuer
|
||||
eben diesen Server sein soll, werden diese Abweichungen in der Regel vom
|
||||
ngIRCd emuliert um die Kompatibilitaet zu wahren.
|
||||
|
||||
Sollte dieses Verhalten nicht erwuenscht sein, so kann mit der configure-
|
||||
Option "--enable-strict-rfc" der ngIRCd so compiliert werden, dass er sich
|
||||
strikt an die entsprechenden RFCs haelt.
|
||||
|
||||
ACHTUNG: an einem so compilierten Server koennen sich andere Server und
|
||||
Clients, die sich nicht genau an das Protokoll halten, u.U. nicht mehr
|
||||
anmelden oder alle Funktionen nutzen! In der Regel ist diese Option daher
|
||||
nicht erwuenscht.
|
||||
|
||||
|
||||
II. Das IRC+-Protokoll
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Der ngIRCd unterstuetzt als Erweiterung zum IRC-Protokoll wie es in den RFCs
|
||||
2810-2813 beschrieben ist, das IRC+-Protokoll. Dieses Protokoll ist dabei
|
||||
kompatibel zum IRC-Protokoll und wird nur verwendet, wenn der ngIRCd fest-
|
||||
stellt, dass ein connectierter Server ebenfalls dieses erweiterte Protokoll
|
||||
unterstuetzt.
|
||||
|
||||
Die Protokoll- und Server-Erkennung wird mit dem "PASS"-Befehl durchgefuehrt
|
||||
(vgl. RFC 2813, Sektion 4.1.1):
|
||||
|
||||
|
||||
II.1 neuen Server-Link registrieren
|
||||
|
||||
Befehl: PASS
|
||||
Parameter: <password> <version> <flags> [<options>]
|
||||
Fuer: mit dieser Syntax nur Server
|
||||
|
||||
<password> enthaelt das Passwort fur den neu aufzubauenden Server-Link,
|
||||
so wie es in der Konfigurationsdatei definiert wurde.
|
||||
|
||||
<version> setzt sich aus zwei Teilen zusammen und ist mindestens 4, maximal
|
||||
14 Zeichen lang: die ersten vier Bytes enthalten die Versionsnummer des
|
||||
unterstuetzten IRC-Protokolls, wobei die ersten zwei Bytes die Major-, die
|
||||
letzten beiden die Minor-Revision angeben. Der String "0210" steht also
|
||||
fuer Protokollversion 2.10.
|
||||
Die folgenden (optionalen!) 10 Bytes enthalten eine von der jeweiligen
|
||||
Implementation abhaengige Versionsnummer. Server, die das IRC+-Protokoll
|
||||
unterstuetzen, liefern hier "-IRC+".
|
||||
|
||||
<flags> setzt sich ebenfalls aus zwei Bestandteilen zusammen und ist
|
||||
maximal 100 Bytes lang. Getrennt werden die beiden Teile mit dem Zeichen
|
||||
"|". Der erste Teil enthaelt den Namen der Implementation, der ngIRCd
|
||||
liefert hier z.B. "ngIRCd", der Originalserver "IRC". Anhand dieser "ID"
|
||||
kann zwischen Serverimplementationen unterschieden werden. Der zweite Teil
|
||||
(nach dem "|") ist implementationsabhaengig und wird nur ausgewertet,
|
||||
wenn die Gegenseite das IRC+-Protokoll unterstuetzt. In diesem Fall wird
|
||||
folgende Syntax erwartet: "<serverversion>[:<serverflags>]".
|
||||
|
||||
<serverversion> ist hier eine ASCII-Klartext-Darstellung der Versionsnummer,
|
||||
<serverflags> zeigt die vom Server unterstuetzten Erweiterungen an (und
|
||||
kann die leere Menge sein).
|
||||
|
||||
Mit dem optionalen Parameter <options> werden Server-Optionen uebermittelt,
|
||||
wie sie in RFC 2813, Sektion 4.1.1 definiert sind.
|
||||
|
||||
Folgende <serverflags> sind zur Zeit definiert:
|
||||
|
||||
- o: IRC-Operatoren duerfen auch dann Channel- und Channel-User-Modes
|
||||
aendern, wenn sie kein Channel-Operator im betroffenen Channel sind.
|
||||
|
||||
- C: der Server unterstuetzt den CHANINFO-Befehl.
|
||||
|
||||
|
||||
II.2 Channel-Modes, persistente Channel und Topic austauschen
|
||||
|
||||
Befehl: CHANINFO
|
||||
Parameter: <channel> +<modes> [[<key> <maxusers>] <topic>]
|
||||
Fuer: Server
|
||||
|
||||
Mit CHANINFO Informiert ein Server den anderen ueber einen Channel: dessen
|
||||
Modes, Channel-Key, User-Limit und dessen Topic. <topic> ist optional.
|
||||
|
||||
Existiert auf dem Server, der das CHANINFO empfaengt, der Channel bereits,
|
||||
so uebernimmt er die Werte jeweils nur dann, wenn er selber noch keine
|
||||
Modes bzw. kein Topic definiert hat. Ansonsten wird der jeweilige Parameter
|
||||
ignoriert.
|
||||
|
||||
Existiert der Channel noch nicht, so wird er mit den entsprechenden Angaben
|
||||
erzeugt.
|
||||
|
||||
Hat ein Channel keinen Key (in <modes> ist der Mode "k" nicht vorhanden),
|
||||
so muss der Parameter <key> ignoriert werden (da <key> vorhanden sein muss,
|
||||
sollte in diesem Fall "*" uebergeben werden). Hat er kein User-Limit (kein
|
||||
"l" in <modes>), so muss <limit> ignoriert werden (<limit> sollte hierbei
|
||||
als "0" uebergeben werden).
|
||||
|
||||
|
||||
--
|
||||
$Id: Protocol.txt,v 1.5.4.1 2003/01/08 20:36:57 alex Exp $
|
||||
68
doc/README-AUX.txt
Normal file
68
doc/README-AUX.txt
Normal file
@@ -0,0 +1,68 @@
|
||||
|
||||
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.
|
||||
|
||||
-- README-AUX.txt --
|
||||
|
||||
|
||||
Seit Version 0.2.2-pre gehoert Apple A/UX zu den offiziell unterstuetzten
|
||||
Plattformen. Er ist im vollen Funktionsumfang nutzbar.
|
||||
|
||||
Ab Version 0.5.0 compiliert zudem der ngIRCd mit dem nativen A/UX-Compiler,
|
||||
d.h. GNU C wird nicht mehr zwingend vorausgesetzt.
|
||||
|
||||
Folgende Software wird jedoch benoetigt:
|
||||
|
||||
- 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
|
||||
|
||||
A/UX beinhaltet ein /bin/sed, dieses unterstuetzt jedoch leider nicht
|
||||
alle Funktionen, die GNU automake/autoconf nutzen.
|
||||
Achtung: bitte bei der Installation von GNU sed sicherstellen, dass
|
||||
immer dieses und nie das von A/UX verwendet wird (also $PATH entsprechend
|
||||
anpassen bzw. die A/UX-Version komplett ersetzen)!
|
||||
|
||||
- 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
|
||||
|
||||
Diese Library beinhaltet Systemfunktionen, die auf UNIXoiden Systemen
|
||||
gaengig, unter A/UX jedoch leider nicht verfuegbar sind. Dazu gehoert
|
||||
u.a. memmove(), strerror() und strdup().
|
||||
|
||||
Nachdem diese Pakete entsprechend installiert sind, reicht ein ganz normales
|
||||
"./configure" und "make" aus, um den ngIRCd unter A/UX zu compilieren.
|
||||
|
||||
|
||||
Noch ein paar Hinweise, wenn es doch (noch) nicht klappt:
|
||||
|
||||
- auf dem System muss entweder ein install vorhanden sein, welches so
|
||||
"broken" ist, dass configure das eigene Shell-Skript waehlt, oder eben
|
||||
eines, welches funktioniert. Leider ist mindestens ein Binary im Um-
|
||||
lauf, welches Probleme verursacht. Das Binary aus folgenden GNU
|
||||
fileutils funktioniert hier aber z.B.:
|
||||
ftp://arthur.ath.cx/pub/UNIX/AUX/Software/Tools/fileutils-4.0.tar.gz
|
||||
|
||||
- das sich im Umlauf befindende vorcompilierte Binary der alten Bash sollte
|
||||
unbedingt ausserhalb von /bin (z.B. unter /usr/local/bin) installiert
|
||||
werden. Ansonsten waehlt es das configure-Script als Shell aus, leider
|
||||
funktioniert das aber nicht.
|
||||
|
||||
- da die /bin/sh von A/UX recht limitiert ist, kann sie u.a. nicht zum
|
||||
Erzeugen des "config.status"-Scripts verwendet werden.
|
||||
Abhilfe: /bin/sh umbenennen (z.B. in "/bin/sh.AUX") und durch einen (am
|
||||
besten symbolischen) Link auf /bin/ksh ersetzen.
|
||||
Dieser Schritt sollte keine Probleme nach sich ziehen und ist daher immer,
|
||||
auch unabhaengig vom ngIRCd, empfehlenswert.
|
||||
|
||||
|
||||
--
|
||||
$Id: README-AUX.txt,v 1.4 2002/11/11 00:59:11 alex Exp $
|
||||
47
doc/README-BeOS.txt
Normal file
47
doc/README-BeOS.txt
Normal file
@@ -0,0 +1,47 @@
|
||||
|
||||
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.
|
||||
|
||||
-- README-BeOS.txt --
|
||||
|
||||
|
||||
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
|
||||
mit diesem Fehler ab:
|
||||
|
||||
select(): Bad file descriptor!
|
||||
|
||||
Es sieht leider so aus, als ob das select() von BeOS nicht mit File-Handles
|
||||
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 "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
|
||||
es eigentlich zu keinen Beeintraechtigungen kommen ...
|
||||
|
||||
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.3 2002/05/19 13:10:26 alex Exp $
|
||||
139
doc/en/INSTALL
Normal file
139
doc/en/INSTALL
Normal file
@@ -0,0 +1,139 @@
|
||||
|
||||
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.
|
||||
|
||||
-- INSTALL --
|
||||
|
||||
|
||||
|
||||
0. Upgrade Information
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Differences to version 0.5.x
|
||||
|
||||
- Starting with version 0.6.0, other servers are identified using asyncronous
|
||||
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/en/sample-ngircd.conf"!).
|
||||
|
||||
|
||||
I. Standard-Installation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
ngIRCd is developed for UNIX-like systems, which means, that the installation
|
||||
on a modern UNIX-like system should be no problem. The only thing is, that
|
||||
the system should be supported by GNU automake and GNU autoconf ("configure").
|
||||
|
||||
The normal installation is like that:
|
||||
|
||||
1) tar xzf ngircd-<Version>.tar.gz
|
||||
2) cd ngircd-<Version>
|
||||
3) ./autogen.sh [only necessary when using CVS]
|
||||
4) ./configure
|
||||
5) make
|
||||
6) make install
|
||||
|
||||
3): "autogen.sh"
|
||||
|
||||
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-archieves, but when using the CVS system.
|
||||
|
||||
The next is therefore only interesting for developpers.
|
||||
|
||||
autogen.sh produces the makefile.in's, which are necessary for the configure
|
||||
script it self, and some more files for make. For this step, there must be
|
||||
GNU automake and GNU autoconf (in recent versions).
|
||||
|
||||
(again: "end users" do not need this step!)
|
||||
|
||||
to 4): "./configure"
|
||||
|
||||
The configure-script is used to detect local system dependancies.
|
||||
|
||||
In the perfect case, configure should recognize all needed libraries, header
|
||||
and so on. If this shouldn't work, "./configure --help" shows more options.
|
||||
|
||||
to 5): "make"
|
||||
|
||||
The make command uses the Makefiles produced by configure and compiles the
|
||||
ngIRCd daemon.
|
||||
|
||||
to 6): "make install"
|
||||
|
||||
Use "make install" to install the server and a sample configuration file on
|
||||
the local system. For this step, root privileges are necessary. If there is
|
||||
already an older configuration file present, it won't be overwritten.
|
||||
|
||||
This are the files that are installed:
|
||||
|
||||
- /usr/local/sbin/ngircd: exectable server
|
||||
- /usr/local/etc/ngircd.conf: sample configuration, if not there
|
||||
|
||||
|
||||
II. Useful make-targets
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The Makefile produced by the configure-script contain always these useful
|
||||
targets:
|
||||
|
||||
- clean: delete every product from the compiler/linker
|
||||
next step: -> make
|
||||
|
||||
- distclean: plus erase all generated Makefiles
|
||||
next step: -> ./configure
|
||||
|
||||
- maintainer-clean: erease all automatic generated files
|
||||
next step: -> ./autogen.sh
|
||||
|
||||
|
||||
III. Sample configuration file ngircd.conf
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In the sample configuration file, there are comments beginning with "#" OR
|
||||
";" -- this is only for the better understanding of the code.
|
||||
|
||||
The file is seperated in three blocks: [Global], [Operator], [Server]. In
|
||||
the [Gobal] part, there is the main configuration, like the server-name
|
||||
and the ports, on which the server should be listening. In the [Operator]
|
||||
section, the server-operators are defined and [Server] is the section,
|
||||
where the server-links are configured.
|
||||
|
||||
The meaning of the variables in the configuration file is explained in the
|
||||
"doc/sample-ngircd.conf", which is also the sample configuration file in
|
||||
/usr/local/etc after running "make install" (if you don't already have one).
|
||||
|
||||
|
||||
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.3 2002/12/18 12:19:07 alex Exp $
|
||||
20
doc/en/Makefile.am
Normal file
20
doc/en/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.2 2002/11/18 14:06:29 alex Exp $
|
||||
#
|
||||
|
||||
EXTRA_DIST = INSTALL README sample-ngircd.conf
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile Makefile.in
|
||||
|
||||
# -eof-
|
||||
101
doc/en/README
Normal file
101
doc/en/README
Normal file
@@ -0,0 +1,101 @@
|
||||
ngIRCd - Next Generation IRC Server
|
||||
|
||||
(c)2001,2002 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.
|
||||
|
||||
-- README --
|
||||
|
||||
Ilja Osthoff, <ilja@glide.ath.cx>
|
||||
|
||||
|
||||
I. Introduction
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
ngIRCd is an Open-Source server for the Internet Realy Chat (IRC), which
|
||||
is developped 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.
|
||||
|
||||
|
||||
|
||||
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, ERROR, INVITE, ISON, JOIN, KICK, KILL,
|
||||
LINKS, LIST, LUSERS, MODE, MOTD, NAMES, NICK, NJOIN, NOTICE, OPER, PART,
|
||||
PASS, PING, PONG, PRIVMSG, QUIT, RESTART, SERVER, SQUIT, TIME, TOPIC,
|
||||
USERHOST, USER, VERSION, WHO, WHOIS.
|
||||
|
||||
|
||||
III. Features (or: why use ngIRCd?)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- no problems with servers which have dynamic ip-adresses
|
||||
- simple, easy understandable configuration file,
|
||||
- freely published C-Sourcecode,
|
||||
- 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.
|
||||
|
||||
|
||||
IV. Documentation
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
English documentation:
|
||||
|
||||
- doc/en/README: the file that you are reading :-)
|
||||
- doc/en/INSTALL: hints for the installation of the ngIRCd
|
||||
|
||||
German documentation:
|
||||
|
||||
- README: readme text in german
|
||||
- INSTALL: german installation instructions
|
||||
- NEWS: what do you think? :-)
|
||||
- Changelog: the complete history of the ngIRCd
|
||||
- doc/FAQ.txt: frequently asked questions and answers
|
||||
- doc/CVS.txt: hints for the CVS-system
|
||||
- doc/RFC.txt: information about the RFC's
|
||||
- doc/sample-ngircd.conf: sample configuration file
|
||||
- doc/README-AUX.txt: installation hints for A/UX
|
||||
- doc/README-BeOS.txt: the same for BeOS
|
||||
|
||||
|
||||
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 newest developper-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 kown bugs, too.
|
||||
|
||||
If you have critics, patches or something else, please feel yourself free
|
||||
to post a mail to: <alex@barton.de> or <alex@arthur.ath.cx>
|
||||
|
||||
|
||||
--
|
||||
$Id: README,v 1.7 2002/11/24 18:48:59 alex Exp $
|
||||
138
doc/en/sample-ngircd.conf
Normal file
138
doc/en/sample-ngircd.conf
Normal file
@@ -0,0 +1,138 @@
|
||||
# $Id: sample-ngircd.conf,v 1.4 2002/12/18 12:19:07 alex Exp $
|
||||
|
||||
#
|
||||
# This is a sample configuration for the ngIRCd, which must adept to the
|
||||
# local preferences and needs.
|
||||
#
|
||||
# Comments are started with "#" or ";".
|
||||
#
|
||||
# Author: Alexander Barton, <alex@barton.de>
|
||||
# Translation by Ilja Osthoff, <ilja@glide.ath.cx>
|
||||
#
|
||||
|
||||
[Global]
|
||||
|
||||
# In the [global] section of this file, there is the place of the
|
||||
# main server configuration. Needed is only the variable "Name",
|
||||
# Info you can adjust, if you like to. For all the others variables,
|
||||
# you can use the defaults, this means you can leave it by default.
|
||||
|
||||
# Server name in the IRC-network
|
||||
Name = irc.the.net
|
||||
|
||||
# Info-text of the server. This will be shown i.e. by a WHOIS- or
|
||||
# LINKS-request.
|
||||
Info = Server Info Text
|
||||
|
||||
# Information about the server and administrator in the ADMIN-request
|
||||
;AdminInfo1 = Description
|
||||
;AdminInfo2 = Location
|
||||
;AdminEMail = admin@irc.server
|
||||
|
||||
# Ports, on which the server will listen. There may be more than
|
||||
# one port, separated with ";". (Default: 6667)
|
||||
;Ports = 6667, 6668, 66694
|
||||
|
||||
# Textfile with the "message of the day" (MOTD). This will be shown
|
||||
# on a user connection with the server.
|
||||
;MotdFile = /usr/local/etc/ngircd.motd
|
||||
|
||||
# User-ID, under which the server is started (for that the server
|
||||
# must be started with root-rights). You can use the name of the
|
||||
# user or the numerical ID.
|
||||
# ATTENTION: the configuration and the MOTD file must be readable
|
||||
# by this user, otherwise RESTART won't work!
|
||||
;ServerUID = 65534
|
||||
|
||||
# Group-ID, under which the server is running (for that the server
|
||||
# must be started with root-rights). You can use the name of the
|
||||
# group or the numerical ID.
|
||||
;ServerGID = 65534
|
||||
|
||||
# After <PingTimeout> seconds, the server will send a ping after
|
||||
# inactivity of this client.
|
||||
;PingTimeout = 120
|
||||
|
||||
# If there is an answer of a client, to which the ping was sended,
|
||||
# not after <PongTimeout> seconds, it will be disconnected.
|
||||
;PongTimeout = 20
|
||||
|
||||
# The server tries every <ConnectRetry> seconds, not yet connected
|
||||
# or not anymore connected servers to connect.
|
||||
;ConnectRetry = 60
|
||||
|
||||
# Should IRC-operators be allowed to use the MODE command even if
|
||||
# they are not(!) channel-operators?
|
||||
;OperCanUseMode = no
|
||||
|
||||
# Maximum number of simultanous connection the server is allowed
|
||||
# to accept (<=0: unlimited):
|
||||
;MaxConnections = -1
|
||||
|
||||
# Maximum number of channels a user can be member of (<=0: no limit):
|
||||
;MaxJoins = 10
|
||||
|
||||
[Operator]
|
||||
# In this [operator]-section, there will be the configuration of
|
||||
# the name and password of an IRC operator. There may be more than
|
||||
# one operator-block (for each operator one).
|
||||
|
||||
# ID of the operator (may be different of the nick)
|
||||
;Name = TheOper
|
||||
|
||||
# Password of the operator
|
||||
;Password = ThePwd
|
||||
|
||||
[Server]
|
||||
# In this [Server] section, there is the configuration of the
|
||||
# servers, which are allowed to connect to your own server.
|
||||
# There may be more than one server-block.
|
||||
# If you configured a port for the connection, then the ngIRCd
|
||||
# tries to connect to this port. If not, it waits for the other
|
||||
# server.
|
||||
#
|
||||
# Server-groups:
|
||||
# The ngIRCd allows "server-groups": that means, that you can assign
|
||||
# server-groups for every server, to which you want the ngIRCd to
|
||||
# connect to. If one server of a server-group won't answer, the
|
||||
# ngIRCd tries the next one of this group.
|
||||
# ATTENTION: Server-groups will only work if you defined a port!
|
||||
|
||||
# IRC-name of the server
|
||||
;Name = irc2.the.net
|
||||
|
||||
# Hostname of the server
|
||||
;Host = connect-to-host.the.net
|
||||
|
||||
# Port of the server, to which the ngIRCd should connect. If you
|
||||
# assign no port, the ngIRCd waits for an answer of that server.
|
||||
;Port = 6666
|
||||
|
||||
# Own password for the connection. This password has to be configured
|
||||
# as "PeerPassword" on the other server.
|
||||
;MyPassword = MySecret
|
||||
|
||||
# Foreign password for this connection. This password has to be
|
||||
# configured as "MyPassword" on the other server.
|
||||
;PeerPassword = PeerSecret
|
||||
|
||||
# Group of that server (optional)
|
||||
;Group = 123
|
||||
|
||||
[Channel]
|
||||
# In the [Channel] there can be defined "persistent channels". This
|
||||
# means, that the server creates the channel and even if all users
|
||||
# left this channel, it will persist. There may be more than one
|
||||
# block. Signed with the mode "P", which can be set or unset, like
|
||||
# normal modes.
|
||||
|
||||
# Name of the channel
|
||||
;Name = #TheName
|
||||
|
||||
# Topic for the channel
|
||||
;Topic = a great topic
|
||||
|
||||
# Channel-modes
|
||||
;Modes = tn
|
||||
|
||||
# -eof-
|
||||
@@ -1,22 +1,164 @@
|
||||
# $Id: sample-ngircd.conf,v 1.2 2002/01/06 16:54:05 alex Exp $
|
||||
# $Id: sample-ngircd.conf,v 1.17 2002/12/18 12:19:07 alex Exp $
|
||||
|
||||
#
|
||||
# Das ist eine Beispiel-Konfiguration fuer den ngIRCd, die an die
|
||||
# jeweiligen Beduerfnisse angepasst werden kann/muss.
|
||||
#
|
||||
# Kommentare werden mit "#" oder ";" eingeleitet.
|
||||
#
|
||||
# +-----------------------------------------------------------------------+
|
||||
# | Please note: English translations of some of the german documentation |
|
||||
# | files can be found in the directory "doc/en" -- please have a look! |
|
||||
# +-----------------------------------------------------------------------+
|
||||
#
|
||||
# Autor: Alexander Barton, <alex@barton.de>
|
||||
# Erweiterungen von 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, d.h. hier
|
||||
# muss die Variable nicht angegeben werden.
|
||||
#
|
||||
|
||||
# Servername im IRC-Netz
|
||||
Name = irc.the.net
|
||||
|
||||
# Info-Text des Servers. Dieser wird z.B. bei WHOIS- oder LINKS-
|
||||
# Abfragen entsprechend mit ausgegeben.
|
||||
Info = Server Info Text
|
||||
Ports = 6667, 6668, 6669
|
||||
MotdFile = /usr/local/etc/ngircd.motd
|
||||
PingTimeout = 120
|
||||
PongTimeout = 10
|
||||
ConnectRetry = 60
|
||||
|
||||
# Informationen ueber den Server und Administrator fuer den
|
||||
# ADMIN-Befehl:
|
||||
;AdminInfo1 = Beschreibung
|
||||
;AdminInfo2 = Standort
|
||||
;AdminEMail = admin@irc.server
|
||||
|
||||
# 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). Diese wird aus-
|
||||
# gegeben, wenn sich ein User mit dem Server verbindet.
|
||||
;MotdFile = /usr/local/etc/ngircd.motd
|
||||
|
||||
# User-ID, unter der der Daemon laufen soll (dazu muss der Server
|
||||
# jedoch mit root-Rechten gestartet werden). Es kann der Name oder
|
||||
# die numerische ID angegeben werden.
|
||||
# ACHTUNG: Die Konfigurations- und MOTD-Datei muessen fuer diesen
|
||||
# Benutzer lesbar sein, ansonsten schlaegt ein RESTART fehl!
|
||||
;ServerUID = ircd
|
||||
|
||||
# Group-ID, zu der der Daemon wechseln soll (hierzu muss der Server
|
||||
# jedoch mit root-Rechten gestartet werden). Es kann der Name oder
|
||||
# die numerische ID angegeben werden.
|
||||
;ServerGID = daemon
|
||||
|
||||
# Nach <PingTimeout> Sekunden verschickt der Server bei Inaktivitaet
|
||||
# von einem Client diesem ein PING.
|
||||
;PingTimeout = 120
|
||||
|
||||
# Antwortet ein Client, der ein PING bekam, nicht innerhalb von
|
||||
# <PongTimeout> Sekunden mit einem PONG, so wird er disconnectiert.
|
||||
;PongTimeout = 20
|
||||
|
||||
# Der Server versucht alle <ConnectRetry> Sekunden, noch nicht bzw.
|
||||
# nicht mehr connectierte Server-Links aufzubauen.
|
||||
;ConnectRetry = 60
|
||||
|
||||
# Sollen IRC-Operatoren immer den MODE-Befehl in Channel benutzen
|
||||
# koennen, auch wenn sie kein(!) Channel-Operator sind?
|
||||
;OperCanUseMode = no
|
||||
|
||||
# Maximale Anzahl von gleichzeitigen Verbindungen, die dieser
|
||||
# Server annehmen darf (<=0: unlimitiert).
|
||||
;MaxConnections = -1
|
||||
|
||||
# Maximale Anzahl von Channels, in denen ein User zeitgleich
|
||||
# Mitglied sein kann (<=0: unlimitiert).
|
||||
;MaxJoins = 10
|
||||
|
||||
[Operator]
|
||||
; Name = TheOper
|
||||
; Password = ThePwd
|
||||
|
||||
#
|
||||
# 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).
|
||||
;Name = TheOper
|
||||
|
||||
# Passwort des IRC-Operators
|
||||
;Password = ThePwd
|
||||
|
||||
[Server]
|
||||
; Host = host2.the.net
|
||||
; Name = irc2.the.net
|
||||
; Port = 6666
|
||||
; Password = ThePwd
|
||||
|
||||
#
|
||||
# In [Server]-Bloecken werden Server konfiguriert, zu denen sich
|
||||
# dieser ngIRCd verbinden soll bzw. von denen Verbindungen angekommen
|
||||
# werden duerfen.
|
||||
# Es koennen mehrere Server konfiguriert werden, d.h. [Server]-
|
||||
# Bloecke koennen mehrfach vorkommen.
|
||||
# Wenn man fuer einen Server einen Port angegeben hat, dann versucht
|
||||
# sich der ngIRCd mit der Gegenseite zu verbinden. Hat man keinen
|
||||
# Port konfiguriert, dann wartet der ngIRCd darauf, dass sich die
|
||||
# Gegenseite mit ihm verbindet.
|
||||
#
|
||||
# Server-Gruppen:
|
||||
# Der ngIRCd unterstuetzt "Server-Gruppen": das bedeutet, man kann
|
||||
# jedem Server, mit dem man sich verbinden will, einer Gruppe zu-
|
||||
# ordnen. Wenn der ngIRCd sich dann mit einem Server aus der Gruppe
|
||||
# verbinden will und keine Antwort erhaelt, dann wird der naechste
|
||||
# Server aus der Gruppe versucht.
|
||||
# Achtung: Gruppen werden nur beachtet, wenn man einen Port fur
|
||||
# die Gegenseite angegeben hat!
|
||||
#
|
||||
|
||||
# IRC-Name des Servers
|
||||
;Name = irc2.the.net
|
||||
|
||||
# DNS-Hostname des Servers
|
||||
;Host = connect-to-host.the.net
|
||||
|
||||
# Port, zu dem dieser Server eine Verbindung herstellen soll. Wird
|
||||
# kein Port angegeben, so wird auf eine Verbindung der Gegenseite
|
||||
# gewartet.
|
||||
;Port = 6666
|
||||
|
||||
# Eigenes Passwort fuer diese Verbindung. Dieses Passwort muss auf
|
||||
# dem anderen Server als "PeerPassword" konfiguriert werden.
|
||||
;MyPassword = MySecret
|
||||
|
||||
# Passwort des Peer-Servers fuer diese Verbindung. Dieses Passwort
|
||||
# muss auf dem anderen Server als "MyPassword" konfiguriert sein.
|
||||
;PeerPassword = PeerSecret
|
||||
|
||||
# Gruppe, zu der dieser Server gehoert (optional).
|
||||
;Group = 123
|
||||
|
||||
[Channel]
|
||||
|
||||
#
|
||||
# Mit [Channel]-Bloecken werden "persistente Channels" definiert,
|
||||
# die nach dem Start des Servers automatisch erzeugt werden und auch
|
||||
# dann erhalten bleiben, wenn keine User mehr im Channel sind. Es
|
||||
# koennen mehrere solcher Bloecke hier konfiguriert werden.
|
||||
# Gekennzeichnet werden solche Channels mit dem Mode "P", der ganz
|
||||
# normal gesetzt und geloescht werden kann.
|
||||
#
|
||||
|
||||
# Name des Channels
|
||||
;Name = #TheName
|
||||
|
||||
# Topic, das gesetzt werden soll
|
||||
;Topic = Ein tolles Topic
|
||||
|
||||
# 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-
|
||||
52
man/ngircd.8
Normal file
52
man/ngircd.8
Normal file
@@ -0,0 +1,52 @@
|
||||
.\"
|
||||
.\" $Id: ngircd.8,v 1.5 2002/11/18 18:49:34 alex Exp $
|
||||
.\"
|
||||
.TH ngircd 8 "September 2002" ngircd "ngIRCd Manual"
|
||||
.SH NAME
|
||||
ngircd \- the next generation IRC daemon
|
||||
.SH SYNOPSIS
|
||||
.B ngircd [
|
||||
.I Options
|
||||
.B ]
|
||||
.SH DESCRIPTION
|
||||
.B ngircd
|
||||
is a portable IRC daemon written from scratch. It is easy to configure,
|
||||
supports server links (even with original ircds) and runs on hosts with
|
||||
changing IP addresses (such as dial-in networks). Currently supported
|
||||
platforms (tested versions) are: 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.
|
||||
.SH OPTIONS
|
||||
.IP --configtest
|
||||
read, validate and display configuration; then exit.
|
||||
.IP "-f file, --config file"
|
||||
use
|
||||
.I file
|
||||
as configuration file.
|
||||
.IP "-n, --nodaemon"
|
||||
don't fork and don't detach from controlling terminal.
|
||||
.IP "-p, --passive"
|
||||
disable automatic connections to other servers.
|
||||
.IP --version
|
||||
output version information and exit.
|
||||
.IP --help
|
||||
display brief help text and exit.
|
||||
.SH FILES
|
||||
.I /usr/local/etc/ngircd.conf
|
||||
.RS
|
||||
The system wide default configuration file.
|
||||
.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-
|
||||
26
man/ngircd.conf.5
Normal file
26
man/ngircd.conf.5
Normal file
@@ -0,0 +1,26 @@
|
||||
.\"
|
||||
.\" $Id: ngircd.conf.5,v 1.6 2002/09/16 11:11:21 alex Exp $
|
||||
.\"
|
||||
.TH ngircd.conf 5 "September 2002" ngircd "ngIRCd Manual"
|
||||
.SH NAME
|
||||
ngircd.conf \- configuration file of ngircd
|
||||
.SH SYNOPSIS
|
||||
.B /usr/local/etc/ngircd.conf
|
||||
.SH DESCRIPTION
|
||||
(coming soon, please have a look at the sample configuration
|
||||
file "doc/sample-ngircd.conf" -- Thank you!)
|
||||
.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)
|
||||
.BR ircd (8)
|
||||
.\"
|
||||
.\" -eof-
|
||||
@@ -9,17 +9,10 @@
|
||||
# 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/01/02 02:41:11 alex Exp $
|
||||
#
|
||||
# $Log: Makefile.am,v $
|
||||
# Revision 1.2 2002/01/02 02:41:11 alex
|
||||
# - fehlenden Copyright-Text ergaenzt.
|
||||
#
|
||||
# Revision 1.1.1.1 2001/12/11 21:53:04 alex
|
||||
# Imported sources to CVS.
|
||||
# $Id: Makefile.am,v 1.4 2002/09/09 10:00:15 alex Exp $
|
||||
#
|
||||
|
||||
SUBDIRS = ngircd
|
||||
SUBDIRS = portab ngircd testsuite
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile Makefile.in config.h config.h.in stamp-h.in
|
||||
|
||||
@@ -9,51 +9,67 @@
|
||||
# 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.10 2002/01/02 02:43:50 alex Exp $
|
||||
#
|
||||
# $Log: Makefile.am,v $
|
||||
# Revision 1.10 2002/01/02 02:43:50 alex
|
||||
# - Copyright-Text ergaenzt bzw. aktualisiert.
|
||||
#
|
||||
# Revision 1.9 2001/12/31 02:18:51 alex
|
||||
# - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
# - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
# - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
#
|
||||
# Revision 1.8 2001/12/30 19:25:03 alex
|
||||
# - in "noinst_HEADERS" waren einige Dateien als .c anstelle .h aufgefuehrt.
|
||||
#
|
||||
# Revision 1.7 2001/12/27 00:37:07 alex
|
||||
# - Erkennung der "portab header" geaendert, CFLAGS werden nun anders gesetzt.
|
||||
#
|
||||
# Revision 1.6 2001/12/23 21:53:54 alex
|
||||
# - Header messages.h eingefuegt.
|
||||
#
|
||||
# Revision 1.5 2001/12/21 22:25:30 alex
|
||||
# - neues Modul "parse" eingebunden.
|
||||
#
|
||||
# Revision 1.4 2001/12/14 08:14:03 alex
|
||||
# - neue Module (irc, client, channel) aufgenommen.
|
||||
#
|
||||
# Revision 1.3 2001/12/13 02:03:33 alex
|
||||
# - beim Compilieren werden nun Informationen fuer den Debugger erzeugt.
|
||||
#
|
||||
# Revision 1.2 2001/12/12 17:20:02 alex
|
||||
# - neue Sourcefiles und Header ergaenzt.
|
||||
#
|
||||
# Revision 1.1.1.1 2001/12/11 21:53:04 alex
|
||||
# - Imported sources to CVS.
|
||||
# $Id: Makefile.am,v 1.31.2.1 2003/01/04 10:58:15 alex Exp $
|
||||
#
|
||||
|
||||
AUTOMAKE_OPTIONS = ../portab/ansi2knr
|
||||
|
||||
INCLUDES = -I$(srcdir)/../portab
|
||||
|
||||
LINTARGS = -weak -warnunixlib +unixlib -booltype BOOLEAN
|
||||
|
||||
sbin_PROGRAMS = ngircd
|
||||
|
||||
ngircd_SOURCES = ngircd.c channel.c client.c conf.c conn.c irc.c log.c \
|
||||
parse.c tool.c
|
||||
ngircd_SOURCES = ngircd.c channel.c client.c conf.c conn.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 resolve.c tool.c
|
||||
|
||||
noinst_HEADERS = ngircd.h channel.h client.h conf.h conn.h irc.h log.h \
|
||||
parse.h tool.h global.h messages.h defines.h
|
||||
ngircd_LDFLAGS = -L../portab
|
||||
|
||||
ngircd_LDADD = -lngportab
|
||||
|
||||
noinst_HEADERS = ngircd.h channel.h client.h conf.h conn.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 resolve.h tool.h \
|
||||
messages.h defines.h
|
||||
|
||||
clean-local:
|
||||
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 ngircd > /dev/null 2>&1" >> check-version
|
||||
chmod 755 check-version
|
||||
|
||||
check-help: Makefile
|
||||
echo "#!/bin/sh" > check-help
|
||||
echo "./ngircd --help | grep help > /dev/null 2>&1" >> check-help
|
||||
chmod 755 check-help
|
||||
|
||||
lint:
|
||||
rm -f lint.out
|
||||
for f in *.c; do \
|
||||
echo "checking $$f ..."; \
|
||||
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-date cvs-version.h
|
||||
|
||||
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 || cp cvs-version.new cvs-version.h
|
||||
|
||||
TESTS = check-version check-help
|
||||
|
||||
# -eof-
|
||||
|
||||
@@ -2,97 +2,117 @@
|
||||
* 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.11 2002/01/29 00:11:10 alex Exp $
|
||||
*
|
||||
* channel.c: Management der Channels
|
||||
*
|
||||
* $Log: channel.c,v $
|
||||
* Revision 1.11 2002/01/29 00:11:10 alex
|
||||
* - neue Funktionen Channel_FirstChannelOf() und Channel_NextChannelOf().
|
||||
*
|
||||
* Revision 1.10 2002/01/28 01:16:15 alex
|
||||
* - neue Funktionen Channel_Name(), Channel_First() und Channel_Next().
|
||||
*
|
||||
* Revision 1.9 2002/01/27 22:47:11 alex
|
||||
* - PART wird nicht mehr an den Server verschickt, von dem es empfangen wurde.
|
||||
*
|
||||
* Revision 1.8 2002/01/27 21:56:54 alex
|
||||
* - weitere Anpassungen an Chennals, v.a. ueber Server-Links.
|
||||
*
|
||||
* Revision 1.7 2002/01/27 17:14:33 alex
|
||||
* - diverse Aenderungen fuer Channels ueber mehrere Server.
|
||||
*
|
||||
* Revision 1.6 2002/01/26 18:41:55 alex
|
||||
* - CHANNEL- und CL2CHAN-Strukturen in Header verlegt,
|
||||
* - einige neue Funktionen (Channel_GetChannel(), Channel_FirstMember(), ...)
|
||||
*
|
||||
* Revision 1.5 2002/01/21 00:12:29 alex
|
||||
* - begonnen, Channels zu implementieren :-)
|
||||
*
|
||||
* Revision 1.4 2002/01/16 22:09:07 alex
|
||||
* - neue Funktion Channel_Count().
|
||||
*
|
||||
* Revision 1.3 2002/01/02 02:42:58 alex
|
||||
* - Copyright-Texte aktualisiert.
|
||||
*
|
||||
* Revision 1.2 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.1 2001/12/14 08:13:43 alex
|
||||
* - neues Modul begonnen :-)
|
||||
* Channel management
|
||||
*/
|
||||
|
||||
|
||||
#define __channel_c__
|
||||
|
||||
|
||||
#include <portab.h>
|
||||
#include "global.h"
|
||||
#include "portab.h"
|
||||
|
||||
#include <imp.h>
|
||||
static char UNUSED id[] = "$Id: channel.c,v 1.38 2002/12/16 23:05:24 alex Exp $";
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "conn.h"
|
||||
#include "client.h"
|
||||
#include "irc.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"
|
||||
#include "exp.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;
|
||||
@@ -117,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;
|
||||
|
||||
@@ -125,7 +146,7 @@ GLOBAL BOOLEAN Channel_Join( CLIENT *Client, CHAR *Name )
|
||||
assert( Name != NULL );
|
||||
|
||||
/* Valider Channel-Name? */
|
||||
if(( Name[0] != '#' ) || ( strlen( Name ) >= CHANNEL_NAME_LEN ))
|
||||
if( ! Channel_IsValidName( Name ))
|
||||
{
|
||||
IRC_WriteStrClient( Client, ERR_NOSUCHCHANNEL_MSG, Client_ID( Client ), Name );
|
||||
return FALSE;
|
||||
@@ -141,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 */
|
||||
@@ -155,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 );
|
||||
@@ -171,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;
|
||||
@@ -208,51 +273,149 @@ 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 CHANNEL *Channel_First( VOID )
|
||||
GLOBAL CHAR *
|
||||
Channel_Modes( CHANNEL *Chan )
|
||||
{
|
||||
assert( Chan != NULL );
|
||||
return Chan->modes;
|
||||
} /* Channel_Modes */
|
||||
|
||||
|
||||
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 */
|
||||
|
||||
CHANNEL *c;
|
||||
UINT32 search_hash;
|
||||
|
||||
assert( Name != NULL );
|
||||
|
||||
search_hash = Hash( Name );
|
||||
c = My_Channels;
|
||||
while( c )
|
||||
{
|
||||
if( strcasecmp( Name, c->name ) == 0 ) return c;
|
||||
if( search_hash == c->hash )
|
||||
{
|
||||
/* lt. Hash-Wert: Treffer! */
|
||||
if( strcasecmp( Name, c->name ) == 0 ) return c;
|
||||
}
|
||||
c = c->next;
|
||||
}
|
||||
return NULL;
|
||||
} /* 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 );
|
||||
@@ -260,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 );
|
||||
@@ -275,24 +440,265 @@ 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 */
|
||||
|
||||
|
||||
LOCAL CHANNEL *New_Chan( CHAR *Name )
|
||||
GLOBAL BOOLEAN
|
||||
Channel_IsValidName( CHAR *Name )
|
||||
{
|
||||
/* Pruefen, ob Name als Channelname gueltig */
|
||||
|
||||
CHAR *ptr, badchars[10];
|
||||
|
||||
assert( Name != NULL );
|
||||
|
||||
if(( Name[0] != '#' ) || ( strlen( Name ) >= CHANNEL_NAME_LEN )) return FALSE;
|
||||
|
||||
ptr = Name;
|
||||
strcpy( badchars, " ,:\x07" );
|
||||
while( *ptr )
|
||||
{
|
||||
if( strchr( badchars, *ptr )) return FALSE;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
} /* Channel_IsValidName */
|
||||
|
||||
|
||||
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
|
||||
* bereits hatte. */
|
||||
|
||||
CHAR x[2];
|
||||
|
||||
assert( Chan != NULL );
|
||||
|
||||
x[0] = Mode; x[1] = '\0';
|
||||
if( ! strchr( Chan->modes, x[0] ))
|
||||
{
|
||||
/* Client hat den Mode noch nicht -> setzen */
|
||||
strcat( Chan->modes, x );
|
||||
return TRUE;
|
||||
}
|
||||
else return FALSE;
|
||||
} /* Channel_ModeAdd */
|
||||
|
||||
|
||||
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
|
||||
* ueberhaupt nicht hatte. */
|
||||
|
||||
CHAR x[2], *p;
|
||||
|
||||
assert( Chan != NULL );
|
||||
|
||||
x[0] = Mode; x[1] = '\0';
|
||||
|
||||
p = strchr( Chan->modes, x[0] );
|
||||
if( ! p ) return FALSE;
|
||||
|
||||
/* Client hat den Mode -> loeschen */
|
||||
while( *p )
|
||||
{
|
||||
*p = *(p + 1);
|
||||
p++;
|
||||
}
|
||||
return TRUE;
|
||||
} /* Channel_ModeDel */
|
||||
|
||||
|
||||
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
|
||||
* Channel-Mode bereits hatte. */
|
||||
|
||||
CL2CHAN *cl2chan;
|
||||
CHAR x[2];
|
||||
|
||||
assert( Chan != NULL );
|
||||
assert( Client != NULL );
|
||||
|
||||
cl2chan = Get_Cl2Chan( Chan, Client );
|
||||
assert( cl2chan != NULL );
|
||||
|
||||
x[0] = Mode; x[1] = '\0';
|
||||
if( ! strchr( cl2chan->modes, x[0] ))
|
||||
{
|
||||
/* Client hat den Mode noch nicht -> setzen */
|
||||
strcat( cl2chan->modes, x );
|
||||
return TRUE;
|
||||
}
|
||||
else return FALSE;
|
||||
} /* Channel_UserModeAdd */
|
||||
|
||||
|
||||
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
|
||||
* ueberhaupt nicht hatte. */
|
||||
|
||||
CL2CHAN *cl2chan;
|
||||
CHAR x[2], *p;
|
||||
|
||||
assert( Chan != NULL );
|
||||
assert( Client != NULL );
|
||||
|
||||
cl2chan = Get_Cl2Chan( Chan, Client );
|
||||
assert( cl2chan != NULL );
|
||||
|
||||
x[0] = Mode; x[1] = '\0';
|
||||
|
||||
p = strchr( cl2chan->modes, x[0] );
|
||||
if( ! p ) return FALSE;
|
||||
|
||||
/* Client hat den Mode -> loeschen */
|
||||
while( *p )
|
||||
{
|
||||
*p = *(p + 1);
|
||||
p++;
|
||||
}
|
||||
return TRUE;
|
||||
} /* Channel_UserModeDel */
|
||||
|
||||
|
||||
GLOBAL CHAR *
|
||||
Channel_UserModes( CHANNEL *Chan, CLIENT *Client )
|
||||
{
|
||||
/* Channel-Modes eines Users liefern */
|
||||
|
||||
CL2CHAN *cl2chan;
|
||||
|
||||
assert( Chan != NULL );
|
||||
assert( Client != NULL );
|
||||
|
||||
cl2chan = Get_Cl2Chan( Chan, Client );
|
||||
assert( cl2chan != NULL );
|
||||
|
||||
return cl2chan->modes;
|
||||
} /* Channel_UserModes */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
Channel_IsMemberOf( CHANNEL *Chan, CLIENT *Client )
|
||||
{
|
||||
/* Pruefen, ob Client Mitglied in Channel ist */
|
||||
|
||||
assert( Chan != NULL );
|
||||
assert( Client != NULL );
|
||||
|
||||
if( Get_Cl2Chan( Chan, Client )) return TRUE;
|
||||
else return FALSE;
|
||||
} /* Channel_IsMemberOf */
|
||||
|
||||
|
||||
GLOBAL CHAR *
|
||||
Channel_Topic( CHANNEL *Chan )
|
||||
{
|
||||
assert( Chan != NULL );
|
||||
return Chan->topic;
|
||||
} /* Channel_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';
|
||||
} /* Channel_SetTopic */
|
||||
|
||||
|
||||
GLOBAL VOID
|
||||
Channel_SetModes( CHANNEL *Chan, CHAR *Modes )
|
||||
{
|
||||
assert( Chan != NULL );
|
||||
assert( Modes != NULL );
|
||||
|
||||
strncpy( Chan->modes, Modes, CHANNEL_MODE_LEN - 1 );
|
||||
Chan->topic[CHANNEL_MODE_LEN - 1] = '\0';
|
||||
} /* Channel_SetModes */
|
||||
|
||||
|
||||
GLOBAL VOID
|
||||
Channel_SetKey( CHANNEL *Chan, CHAR *Key )
|
||||
{
|
||||
assert( Chan != NULL );
|
||||
assert( Key != NULL );
|
||||
|
||||
strncpy( Chan->key, Key, CLIENT_PASS_LEN - 1 );
|
||||
Chan->key[CLIENT_PASS_LEN - 1] = '\0';
|
||||
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 */
|
||||
is_member = has_voice = is_op = FALSE;
|
||||
if( Channel_IsMemberOf( Chan, From ))
|
||||
{
|
||||
is_member = TRUE;
|
||||
if( strchr( Channel_UserModes( Chan, From ), 'v' )) has_voice = TRUE;
|
||||
if( strchr( Channel_UserModes( Chan, From ), 'o' )) is_op = TRUE;
|
||||
}
|
||||
|
||||
/* pruefen, ob Client in Channel schreiben darf */
|
||||
ok = TRUE;
|
||||
if( strchr( Channel_Modes( Chan ), 'n' ) && ( ! is_member )) ok = FALSE;
|
||||
if( strchr( Channel_Modes( Chan ), 'm' ) && ( ! is_op ) && ( ! has_voice )) ok = FALSE;
|
||||
|
||||
if( ! ok ) return IRC_WriteStrClient( From, ERR_CANNOTSENDTOCHAN_MSG, Client_ID( From ), Channel_Name( Chan ));
|
||||
|
||||
/* Text senden */
|
||||
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 */
|
||||
|
||||
|
||||
GLOBAL CHANNEL *
|
||||
Channel_Create( CHAR *Name )
|
||||
{
|
||||
/* Neue Channel-Struktur anlegen */
|
||||
|
||||
|
||||
CHANNEL *c;
|
||||
|
||||
assert( Name != NULL );
|
||||
@@ -300,21 +706,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 );
|
||||
strncpy( c->name, Name, CHANNEL_NAME_LEN - 1 );
|
||||
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;
|
||||
|
||||
@@ -331,21 +746,24 @@ 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;
|
||||
|
||||
assert( Chan != NULL );
|
||||
assert( Client != NULL );
|
||||
|
||||
/* neue CL2CHAN-Struktur anlegen */
|
||||
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;
|
||||
cl2chan->client = Client;
|
||||
strcpy( cl2chan->modes, "" );
|
||||
|
||||
/* Verketten */
|
||||
cl2chan->next = My_Cl2Chan;
|
||||
@@ -357,7 +775,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;
|
||||
@@ -385,26 +804,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;
|
||||
|
||||
@@ -421,7 +864,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 */
|
||||
|
||||
@@ -439,6 +883,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,64 +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: channel.h,v 1.9 2002/01/29 00:11:19 alex Exp $
|
||||
* $Id: channel.h,v 1.26 2002/12/16 23:05:24 alex Exp $
|
||||
*
|
||||
* channel.h: Management der Channels (Header)
|
||||
*
|
||||
* $Log: channel.h,v $
|
||||
* Revision 1.9 2002/01/29 00:11:19 alex
|
||||
* - neue Funktionen Channel_FirstChannelOf() und Channel_NextChannelOf().
|
||||
*
|
||||
* Revision 1.8 2002/01/28 01:16:15 alex
|
||||
* - neue Funktionen Channel_Name(), Channel_First() und Channel_Next().
|
||||
*
|
||||
* Revision 1.7 2002/01/26 18:41:55 alex
|
||||
* - CHANNEL- und CL2CHAN-Strukturen in Header verlegt,
|
||||
* - einige neue Funktionen (Channel_GetChannel(), Channel_FirstMember(), ...)
|
||||
*
|
||||
* Revision 1.6 2002/01/21 00:11:59 alex
|
||||
* - Definition der CHANNEL-Struktur aus Header entfernt,
|
||||
* - neue Funktionen Channel_Join(), Channel_Part() und Channel_RemoveClient().
|
||||
*
|
||||
* Revision 1.5 2002/01/16 22:09:07 alex
|
||||
* - neue Funktion Channel_Count().
|
||||
*
|
||||
* Revision 1.4 2002/01/02 02:42:58 alex
|
||||
* - Copyright-Texte aktualisiert.
|
||||
*
|
||||
* Revision 1.3 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.2 2001/12/23 21:54:30 alex
|
||||
* - Konstanten um Prefix "CHANNEL_" erweitert.
|
||||
*
|
||||
* Revision 1.1 2001/12/14 08:13:43 alex
|
||||
* - neues Modul begonnen :-)
|
||||
* Channel management (header)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __channel_h__
|
||||
#define __channel_h__
|
||||
|
||||
#include "client.h"
|
||||
|
||||
#if defined(__channel_c__) | defined(S_SPLINT_S)
|
||||
|
||||
#ifdef __channel_c__
|
||||
#include "defines.h"
|
||||
|
||||
typedef struct _CHANNEL
|
||||
{
|
||||
struct _CHANNEL *next;
|
||||
CHAR name[CHANNEL_NAME_LEN]; /* Name des Channel */
|
||||
CHAR modes[CHANNEL_MODE_LEN]; /* Channel-Modes */
|
||||
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
|
||||
@@ -78,30 +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 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 CHANNEL *Channel_Search( CHAR *Name );
|
||||
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_First( VOID );
|
||||
GLOBAL CHANNEL *Channel_Next( CHANNEL *Chan );
|
||||
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 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_Search PARAMS(( CHAR *Name ));
|
||||
|
||||
GLOBAL CLIENT *Channel_GetClient( CL2CHAN *Cl2Chan );
|
||||
GLOBAL CHANNEL *Channel_GetChannel( CL2CHAN *Cl2Chan );
|
||||
GLOBAL CHANNEL *Channel_First PARAMS(( VOID ));
|
||||
GLOBAL CHANNEL *Channel_Next PARAMS(( CHANNEL *Chan ));
|
||||
|
||||
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 CLIENT *Channel_GetClient PARAMS(( CL2CHAN *Cl2Chan ));
|
||||
GLOBAL CHANNEL *Channel_GetChannel PARAMS(( CL2CHAN *Cl2Chan ));
|
||||
|
||||
GLOBAL BOOLEAN Channel_IsValidName PARAMS(( CHAR *Name ));
|
||||
|
||||
GLOBAL BOOLEAN Channel_ModeAdd PARAMS(( CHANNEL *Chan, CHAR Mode ));
|
||||
GLOBAL BOOLEAN Channel_ModeDel PARAMS(( CHANNEL *Chan, CHAR Mode ));
|
||||
|
||||
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_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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,197 +2,138 @@
|
||||
* 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.21 2002/01/29 00:14:49 alex Exp $
|
||||
* $Id: client.h,v 1.32.2.1 2002/12/22 23:42:28 alex Exp $
|
||||
*
|
||||
* client.h: Konfiguration des ngircd (Header)
|
||||
*
|
||||
* $Log: client.h,v $
|
||||
* Revision 1.21 2002/01/29 00:14:49 alex
|
||||
* - neue Funktion Client_TopServer(), Client_NewXXX() angepasst.
|
||||
*
|
||||
* Revision 1.20 2002/01/21 00:06:49 alex
|
||||
* - Channel-Pointer aus Client-Struktur entfernt. Wird nun dynamisch verwaltet :-)
|
||||
*
|
||||
* Revision 1.19 2002/01/16 22:10:35 alex
|
||||
* - neue Funktionen Client_xxxCount().
|
||||
*
|
||||
* Revision 1.18 2002/01/07 23:42:12 alex
|
||||
* - Es werden fuer alle Server eigene Token generiert,
|
||||
* - QUIT von einem Server fuer einen User wird an andere Server geforwarded,
|
||||
* - ebenso NICK-Befehle, die "fremde" User einfuehren.
|
||||
*
|
||||
* Revision 1.17 2002/01/06 15:18:14 alex
|
||||
* - Loglevel und Meldungen nochmals geaendert. Level passen nun besser.
|
||||
*
|
||||
* Revision 1.16 2002/01/05 23:26:05 alex
|
||||
* - Vorbereitungen fuer Ident-Abfragen in Client-Strukturen.
|
||||
*
|
||||
* Revision 1.15 2002/01/05 20:08:17 alex
|
||||
* - neue Funktion Client_NextHop().
|
||||
*
|
||||
* Revision 1.14 2002/01/04 01:21:22 alex
|
||||
* - Client-Strukturen koennen von anderen Modulen nun nur noch ueber die
|
||||
* enstprechenden (zum Teil neuen) Funktionen angesprochen werden.
|
||||
*
|
||||
* Revision 1.13 2002/01/03 02:28:06 alex
|
||||
* - neue Funktion Client_CheckID(), diverse Aenderungen fuer Server-Links.
|
||||
*
|
||||
* Revision 1.12 2002/01/02 02:42:58 alex
|
||||
* - Copyright-Texte aktualisiert.
|
||||
*
|
||||
* Revision 1.11 2001/12/31 15:33:13 alex
|
||||
* - neuer Befehl NAMES, kleinere Bugfixes.
|
||||
* - Bug bei PING behoben: war zu restriktiv implementiert :-)
|
||||
*
|
||||
* Revision 1.10 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.9 2001/12/29 20:18:18 alex
|
||||
* - neue Funktion Client_SetHostname().
|
||||
*
|
||||
* Revision 1.8 2001/12/29 03:10:47 alex
|
||||
* - Client-Modes implementiert; Loglevel mal wieder angepasst.
|
||||
*
|
||||
* Revision 1.7 2001/12/27 19:13:47 alex
|
||||
* - neue Funktion Client_Search(), besseres Logging.
|
||||
*
|
||||
* Revision 1.6 2001/12/27 16:54:51 alex
|
||||
* - neue Funktion Client_GetID(), liefert die "Client ID".
|
||||
*
|
||||
* Revision 1.5 2001/12/26 14:45:37 alex
|
||||
* - "Code Cleanups".
|
||||
*
|
||||
* Revision 1.4 2001/12/26 03:19:16 alex
|
||||
* - neue Funktion Client_Nick().
|
||||
*
|
||||
* Revision 1.3 2001/12/25 19:21:26 alex
|
||||
* - Client-Typ ("Status") besser unterteilt, My_Clients ist zudem nun global.
|
||||
*
|
||||
* Revision 1.2 2001/12/23 22:03:47 alex
|
||||
* - einige neue Funktionen,
|
||||
* - Konstanten um "CLIENT_"-Prefix erweitert.
|
||||
*
|
||||
* Revision 1.1 2001/12/14 08:13:43 alex
|
||||
* - neues Modul begonnen :-)
|
||||
* 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 */
|
||||
|
||||
#define CLIENT_TYPE INT
|
||||
|
||||
|
||||
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;
|
||||
#if defined(__client_c__) | defined(S_SPLINT_S)
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#ifdef __client_c__
|
||||
typedef struct _CLIENT
|
||||
{
|
||||
CHAR id[CLIENT_ID_LEN]; /* Nick (User) bzw. ID (Server) */
|
||||
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 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
|
||||
|
||||
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 );
|
||||
GLOBAL VOID Client_Destroy PARAMS((CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN SendQuit ));
|
||||
|
||||
GLOBAL CLIENT *Client_ThisServer( VOID );
|
||||
GLOBAL CLIENT *Client_ThisServer PARAMS((VOID ));
|
||||
|
||||
GLOBAL CLIENT *Client_GetFromConn( CONN_ID Idx );
|
||||
GLOBAL CLIENT *Client_GetFromID( CHAR *Nick );
|
||||
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 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_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 PARAMS((CHAR *Nick ));
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,140 +1,225 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
|
||||
* Copyright (c)2001,2002 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.c,v 1.13 2002/01/18 15:51:44 alex Exp $
|
||||
*
|
||||
* conf.h: Konfiguration des ngircd
|
||||
*
|
||||
* $Log: conf.c,v $
|
||||
* Revision 1.13 2002/01/18 15:51:44 alex
|
||||
* - Server-Verbinungen werden beim Start erst nach kurzer Pause aufgebaut.
|
||||
*
|
||||
* Revision 1.12 2002/01/05 23:26:24 alex
|
||||
* - Fehlermeldungen korrigiert.
|
||||
*
|
||||
* Revision 1.11 2002/01/05 16:51:49 alex
|
||||
* - Bug bei Remote-Server-Namen entfernt: diese wurden falsch gekuerzt.
|
||||
*
|
||||
* Revision 1.10 2002/01/03 02:27:20 alex
|
||||
* - das Server-Passwort kann nun konfiguriert werden.
|
||||
*
|
||||
* Revision 1.9 2002/01/02 02:49:15 alex
|
||||
* - Konfigurationsdatei "Samba like" umgestellt.
|
||||
* - es koennen nun mehrere Server und Oprtatoren konfiguriert werden.
|
||||
*
|
||||
* Revision 1.7 2002/01/01 18:25:44 alex
|
||||
* - #include's fuer stdlib.h ergaenzt.
|
||||
*
|
||||
* Revision 1.6 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.5 2001/12/30 19:26:11 alex
|
||||
* - Unterstuetzung fuer die Konfigurationsdatei eingebaut.
|
||||
*
|
||||
* Revision 1.4 2001/12/26 22:48:53 alex
|
||||
* - MOTD-Datei ist nun konfigurierbar und wird gelesen.
|
||||
*
|
||||
* Revision 1.3 2001/12/26 14:45:37 alex
|
||||
* - "Code Cleanups".
|
||||
*
|
||||
* Revision 1.2 2001/12/26 03:19:57 alex
|
||||
* - erste Konfigurations-Variablen definiert: PING/PONG-Timeout.
|
||||
*
|
||||
* Revision 1.1 2001/12/12 17:18:20 alex
|
||||
* - Modul fuer Server-Konfiguration begonnen.
|
||||
* Configuration management (reading, parsing & validation)
|
||||
*/
|
||||
|
||||
|
||||
#include <portab.h>
|
||||
#include "global.h"
|
||||
#include "portab.h"
|
||||
|
||||
#include <imp.h>
|
||||
static char UNUSED id[] = "$Id: conf.c,v 1.47 2002/12/18 02:53:36 alex Exp $";
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_CTYPE_H
|
||||
# include <ctype.h>
|
||||
#endif
|
||||
|
||||
#include "ngircd.h"
|
||||
#include "conn.h"
|
||||
#include "client.h"
|
||||
#include "defines.h"
|
||||
#include "log.h"
|
||||
#include "resolve.h"
|
||||
#include "tool.h"
|
||||
|
||||
#include <exp.h>
|
||||
#include "exp.h"
|
||||
#include "conf.h"
|
||||
|
||||
|
||||
LOCAL VOID Read_Config( VOID );
|
||||
|
||||
GLOBAL VOID Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg );
|
||||
GLOBAL VOID Handle_OPERATOR( INT Line, CHAR *Var, CHAR *Arg );
|
||||
GLOBAL VOID Handle_SERVER( INT Line, CHAR *Var, CHAR *Arg );
|
||||
|
||||
LOCAL VOID Validate_Config( VOID );
|
||||
LOCAL BOOLEAN Use_Log = TRUE;
|
||||
|
||||
|
||||
GLOBAL VOID Conf_Init( VOID )
|
||||
LOCAL VOID Set_Defaults PARAMS(( VOID ));
|
||||
LOCAL VOID Read_Config PARAMS(( VOID ));
|
||||
LOCAL VOID Validate_Config PARAMS(( BOOLEAN TestOnly ));
|
||||
|
||||
LOCAL VOID Handle_GLOBAL PARAMS(( INT Line, CHAR *Var, CHAR *Arg ));
|
||||
LOCAL VOID Handle_OPERATOR PARAMS(( INT Line, CHAR *Var, CHAR *Arg ));
|
||||
LOCAL VOID Handle_SERVER PARAMS(( INT Line, CHAR *Var, CHAR *Arg ));
|
||||
LOCAL VOID Handle_CHANNEL PARAMS(( INT Line, CHAR *Var, CHAR *Arg ));
|
||||
|
||||
LOCAL VOID Config_Error PARAMS(( CONST INT Level, CONST CHAR *Format, ... ));
|
||||
|
||||
|
||||
GLOBAL VOID
|
||||
Conf_Init( VOID )
|
||||
{
|
||||
/* Konfigurationsvariablen initialisieren: zunaechst Default-
|
||||
* Werte setzen, dann Konfigurationsdtaei einlesen. */
|
||||
Set_Defaults( );
|
||||
Read_Config( );
|
||||
Validate_Config( FALSE );
|
||||
} /* Config_Init */
|
||||
|
||||
strcpy( Conf_File, "/usr/local/etc/ngircd.conf" );
|
||||
|
||||
GLOBAL INT
|
||||
Conf_Test( VOID )
|
||||
{
|
||||
/* Read configuration, validate and output it. */
|
||||
|
||||
struct passwd *pwd;
|
||||
struct group *grp;
|
||||
INT i;
|
||||
|
||||
Use_Log = FALSE;
|
||||
Set_Defaults( );
|
||||
|
||||
Read_Config( );
|
||||
Validate_Config( TRUE );
|
||||
|
||||
/* If stdin is a valid tty wait for a key: */
|
||||
if( isatty( fileno( stdout )))
|
||||
{
|
||||
puts( "OK, press enter to see a dump of your service configuration ..." );
|
||||
getchar( );
|
||||
}
|
||||
else puts( "Ok, dump of your server configuration follows:\n" );
|
||||
|
||||
puts( "[GLOBAL]" );
|
||||
printf( " ServerName = %s\n", Conf_ServerName );
|
||||
printf( " ServerInfo = %s\n", Conf_ServerInfo );
|
||||
printf( " ServerPwd = %s\n", Conf_ServerPwd );
|
||||
printf( " AdminInfo1 = %s\n", Conf_ServerAdmin1 );
|
||||
printf( " AdminInfo2 = %s\n", Conf_ServerAdmin2 );
|
||||
printf( " AdminEMail = %s\n", Conf_ServerAdminMail );
|
||||
printf( " MotdFile = %s\n", Conf_MotdFile );
|
||||
printf( " Ports = " );
|
||||
for( i = 0; i < Conf_ListenPorts_Count; i++ )
|
||||
{
|
||||
if( i != 0 ) printf( ", " );
|
||||
printf( "%u", Conf_ListenPorts[i] );
|
||||
}
|
||||
puts( "" );
|
||||
pwd = getpwuid( Conf_UID );
|
||||
if( pwd ) printf( " ServerUID = %s\n", pwd->pw_name );
|
||||
else printf( " ServerUID = %ld\n", (LONG)Conf_UID );
|
||||
grp = getgrgid( Conf_GID );
|
||||
if( grp ) printf( " ServerGID = %s\n", grp->gr_name );
|
||||
else printf( " ServerGID = %ld\n", (LONG)Conf_GID );
|
||||
printf( " PingTimeout = %d\n", Conf_PingTimeout );
|
||||
printf( " PongTimeout = %d\n", Conf_PongTimeout );
|
||||
printf( " ConnectRetry = %d\n", Conf_ConnectRetry );
|
||||
printf( " OperCanUseMode = %s\n", Conf_OperCanMode == TRUE ? "yes" : "no" );
|
||||
if( Conf_MaxConnections > 0 ) printf( " MaxConnections = %ld\n", Conf_MaxConnections );
|
||||
else printf( " MaxConnections = -1\n" );
|
||||
if( Conf_MaxJoins > 0 ) printf( " MaxJoins = %d\n", Conf_MaxJoins );
|
||||
else printf( " MaxJoins = -1\n" );
|
||||
puts( "" );
|
||||
|
||||
for( i = 0; i < Conf_Oper_Count; i++ )
|
||||
{
|
||||
if( ! Conf_Oper[i].name[0] ) continue;
|
||||
|
||||
/* Valid "Operator" section */
|
||||
puts( "[OPERATOR]" );
|
||||
printf( " Name = %s\n", Conf_Oper[i].name );
|
||||
printf( " Password = %s\n", Conf_Oper[i].pwd );
|
||||
puts( "" );
|
||||
}
|
||||
|
||||
for( i = 0; i < Conf_Server_Count; i++ )
|
||||
{
|
||||
if( ! Conf_Server[i].name[0] ) continue;
|
||||
|
||||
/* Valid "Server" section */
|
||||
puts( "[SERVER]" );
|
||||
printf( " Name = %s\n", Conf_Server[i].name );
|
||||
printf( " Host = %s\n", Conf_Server[i].host );
|
||||
printf( " Port = %d\n", Conf_Server[i].port );
|
||||
printf( " MyPassword = %s\n", Conf_Server[i].pwd_in );
|
||||
printf( " PeerPassword = %s\n", Conf_Server[i].pwd_out );
|
||||
printf( " Group = %d\n", Conf_Server[i].group );
|
||||
puts( "" );
|
||||
}
|
||||
|
||||
for( i = 0; i < Conf_Channel_Count; i++ )
|
||||
{
|
||||
if( ! Conf_Channel[i].name[0] ) continue;
|
||||
|
||||
/* Valid "Channel" section */
|
||||
puts( "[CHANNEL]" );
|
||||
printf( " Name = %s\n", Conf_Channel[i].name );
|
||||
printf( " Modes = %s\n", Conf_Channel[i].modes );
|
||||
printf( " Topic = %s\n", Conf_Channel[i].topic );
|
||||
puts( "" );
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* Conf_Test */
|
||||
|
||||
|
||||
LOCAL VOID
|
||||
Set_Defaults( VOID )
|
||||
{
|
||||
/* Initialize configuration variables with default values. */
|
||||
|
||||
strcpy( Conf_ServerName, "" );
|
||||
strcpy( Conf_ServerInfo, PACKAGE" "VERSION );
|
||||
sprintf( Conf_ServerInfo, "%s %s", PACKAGE, VERSION );
|
||||
strcpy( Conf_ServerPwd, "" );
|
||||
|
||||
strcpy( Conf_MotdFile, "/usr/local/etc/ngircd.motd" );
|
||||
strcpy( Conf_ServerAdmin1, "" );
|
||||
strcpy( Conf_ServerAdmin2, "" );
|
||||
strcpy( Conf_ServerAdminMail, "" );
|
||||
|
||||
strcpy( Conf_MotdFile, MOTD_FILE );
|
||||
|
||||
Conf_ListenPorts_Count = 0;
|
||||
|
||||
Conf_UID = Conf_GID = 0;
|
||||
|
||||
Conf_PingTimeout = 120;
|
||||
Conf_PongTimeout = 10;
|
||||
Conf_PongTimeout = 20;
|
||||
|
||||
Conf_ConnectRetry = 60;
|
||||
|
||||
Conf_Oper_Count = 0;
|
||||
|
||||
Conf_Server_Count = 0;
|
||||
Conf_Channel_Count = 0;
|
||||
|
||||
/* Konfigurationsdatei einlesen und validieren */
|
||||
Read_Config( );
|
||||
Validate_Config( );
|
||||
} /* Config_Init */
|
||||
Conf_OperCanMode = FALSE;
|
||||
|
||||
Conf_MaxConnections = -1;
|
||||
Conf_MaxJoins = 10;
|
||||
} /* Set_Defaults */
|
||||
|
||||
|
||||
GLOBAL VOID Conf_Exit( VOID )
|
||||
LOCAL VOID
|
||||
Read_Config( VOID )
|
||||
{
|
||||
/* ... */
|
||||
} /* Config_Exit */
|
||||
|
||||
|
||||
LOCAL VOID Read_Config( VOID )
|
||||
{
|
||||
/* Konfigurationsdatei einlesen. */
|
||||
/* Read configuration file. */
|
||||
|
||||
CHAR section[LINE_LEN], str[LINE_LEN], *var, *arg, *ptr;
|
||||
INT line;
|
||||
FILE *fd;
|
||||
|
||||
fd = fopen( Conf_File, "r" );
|
||||
fd = fopen( NGIRCd_ConfFile, "r" );
|
||||
if( ! fd )
|
||||
{
|
||||
/* Keine Konfigurationsdatei gefunden */
|
||||
Log( LOG_ALERT, "Can't read configuration \"%s\": %s", Conf_File, strerror( errno ));
|
||||
Log( LOG_ALERT, PACKAGE" exiting due to fatal errors!" );
|
||||
/* No configuration file found! */
|
||||
Config_Error( LOG_ALERT, "Can't read configuration \"%s\": %s", NGIRCd_ConfFile, strerror( errno ));
|
||||
Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
Config_Error( LOG_INFO, "Reading configuration from \"%s\" ...", NGIRCd_ConfFile );
|
||||
|
||||
line = 0;
|
||||
strcpy( section, "" );
|
||||
while( TRUE )
|
||||
@@ -143,20 +228,20 @@ LOCAL VOID Read_Config( VOID )
|
||||
ngt_TrimStr( str );
|
||||
line++;
|
||||
|
||||
/* Kommentarzeilen und leere Zeilen ueberspringen */
|
||||
/* Skip comments and empty lines */
|
||||
if( str[0] == ';' || str[0] == '#' || str[0] == '\0' ) continue;
|
||||
|
||||
/* Anfang eines Abschnittes? */
|
||||
/* Is this the beginning of a new section? */
|
||||
if(( str[0] == '[' ) && ( str[strlen( str ) - 1] == ']' ))
|
||||
{
|
||||
strcpy( section, str );
|
||||
if( strcasecmp( section, "[GLOBAL]" ) == 0 ) continue;
|
||||
if( strcasecmp( section, "[OPERATOR]" ) == 0 )
|
||||
{
|
||||
if( Conf_Oper_Count + 1 > MAX_OPERATORS ) Log( LOG_ERR, "Too many operators configured." );
|
||||
if( Conf_Oper_Count + 1 > MAX_OPERATORS ) Config_Error( LOG_ERR, "Too many operators configured." );
|
||||
else
|
||||
{
|
||||
/* neuen Operator initialisieren */
|
||||
/* Initialize new operator structure */
|
||||
strcpy( Conf_Oper[Conf_Oper_Count].name, "" );
|
||||
strcpy( Conf_Oper[Conf_Oper_Count].pwd, "" );
|
||||
Conf_Oper_Count++;
|
||||
@@ -165,31 +250,46 @@ LOCAL VOID Read_Config( VOID )
|
||||
}
|
||||
if( strcasecmp( section, "[SERVER]" ) == 0 )
|
||||
{
|
||||
if( Conf_Server_Count + 1 > MAX_SERVERS ) Log( LOG_ERR, "Too many servers configured." );
|
||||
if( Conf_Server_Count + 1 > MAX_SERVERS ) Config_Error( LOG_ERR, "Too many servers configured." );
|
||||
else
|
||||
{
|
||||
/* neuen Server ("Peer") initialisieren */
|
||||
/* Initialize new server structure */
|
||||
strcpy( Conf_Server[Conf_Server_Count].host, "" );
|
||||
strcpy( Conf_Server[Conf_Server_Count].ip, "" );
|
||||
strcpy( Conf_Server[Conf_Server_Count].name, "" );
|
||||
strcpy( Conf_Server[Conf_Server_Count].pwd, "" );
|
||||
strcpy( Conf_Server[Conf_Server_Count].pwd_in, "" );
|
||||
strcpy( Conf_Server[Conf_Server_Count].pwd_out, "" );
|
||||
Conf_Server[Conf_Server_Count].port = 0;
|
||||
Conf_Server[Conf_Server_Count].group = -1;
|
||||
Conf_Server[Conf_Server_Count].lasttry = time( NULL ) - Conf_ConnectRetry + STARTUP_DELAY;
|
||||
Conf_Server[Conf_Server_Count].res_stat = NULL;
|
||||
Conf_Server_Count++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Log( LOG_ERR, "%s, line %d: Unknown section \"%s\"!", Conf_File, line, section );
|
||||
if( strcasecmp( section, "[CHANNEL]" ) == 0 )
|
||||
{
|
||||
if( Conf_Channel_Count + 1 > MAX_DEFCHANNELS ) Config_Error( LOG_ERR, "Too many pre-defined channels configured." );
|
||||
else
|
||||
{
|
||||
/* Initialize new channel structure */
|
||||
strcpy( Conf_Channel[Conf_Channel_Count].name, "" );
|
||||
strcpy( Conf_Channel[Conf_Channel_Count].modes, "" );
|
||||
strcpy( Conf_Channel[Conf_Channel_Count].topic, "" );
|
||||
Conf_Channel_Count++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
Config_Error( LOG_ERR, "%s, line %d: Unknown section \"%s\"!", NGIRCd_ConfFile, line, section );
|
||||
section[0] = 0x1;
|
||||
}
|
||||
if( section[0] == 0x1 ) continue;
|
||||
|
||||
/* In Variable und Argument zerlegen */
|
||||
/* Split line into variable name and parameters */
|
||||
ptr = strchr( str, '=' );
|
||||
if( ! ptr )
|
||||
{
|
||||
Log( LOG_ERR, "%s, line %d: Syntax error!", Conf_File, line );
|
||||
Config_Error( LOG_ERR, "%s, line %d: Syntax error!", NGIRCd_ConfFile, line );
|
||||
continue;
|
||||
}
|
||||
*ptr = '\0';
|
||||
@@ -199,17 +299,28 @@ LOCAL VOID Read_Config( VOID )
|
||||
if( strcasecmp( section, "[GLOBAL]" ) == 0 ) Handle_GLOBAL( line, var, arg );
|
||||
else if( strcasecmp( section, "[OPERATOR]" ) == 0 ) Handle_OPERATOR( line, var, arg );
|
||||
else if( strcasecmp( section, "[SERVER]" ) == 0 ) Handle_SERVER( line, var, arg );
|
||||
else Log( LOG_ERR, "%s, line %d: Variable \"%s\" outside section!", Conf_File, line, var );
|
||||
else if( strcasecmp( section, "[CHANNEL]" ) == 0 ) Handle_CHANNEL( line, var, arg );
|
||||
else Config_Error( LOG_ERR, "%s, line %d: Variable \"%s\" outside section!", NGIRCd_ConfFile, line, var );
|
||||
}
|
||||
|
||||
fclose( fd );
|
||||
|
||||
/* If there are no ports configured use the default: 6667 */
|
||||
if( Conf_ListenPorts_Count < 1 )
|
||||
{
|
||||
Conf_ListenPorts_Count = 1;
|
||||
Conf_ListenPorts[0] = 6667;
|
||||
}
|
||||
} /* Read_Config */
|
||||
|
||||
|
||||
GLOBAL VOID Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
|
||||
LOCAL VOID
|
||||
Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
|
||||
{
|
||||
struct passwd *pwd;
|
||||
struct group *grp;
|
||||
CHAR *ptr;
|
||||
INT port;
|
||||
LONG port;
|
||||
|
||||
assert( Line > 0 );
|
||||
assert( Var != NULL );
|
||||
@@ -217,39 +328,66 @@ GLOBAL VOID Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
|
||||
|
||||
if( strcasecmp( Var, "Name" ) == 0 )
|
||||
{
|
||||
/* Der Server-Name */
|
||||
strncpy( Conf_ServerName, Arg, CLIENT_ID_LEN );
|
||||
/* Server name */
|
||||
strncpy( Conf_ServerName, Arg, CLIENT_ID_LEN - 1 );
|
||||
Conf_ServerName[CLIENT_ID_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > CLIENT_ID_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Name\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Info" ) == 0 )
|
||||
{
|
||||
/* Server-Info-Text */
|
||||
strncpy( Conf_ServerInfo, Arg, CLIENT_INFO_LEN );
|
||||
/* Info text of server */
|
||||
strncpy( Conf_ServerInfo, Arg, CLIENT_INFO_LEN - 1 );
|
||||
Conf_ServerInfo[CLIENT_INFO_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > CLIENT_INFO_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Info\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Password" ) == 0 )
|
||||
{
|
||||
/* Der Server-Name */
|
||||
strncpy( Conf_ServerPwd, Arg, CLIENT_PASS_LEN );
|
||||
/* Global server password */
|
||||
strncpy( Conf_ServerPwd, Arg, CLIENT_PASS_LEN - 1 );
|
||||
Conf_ServerPwd[CLIENT_PASS_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > CLIENT_PASS_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Password\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "AdminInfo1" ) == 0 )
|
||||
{
|
||||
/* Administrative info #1 */
|
||||
strncpy( Conf_ServerAdmin1, Arg, CLIENT_INFO_LEN - 1 );
|
||||
Conf_ServerAdmin1[CLIENT_INFO_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > CLIENT_INFO_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"AdminInfo1\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "AdminInfo2" ) == 0 )
|
||||
{
|
||||
/* Administrative info #2 */
|
||||
strncpy( Conf_ServerAdmin2, Arg, CLIENT_INFO_LEN - 1 );
|
||||
Conf_ServerAdmin2[CLIENT_INFO_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > CLIENT_INFO_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"AdminInfo2\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "AdminEMail" ) == 0 )
|
||||
{
|
||||
/* Administrative email contact */
|
||||
strncpy( Conf_ServerAdminMail, Arg, CLIENT_INFO_LEN - 1 );
|
||||
Conf_ServerAdminMail[CLIENT_INFO_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > CLIENT_INFO_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"AdminEMail\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Ports" ) == 0 )
|
||||
{
|
||||
/* Ports, durch "," getrennt, auf denen der Server
|
||||
* Verbindungen annehmen soll */
|
||||
/* Ports on that the server should listen. More port numbers
|
||||
* must be separated by "," */
|
||||
ptr = strtok( Arg, "," );
|
||||
while( ptr )
|
||||
{
|
||||
ngt_TrimStr( ptr );
|
||||
port = atol( ptr );
|
||||
if( Conf_ListenPorts_Count + 1 > MAX_LISTEN_PORTS ) Log( LOG_ERR, "Too many listen ports configured. Port %ld ignored.", port );
|
||||
if( Conf_ListenPorts_Count + 1 > MAX_LISTEN_PORTS ) Config_Error( LOG_ERR, "Too many listen ports configured. Port %ld ignored.", port );
|
||||
else
|
||||
{
|
||||
if( port > 0 && port < 0xFFFF ) Conf_ListenPorts[Conf_ListenPorts_Count++] = port;
|
||||
else Log( LOG_ERR, "%s, line %d (section \"Global\"): Illegal port number %ld!", Conf_File, Line, port );
|
||||
if( port > 0 && port < 0xFFFF ) Conf_ListenPorts[Conf_ListenPorts_Count++] = (UINT)port;
|
||||
else Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Illegal port number %ld!", NGIRCd_ConfFile, Line, port );
|
||||
}
|
||||
ptr = strtok( NULL, "," );
|
||||
}
|
||||
@@ -257,38 +395,111 @@ GLOBAL VOID Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
|
||||
}
|
||||
if( strcasecmp( Var, "MotdFile" ) == 0 )
|
||||
{
|
||||
/* Datei mit der "message of the day" (MOTD) */
|
||||
strncpy( Conf_MotdFile, Arg, FNAME_LEN );
|
||||
/* "Message of the day" (MOTD) file */
|
||||
strncpy( Conf_MotdFile, Arg, FNAME_LEN - 1 );
|
||||
Conf_MotdFile[FNAME_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > FNAME_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MotdFile\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "ServerUID" ) == 0 )
|
||||
{
|
||||
/* UID the daemon should switch to */
|
||||
pwd = getpwnam( Arg );
|
||||
if( pwd ) Conf_UID = pwd->pw_uid;
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_ISDIGIT
|
||||
if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"ServerUID\" is not a number!", NGIRCd_ConfFile, Line );
|
||||
else
|
||||
#endif
|
||||
Conf_UID = (UINT)atoi( Arg );
|
||||
}
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "ServerGID" ) == 0 )
|
||||
{
|
||||
/* GID the daemon should use */
|
||||
grp = getgrnam( Arg );
|
||||
if( grp ) Conf_GID = grp->gr_gid;
|
||||
else
|
||||
{
|
||||
#ifdef HAVE_ISDIGIT
|
||||
if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"ServerGID\" is not a number!", NGIRCd_ConfFile, Line );
|
||||
else
|
||||
#endif
|
||||
Conf_GID = (UINT)atoi( Arg );
|
||||
}
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "PingTimeout" ) == 0 )
|
||||
{
|
||||
/* PING-Timeout */
|
||||
/* PING timeout */
|
||||
Conf_PingTimeout = atoi( Arg );
|
||||
if(( Conf_PingTimeout ) < 5 ) Conf_PingTimeout = 5;
|
||||
if( Conf_PingTimeout < 5 )
|
||||
{
|
||||
Config_Error( LOG_WARNING, "%s, line %d: Value of \"PingTimeout\" too low!", NGIRCd_ConfFile, Line );
|
||||
Conf_PingTimeout = 5;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "PongTimeout" ) == 0 )
|
||||
{
|
||||
/* PONG-Timeout */
|
||||
/* PONG timeout */
|
||||
Conf_PongTimeout = atoi( Arg );
|
||||
if(( Conf_PongTimeout ) < 5 ) Conf_PongTimeout = 5;
|
||||
if( Conf_PongTimeout < 5 )
|
||||
{
|
||||
Config_Error( LOG_WARNING, "%s, line %d: Value of \"PongTimeout\" too low!", NGIRCd_ConfFile, Line );
|
||||
Conf_PongTimeout = 5;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "ConnectRetry" ) == 0 )
|
||||
{
|
||||
/* Sekunden zwischen Verbindungsversuchen zu anderen Servern */
|
||||
/* Seconds between connection attempts to other servers */
|
||||
Conf_ConnectRetry = atoi( Arg );
|
||||
if(( Conf_ConnectRetry ) < 5 ) Conf_ConnectRetry = 5;
|
||||
if( Conf_ConnectRetry < 5 )
|
||||
{
|
||||
Config_Error( LOG_WARNING, "%s, line %d: Value of \"ConnectRetry\" too low!", NGIRCd_ConfFile, Line );
|
||||
Conf_ConnectRetry = 5;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Log( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", Conf_File, Line, Var );
|
||||
if( strcasecmp( Var, "OperCanUseMode" ) == 0 )
|
||||
{
|
||||
/* Are IRC operators allowed to use MODE in channels they aren't Op in? */
|
||||
if( strcasecmp( Arg, "yes" ) == 0 ) Conf_OperCanMode = TRUE;
|
||||
else if( strcasecmp( Arg, "true" ) == 0 ) Conf_OperCanMode = TRUE;
|
||||
else if( atoi( Arg ) != 0 ) Conf_OperCanMode = TRUE;
|
||||
else Conf_OperCanMode = FALSE;
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "MaxConnections" ) == 0 )
|
||||
{
|
||||
/* Maximum number of connections. Values <= 0 are equal to "no limit". */
|
||||
#ifdef HAVE_ISDIGIT
|
||||
if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MaxConnections\" is not a number!", NGIRCd_ConfFile, Line );
|
||||
else
|
||||
#endif
|
||||
Conf_MaxConnections = atol( Arg );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "MaxJoins" ) == 0 )
|
||||
{
|
||||
/* Maximum number of channels a user can join. Values <= 0 are equal to "no limit". */
|
||||
#ifdef HAVE_ISDIGIT
|
||||
if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MaxJoins\" is not a number!", NGIRCd_ConfFile, Line );
|
||||
else
|
||||
#endif
|
||||
Conf_MaxJoins = atoi( Arg );
|
||||
return;
|
||||
}
|
||||
|
||||
Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var );
|
||||
} /* Handle_GLOBAL */
|
||||
|
||||
|
||||
GLOBAL VOID Handle_OPERATOR( INT Line, CHAR *Var, CHAR *Arg )
|
||||
LOCAL VOID
|
||||
Handle_OPERATOR( INT Line, CHAR *Var, CHAR *Arg )
|
||||
{
|
||||
assert( Line > 0 );
|
||||
assert( Var != NULL );
|
||||
@@ -297,26 +508,29 @@ GLOBAL VOID Handle_OPERATOR( INT Line, CHAR *Var, CHAR *Arg )
|
||||
|
||||
if( strcasecmp( Var, "Name" ) == 0 )
|
||||
{
|
||||
/* Name des IRC Operator */
|
||||
strncpy( Conf_Oper[Conf_Oper_Count - 1].name, Arg, CLIENT_ID_LEN );
|
||||
Conf_Oper[Conf_Oper_Count - 1].name[CLIENT_ID_LEN - 1] = '\0';
|
||||
/* Name of IRC operator */
|
||||
strncpy( Conf_Oper[Conf_Oper_Count - 1].name, Arg, CLIENT_PASS_LEN - 1 );
|
||||
Conf_Oper[Conf_Oper_Count - 1].name[CLIENT_PASS_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > CLIENT_PASS_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Name\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Password" ) == 0 )
|
||||
{
|
||||
/* Passwort des IRC Operator */
|
||||
strncpy( Conf_Oper[Conf_Oper_Count - 1].pwd, Arg, CLIENT_PASS_LEN );
|
||||
/* Password of IRC operator */
|
||||
strncpy( Conf_Oper[Conf_Oper_Count - 1].pwd, Arg, CLIENT_PASS_LEN - 1 );
|
||||
Conf_Oper[Conf_Oper_Count - 1].pwd[CLIENT_PASS_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > CLIENT_PASS_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Password\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
|
||||
Log( LOG_ERR, "%s, line %d (section \"Operator\"): Unknown variable \"%s\"!", Conf_File, Line, Var );
|
||||
Config_Error( LOG_ERR, "%s, line %d (section \"Operator\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var );
|
||||
} /* Handle_OPERATOR */
|
||||
|
||||
|
||||
GLOBAL VOID Handle_SERVER( INT Line, CHAR *Var, CHAR *Arg )
|
||||
LOCAL VOID
|
||||
Handle_SERVER( INT Line, CHAR *Var, CHAR *Arg )
|
||||
{
|
||||
INT port;
|
||||
LONG port;
|
||||
|
||||
assert( Line > 0 );
|
||||
assert( Var != NULL );
|
||||
@@ -324,49 +538,171 @@ GLOBAL VOID Handle_SERVER( INT Line, CHAR *Var, CHAR *Arg )
|
||||
|
||||
if( strcasecmp( Var, "Host" ) == 0 )
|
||||
{
|
||||
/* Hostname des Servers */
|
||||
strncpy( Conf_Server[Conf_Server_Count - 1].host, Arg, HOST_LEN );
|
||||
/* Hostname of the server */
|
||||
strncpy( Conf_Server[Conf_Server_Count - 1].host, Arg, HOST_LEN - 1 );
|
||||
Conf_Server[Conf_Server_Count - 1].host[HOST_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > HOST_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Host\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Name" ) == 0 )
|
||||
{
|
||||
/* Name des Servers ("Nick") */
|
||||
strncpy( Conf_Server[Conf_Server_Count - 1].name, Arg, CLIENT_ID_LEN );
|
||||
/* Name of the server ("Nick"/"ID") */
|
||||
strncpy( Conf_Server[Conf_Server_Count - 1].name, Arg, CLIENT_ID_LEN - 1 );
|
||||
Conf_Server[Conf_Server_Count - 1].name[CLIENT_ID_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > CLIENT_ID_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Name\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Password" ) == 0 )
|
||||
if( strcasecmp( Var, "MyPassword" ) == 0 )
|
||||
{
|
||||
/* Passwort des Servers */
|
||||
strncpy( Conf_Server[Conf_Server_Count - 1].pwd, Arg, CLIENT_PASS_LEN );
|
||||
Conf_Server[Conf_Server_Count - 1].pwd[CLIENT_PASS_LEN - 1] = '\0';
|
||||
/* Password of this server which is sent to the peer */
|
||||
strncpy( Conf_Server[Conf_Server_Count - 1].pwd_in, Arg, CLIENT_PASS_LEN - 1 );
|
||||
Conf_Server[Conf_Server_Count - 1].pwd_in[CLIENT_PASS_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > CLIENT_PASS_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MyPassword\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "PeerPassword" ) == 0 )
|
||||
{
|
||||
/* Passwort of the peer which must be received */
|
||||
strncpy( Conf_Server[Conf_Server_Count - 1].pwd_out, Arg, CLIENT_PASS_LEN - 1 );
|
||||
Conf_Server[Conf_Server_Count - 1].pwd_out[CLIENT_PASS_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > CLIENT_PASS_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"PeerPassword\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Port" ) == 0 )
|
||||
{
|
||||
/* Port, zu dem Verbunden werden soll */
|
||||
/* Port to which this server should connect */
|
||||
port = atol( Arg );
|
||||
if( port > 0 && port < 0xFFFF ) Conf_Server[Conf_Server_Count - 1].port = port;
|
||||
else Log( LOG_ERR, "%s, line %d (section \"Server\"): Illegal port number %ld!", Conf_File, Line, port );
|
||||
if( port > 0 && port < 0xFFFF ) Conf_Server[Conf_Server_Count - 1].port = (INT)port;
|
||||
else Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Illegal port number %ld!", NGIRCd_ConfFile, Line, port );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Group" ) == 0 )
|
||||
{
|
||||
/* Server group */
|
||||
#ifdef HAVE_ISDIGIT
|
||||
if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Group\" is not a number!", NGIRCd_ConfFile, Line );
|
||||
else
|
||||
#endif
|
||||
Conf_Server[Conf_Server_Count - 1].group = atoi( Arg );
|
||||
return;
|
||||
}
|
||||
|
||||
Log( LOG_ERR, "%s, line %d (section \"Server\"): Unknown variable \"%s\"!", Conf_File, Line, Var );
|
||||
Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var );
|
||||
} /* Handle_SERVER */
|
||||
|
||||
|
||||
LOCAL VOID Validate_Config( VOID )
|
||||
LOCAL VOID
|
||||
Handle_CHANNEL( INT Line, CHAR *Var, CHAR *Arg )
|
||||
{
|
||||
/* Konfiguration ueberpruefen */
|
||||
assert( Line > 0 );
|
||||
assert( Var != NULL );
|
||||
assert( Arg != NULL );
|
||||
|
||||
if( strcasecmp( Var, "Name" ) == 0 )
|
||||
{
|
||||
/* Name of the channel */
|
||||
strncpy( Conf_Channel[Conf_Channel_Count - 1].name, Arg, CHANNEL_NAME_LEN - 1 );
|
||||
Conf_Channel[Conf_Channel_Count - 1].name[CHANNEL_NAME_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > CHANNEL_NAME_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Name\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Modes" ) == 0 )
|
||||
{
|
||||
/* Initial modes */
|
||||
strncpy( Conf_Channel[Conf_Channel_Count - 1].modes, Arg, CHANNEL_MODE_LEN - 1 );
|
||||
Conf_Channel[Conf_Channel_Count - 1].modes[CHANNEL_MODE_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > CHANNEL_MODE_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Modes\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Topic" ) == 0 )
|
||||
{
|
||||
/* Initial topic */
|
||||
strncpy( Conf_Channel[Conf_Channel_Count - 1].topic, Arg, CHANNEL_TOPIC_LEN - 1 );
|
||||
Conf_Channel[Conf_Channel_Count - 1].topic[CHANNEL_TOPIC_LEN - 1] = '\0';
|
||||
if( strlen( Arg ) > CHANNEL_TOPIC_LEN - 1 ) Config_Error( LOG_WARNING, "%s, line %d: Value of \"Topic\" too long!", NGIRCd_ConfFile, Line );
|
||||
return;
|
||||
}
|
||||
|
||||
Config_Error( LOG_ERR, "%s, line %d (section \"Channel\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var );
|
||||
} /* Handle_CHANNEL */
|
||||
|
||||
|
||||
LOCAL VOID
|
||||
Validate_Config( BOOLEAN Configtest )
|
||||
{
|
||||
/* Validate configuration settings. */
|
||||
|
||||
if( ! Conf_ServerName[0] )
|
||||
{
|
||||
/* Kein Servername konfiguriert */
|
||||
Log( LOG_ALERT, "No server name configured in \"%s\"!", Conf_File );
|
||||
Log( LOG_ALERT, PACKAGE" exiting due to fatal errors!" );
|
||||
exit( 1 );
|
||||
/* No server name configured! */
|
||||
Config_Error( LOG_ALERT, "No server name configured in \"%s\" ('ServerName')!", NGIRCd_ConfFile );
|
||||
if( ! Configtest )
|
||||
{
|
||||
Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef STRICT_RFC
|
||||
if( ! Conf_ServerAdminMail[0] )
|
||||
{
|
||||
/* No administrative contact configured! */
|
||||
Config_Error( LOG_ALERT, "No administrator email address configured in \"%s\" ('AdminEMail')!", NGIRCd_ConfFile );
|
||||
if( ! Configtest )
|
||||
{
|
||||
Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if( ! Conf_ServerAdmin1[0] && ! Conf_ServerAdmin2[0] && ! Conf_ServerAdminMail[0] )
|
||||
{
|
||||
/* No administrative information configured! */
|
||||
Config_Error( LOG_WARNING, "No administrative information configured but required by RFC!" );
|
||||
}
|
||||
#ifdef FD_SETSIZE
|
||||
if(( Conf_MaxConnections > (LONG)FD_SETSIZE ) || ( Conf_MaxConnections < 1 ))
|
||||
{
|
||||
Conf_MaxConnections = (LONG)FD_SETSIZE;
|
||||
Config_Error( LOG_ERR, "Setting MaxConnections to %ld, select() can't handle more file descriptors!", Conf_MaxConnections );
|
||||
}
|
||||
#else
|
||||
Config_Error( LOG_WARN, "Don't know how many file descriptors select() can handle on this system, don't set MaxConnections too high!" );
|
||||
#endif
|
||||
} /* Validate_Config */
|
||||
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
LOCAL VOID Config_Error( CONST INT Level, CONST CHAR *Format, ... )
|
||||
#else
|
||||
LOCAL VOID Config_Error( Level, Format, va_alist )
|
||||
CONST INT Level;
|
||||
CONST CHAR *Format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
/* Error! Write to console and/or logfile. */
|
||||
|
||||
CHAR msg[MAX_LOG_MSG_LEN];
|
||||
va_list ap;
|
||||
|
||||
assert( Format != NULL );
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
va_start( ap, Format );
|
||||
#else
|
||||
va_start( ap );
|
||||
#endif
|
||||
vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
|
||||
va_end( ap );
|
||||
|
||||
/* During "normal operations" the log functions of the daemon should
|
||||
* be used, but during testing of the configuration file, all messages
|
||||
* should go directly to the console: */
|
||||
if( Use_Log ) Log( Level, "%s", msg );
|
||||
else puts( msg );
|
||||
} /* Config_Error */
|
||||
|
||||
|
||||
/* -eof- */
|
||||
|
||||
@@ -2,44 +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.9 2002/01/03 02:27:20 alex Exp $
|
||||
* $Id: conf.h,v 1.24 2002/12/14 13:36:19 alex Exp $
|
||||
*
|
||||
* conf.h: Konfiguration des ngircd (Header)
|
||||
*
|
||||
* $Log: conf.h,v $
|
||||
* Revision 1.9 2002/01/03 02:27:20 alex
|
||||
* - das Server-Passwort kann nun konfiguriert werden.
|
||||
*
|
||||
* Revision 1.8 2002/01/02 02:49:16 alex
|
||||
* - Konfigurationsdatei "Samba like" umgestellt.
|
||||
* - es koennen nun mehrere Server und Oprtatoren konfiguriert werden.
|
||||
*
|
||||
* Revision 1.6 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.5 2001/12/30 19:26:11 alex
|
||||
* - Unterstuetzung fuer die Konfigurationsdatei eingebaut.
|
||||
*
|
||||
* Revision 1.4 2001/12/26 22:48:53 alex
|
||||
* - MOTD-Datei ist nun konfigurierbar und wird gelesen.
|
||||
*
|
||||
* Revision 1.3 2001/12/26 14:45:37 alex
|
||||
* - "Code Cleanups".
|
||||
*
|
||||
* Revision 1.2 2001/12/26 03:19:57 alex
|
||||
* - erste Konfigurations-Variablen definiert: PING/PONG-Timeout.
|
||||
*
|
||||
* Revision 1.1 2001/12/12 17:18:20 alex
|
||||
* - Modul fuer Server-Konfiguration begonnen.
|
||||
* Configuration management (header)
|
||||
*/
|
||||
|
||||
|
||||
@@ -48,62 +19,92 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
|
||||
typedef struct _Conf_Oper
|
||||
{
|
||||
CHAR name[CLIENT_PASS_LEN];
|
||||
CHAR pwd[CLIENT_PASS_LEN];
|
||||
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];
|
||||
CHAR ip[16];
|
||||
CHAR name[CLIENT_ID_LEN];
|
||||
CHAR pwd[CLIENT_PASS_LEN];
|
||||
INT port;
|
||||
time_t lasttry;
|
||||
RES_STAT *res_stat;
|
||||
CHAR host[HOST_LEN]; /* Hostname */
|
||||
CHAR ip[16]; /* IP address (Resolver) */
|
||||
CHAR name[CLIENT_ID_LEN]; /* IRC-Client-ID */
|
||||
CHAR pwd_in[CLIENT_PASS_LEN]; /* Password which must be received */
|
||||
CHAR pwd_out[CLIENT_PASS_LEN]; /* Password to send to peer */
|
||||
INT port; /* Server port */
|
||||
INT group; /* Group of server */
|
||||
time_t lasttry; /* Last connect attempt */
|
||||
RES_STAT *res_stat; /* Status of the resolver */
|
||||
} 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;
|
||||
|
||||
/* Konfigurationsdatei */
|
||||
GLOBAL CHAR Conf_File[FNAME_LEN];
|
||||
|
||||
/* Name ("Nick") des Servers */
|
||||
/* 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 */
|
||||
GLOBAL INT Conf_ListenPorts[MAX_LISTEN_PORTS];
|
||||
/* Ports the server should listen on */
|
||||
GLOBAL UINT Conf_ListenPorts[MAX_LISTEN_PORTS];
|
||||
GLOBAL INT Conf_ListenPorts_Count;
|
||||
|
||||
/* Timeouts fuer PING und PONG */
|
||||
/* User and group ID the server should run with */
|
||||
GLOBAL UINT Conf_UID;
|
||||
GLOBAL UINT Conf_GID;
|
||||
|
||||
/* 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;
|
||||
|
||||
GLOBAL VOID Conf_Init( VOID );
|
||||
GLOBAL VOID Conf_Exit( VOID );
|
||||
/* 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;
|
||||
|
||||
|
||||
GLOBAL VOID Conf_Init PARAMS((VOID ));
|
||||
GLOBAL INT Conf_Test PARAMS((VOID ));
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
1766
src/ngircd/conn.c
1766
src/ngircd/conn.c
File diff suppressed because it is too large
Load Diff
@@ -2,49 +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.10 2002/01/06 15:18:15 alex Exp $
|
||||
* $Id: conn.h,v 1.26.2.1 2003/03/09 20:16:46 alex Exp $
|
||||
*
|
||||
* conn.h: Verwaltung aller Netz-Verbindungen ("connections") (Header)
|
||||
*
|
||||
* $Log: conn.h,v $
|
||||
* Revision 1.10 2002/01/06 15:18:15 alex
|
||||
* - Loglevel und Meldungen nochmals geaendert. Level passen nun besser.
|
||||
*
|
||||
* Revision 1.9 2002/01/02 02:44:36 alex
|
||||
* - neue Defines fuer max. Anzahl Server und Operatoren.
|
||||
*
|
||||
* Revision 1.8 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.7 2001/12/26 14:45:37 alex
|
||||
* - "Code Cleanups".
|
||||
*
|
||||
* Revision 1.6 2001/12/25 22:03:47 alex
|
||||
* - Conn_Close() eingefuehrt: war die lokale Funktion Close_Connection().
|
||||
*
|
||||
* Revision 1.5 2001/12/23 21:57:48 alex
|
||||
* - Conn_WriteStr() unterstuetzt nun variable Parameter.
|
||||
*
|
||||
* Revision 1.4 2001/12/15 00:08:27 alex
|
||||
* - neue globale Funktionen: Conn_Write() und Conn_WriteStr().
|
||||
*
|
||||
* Revision 1.3 2001/12/14 08:15:45 alex
|
||||
* - CONN_ID wird definiert.
|
||||
*
|
||||
* Revision 1.2 2001/12/13 01:33:32 alex
|
||||
* - Conn_Handler() unterstuetzt nun einen Timeout (in Sekunden).
|
||||
*
|
||||
* Revision 1.1 2001/12/12 17:18:38 alex
|
||||
* - Modul zur Verwaltung aller Netzwerk-Verbindungen begonnen.
|
||||
* Connection management (header)
|
||||
*/
|
||||
|
||||
|
||||
@@ -52,29 +18,72 @@
|
||||
#define __conn_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
|
||||
{
|
||||
INT pid; /* PID des Child-Prozess */
|
||||
INT pipe[2]; /* Pipe fuer IPC */
|
||||
} RES_STAT;
|
||||
|
||||
GLOBAL VOID Conn_Init PARAMS((VOID ));
|
||||
GLOBAL VOID Conn_Exit PARAMS(( VOID ));
|
||||
|
||||
GLOBAL INT Conn_InitListeners PARAMS(( VOID ));
|
||||
GLOBAL VOID Conn_ExitListeners PARAMS(( VOID ));
|
||||
|
||||
GLOBAL BOOLEAN Conn_NewListener PARAMS(( CONST UINT Port ));
|
||||
|
||||
GLOBAL VOID Conn_Handler PARAMS(( VOID ));
|
||||
|
||||
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_Close PARAMS(( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient ));
|
||||
|
||||
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 VOID Conn_SetServer PARAMS(( CONN_ID Idx, INT ConfServer ));
|
||||
|
||||
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 ));
|
||||
|
||||
#ifdef USE_ZLIB
|
||||
GLOBAL BOOLEAN Conn_InitZip PARAMS(( CONN_ID Idx ));
|
||||
GLOBAL LONG Conn_SendBytesZip PARAMS(( CONN_ID Idx ));
|
||||
GLOBAL LONG Conn_RecvBytesZip PARAMS(( CONN_ID Idx ));
|
||||
#endif
|
||||
|
||||
GLOBAL VOID Conn_ResetWCounter PARAMS(( VOID ));
|
||||
GLOBAL LONG Conn_WCounter PARAMS(( VOID ));
|
||||
|
||||
|
||||
GLOBAL VOID Conn_Init( VOID );
|
||||
GLOBAL VOID Conn_Exit( VOID );
|
||||
|
||||
GLOBAL BOOLEAN Conn_NewListener( CONST INT Port );
|
||||
|
||||
GLOBAL VOID Conn_Handler( INT Timeout );
|
||||
|
||||
GLOBAL BOOLEAN Conn_Write( CONN_ID Idx, CHAR *Data, INT Len );
|
||||
GLOBAL BOOLEAN Conn_WriteStr( CONN_ID Idx, CHAR *Format, ... );
|
||||
|
||||
GLOBAL VOID Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient );
|
||||
|
||||
GLOBAL VOID Conn_UpdateIdle( CONN_ID Idx );
|
||||
GLOBAL INT32 Conn_GetIdle( CONN_ID Idx );
|
||||
GLOBAL INT Conn_MaxFD;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,40 +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: defines.h,v 1.7 2002/01/22 17:15:39 alex Exp $
|
||||
* $Id: defines.h,v 1.40 2002/12/16 23:10:56 alex Exp $
|
||||
*
|
||||
* defines.h: (globale) Konstanten
|
||||
*
|
||||
* $Log: defines.h,v $
|
||||
* Revision 1.7 2002/01/22 17:15:39 alex
|
||||
* - die Fehlermeldung "interrupted system call" sollte nicht mehr auftreten.
|
||||
*
|
||||
* Revision 1.6 2002/01/21 00:03:16 alex
|
||||
* - neue Konstante CHANNEL_MODE_LEN.
|
||||
*
|
||||
* Revision 1.5 2002/01/18 15:51:44 alex
|
||||
* - Server-Verbinungen werden beim Start erst nach kurzer Pause aufgebaut.
|
||||
*
|
||||
* Revision 1.4 2002/01/07 15:29:53 alex
|
||||
* - PASSSERVERADD definiert, wird beim PASS-Befehl an Server verwendet.
|
||||
*
|
||||
* Revision 1.3 2002/01/03 02:24:00 alex
|
||||
* - Protokollversion und Suffix definiert.
|
||||
*
|
||||
* Revision 1.2 2002/01/02 02:44:36 alex
|
||||
* - neue Defines fuer max. Anzahl Server und Operatoren.
|
||||
*
|
||||
* Revision 1.1 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
* Global defines of ngIRCd.
|
||||
*/
|
||||
|
||||
#ifndef __defines_h__
|
||||
@@ -44,6 +19,8 @@
|
||||
|
||||
#define NONE -1
|
||||
|
||||
#define TIME_RES 2 /* Zeit-Aufloesung des Servers in Sekunden */
|
||||
|
||||
#define FNAME_LEN 256 /* max. Laenge eines Dateinamen */
|
||||
|
||||
#define LINE_LEN 256 /* max. Laenge einer Konfigurationszeile */
|
||||
@@ -52,11 +29,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 */
|
||||
@@ -66,21 +47,57 @@
|
||||
#define CLIENT_HOST_LEN 64 /* max. Laenge des Hostname */
|
||||
#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 */
|
||||
#define CHANNEL_TOPIC_LEN 128 /* max. Laenge eines Channel-Topics */
|
||||
|
||||
#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 "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 */
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
# define CONFIG_FILE SYSCONFDIR"/ngircd.conf"
|
||||
# define MOTD_FILE SYSCONFDIR"/ngircd.motd"
|
||||
#else
|
||||
# define CONFIG_FILE "ngircd.conf"
|
||||
# define MOTD_FILE "ngircd.motd"
|
||||
#endif
|
||||
#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 */
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,58 +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: global.h,v 1.6 2002/01/05 15:55:11 alex Exp $
|
||||
*
|
||||
* global.h: Globaler Header, wir in jedes(!) Modul eingebunden.
|
||||
*
|
||||
* $Log: global.h,v $
|
||||
* Revision 1.6 2002/01/05 15:55:11 alex
|
||||
* - Wrapper fuer inet_aton(): liefert immer Fehler.
|
||||
*
|
||||
* Revision 1.5 2002/01/02 02:42:58 alex
|
||||
* - Copyright-Texte aktualisiert.
|
||||
*
|
||||
* Revision 1.4 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.3 2001/12/14 08:14:34 alex
|
||||
* - NONE als -1 definiert. Macht den Source lesbarer ;-)
|
||||
*
|
||||
* Revision 1.2 2001/12/12 01:58:53 alex
|
||||
* - Test auf socklen_t verbessert.
|
||||
*
|
||||
* Revision 1.1.1.1 2001/12/11 21:53:04 alex
|
||||
* Imported sources to CVS.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __global_h__
|
||||
#define __global_h__
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "defines.h"
|
||||
|
||||
#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
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* -eof- */
|
||||
128
src/ngircd/hash.c
Normal file
128
src/ngircd/hash.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Hash calculation
|
||||
*/
|
||||
|
||||
|
||||
#include "portab.h"
|
||||
|
||||
static char UNUSED id[] = "$Id: hash.c,v 1.6 2002/12/12 12:24:18 alex Exp $";
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "log.h"
|
||||
#include "tool.h"
|
||||
|
||||
#include "exp.h"
|
||||
#include "hash.h"
|
||||
|
||||
|
||||
LOCAL UINT32 jenkins_hash PARAMS(( register UINT8 *k, register UINT32 length, register UINT32 initval ));
|
||||
|
||||
|
||||
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';
|
||||
|
||||
return jenkins_hash( (UINT8 *)ngt_LowerStr( buffer ), strlen( buffer ), 42 );
|
||||
} /* Hash */
|
||||
|
||||
|
||||
/*
|
||||
* Die hier verwendete Hash-Funktion stammt aus lookup2.c von Bob Jenkins
|
||||
* (URL: <http://burtleburtle.net/bob/c/lookup2.c>). Aus dem Header:
|
||||
* --------------------------------------------------------------------
|
||||
* lookup2.c, by Bob Jenkins, December 1996, Public Domain.
|
||||
* hash(), hash2(), hash3, and mix() are externally useful functions.
|
||||
* Routines to test the hash are included if SELF_TEST is defined.
|
||||
* You can use this free for any purpose. It has no warranty.
|
||||
* --------------------------------------------------------------------
|
||||
* nicht alle seiner Funktionen werden hier genutzt.
|
||||
*/
|
||||
|
||||
|
||||
#define hashsize(n) ((UINT32)1<<(n))
|
||||
#define hashmask(n) (hashsize(n)-1)
|
||||
|
||||
#define mix(a,b,c) \
|
||||
{ \
|
||||
a -= b; a -= c; a ^= (c>>13); \
|
||||
b -= c; b -= a; b ^= (a<<8); \
|
||||
c -= a; c -= b; c ^= (b>>13); \
|
||||
a -= b; a -= c; a ^= (c>>12); \
|
||||
b -= c; b -= a; b ^= (a<<16); \
|
||||
c -= a; c -= b; c ^= (b>>5); \
|
||||
a -= b; a -= c; a ^= (c>>3); \
|
||||
b -= c; b -= a; b ^= (a<<10); \
|
||||
c -= a; c -= b; c ^= (b>>15); \
|
||||
} /* mix */
|
||||
|
||||
|
||||
LOCAL UINT32
|
||||
jenkins_hash( register UINT8 *k, register UINT32 length, register UINT32 initval )
|
||||
{
|
||||
/* k: the key
|
||||
* length: length of the key
|
||||
* initval: the previous hash, or an arbitrary value
|
||||
*/
|
||||
|
||||
register UINT32 a,b,c,len;
|
||||
|
||||
/* Set up the internal state */
|
||||
len = length;
|
||||
a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
|
||||
c = initval; /* the previous hash value */
|
||||
|
||||
/* handle most of the key */
|
||||
while (len >= 12)
|
||||
{
|
||||
a += (k[0] +((UINT32)k[1]<<8) +((UINT32)k[2]<<16) +((UINT32)k[3]<<24));
|
||||
b += (k[4] +((UINT32)k[5]<<8) +((UINT32)k[6]<<16) +((UINT32)k[7]<<24));
|
||||
c += (k[8] +((UINT32)k[9]<<8) +((UINT32)k[10]<<16)+((UINT32)k[11]<<24));
|
||||
mix(a,b,c);
|
||||
k += 12; len -= 12;
|
||||
}
|
||||
|
||||
/* handle the last 11 bytes */
|
||||
c += length;
|
||||
switch(len) /* all the case statements fall through */
|
||||
{
|
||||
case 11: c+=((UINT32)k[10]<<24);
|
||||
case 10: c+=((UINT32)k[9]<<16);
|
||||
case 9 : c+=((UINT32)k[8]<<8);
|
||||
/* the first byte of c is reserved for the length */
|
||||
case 8 : b+=((UINT32)k[7]<<24);
|
||||
case 7 : b+=((UINT32)k[6]<<16);
|
||||
case 6 : b+=((UINT32)k[5]<<8);
|
||||
case 5 : b+=k[4];
|
||||
case 4 : a+=((UINT32)k[3]<<24);
|
||||
case 3 : a+=((UINT32)k[2]<<16);
|
||||
case 2 : a+=((UINT32)k[1]<<8);
|
||||
case 1 : a+=k[0];
|
||||
/* case 0: nothing left to add */
|
||||
}
|
||||
mix(a,b,c);
|
||||
|
||||
/* report the result */
|
||||
return c;
|
||||
} /* jenkins_hash */
|
||||
|
||||
|
||||
/* -eof- */
|
||||
27
src/ngircd/hash.h
Normal file
27
src/ngircd/hash.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: hash.h,v 1.4 2002/12/12 12:23:43 alex Exp $
|
||||
*
|
||||
* Hash calculation (header)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __hash_h__
|
||||
#define __hash_h__
|
||||
|
||||
|
||||
GLOBAL UINT32 Hash PARAMS((CHAR *String ));
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* -eof- */
|
||||
429
src/ngircd/irc-channel.c
Normal file
429
src/ngircd/irc-channel.c
Normal file
@@ -0,0 +1,429 @@
|
||||
/*
|
||||
* 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 channel commands
|
||||
*/
|
||||
|
||||
|
||||
#include "portab.h"
|
||||
|
||||
static char UNUSED id[] = "$Id: irc-channel.c,v 1.21.2.5 2003/01/08 23:09:34 alex Exp $";
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "defines.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 )
|
||||
{
|
||||
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 );
|
||||
|
||||
/* Bad number of arguments? */
|
||||
if(( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
|
||||
|
||||
/* Who is the sender? */
|
||||
if( Client_Type( Client ) == CLIENT_SERVER ) target = Client_Search( Req->prefix );
|
||||
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 )
|
||||
{
|
||||
chan = flags = NULL;
|
||||
|
||||
/* wird der Channel neu angelegt? */
|
||||
if( Channel_Search( channame )) is_new_chan = FALSE;
|
||||
else is_new_chan = TRUE;
|
||||
|
||||
/* Hat ein Server Channel-User-Modes uebergeben? */
|
||||
if( Client_Type( Client ) == CLIENT_SERVER )
|
||||
{
|
||||
/* Channel-Flags extrahieren */
|
||||
flags = strchr( channame, 0x7 );
|
||||
if( flags )
|
||||
{
|
||||
*flags = '\0';
|
||||
flags++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Lokaler Client? */
|
||||
if( Client_Type( Client ) == CLIENT_USER )
|
||||
{
|
||||
/* 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) */
|
||||
if( ! Channel_Join( target, channame ))
|
||||
{
|
||||
/* naechsten Namen ermitteln */
|
||||
channame = strtok( NULL, "," );
|
||||
continue;
|
||||
}
|
||||
if( ! chan ) chan = Channel_Search( channame );
|
||||
assert( chan != NULL );
|
||||
|
||||
/* Modes setzen (wenn vorhanden) */
|
||||
while( flags && *flags )
|
||||
{
|
||||
Channel_UserModeAdd( chan, target, *flags );
|
||||
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 ));
|
||||
if( modes[1] ) modes[0] = 0x7;
|
||||
else modes[0] = '\0';
|
||||
|
||||
/* An andere Server weiterleiten */
|
||||
IRC_WriteStrServersPrefix( Client, target, "JOIN :%s%s", channame, modes );
|
||||
|
||||
/* im Channel bekannt machen */
|
||||
IRC_WriteStrChannelPrefix( Client, chan, target, FALSE, "JOIN :%s", channame );
|
||||
if( modes[1] )
|
||||
{
|
||||
/* Modes im Channel bekannt machen */
|
||||
IRC_WriteStrChannelPrefix( Client, chan, target, FALSE, "MODE %s +%s %s", channame, &modes[1], Client_ID( target ));
|
||||
}
|
||||
|
||||
if( Client_Type( Client ) == CLIENT_USER )
|
||||
{
|
||||
/* an Client bestaetigen */
|
||||
IRC_WriteStrClientPrefix( Client, target, "JOIN :%s", channame );
|
||||
|
||||
/* Topic an Client schicken */
|
||||
topic = Channel_Topic( chan );
|
||||
if( *topic ) IRC_WriteStrClient( Client, RPL_TOPIC_MSG, Client_ID( Client ), channame, topic );
|
||||
|
||||
/* Mitglieder an Client Melden */
|
||||
IRC_Send_NAMES( Client, chan );
|
||||
IRC_WriteStrClient( Client, RPL_ENDOFNAMES_MSG, Client_ID( Client ), Channel_Name( chan ));
|
||||
}
|
||||
|
||||
/* naechsten Namen ermitteln */
|
||||
channame = strtok( NULL, "," );
|
||||
}
|
||||
return CONNECTED;
|
||||
} /* IRC_JOIN */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_PART( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
CLIENT *target;
|
||||
CHAR *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 );
|
||||
|
||||
/* 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 );
|
||||
|
||||
/* Channel-Namen durchgehen */
|
||||
chan = strtok( Req->argv[0], "," );
|
||||
while( chan )
|
||||
{
|
||||
if( ! Channel_Part( target, Client, chan, Req->argc > 1 ? Req->argv[1] : Client_ID( target )))
|
||||
{
|
||||
/* naechsten Namen ermitteln */
|
||||
chan = strtok( NULL, "," );
|
||||
continue;
|
||||
}
|
||||
|
||||
/* naechsten Namen ermitteln */
|
||||
chan = strtok( NULL, "," );
|
||||
}
|
||||
return CONNECTED;
|
||||
} /* IRC_PART */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_TOPIC( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
CHANNEL *chan;
|
||||
CLIENT *from;
|
||||
CHAR *topic;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
/* Falsche Anzahl Parameter? */
|
||||
if(( Req->argc < 1 ) || ( 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 );
|
||||
|
||||
/* Welcher Channel? */
|
||||
chan = Channel_Search( 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] );
|
||||
|
||||
if( Req->argc == 1 )
|
||||
{
|
||||
/* Topic erfragen */
|
||||
topic = Channel_Topic( chan );
|
||||
if( *topic ) return IRC_WriteStrClient( from, RPL_TOPIC_MSG, Client_ID( from ), Channel_Name( chan ), topic );
|
||||
else return IRC_WriteStrClient( from, RPL_NOTOPIC_MSG, Client_ID( from ), Channel_Name( chan ));
|
||||
}
|
||||
|
||||
if( strchr( Channel_Modes( chan ), 't' ))
|
||||
{
|
||||
/* Topic Lock. Ist der User ein Channel Operator? */
|
||||
if( ! strchr( Channel_UserModes( chan, from ), 'o' )) return IRC_WriteStrClient( from, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( from ), Channel_Name( chan ));
|
||||
}
|
||||
|
||||
/* Topic setzen */
|
||||
Channel_SetTopic( chan, Req->argv[1] );
|
||||
Log( LOG_DEBUG, "User \"%s\" set topic on \"%s\": %s", Client_Mask( from ), Channel_Name( chan ), Req->argv[1][0] ? Req->argv[1] : "<none>" );
|
||||
|
||||
/* im Channel bekannt machen und an Server weiterleiten */
|
||||
IRC_WriteStrServersPrefix( Client, from, "TOPIC %s :%s", Req->argv[0], Req->argv[1] );
|
||||
IRC_WriteStrChannelPrefix( Client, chan, from, FALSE, "TOPIC %s :%s", Req->argv[0], Req->argv[1] );
|
||||
|
||||
if( Client_Type( Client ) == CLIENT_USER ) return IRC_WriteStrClientPrefix( Client, Client, "TOPIC %s :%s", Req->argv[0], Req->argv[1] );
|
||||
else return CONNECTED;
|
||||
} /* 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 )
|
||||
{
|
||||
CLIENT *from;
|
||||
CHANNEL *chan;
|
||||
CHAR *ptr;
|
||||
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] );
|
||||
|
||||
/* Delete modes which we never want to inherit */
|
||||
Channel_ModeDel( chan, 'l' );
|
||||
Channel_ModeDel( chan, 'k' );
|
||||
|
||||
/* Inform members of this channel */
|
||||
IRC_WriteStrChannelPrefix( Client, chan, from, FALSE, "MODE %s +%s", Req->argv[0], Channel_Modes( chan ));
|
||||
}
|
||||
}
|
||||
else Log( LOG_WARNING, "CHANNELINFO: 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- */
|
||||
33
src/ngircd/irc-channel.h
Normal file
33
src/ngircd/irc-channel.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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-channel.h,v 1.6 2002/12/12 12:23:43 alex Exp $
|
||||
*
|
||||
* IRC channel commands (header)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __irc_channel_h__
|
||||
#define __irc_channel_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_LIST PARAMS((CLIENT *Client, REQUEST *Req ));
|
||||
|
||||
GLOBAL BOOLEAN IRC_CHANINFO PARAMS((CLIENT *Client, REQUEST *Req ));
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* -eof- */
|
||||
879
src/ngircd/irc-info.c
Normal file
879
src/ngircd/irc-info.c
Normal file
@@ -0,0 +1,879 @@
|
||||
/*
|
||||
* 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.8.2.2 2003/01/01 13:46:37 alex Exp $";
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ngircd.h"
|
||||
#include "conn.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;
|
||||
|
||||
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" */
|
||||
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_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 );
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
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] );
|
||||
}
|
||||
}
|
||||
|
||||
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( );
|
||||
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, "%s", 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, "%s", rpl )) return DISCONNECTED;
|
||||
}
|
||||
|
||||
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 ), Conn_SendBytesZip( con ), Conn_SendBytes( con ), Conn_RecvMsg( con ), Conn_RecvBytesZip( 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;
|
||||
}
|
||||
|
||||
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" */
|
||||
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_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 */
|
||||
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 */
|
||||
return IRC_WriteStrClient( Client, RPL_VERSION_MSG, Client_ID( prefix ), PACKAGE, VERSION, NGIRCd_DebugLevel, Conf_ServerName, NGIRCd_VersionAddition( ));
|
||||
} /* 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' )) 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_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 */
|
||||
sprintf( 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] != ':' ) 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 ))
|
||||
{
|
||||
/* Line becomes too long: send it! */
|
||||
if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
|
||||
sprintf( 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 */
|
||||
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, "%s", 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, "%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' )) 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 */
|
||||
|
||||
|
||||
/* -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- */
|
||||
482
src/ngircd/irc-login.c
Normal file
482
src/ngircd/irc-login.c
Normal file
@@ -0,0 +1,482 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Login and logout
|
||||
*/
|
||||
|
||||
|
||||
#include "portab.h"
|
||||
|
||||
static char UNUSED id[] = "$Id: irc-login.c,v 1.27.2.2 2003/01/01 13:46:37 alex Exp $";
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ngircd.h"
|
||||
#include "resolve.h"
|
||||
#include "conf.h"
|
||||
#include "conn.h"
|
||||
#include "client.h"
|
||||
#include "channel.h"
|
||||
#include "log.h"
|
||||
#include "messages.h"
|
||||
#include "parse.h"
|
||||
#include "irc-info.h"
|
||||
#include "irc-write.h"
|
||||
|
||||
#include "exp.h"
|
||||
#include "irc-login.h"
|
||||
|
||||
|
||||
LOCAL BOOLEAN Hello_User PARAMS(( CLIENT *Client ));
|
||||
LOCAL VOID Kill_Nick PARAMS(( CHAR *Nick, CHAR *Reason ));
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_PASS( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
/* Fehler liefern, wenn kein lokaler Client */
|
||||
if( Client_Conn( Client ) <= NONE ) return IRC_WriteStrClient( Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( Client ), Req->command );
|
||||
|
||||
if(( Client_Type( Client ) == CLIENT_UNKNOWN ) && ( Req->argc == 1))
|
||||
{
|
||||
/* noch nicht registrierte unbekannte Verbindung */
|
||||
Log( LOG_DEBUG, "Connection %d: got PASS command ...", Client_Conn( Client ));
|
||||
|
||||
/* Passwort speichern */
|
||||
Client_SetPassword( Client, Req->argv[0] );
|
||||
|
||||
Client_SetType( Client, CLIENT_GOTPASS );
|
||||
return CONNECTED;
|
||||
}
|
||||
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 ))
|
||||
{
|
||||
/* Falsche Anzahl Parameter? */
|
||||
return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
|
||||
}
|
||||
else return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
|
||||
} /* IRC_PASS */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_NICK( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
CLIENT *intr_c, *target, *c;
|
||||
CHAR *modes;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
/* Zumindest BitchX sendet NICK-USER in der falschen Reihenfolge. */
|
||||
#ifndef STRICT_RFC
|
||||
if( Client_Type( Client ) == CLIENT_UNKNOWN || Client_Type( Client ) == CLIENT_GOTPASS || Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTUSER || Client_Type( Client ) == CLIENT_USER || ( Client_Type( Client ) == CLIENT_SERVER && Req->argc == 1 ))
|
||||
#else
|
||||
if( Client_Type( Client ) == CLIENT_UNKNOWN || Client_Type( Client ) == CLIENT_GOTPASS || Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_USER || ( Client_Type( Client ) == CLIENT_SERVER && Req->argc == 1 ))
|
||||
#endif
|
||||
{
|
||||
/* User-Registrierung bzw. Nick-Aenderung */
|
||||
|
||||
/* Falsche Anzahl Parameter? */
|
||||
if( Req->argc != 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
|
||||
|
||||
/* "Ziel-Client" ermitteln */
|
||||
if( Client_Type( Client ) == CLIENT_SERVER )
|
||||
{
|
||||
target = Client_Search( Req->prefix );
|
||||
if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Ist der Client "restricted"? */
|
||||
if( Client_HasMode( Client, 'r' )) return IRC_WriteStrClient( Client, ERR_RESTRICTED_MSG, Client_ID( Client ));
|
||||
target = Client;
|
||||
}
|
||||
|
||||
#ifndef STRICT_RFC
|
||||
/* Wenn der Client zu seinem eigenen Nick wechseln will, so machen
|
||||
* wir nichts. So macht es das Original und mind. Snak hat probleme,
|
||||
* 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 :-) */
|
||||
if( strcasecmp( Client_ID( target ), Req->argv[0] ) != 0 )
|
||||
{
|
||||
if( ! Client_CheckNick( target, Req->argv[0] )) return CONNECTED;
|
||||
}
|
||||
|
||||
if(( Client_Type( target ) != CLIENT_USER ) && ( Client_Type( target ) != CLIENT_SERVER ))
|
||||
{
|
||||
/* Neuer Client */
|
||||
Log( LOG_DEBUG, "Connection %d: got valid NICK command ...", Client_Conn( Client ));
|
||||
|
||||
/* Client-Nick registrieren */
|
||||
Client_SetID( target, Req->argv[0] );
|
||||
|
||||
/* schon ein USER da? Dann registrieren! */
|
||||
if( Client_Type( Client ) == CLIENT_GOTUSER ) return Hello_User( Client );
|
||||
else Client_SetType( Client, CLIENT_GOTNICK );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nick-Aenderung */
|
||||
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] );
|
||||
IRC_WriteStrServersPrefix( Client, target, "NICK :%s", Req->argv[0] );
|
||||
IRC_WriteStrRelatedPrefix( target, target, FALSE, "NICK :%s", Req->argv[0] );
|
||||
|
||||
/* neuen Client-Nick speichern */
|
||||
Client_SetID( target, Req->argv[0] );
|
||||
}
|
||||
|
||||
return CONNECTED;
|
||||
}
|
||||
else if( Client_Type( Client ) == CLIENT_SERVER )
|
||||
{
|
||||
/* Server fuehrt neuen Client ein */
|
||||
|
||||
/* Falsche Anzahl Parameter? */
|
||||
if( Req->argc != 7 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
|
||||
|
||||
/* Nick ueberpruefen */
|
||||
c = Client_Search( Req->argv[0] );
|
||||
if( c )
|
||||
{
|
||||
/* Der neue Nick ist auf diesem Server bereits registriert:
|
||||
* sowohl der neue, als auch der alte Client muessen nun
|
||||
* disconnectiert werden. */
|
||||
Log( LOG_ERR, "Server %s introduces already registered nick \"%s\"!", Client_ID( Client ), Req->argv[0] );
|
||||
Kill_Nick( Req->argv[0], "Nick collision" );
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
/* Server, zu dem der Client connectiert ist, suchen */
|
||||
intr_c = Client_GetFromToken( Client, atoi( Req->argv[4] ));
|
||||
if( ! intr_c )
|
||||
{
|
||||
Log( LOG_ERR, "Server %s introduces nick \"%s\" on unknown server!?", Client_ID( Client ), Req->argv[0] );
|
||||
Kill_Nick( Req->argv[0], "Unknown server" );
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
/* Neue Client-Struktur anlegen */
|
||||
c = Client_NewRemoteUser( intr_c, Req->argv[0], atoi( Req->argv[1] ), Req->argv[2], Req->argv[3], atoi( Req->argv[4] ), Req->argv[5] + 1, Req->argv[6], TRUE );
|
||||
if( ! c )
|
||||
{
|
||||
/* Eine neue Client-Struktur konnte nicht angelegt werden.
|
||||
* Der Client muss disconnectiert werden, damit der Netz-
|
||||
* status konsistent bleibt. */
|
||||
Log( LOG_ALERT, "Can't create client structure! (on connection %d)", Client_Conn( Client ));
|
||||
Kill_Nick( Req->argv[0], "Server error" );
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
modes = Client_Modes( c );
|
||||
if( *modes ) Log( LOG_DEBUG, "User \"%s\" (+%s) registered (via %s, on %s, %d hop%s).", Client_Mask( c ), modes, Client_ID( Client ), Client_ID( intr_c ), Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
|
||||
else Log( LOG_DEBUG, "User \"%s\" registered (via %s, on %s, %d hop%s).", Client_Mask( c ), Client_ID( Client ), Client_ID( intr_c ), Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
|
||||
|
||||
/* Andere Server, ausser dem Introducer, informieren */
|
||||
IRC_WriteStrServersPrefix( Client, Client, "NICK %s %d %s %s %d %s :%s", Req->argv[0], atoi( Req->argv[1] ) + 1, Req->argv[2], Req->argv[3], Client_MyToken( intr_c ), Req->argv[5], Req->argv[6] );
|
||||
|
||||
return CONNECTED;
|
||||
}
|
||||
else return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
|
||||
} /* IRC_NICK */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_USER( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
#ifndef STRICT_RFC
|
||||
if( Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTPASS || Client_Type( Client ) == CLIENT_UNKNOWN )
|
||||
#else
|
||||
if( Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTPASS )
|
||||
#endif
|
||||
{
|
||||
/* Falsche Anzahl Parameter? */
|
||||
if( Req->argc != 4 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
|
||||
|
||||
Client_SetUser( Client, Req->argv[0], FALSE );
|
||||
Client_SetInfo( Client, Req->argv[3] );
|
||||
|
||||
Log( LOG_DEBUG, "Connection %d: got valid USER command ...", Client_Conn( Client ));
|
||||
if( Client_Type( Client ) == CLIENT_GOTNICK ) return Hello_User( Client );
|
||||
else Client_SetType( Client, CLIENT_GOTUSER );
|
||||
return CONNECTED;
|
||||
}
|
||||
else if( Client_Type( Client ) == CLIENT_USER || Client_Type( Client ) == CLIENT_SERVER || Client_Type( Client ) == CLIENT_SERVICE )
|
||||
{
|
||||
return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
|
||||
}
|
||||
else return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
|
||||
} /* IRC_USER */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_QUIT( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
CLIENT *target;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
if ( Client_Type( Client ) == CLIENT_SERVER )
|
||||
{
|
||||
/* Server */
|
||||
|
||||
/* Falsche Anzahl Parameter? */
|
||||
if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
|
||||
|
||||
target = Client_Search( Req->prefix );
|
||||
if( ! target )
|
||||
{
|
||||
/* Den Client kennen wir nicht (mehr), also nichts zu tun. */
|
||||
Log( LOG_WARNING, "Got QUIT from %s for unknown client!?", Client_ID( Client ));
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
if( Req->argc == 0 ) Client_Destroy( target, "Got QUIT command.", NULL, TRUE );
|
||||
else Client_Destroy( target, "Got QUIT command.", Req->argv[0], TRUE );
|
||||
|
||||
return CONNECTED;
|
||||
}
|
||||
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 )
|
||||
{
|
||||
CLIENT *target, *from;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
/* Falsche Anzahl Parameter? */
|
||||
if( Req->argc < 1 ) return IRC_WriteStrClient( Client, ERR_NOORIGIN_MSG, Client_ID( Client ));
|
||||
#ifdef STRICT_RFC
|
||||
if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
|
||||
#endif
|
||||
|
||||
if( Req->argc > 1 )
|
||||
{
|
||||
/* es wurde ein Ziel-Client angegeben */
|
||||
target = Client_Search( 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 */
|
||||
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 );
|
||||
return IRC_WriteStrClientPrefix( target, from, "PING %s :%s", Client_ID( from ), Req->argv[1] );
|
||||
}
|
||||
}
|
||||
|
||||
Log( LOG_DEBUG, "Connection %d: got PING, sending PONG ...", Client_Conn( Client ));
|
||||
return IRC_WriteStrClient( Client, "PONG %s :%s", Client_ID( Client_ThisServer( )), Client_ID( Client ));
|
||||
} /* IRC_PING */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_PONG( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
CLIENT *target, *from;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
/* 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 );
|
||||
|
||||
/* forwarden? */
|
||||
if( Req->argc == 2 )
|
||||
{
|
||||
target = Client_Search( 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 */
|
||||
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 );
|
||||
return IRC_WriteStrClientPrefix( target, from, "PONG %s :%s", Client_ID( from ), Req->argv[1] );
|
||||
}
|
||||
}
|
||||
|
||||
/* Der Connection-Timestamp wurde schon beim Lesen aus dem Socket
|
||||
* aktualisiert, daher muss das hier nicht mehr gemacht werden. */
|
||||
|
||||
if( Client_Conn( Client ) > NONE ) Log( LOG_DEBUG, "Connection %d: received PONG. Lag: %ld seconds.", Client_Conn( Client ), time( NULL ) - Conn_LastPing( Client_Conn( Client )));
|
||||
else Log( LOG_DEBUG, "Connection %d: received PONG.", Client_Conn( Client ));
|
||||
|
||||
return CONNECTED;
|
||||
} /* IRC_PONG */
|
||||
|
||||
|
||||
LOCAL BOOLEAN
|
||||
Hello_User( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
|
||||
/* Passwort ueberpruefen */
|
||||
if( strcmp( Client_Password( Client ), Conf_ServerPwd ) != 0 )
|
||||
{
|
||||
/* Falsches Passwort */
|
||||
Log( LOG_ERR, "User \"%s\" rejected (connection %d): Bad password!", Client_Mask( Client ), Client_Conn( Client ));
|
||||
Conn_Close( Client_Conn( Client ), NULL, "Bad password", TRUE );
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
Log( LOG_NOTICE, "User \"%s\" registered (connection %d).", Client_Mask( Client ), Client_Conn( Client ));
|
||||
|
||||
/* Andere Server informieren */
|
||||
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( )), 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( )), VERSION, USERMODES, CHANMODES )) return FALSE;
|
||||
|
||||
/* Features */
|
||||
if( ! IRC_WriteStrClient( Client, RPL_FEATURE_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;
|
||||
|
||||
return CONNECTED;
|
||||
} /* Hello_User */
|
||||
|
||||
|
||||
LOCAL VOID
|
||||
Kill_Nick( CHAR *Nick, CHAR *Reason )
|
||||
{
|
||||
CLIENT *c;
|
||||
|
||||
assert( Nick != NULL );
|
||||
assert( Reason != NULL );
|
||||
|
||||
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 );
|
||||
} /* Kill_Nick */
|
||||
|
||||
|
||||
/* -eof- */
|
||||
32
src/ngircd/irc-login.h
Normal file
32
src/ngircd/irc-login.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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-login.h,v 1.5 2002/12/12 12:23:43 alex Exp $
|
||||
*
|
||||
* Login and logout (header)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __irc_login_h__
|
||||
#define __irc_login_h__
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
/* -eof- */
|
||||
714
src/ngircd/irc-mode.c
Normal file
714
src/ngircd/irc-mode.c
Normal file
@@ -0,0 +1,714 @@
|
||||
/*
|
||||
* 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 commands for mode changes (MODE, AWAY, ...)
|
||||
*/
|
||||
|
||||
|
||||
#include "portab.h"
|
||||
|
||||
static char UNUSED id[] = "$Id: irc-mode.c,v 1.24.2.5 2003/01/21 21:05:19 alex Exp $";
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "conn.h"
|
||||
#include "client.h"
|
||||
#include "channel.h"
|
||||
#include "defines.h"
|
||||
#include "irc-write.h"
|
||||
#include "lists.h"
|
||||
#include "log.h"
|
||||
#include "parse.h"
|
||||
#include "messages.h"
|
||||
#include "resolve.h"
|
||||
#include "conf.h"
|
||||
|
||||
#include "exp.h"
|
||||
#include "irc-mode.h"
|
||||
|
||||
|
||||
LOCAL BOOLEAN Client_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target ));
|
||||
LOCAL BOOLEAN Channel_Mode PARAMS(( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel ));
|
||||
|
||||
LOCAL BOOLEAN Add_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern ));
|
||||
LOCAL BOOLEAN Add_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern ));
|
||||
|
||||
LOCAL BOOLEAN Del_Invite PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern ));
|
||||
LOCAL BOOLEAN Del_Ban PARAMS(( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern ));
|
||||
|
||||
LOCAL BOOLEAN Send_ListChange PARAMS(( CHAR *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Mask ));
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_MODE( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
CLIENT *cl, *origin;
|
||||
CHANNEL *chan;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
/* No parameters? */
|
||||
if( Req->argc < 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
|
||||
|
||||
/* Origin for answers */
|
||||
if( Client_Type( Client ) == CLIENT_SERVER )
|
||||
{
|
||||
origin = Client_Search( Req->prefix );
|
||||
if( ! origin ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
|
||||
}
|
||||
else origin = Client;
|
||||
|
||||
/* Channel or user mode? */
|
||||
cl = chan = NULL;
|
||||
if( Client_IsValidNick( Req->argv[0] )) cl = Client_Search( Req->argv[0] );
|
||||
if( Channel_IsValidName( Req->argv[0] )) chan = Channel_Search( Req->argv[0] );
|
||||
|
||||
if( cl ) return Client_Mode( Client, Req, origin, cl );
|
||||
if( chan ) return Channel_Mode( Client, Req, origin, chan );
|
||||
|
||||
/* No target found! */
|
||||
return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] );
|
||||
} /* IRC_MODE */
|
||||
|
||||
|
||||
LOCAL BOOLEAN
|
||||
Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
|
||||
{
|
||||
/* Handle client mode requests */
|
||||
|
||||
CHAR the_modes[COMMAND_LEN], x[2], *mode_ptr;
|
||||
BOOLEAN ok, set;
|
||||
INT mode_arg;
|
||||
|
||||
/* Is the client allowed to request or change the modes? */
|
||||
if( Client_Type( Client ) == CLIENT_USER )
|
||||
{
|
||||
/* Users are only allowed to manipulate their own modes! */
|
||||
if( Target != Client ) return IRC_WriteStrClient( Client, ERR_USERSDONTMATCH_MSG, Client_ID( Client ));
|
||||
}
|
||||
|
||||
/* Mode request: let's answer it :-) */
|
||||
if( Req->argc == 1 ) return IRC_WriteStrClient( Origin, RPL_UMODEIS_MSG, Client_ID( Origin ), Client_Modes( Target ));
|
||||
|
||||
mode_arg = 1;
|
||||
mode_ptr = Req->argv[mode_arg];
|
||||
|
||||
/* Initial state: set or unset modes? */
|
||||
if( *mode_ptr == '+' ) set = TRUE;
|
||||
else if( *mode_ptr == '-' ) set = FALSE;
|
||||
else return IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG_MSG, Client_ID( Origin ));
|
||||
|
||||
/* Prepare reply string */
|
||||
if( set ) strcpy( the_modes, "+" );
|
||||
else strcpy( the_modes, "-" );
|
||||
|
||||
x[1] = '\0';
|
||||
ok = CONNECTED;
|
||||
while( mode_ptr )
|
||||
{
|
||||
mode_ptr++;
|
||||
if( ! *mode_ptr )
|
||||
{
|
||||
/* Try next argument if there's any */
|
||||
mode_arg++;
|
||||
if( mode_arg < Req->argc ) mode_ptr = Req->argv[mode_arg];
|
||||
else break;
|
||||
}
|
||||
|
||||
switch( *mode_ptr )
|
||||
{
|
||||
case '+':
|
||||
case '-':
|
||||
if((( *mode_ptr == '+' ) && ( ! set )) || (( *mode_ptr == '-' ) && ( set )))
|
||||
{
|
||||
/* Action modifier ("+"/"-") must be changed ... */
|
||||
if(( the_modes[strlen( the_modes ) - 1] == '+' ) || ( the_modes[strlen( the_modes ) - 1] == '-' ))
|
||||
{
|
||||
/* Adjust last action modifier in result */
|
||||
the_modes[strlen( the_modes ) - 1] = *mode_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Append modifier character to result string */
|
||||
x[0] = *mode_ptr; strcat( the_modes, x );
|
||||
}
|
||||
if( *mode_ptr == '+' ) set = TRUE;
|
||||
else set = FALSE;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Validate modes */
|
||||
x[0] = '\0';
|
||||
switch( *mode_ptr )
|
||||
{
|
||||
case 'a':
|
||||
/* Away */
|
||||
if( Client_Type( Client ) == CLIENT_SERVER )
|
||||
{
|
||||
x[0] = 'a';
|
||||
Client_SetAway( Client, DEFAULT_AWAY_MSG );
|
||||
}
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin ));
|
||||
break;
|
||||
case 'i':
|
||||
/* Invisible */
|
||||
x[0] = 'i';
|
||||
break;
|
||||
case 'o':
|
||||
/* IRC operator (only unsetable!) */
|
||||
if(( ! set ) || ( Client_Type( Client ) == CLIENT_SERVER ))
|
||||
{
|
||||
Client_SetOperByMe( Target, FALSE );
|
||||
x[0] = 'o';
|
||||
}
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin ));
|
||||
break;
|
||||
case 'r':
|
||||
/* Restricted (only setable) */
|
||||
if(( set ) || ( Client_Type( Client ) == CLIENT_SERVER )) x[0] = 'r';
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_RESTRICTED_MSG, Client_ID( Origin ));
|
||||
break;
|
||||
case 's':
|
||||
/* Server messages */
|
||||
x[0] = 's';
|
||||
break;
|
||||
default:
|
||||
Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\"!?", set ? '+' : '-', *mode_ptr, Client_ID( Origin ));
|
||||
if( Client_Type( Client ) != CLIENT_SERVER ) ok = IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Origin ), set ? '+' : '-', *mode_ptr );
|
||||
x[0] = '\0';
|
||||
goto client_exit;
|
||||
}
|
||||
if( ! ok ) break;
|
||||
|
||||
/* Is there a valid mode change? */
|
||||
if( ! x[0] ) continue;
|
||||
|
||||
if( set )
|
||||
{
|
||||
/* Set mode */
|
||||
if( Client_ModeAdd( Target, x[0] )) strcat( the_modes, x );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unset mode */
|
||||
if( Client_ModeDel( Target, x[0] )) strcat( the_modes, x );
|
||||
}
|
||||
}
|
||||
client_exit:
|
||||
|
||||
/* Are there changed modes? */
|
||||
if( the_modes[1] )
|
||||
{
|
||||
/* Remoce needless action modifier characters */
|
||||
if(( the_modes[strlen( the_modes ) - 1] == '+' ) || ( the_modes[strlen( the_modes ) - 1] == '-' )) the_modes[strlen( the_modes ) - 1] = '\0';
|
||||
|
||||
if( Client_Type( Client ) == CLIENT_SERVER )
|
||||
{
|
||||
/* Forward modes to other servers */
|
||||
IRC_WriteStrServersPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Send reply to client and inform other servers */
|
||||
ok = IRC_WriteStrClientPrefix( Client, Origin, "MODE %s %s", Client_ID( Target ), the_modes );
|
||||
IRC_WriteStrServersPrefix( Client, Origin, "MODE %s :%s", Client_ID( Target ), the_modes );
|
||||
}
|
||||
Log( LOG_DEBUG, "User \"%s\": Mode change, now \"%s\".", Client_Mask( Target ), Client_Modes( Target ));
|
||||
}
|
||||
|
||||
return ok;
|
||||
} /* Client_Mode */
|
||||
|
||||
|
||||
LOCAL BOOLEAN
|
||||
Channel_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel )
|
||||
{
|
||||
/* Handle channel and channel-user modes */
|
||||
|
||||
CHAR the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2], argadd[CLIENT_PASS_LEN], *mode_ptr;
|
||||
BOOLEAN ok, set, modeok, skiponce;
|
||||
INT mode_arg, arg_arg;
|
||||
CLIENT *client;
|
||||
LONG l;
|
||||
|
||||
/* Mode request: let's answer it :-) */
|
||||
if( Req->argc == 1 )
|
||||
{
|
||||
/* Member or not? -- That's the question! */
|
||||
if( ! Channel_IsMemberOf( Channel, Origin )) return IRC_WriteStrClient( Origin, RPL_CHANNELMODEIS_MSG, Client_ID( Origin ), Channel_Name( Channel ), Channel_Modes( Channel ));
|
||||
|
||||
/* The sender is a member: generate extended reply */
|
||||
strcpy( the_modes, Channel_Modes( Channel ));
|
||||
mode_ptr = the_modes;
|
||||
strcpy( the_args, "" );
|
||||
while( *mode_ptr )
|
||||
{
|
||||
switch( *mode_ptr )
|
||||
{
|
||||
case 'l':
|
||||
snprintf( argadd, sizeof( argadd ), " %ld", Channel_MaxUsers( Channel ));
|
||||
strcat( the_args, argadd );
|
||||
break;
|
||||
case 'k':
|
||||
strcat( the_args, " " );
|
||||
strcat( the_args, Channel_Key( Channel ));
|
||||
break;
|
||||
}
|
||||
mode_ptr++;
|
||||
}
|
||||
if( the_args[0] ) strcat( the_modes, the_args );
|
||||
|
||||
return IRC_WriteStrClient( Origin, RPL_CHANNELMODEIS_MSG, Client_ID( Origin ), Channel_Name( Channel ), the_modes );
|
||||
}
|
||||
|
||||
/* Is the user allowed to change modes? */
|
||||
if( Client_Type( Client ) == CLIENT_USER )
|
||||
{
|
||||
/* Is the originating user on that channel? */
|
||||
if( ! Channel_IsMemberOf( Channel, Origin )) return IRC_WriteStrClient( Origin, ERR_NOTONCHANNEL_MSG, Client_ID( Origin ), Channel_Name( Channel ));
|
||||
|
||||
/* Is he channel operator? */
|
||||
if( strchr( Channel_UserModes( Channel, Origin ), 'o' )) modeok = TRUE;
|
||||
else modeok = FALSE;
|
||||
if( Conf_OperCanMode )
|
||||
{
|
||||
/* auch IRC-Operatoren duerfen MODE verwenden */
|
||||
if( Client_OperByMe( Origin )) modeok = TRUE;
|
||||
}
|
||||
}
|
||||
else modeok = TRUE;
|
||||
|
||||
mode_arg = 1;
|
||||
mode_ptr = Req->argv[mode_arg];
|
||||
if( Req->argc > mode_arg + 1 ) arg_arg = mode_arg + 1;
|
||||
else arg_arg = -1;
|
||||
|
||||
/* Initial state: set or unset modes? */
|
||||
skiponce = FALSE;
|
||||
if( *mode_ptr == '-' ) set = FALSE;
|
||||
else if( *mode_ptr == '+' ) set = TRUE;
|
||||
else set = skiponce = TRUE;
|
||||
|
||||
/* Prepare reply string */
|
||||
if( set ) strcpy( the_modes, "+" );
|
||||
else strcpy( the_modes, "-" );
|
||||
strcpy( the_args, " " );
|
||||
|
||||
x[1] = '\0';
|
||||
ok = CONNECTED;
|
||||
while( mode_ptr )
|
||||
{
|
||||
if( ! skiponce ) mode_ptr++;
|
||||
if( ! *mode_ptr )
|
||||
{
|
||||
/* Try next argument if there's any */
|
||||
if( arg_arg > mode_arg ) mode_arg = arg_arg;
|
||||
else mode_arg++;
|
||||
if( mode_arg < Req->argc ) mode_ptr = Req->argv[mode_arg];
|
||||
else break;
|
||||
if( Req->argc > mode_arg + 1 ) arg_arg = mode_arg + 1;
|
||||
else arg_arg = -1;
|
||||
}
|
||||
skiponce = FALSE;
|
||||
|
||||
switch( *mode_ptr )
|
||||
{
|
||||
case '+':
|
||||
case '-':
|
||||
if((( *mode_ptr == '+' ) && ( ! set )) || (( *mode_ptr == '-' ) && ( set )))
|
||||
{
|
||||
/* Action modifier ("+"/"-") must be changed ... */
|
||||
if(( the_modes[strlen( the_modes ) - 1] == '+' ) || ( the_modes[strlen( the_modes ) - 1] == '-' ))
|
||||
{
|
||||
/* Adjust last action modifier in result */
|
||||
the_modes[strlen( the_modes ) - 1] = *mode_ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Append modifier character to result string */
|
||||
x[0] = *mode_ptr; strcat( the_modes, x );
|
||||
}
|
||||
if( *mode_ptr == '+' ) set = TRUE;
|
||||
else set = FALSE;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Are there arguments left? */
|
||||
if( arg_arg >= Req->argc ) arg_arg = -1;
|
||||
|
||||
/* Validate modes */
|
||||
x[0] = '\0';
|
||||
argadd[0] = '\0';
|
||||
client = NULL;
|
||||
switch( *mode_ptr )
|
||||
{
|
||||
/* Channel modes */
|
||||
case 'i':
|
||||
/* Invite-Only */
|
||||
if( modeok ) x[0] = 'i';
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
|
||||
break;
|
||||
case 'm':
|
||||
/* Moderated */
|
||||
if( modeok ) x[0] = 'm';
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
|
||||
break;
|
||||
case 'n':
|
||||
/* kein Schreiben in den Channel von aussen */
|
||||
if( modeok ) x[0] = 'n';
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
|
||||
break;
|
||||
case 't':
|
||||
/* Topic Lock */
|
||||
if( modeok ) x[0] = 't';
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
|
||||
break;
|
||||
case 'P':
|
||||
/* Persistent channel */
|
||||
if( modeok )
|
||||
{
|
||||
if( set && ( ! Client_OperByMe( Client )))
|
||||
{
|
||||
/* Only IRC operators are allowed to set P mode */
|
||||
ok = IRC_WriteStrClient( Origin, ERR_NOPRIVILEGES_MSG, Client_ID( Origin ));
|
||||
}
|
||||
else x[0] = 'P';
|
||||
}
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
|
||||
break;
|
||||
|
||||
/* Channel user modes */
|
||||
case 'o':
|
||||
/* Channel operator */
|
||||
case 'v':
|
||||
/* Voice */
|
||||
if( arg_arg > mode_arg )
|
||||
{
|
||||
if( modeok )
|
||||
{
|
||||
client = Client_Search( Req->argv[arg_arg] );
|
||||
if( client ) x[0] = *mode_ptr;
|
||||
else ok = IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[arg_arg] );
|
||||
}
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
|
||||
Req->argv[arg_arg][0] = '\0';
|
||||
arg_arg++;
|
||||
}
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command );
|
||||
break;
|
||||
case 'k':
|
||||
/* Channel key */
|
||||
if( ! set )
|
||||
{
|
||||
if( modeok ) x[0] = *mode_ptr;
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
|
||||
break;
|
||||
}
|
||||
if( arg_arg > mode_arg )
|
||||
{
|
||||
if( modeok )
|
||||
{
|
||||
Channel_ModeDel( Channel, 'k' );
|
||||
Channel_SetKey( Channel, Req->argv[arg_arg] );
|
||||
strcpy( argadd, Channel_Key( Channel ));
|
||||
x[0] = *mode_ptr;
|
||||
}
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
|
||||
Req->argv[arg_arg][0] = '\0';
|
||||
arg_arg++;
|
||||
}
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command );
|
||||
break;
|
||||
case 'l':
|
||||
/* Member limit */
|
||||
if( ! set )
|
||||
{
|
||||
if( modeok ) x[0] = *mode_ptr;
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
|
||||
break;
|
||||
}
|
||||
if( arg_arg > mode_arg )
|
||||
{
|
||||
if( modeok )
|
||||
{
|
||||
l = atol( Req->argv[arg_arg] );
|
||||
if( l > 0 && l < 0xFFFF )
|
||||
{
|
||||
Channel_ModeDel( Channel, 'l' );
|
||||
Channel_SetMaxUsers( Channel, l );
|
||||
sprintf( argadd, "%ld", l );
|
||||
x[0] = *mode_ptr;
|
||||
}
|
||||
}
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
|
||||
Req->argv[arg_arg][0] = '\0';
|
||||
arg_arg++;
|
||||
}
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_NEEDMOREPARAMS_MSG, Client_ID( Origin ), Req->command );
|
||||
break;
|
||||
|
||||
/* Channel lists */
|
||||
case 'I':
|
||||
/* Invite lists */
|
||||
if( arg_arg > mode_arg )
|
||||
{
|
||||
/* modify list */
|
||||
if( modeok )
|
||||
{
|
||||
if( set ) Add_Invite( Origin, Client, Channel, Req->argv[arg_arg] );
|
||||
else Del_Invite( Origin, Client, Channel, Req->argv[arg_arg] );
|
||||
}
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
|
||||
Req->argv[arg_arg][0] = '\0';
|
||||
arg_arg++;
|
||||
}
|
||||
else Lists_ShowInvites( Origin, Channel );
|
||||
break;
|
||||
case 'b':
|
||||
/* Ban lists */
|
||||
if( arg_arg > mode_arg )
|
||||
{
|
||||
/* modify list */
|
||||
if( modeok )
|
||||
{
|
||||
if( set ) Add_Ban( Origin, Client, Channel, Req->argv[arg_arg] );
|
||||
else Del_Ban( Origin, Client, Channel, Req->argv[arg_arg] );
|
||||
}
|
||||
else ok = IRC_WriteStrClient( Origin, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Origin ), Channel_Name( Channel ));
|
||||
Req->argv[arg_arg][0] = '\0';
|
||||
arg_arg++;
|
||||
}
|
||||
else Lists_ShowBans( Origin, Channel );
|
||||
break;
|
||||
|
||||
default:
|
||||
Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\" on %s!?", set ? '+' : '-', *mode_ptr, Client_ID( Origin ), Channel_Name( Channel ));
|
||||
if( Client_Type( Client ) != CLIENT_SERVER ) ok = IRC_WriteStrClient( Origin, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Origin ), set ? '+' : '-', *mode_ptr );
|
||||
x[0] = '\0';
|
||||
goto chan_exit;
|
||||
}
|
||||
if( ! ok ) break;
|
||||
|
||||
/* Is there a valid mode change? */
|
||||
if( ! x[0] ) continue;
|
||||
|
||||
/* Validate target client */
|
||||
if( client && ( ! Channel_IsMemberOf( Channel, client )))
|
||||
{
|
||||
if( ! IRC_WriteStrClient( Origin, ERR_USERNOTINCHANNEL_MSG, Client_ID( Origin ), Client_ID( client ), Channel_Name( Channel ))) break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( set )
|
||||
{
|
||||
/* Set mode */
|
||||
if( client )
|
||||
{
|
||||
/* Channel-User-Mode */
|
||||
if( Channel_UserModeAdd( Channel, client, x[0] ))
|
||||
{
|
||||
strcat( the_args, Client_ID( client ));
|
||||
strcat( the_args, " " ); strcat( the_modes, x );
|
||||
Log( LOG_DEBUG, "User \"%s\": Mode change on %s, now \"%s\"", Client_Mask( client ), Channel_Name( Channel ), Channel_UserModes( Channel, client ));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Channel-Mode */
|
||||
if( Channel_ModeAdd( Channel, x[0] ))
|
||||
{
|
||||
strcat( the_modes, x );
|
||||
Log( LOG_DEBUG, "Channel %s: Mode change, now \"%s\".", Channel_Name( Channel ), Channel_Modes( Channel ));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Unset mode */
|
||||
if( client )
|
||||
{
|
||||
/* Channel-User-Mode */
|
||||
if( Channel_UserModeDel( Channel, client, x[0] ))
|
||||
{
|
||||
strcat( the_args, Client_ID( client ));
|
||||
strcat( the_args, " " ); strcat( the_modes, x );
|
||||
Log( LOG_DEBUG, "User \"%s\": Mode change on %s, now \"%s\"", Client_Mask( client ), Channel_Name( Channel ), Channel_UserModes( Channel, client ));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Channel-Mode */
|
||||
if( Channel_ModeDel( Channel, x[0] ))
|
||||
{
|
||||
strcat( the_modes, x );
|
||||
Log( LOG_DEBUG, "Channel %s: Mode change, now \"%s\".", Channel_Name( Channel ), Channel_Modes( Channel ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Are there additional arguments to add? */
|
||||
if( argadd[0] )
|
||||
{
|
||||
if( the_args[strlen( the_args ) - 1] != ' ' ) strcat( the_args, " " );
|
||||
strcat( the_args, argadd );
|
||||
}
|
||||
}
|
||||
chan_exit:
|
||||
|
||||
/* Are there changed modes? */
|
||||
if( the_modes[1] )
|
||||
{
|
||||
/* Clean up mode string */
|
||||
if(( the_modes[strlen( the_modes ) - 1] == '+' ) || ( the_modes[strlen( the_modes ) - 1] == '-' )) the_modes[strlen( the_modes ) - 1] = '\0';
|
||||
|
||||
/* Clean up argument string if there are none */
|
||||
if( ! the_args[1] ) the_args[0] = '\0';
|
||||
|
||||
if( Client_Type( Client ) == CLIENT_SERVER )
|
||||
{
|
||||
/* Forward mode changes to channel users and other servers */
|
||||
IRC_WriteStrServersPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
|
||||
IRC_WriteStrChannelPrefix( Client, Channel, Origin, FALSE, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Send reply to client and inform other servers and channel users */
|
||||
ok = IRC_WriteStrClientPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
|
||||
IRC_WriteStrServersPrefix( Client, Origin, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
|
||||
IRC_WriteStrChannelPrefix( Client, Channel, Origin, FALSE, "MODE %s %s%s", Channel_Name( Channel ), the_modes, the_args );
|
||||
}
|
||||
}
|
||||
|
||||
return CONNECTED;
|
||||
} /* Channel_Mode */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_AWAY( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
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 == 1 ) && (Req->argv[0][0] ))
|
||||
{
|
||||
/* AWAY setzen */
|
||||
Client_SetAway( Client, Req->argv[0] );
|
||||
Client_ModeAdd( Client, 'a' );
|
||||
IRC_WriteStrServersPrefix( Client, Client, "MODE %s :+a", Client_ID( Client ));
|
||||
return IRC_WriteStrClient( Client, RPL_NOWAWAY_MSG, Client_ID( Client ));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* AWAY loeschen */
|
||||
Client_ModeDel( Client, 'a' );
|
||||
IRC_WriteStrServersPrefix( Client, Client, "MODE %s :-a", Client_ID( Client ));
|
||||
return IRC_WriteStrClient( Client, RPL_UNAWAY_MSG, Client_ID( Client ));
|
||||
}
|
||||
} /* IRC_AWAY */
|
||||
|
||||
|
||||
LOCAL BOOLEAN
|
||||
Add_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern )
|
||||
{
|
||||
CHAR *mask;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Channel != NULL );
|
||||
assert( Pattern != NULL );
|
||||
|
||||
mask = Lists_MakeMask( Pattern );
|
||||
|
||||
if( ! Lists_AddInvited( Prefix, mask, Channel, FALSE )) return CONNECTED;
|
||||
return Send_ListChange( "+I", Prefix, Client, Channel, mask );
|
||||
} /* Add_Invite */
|
||||
|
||||
|
||||
LOCAL BOOLEAN
|
||||
Add_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern )
|
||||
{
|
||||
CHAR *mask;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Channel != NULL );
|
||||
assert( Pattern != NULL );
|
||||
|
||||
mask = Lists_MakeMask( Pattern );
|
||||
|
||||
if( ! Lists_AddBanned( Prefix, mask, Channel )) return CONNECTED;
|
||||
return Send_ListChange( "+b", Prefix, Client, Channel, mask );
|
||||
} /* Add_Ban */
|
||||
|
||||
|
||||
LOCAL BOOLEAN
|
||||
Del_Invite( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern )
|
||||
{
|
||||
CHAR *mask;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Channel != NULL );
|
||||
assert( Pattern != NULL );
|
||||
|
||||
mask = Lists_MakeMask( Pattern );
|
||||
Lists_DelInvited( mask, Channel );
|
||||
return Send_ListChange( "-I", Prefix, Client, Channel, mask );
|
||||
} /* Del_Invite */
|
||||
|
||||
|
||||
LOCAL BOOLEAN
|
||||
Del_Ban( CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Pattern )
|
||||
{
|
||||
CHAR *mask;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Channel != NULL );
|
||||
assert( Pattern != NULL );
|
||||
|
||||
mask = Lists_MakeMask( Pattern );
|
||||
Lists_DelBanned( mask, Channel );
|
||||
return Send_ListChange( "-b", Prefix, Client, Channel, mask );
|
||||
} /* Del_Ban */
|
||||
|
||||
|
||||
LOCAL BOOLEAN
|
||||
Send_ListChange( CHAR *Mode, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel, CHAR *Mask )
|
||||
{
|
||||
/* Bestaetigung an Client schicken & andere Server sowie Channel-User informieren */
|
||||
|
||||
BOOLEAN ok;
|
||||
|
||||
if( Client_Type( Client ) == CLIENT_USER )
|
||||
{
|
||||
/* Bestaetigung an Client */
|
||||
ok = IRC_WriteStrClientPrefix( Client, Prefix, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
|
||||
}
|
||||
else ok = TRUE;
|
||||
|
||||
/* an andere Server */
|
||||
IRC_WriteStrServersPrefix( Client, Prefix, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
|
||||
|
||||
/* und lokale User im Channel */
|
||||
IRC_WriteStrChannelPrefix( Client, Channel, Prefix, FALSE, "MODE %s %s %s", Channel_Name( Channel ), Mode, Mask );
|
||||
|
||||
return ok;
|
||||
} /* Send_ListChange */
|
||||
|
||||
|
||||
/* -eof- */
|
||||
28
src/ngircd/irc-mode.h
Normal file
28
src/ngircd/irc-mode.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-mode.h,v 1.5 2002/12/12 12:23:43 alex Exp $
|
||||
*
|
||||
* IRC commands for mode changes (header)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __irc_mode_h__
|
||||
#define __irc_mode_h__
|
||||
|
||||
|
||||
GLOBAL BOOLEAN IRC_MODE PARAMS((CLIENT *Client, REQUEST *Req ));
|
||||
GLOBAL BOOLEAN IRC_AWAY PARAMS((CLIENT *Client, REQUEST *Req ));
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* -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- */
|
||||
153
src/ngircd/irc-oper.c
Normal file
153
src/ngircd/irc-oper.c
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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 operator commands
|
||||
*/
|
||||
|
||||
|
||||
#include "portab.h"
|
||||
|
||||
static char UNUSED id[] = "$Id: irc-oper.c,v 1.13 2002/12/12 12:33:14 alex Exp $";
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ngircd.h"
|
||||
#include "resolve.h"
|
||||
#include "conf.h"
|
||||
#include "conn.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 )
|
||||
{
|
||||
INT i;
|
||||
|
||||
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 );
|
||||
|
||||
/* Operator suchen */
|
||||
for( i = 0; i < Conf_Oper_Count; i++)
|
||||
{
|
||||
if( Conf_Oper[i].name[0] && Conf_Oper[i].pwd[0] && ( strcmp( Conf_Oper[i].name, Req->argv[0] ) == 0 )) break;
|
||||
}
|
||||
if( i >= Conf_Oper_Count )
|
||||
{
|
||||
Log( LOG_WARNING, "Got invalid OPER from \"%s\": Name \"%s\" not configured!", Client_Mask( Client ), Req->argv[0] );
|
||||
return IRC_WriteStrClient( Client, ERR_PASSWDMISMATCH_MSG, Client_ID( Client ));
|
||||
}
|
||||
|
||||
/* Stimmt das Passwort? */
|
||||
if( strcmp( Conf_Oper[i].pwd, Req->argv[1] ) != 0 )
|
||||
{
|
||||
Log( LOG_WARNING, "Got invalid OPER from \"%s\": Bad password for \"%s\"!", Client_Mask( Client ), Conf_Oper[i].name );
|
||||
return IRC_WriteStrClient( Client, ERR_PASSWDMISMATCH_MSG, Client_ID( Client ));
|
||||
}
|
||||
|
||||
if( ! Client_HasMode( Client, 'o' ))
|
||||
{
|
||||
/* noch kein o-Mode gesetzt */
|
||||
Client_ModeAdd( Client, 'o' );
|
||||
if( ! IRC_WriteStrClient( Client, "MODE %s :+o", Client_ID( Client ))) return DISCONNECTED;
|
||||
IRC_WriteStrServersPrefix( NULL, Client, "MODE %s :+o", Client_ID( Client ));
|
||||
}
|
||||
|
||||
if( ! Client_OperByMe( Client )) Log( LOG_NOTICE|LOG_snotice, "Got valid OPER from \"%s\", user is an IRC operator now.", Client_Mask( Client ));
|
||||
|
||||
Client_SetOperByMe( Client, TRUE );
|
||||
return IRC_WriteStrClient( Client, RPL_YOUREOPER_MSG, Client_ID( Client ));
|
||||
} /* IRC_OPER */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_DIE( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
/* Falsche Anzahl Parameter? */
|
||||
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;
|
||||
return CONNECTED;
|
||||
} /* IRC_DIE */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_REHASH( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
/* Falsche Anzahl Parameter? */
|
||||
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 REHASH command from \"%s\", re-reading configuration ...", Client_Mask( Client ));
|
||||
NGIRCd_Rehash( );
|
||||
|
||||
return CONNECTED;
|
||||
} /* IRC_REHASH */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_RESTART( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
/* Falsche Anzahl Parameter? */
|
||||
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 RESTART command from \"%s\", going down!", Client_Mask( Client ));
|
||||
NGIRCd_Restart = TRUE;
|
||||
return CONNECTED;
|
||||
} /* IRC_RESTART */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_CONNECT(CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
/* Vorlaeufige Version zu Debug-Zwecken: es wird einfach
|
||||
* der "passive mode" aufgehoben, mehr passiert nicht ... */
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
/* Falsche Anzahl Parameter? */
|
||||
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 CONNECT command from \"%s\".", Client_Mask( Client ));
|
||||
NGIRCd_Passive = FALSE;
|
||||
return CONNECTED;
|
||||
} /* IRC_CONNECT */
|
||||
|
||||
|
||||
/* -eof- */
|
||||
31
src/ngircd/irc-oper.h
Normal file
31
src/ngircd/irc-oper.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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-oper.h,v 1.9 2002/12/12 12:23:43 alex Exp $
|
||||
*
|
||||
* IRC operator commands (header)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __irc_oper_h__
|
||||
#define __irc_oper_h__
|
||||
|
||||
|
||||
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 ));
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* -eof- */
|
||||
383
src/ngircd/irc-server.c
Normal file
383
src/ngircd/irc-server.c
Normal file
@@ -0,0 +1,383 @@
|
||||
/*
|
||||
* 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 commands for server links
|
||||
*/
|
||||
|
||||
|
||||
#include "portab.h"
|
||||
|
||||
static char UNUSED id[] = "$Id: irc-server.c,v 1.24 2002/12/12 12:24:18 alex Exp $";
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "resolve.h"
|
||||
#include "conf.h"
|
||||
#include "conn.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 )
|
||||
{
|
||||
CHAR str[LINE_LEN], *ptr;
|
||||
CLIENT *from, *c, *cl;
|
||||
CL2CHAN *cl2chan;
|
||||
INT max_hops, i;
|
||||
CHANNEL *chan;
|
||||
BOOLEAN ok;
|
||||
CONN_ID con;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Req != NULL );
|
||||
|
||||
/* Fehler liefern, wenn kein lokaler Client */
|
||||
if( Client_Conn( Client ) <= NONE ) return IRC_WriteStrClient( Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( Client ), Req->command );
|
||||
|
||||
if( Client_Type( Client ) == CLIENT_GOTPASSSERVER )
|
||||
{
|
||||
/* Verbindung soll als Server-Server-Verbindung registriert werden */
|
||||
Log( LOG_DEBUG, "Connection %d: got SERVER command (new server link) ...", Client_Conn( Client ));
|
||||
|
||||
/* Falsche Anzahl Parameter? */
|
||||
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 )
|
||||
{
|
||||
/* 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_in ) != 0 )
|
||||
{
|
||||
/* Falsches Passwort */
|
||||
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;
|
||||
}
|
||||
|
||||
/* Ist ein Server mit dieser ID bereits registriert? */
|
||||
if( ! Client_CheckID( Client, Req->argv[0] )) return DISCONNECTED;
|
||||
|
||||
/* Server-Strukturen fuellen ;-) */
|
||||
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 (d.h., bauen nicht wir
|
||||
* selber die Verbindung zu einem anderen Server auf)? */
|
||||
con = Client_Conn( Client );
|
||||
if( Client_Token( Client ) != TOKEN_OUTBOUND )
|
||||
{
|
||||
/* Eingehende Verbindung: Unseren SERVER- und PASS-Befehl senden */
|
||||
ok = TRUE;
|
||||
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( con, "Unexpected server behavior!", NULL, FALSE );
|
||||
return DISCONNECTED;
|
||||
}
|
||||
Client_SetIntroducer( Client, Client );
|
||||
Client_SetToken( Client, 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 ), con );
|
||||
|
||||
Client_SetType( Client, CLIENT_SERVER );
|
||||
Conn_SetServer( con, i );
|
||||
|
||||
#ifdef USE_ZLIB
|
||||
/* Kompression initialisieren, wenn erforderlich */
|
||||
if( strchr( Client_Flags( Client ), 'Z' ))
|
||||
{
|
||||
if( ! Conn_InitZip( con ))
|
||||
{
|
||||
/* Fehler! */
|
||||
Conn_Close( con, "Can't inizialize compression (zlib)!", NULL, FALSE );
|
||||
return DISCONNECTED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* maximalen Hop Count ermitteln */
|
||||
max_hops = 0;
|
||||
c = Client_First( );
|
||||
while( c )
|
||||
{
|
||||
if( Client_Hops( c ) > max_hops ) max_hops = Client_Hops( c );
|
||||
c = Client_Next( c );
|
||||
}
|
||||
|
||||
/* Alle bisherigen Server dem neuen Server bekannt machen,
|
||||
* die bisherigen Server ueber den neuen informierenn */
|
||||
for( i = 0; i < ( max_hops + 1 ); i++ )
|
||||
{
|
||||
c = Client_First( );
|
||||
while( c )
|
||||
{
|
||||
if(( Client_Type( c ) == CLIENT_SERVER ) && ( c != Client ) && ( c != Client_ThisServer( )) && ( Client_Hops( c ) == i ))
|
||||
{
|
||||
if( Client_Conn( c ) > NONE )
|
||||
{
|
||||
/* Dem gefundenen Server gleich den neuen
|
||||
* Server bekannt machen */
|
||||
if( ! IRC_WriteStrClient( c, "SERVER %s %d %d :%s", Client_ID( Client ), Client_Hops( Client ) + 1, Client_MyToken( Client ), Client_Info( Client ))) return DISCONNECTED;
|
||||
}
|
||||
|
||||
/* Den neuen Server ueber den alten informieren */
|
||||
if( ! IRC_WriteStrClientPrefix( Client, Client_Hops( c ) == 1 ? Client_ThisServer( ) : Client_Introducer( c ), "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ))) return DISCONNECTED;
|
||||
}
|
||||
c = Client_Next( c );
|
||||
}
|
||||
}
|
||||
|
||||
/* alle User dem neuen Server bekannt machen */
|
||||
c = Client_First( );
|
||||
while( c )
|
||||
{
|
||||
if( Client_Type( c ) == CLIENT_USER )
|
||||
{
|
||||
/* User an neuen Server melden */
|
||||
if( ! IRC_WriteStrClient( Client, "NICK %s %d %s %s %d +%s :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_User( c ), Client_Hostname( c ), Client_MyToken( Client_Introducer( c )), Client_Modes( c ), Client_Info( c ))) return DISCONNECTED;
|
||||
}
|
||||
c = Client_Next( c );
|
||||
}
|
||||
|
||||
/* Channels dem neuen Server bekannt machen */
|
||||
chan = Channel_First( );
|
||||
while( chan )
|
||||
{
|
||||
#ifdef IRCPLUS
|
||||
/* Wenn unterstuetzt, CHANINFO senden */
|
||||
if( strchr( Client_Flags( Client ), 'C' ))
|
||||
{
|
||||
/* CHANINFO senden */
|
||||
if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s :%s", Channel_Name( chan ), Channel_Modes( chan ), Channel_Topic( chan ))) return DISCONNECTED;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* alle Member suchen */
|
||||
cl2chan = Channel_FirstMember( chan );
|
||||
sprintf( 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( strlen( str ) > ( LINE_LEN - CLIENT_NICK_LEN - 8 ))
|
||||
{
|
||||
/* Zeile senden */
|
||||
if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
|
||||
sprintf( str, "NJOIN %s :", Channel_Name( chan ));
|
||||
}
|
||||
|
||||
cl2chan = Channel_NextMember( chan, cl2chan );
|
||||
}
|
||||
|
||||
/* noch Daten da? */
|
||||
if( str[strlen( str ) - 1] != ':')
|
||||
{
|
||||
/* Ja; Also senden ... */
|
||||
if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
|
||||
}
|
||||
|
||||
/* naechsten Channel suchen */
|
||||
chan = Channel_Next( chan );
|
||||
}
|
||||
|
||||
return CONNECTED;
|
||||
}
|
||||
else if( Client_Type( Client ) == CLIENT_SERVER )
|
||||
{
|
||||
/* Neuer Server wird im Netz angekuendigt */
|
||||
|
||||
/* Falsche Anzahl Parameter? */
|
||||
if( Req->argc != 4 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
|
||||
|
||||
/* Ist ein Server mit dieser ID bereits registriert? */
|
||||
if( ! Client_CheckID( Client, Req->argv[0] )) return DISCONNECTED;
|
||||
|
||||
/* Ueberfluessige Hostnamen aus Info-Text entfernen */
|
||||
ptr = strchr( Req->argv[3] + 2, '[' );
|
||||
if( ! ptr ) ptr = Req->argv[3];
|
||||
|
||||
from = Client_Search( Req->prefix );
|
||||
if( ! from )
|
||||
{
|
||||
/* Hm, Server, der diesen einfuehrt, ist nicht bekannt!? */
|
||||
Log( LOG_ALERT, "Unknown ID in prefix of SERVER: \"%s\"! (on connection %d)", Req->prefix, Client_Conn( Client ));
|
||||
Conn_Close( Client_Conn( Client ), NULL, "Unknown ID in prefix of SERVER", TRUE );
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
/* Neue Client-Struktur anlegen */
|
||||
c = Client_NewRemoteServer( Client, Req->argv[0], from, atoi( Req->argv[1] ), atoi( Req->argv[2] ), ptr, TRUE );
|
||||
if( ! c )
|
||||
{
|
||||
/* Neue Client-Struktur konnte nicht angelegt werden */
|
||||
Log( LOG_ALERT, "Can't create client structure for server! (on connection %d)", Client_Conn( Client ));
|
||||
Conn_Close( Client_Conn( Client ), NULL, "Can't allocate client structure for remote server", TRUE );
|
||||
return DISCONNECTED;
|
||||
}
|
||||
|
||||
/* Log-Meldung zusammenbauen und ausgeben */
|
||||
if(( Client_Hops( c ) > 1 ) && ( Req->prefix[0] )) sprintf( 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": "" );
|
||||
|
||||
/* Andere Server informieren */
|
||||
IRC_WriteStrServersPrefix( Client, from, "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ));
|
||||
|
||||
return CONNECTED;
|
||||
}
|
||||
else return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
|
||||
} /* IRC_SERVER */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_NJOIN( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
CHAR str[COMMAND_LEN], *channame, *ptr, modes[8];
|
||||
BOOLEAN is_op, is_voiced;
|
||||
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 );
|
||||
|
||||
strncpy( str, Req->argv[1], COMMAND_LEN - 1 );
|
||||
str[COMMAND_LEN - 1] = '\0';
|
||||
|
||||
channame = Req->argv[0];
|
||||
ptr = strtok( str, "," );
|
||||
while( ptr )
|
||||
{
|
||||
is_op = is_voiced = FALSE;
|
||||
|
||||
/* Prefixe abschneiden */
|
||||
while(( *ptr == '@' ) || ( *ptr == '+' ))
|
||||
{
|
||||
if( *ptr == '@' ) is_op = TRUE;
|
||||
if( *ptr == '+' ) is_voiced = TRUE;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
c = Client_Search( ptr );
|
||||
if( c )
|
||||
{
|
||||
Channel_Join( c, channame );
|
||||
chan = Channel_Search( channame );
|
||||
assert( chan != NULL );
|
||||
|
||||
if( is_op ) Channel_UserModeAdd( chan, c, 'o' );
|
||||
if( is_voiced ) Channel_UserModeAdd( chan, c, 'v' );
|
||||
|
||||
/* im Channel bekannt machen */
|
||||
IRC_WriteStrChannelPrefix( Client, chan, c, FALSE, "JOIN :%s", channame );
|
||||
|
||||
/* Channel-User-Modes setzen */
|
||||
strcpy( modes, Channel_UserModes( chan, c ));
|
||||
if( modes[0] )
|
||||
{
|
||||
/* Modes im Channel bekannt machen */
|
||||
IRC_WriteStrChannelPrefix( Client, chan, Client, FALSE, "MODE %s +%s %s", channame, modes, Client_ID( c ));
|
||||
}
|
||||
}
|
||||
else Log( LOG_ERR, "Got NJOIN for unknown nick \"%s\" for channel \"%s\"!", ptr, channame );
|
||||
|
||||
/* naechsten Nick suchen */
|
||||
ptr = strtok( NULL, "," );
|
||||
}
|
||||
|
||||
/* an andere Server weiterleiten */
|
||||
IRC_WriteStrServersPrefix( Client, Client_ThisServer( ), "NJOIN %s :%s", Req->argv[0], Req->argv[1] );
|
||||
|
||||
return CONNECTED;
|
||||
} /* IRC_NJOIN */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN
|
||||
IRC_SQUIT( CLIENT *Client, REQUEST *Req )
|
||||
{
|
||||
CLIENT *target;
|
||||
CHAR msg[LINE_LEN + 64];
|
||||
|
||||
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 );
|
||||
|
||||
Log( LOG_DEBUG, "Got SQUIT from %s for \"%s\": \"%s\" ...", Client_ID( Client ), Req->argv[0], Req->argv[1] );
|
||||
|
||||
target = Client_Search( Req->argv[0] );
|
||||
if( ! target )
|
||||
{
|
||||
/* Den Server kennen wir nicht (mehr), also nichts zu tun. */
|
||||
Log( LOG_WARNING, "Got SQUIT from %s for unknown server \"%s\"!?", Client_ID( Client ), Req->argv[0] );
|
||||
return CONNECTED;
|
||||
}
|
||||
|
||||
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 ));
|
||||
}
|
||||
else sprintf( msg, "Got SQUIT from %s.", Client_ID( Client ));
|
||||
|
||||
if( Client_Conn( target ) > NONE )
|
||||
{
|
||||
/* dieser Server hat die Connection */
|
||||
if( Req->argv[1][0] ) Conn_Close( Client_Conn( target ), msg, Req->argv[1], TRUE );
|
||||
else Conn_Close( Client_Conn( target ), msg, NULL, TRUE );
|
||||
return DISCONNECTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Verbindung hielt anderer Server */
|
||||
Client_Destroy( target, msg, Req->argv[1], FALSE );
|
||||
return CONNECTED;
|
||||
}
|
||||
} /* IRC_SQUIT */
|
||||
|
||||
|
||||
/* -eof- */
|
||||
29
src/ngircd/irc-server.h
Normal file
29
src/ngircd/irc-server.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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-server.h,v 1.4 2002/12/12 12:23:43 alex Exp $
|
||||
*
|
||||
* IRC commands for server links (header)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __irc_server_h__
|
||||
#define __irc_server_h__
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
/* -eof- */
|
||||
409
src/ngircd/irc-write.c
Normal file
409
src/ngircd/irc-write.c
Normal file
@@ -0,0 +1,409 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* Sending IRC commands over the network
|
||||
*/
|
||||
|
||||
|
||||
#include "portab.h"
|
||||
|
||||
static char UNUSED id[] = "$Id: irc-write.c,v 1.13 2002/12/12 12:24:18 alex Exp $";
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "conn.h"
|
||||
#include "client.h"
|
||||
#include "channel.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include "exp.h"
|
||||
#include "irc-write.h"
|
||||
|
||||
|
||||
#define SEND_TO_USER 1
|
||||
#define SEND_TO_SERVER 2
|
||||
|
||||
|
||||
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;
|
||||
va_list ap;
|
||||
|
||||
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( ), "%s", buffer );
|
||||
|
||||
return ok;
|
||||
} /* IRC_WriteStrClient */
|
||||
|
||||
|
||||
#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. */
|
||||
|
||||
CHAR buffer[1000];
|
||||
va_list ap;
|
||||
|
||||
assert( Client != NULL );
|
||||
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 );
|
||||
|
||||
return Conn_WriteStr( Client_Conn( Client_NextHop( Client )), ":%s %s", Get_Prefix( Client_NextHop( Client ), Prefix ), buffer );
|
||||
} /* IRC_WriteStrClientPrefix */
|
||||
|
||||
|
||||
#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;
|
||||
|
||||
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, "%s", buffer );
|
||||
} /* IRC_WriteStrChannel */
|
||||
|
||||
|
||||
#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 ok = CONNECTED;
|
||||
CHAR buffer[1000];
|
||||
CL2CHAN *cl2chan;
|
||||
CONN_ID conn;
|
||||
CLIENT *c;
|
||||
va_list ap;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Chan != 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 );
|
||||
|
||||
Conn_ClearFlags( );
|
||||
|
||||
/* An alle Clients, die in den selben Channels sind.
|
||||
* Dabei aber nur einmal je Remote-Server */
|
||||
cl2chan = Channel_FirstMember( Chan );
|
||||
while( cl2chan )
|
||||
{
|
||||
c = Channel_GetClient( cl2chan );
|
||||
if( ! Remote )
|
||||
{
|
||||
if( Client_Conn( c ) <= NONE ) c = NULL;
|
||||
else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
|
||||
}
|
||||
if( c ) c = Client_NextHop( c );
|
||||
|
||||
if( c && ( c != Client ))
|
||||
{
|
||||
/* Ok, anderer Client */
|
||||
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: alle Verbindungen durchgehen ... */
|
||||
conn = Conn_First( );
|
||||
while( conn != NONE )
|
||||
{
|
||||
/* 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 */
|
||||
|
||||
|
||||
#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 */
|
||||
IRC_WriteStrServersPrefix( ExceptOf, Client_ThisServer( ), "%s", buffer );
|
||||
} /* IRC_WriteStrServers */
|
||||
|
||||
|
||||
#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;
|
||||
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 );
|
||||
|
||||
c = Client_First( );
|
||||
while( c )
|
||||
{
|
||||
if(( Client_Type( c ) == CLIENT_SERVER ) && ( Client_Conn( c ) > NONE ) && ( c != Client_ThisServer( )) && ( c != ExceptOf ))
|
||||
{
|
||||
/* 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_WriteStrServersPrefixFlag */
|
||||
|
||||
|
||||
#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 ok = CONNECTED;
|
||||
CL2CHAN *chan_cl2chan, *cl2chan;
|
||||
CHAR buffer[1000];
|
||||
CHANNEL *chan;
|
||||
CONN_ID conn;
|
||||
va_list ap;
|
||||
CLIENT *c;
|
||||
|
||||
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 */
|
||||
Conn_ClearFlags( );
|
||||
|
||||
/* An alle Clients, die in einem Channel mit dem "Ausloeser" sind,
|
||||
* den Text schicken. An Remote-Server aber jeweils nur einmal. */
|
||||
chan_cl2chan = Channel_FirstChannelOf( Client );
|
||||
while( chan_cl2chan )
|
||||
{
|
||||
/* Channel des Users durchsuchen */
|
||||
chan = Channel_GetChannel( chan_cl2chan );
|
||||
cl2chan = Channel_FirstMember( chan );
|
||||
while( cl2chan )
|
||||
{
|
||||
c = Channel_GetClient( cl2chan );
|
||||
if( ! Remote )
|
||||
{
|
||||
if( Client_Conn( c ) <= NONE ) c = NULL;
|
||||
else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
|
||||
}
|
||||
if( c ) c = Client_NextHop( c );
|
||||
|
||||
if( c && ( c != Client ))
|
||||
{
|
||||
/* Ok, anderer Client */
|
||||
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 );
|
||||
}
|
||||
|
||||
/* naechsten Channel */
|
||||
chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan );
|
||||
}
|
||||
|
||||
/* Senden: alle Verbindungen durchgehen ... */
|
||||
conn = Conn_First( );
|
||||
while( conn != NONE )
|
||||
{
|
||||
/* 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 )
|
||||
{
|
||||
assert( Target != NULL );
|
||||
assert( Client != NULL );
|
||||
|
||||
if( Client_Type( Target ) == CLIENT_SERVER ) return Client_ID( Client );
|
||||
else return Client_Mask( Client );
|
||||
} /* Get_Prefix */
|
||||
|
||||
|
||||
/* -eof- */
|
||||
37
src/ngircd/irc-write.h
Normal file
37
src/ngircd/irc-write.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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-write.h,v 1.5 2002/12/12 12:23:43 alex Exp $
|
||||
*
|
||||
* Sending IRC commands over the network (header)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __irc_write_h__
|
||||
#define __irc_write_h__
|
||||
|
||||
|
||||
GLOBAL BOOLEAN IRC_WriteStrClient PARAMS((CLIENT *Client, CHAR *Format, ... ));
|
||||
GLOBAL BOOLEAN IRC_WriteStrClientPrefix PARAMS((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 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 BOOLEAN IRC_WriteStrRelatedPrefix PARAMS((CLIENT *Client, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... ));
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* -eof- */
|
||||
1809
src/ngircd/irc.c
1809
src/ngircd/irc.c
File diff suppressed because it is too large
Load Diff
137
src/ngircd/irc.h
137
src/ngircd/irc.h
@@ -2,141 +2,26 @@
|
||||
* 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.21 2002/01/27 21:53:57 alex Exp $
|
||||
* $Id: irc.h,v 1.36 2002/12/12 12:23:43 alex Exp $
|
||||
*
|
||||
* irc.h: IRC-Befehle (Header)
|
||||
*
|
||||
* $Log: irc.h,v $
|
||||
* Revision 1.21 2002/01/27 21:53:57 alex
|
||||
* - IRC_WriteStrServersPrefixID() und IRC_WriteStrClientPrefixID() wieder entfernt.
|
||||
*
|
||||
* Revision 1.20 2002/01/27 17:15:49 alex
|
||||
* - anderungen an den Funktions-Prototypen von IRC_WriteStrChannel() und
|
||||
* IRC_WriteStrChannelPrefix(),
|
||||
* - neue: IRC_WriteStrClientPrefixID() und IRC_WriteStrServersPrefixID().
|
||||
*
|
||||
* Revision 1.19 2002/01/26 18:43:11 alex
|
||||
* - neue Funktionen IRC_WriteStrChannelPrefix() und IRC_WriteStrChannel(),
|
||||
* die IRC_Write_xxx_Related() sind dafuer entfallen.
|
||||
* - IRC_PRIVMSG() kann nun auch mit Channels als Ziel umgehen.
|
||||
*
|
||||
* Revision 1.18 2002/01/21 00:04:13 alex
|
||||
* - neue Funktionen IRC_JOIN, IRC_PART, IRC_WriteStrRelatedPrefix und
|
||||
* IRC_WriteStrRelatedChannelPrefix().
|
||||
*
|
||||
* Revision 1.17 2002/01/11 23:50:55 alex
|
||||
* - LINKS implementiert, LUSERS begonnen.
|
||||
*
|
||||
* Revision 1.16 2002/01/05 19:15:03 alex
|
||||
* - Fehlerpruefung bei select() in der "Hauptschleife" korrigiert.
|
||||
*
|
||||
* Revision 1.15 2002/01/04 17:58:21 alex
|
||||
* - IRC_WriteStrXXX()-Funktionen angepasst; neuer Befehl SQUIT.
|
||||
*
|
||||
* Revision 1.14 2002/01/03 02:26:07 alex
|
||||
* - neue Befehle SERVER und NJOIN begonnen.
|
||||
*
|
||||
* Revision 1.13 2002/01/02 02:51:39 alex
|
||||
* - Copyright-Texte angepasst.
|
||||
* - neuer Befehl "ERROR".
|
||||
*
|
||||
* Revision 1.11 2001/12/31 15:33:13 alex
|
||||
* - neuer Befehl NAMES, kleinere Bugfixes.
|
||||
* - Bug bei PING behoben: war zu restriktiv implementiert :-)
|
||||
*
|
||||
* Revision 1.10 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.9 2001/12/29 03:09:31 alex
|
||||
* - Neue Funktion IRC_MODE() implementiert.
|
||||
*
|
||||
* Revision 1.8 2001/12/27 19:17:26 alex
|
||||
* - neue Befehle PRIVMSG, NOTICE, PING.
|
||||
*
|
||||
* Revision 1.7 2001/12/27 16:55:41 alex
|
||||
* - neu: IRC_WriteStrRelated(), Aenderungen auch in IRC_WriteStrClient().
|
||||
*
|
||||
* Revision 1.6 2001/12/26 14:45:37 alex
|
||||
* - "Code Cleanups".
|
||||
*
|
||||
* Revision 1.5 2001/12/26 03:21:46 alex
|
||||
* - PING/PONG-Befehle implementiert,
|
||||
* - Meldungen ueberarbeitet: enthalten nun (fast) immer den Nick.
|
||||
*
|
||||
* Revision 1.4 2001/12/25 22:02:42 alex
|
||||
* - neuer IRC-Befehl "/QUIT". Verbessertes Logging & Debug-Ausgaben.
|
||||
*
|
||||
* Revision 1.3 2001/12/25 19:19:30 alex
|
||||
* - bessere Fehler-Abfragen, diverse Bugfixes.
|
||||
* - Nicks werden nur einmal vergeben :-)
|
||||
* - /MOTD wird unterstuetzt.
|
||||
*
|
||||
* Revision 1.2 2001/12/23 21:57:16 alex
|
||||
* - erste IRC-Befehle zu implementieren begonnen.
|
||||
*
|
||||
* Revision 1.1 2001/12/14 08:13:43 alex
|
||||
* - neues Modul begonnen :-)
|
||||
* IRC commands (header)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __irc_h__
|
||||
#define __irc_h__
|
||||
|
||||
#include "parse.h"
|
||||
#include "channel.h"
|
||||
|
||||
|
||||
GLOBAL VOID IRC_Init( VOID );
|
||||
GLOBAL VOID IRC_Exit( VOID );
|
||||
|
||||
GLOBAL BOOLEAN IRC_WriteStrClient( CLIENT *Client, CHAR *Format, ... );
|
||||
GLOBAL BOOLEAN IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, 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( CLIENT *ExceptOf, CHAR *Format, ... );
|
||||
GLOBAL VOID IRC_WriteStrServersPrefix( CLIENT *ExceptOf, CLIENT *Prefix, CHAR *Format, ... );
|
||||
|
||||
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_SERVER( CLIENT *Client, REQUEST *Req );
|
||||
GLOBAL BOOLEAN IRC_NJOIN( 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_SQUIT( CLIENT *Client, REQUEST *Req );
|
||||
|
||||
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_PRIVMSG( CLIENT *Client, REQUEST *Req );
|
||||
GLOBAL BOOLEAN IRC_NOTICE( CLIENT *Client, REQUEST *Req );
|
||||
|
||||
GLOBAL BOOLEAN IRC_MODE( 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_OPER( CLIENT *Client, REQUEST *Req );
|
||||
GLOBAL BOOLEAN IRC_DIE( CLIENT *Client, REQUEST *Req );
|
||||
GLOBAL BOOLEAN IRC_RESTART( CLIENT *Client, REQUEST *Req );
|
||||
|
||||
GLOBAL BOOLEAN IRC_ERROR( CLIENT *Client, REQUEST *Req );
|
||||
|
||||
GLOBAL BOOLEAN IRC_JOIN( CLIENT *Client, REQUEST *Req );
|
||||
GLOBAL BOOLEAN IRC_PART( CLIENT *Client, REQUEST *Req );
|
||||
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 ));
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
447
src/ngircd/lists.c
Normal file
447
src/ngircd/lists.c
Normal file
@@ -0,0 +1,447 @@
|
||||
/*
|
||||
* 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.10 2002/12/12 12:24:18 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 @<40>vorhanden: als Nick annehmen */
|
||||
strncpy( TheMask, Pattern, MASK_LEN - 5 );
|
||||
TheMask[MASK_LEN - 5] = '\0';
|
||||
strcat( TheMask, "!*@*" );
|
||||
return TheMask;
|
||||
}
|
||||
|
||||
if(( ! at ) && ( excl ))
|
||||
{
|
||||
/* Domain fehlt */
|
||||
strncpy( TheMask, Pattern, MASK_LEN - 3 );
|
||||
TheMask[MASK_LEN - 3] = '\0';
|
||||
strcat( TheMask, "@*" );
|
||||
return TheMask;
|
||||
}
|
||||
|
||||
if(( at ) && ( ! excl ))
|
||||
{
|
||||
/* User fehlt */
|
||||
*at = '\0'; at++;
|
||||
strncpy( TheMask, Pattern, MASK_LEN - 4 );
|
||||
TheMask[MASK_LEN - 4] = '\0';
|
||||
strcat( TheMask, "!*@" );
|
||||
strncat( TheMask, at, strlen( TheMask ) - MASK_LEN - 1 );
|
||||
TheMask[MASK_LEN - 1] = '\0';
|
||||
return TheMask;
|
||||
}
|
||||
|
||||
/* alle Teile vorhanden */
|
||||
strncpy( TheMask, Pattern, MASK_LEN - 1 );
|
||||
TheMask[MASK_LEN - 1] = '\0';
|
||||
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;
|
||||
}
|
||||
|
||||
strncpy( c2c->mask, Mask, MASK_LEN );
|
||||
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- */
|
||||
269
src/ngircd/log.c
269
src/ngircd/log.c
@@ -2,123 +2,163 @@
|
||||
* 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.17 2002/01/11 14:45:37 alex Exp $
|
||||
*
|
||||
* log.c: Logging-Funktionen
|
||||
*
|
||||
* $Log: log.c,v $
|
||||
* Revision 1.17 2002/01/11 14:45:37 alex
|
||||
* - Anpassungen an neue Kommandozeilen-Optionen "--debug" und "--nodaemon".
|
||||
*
|
||||
* Revision 1.16 2002/01/05 15:54:40 alex
|
||||
* - syslog() etc. wurde verwendet, auch wenn USE_SYSLOG nicht definiert war.
|
||||
*
|
||||
* Revision 1.15 2002/01/02 02:42:58 alex
|
||||
* - Copyright-Texte aktualisiert.
|
||||
*
|
||||
* Revision 1.14 2002/01/01 18:01:43 alex
|
||||
* - Architektur und Betriebssystem in Start-Meldung aufgenommen.
|
||||
*
|
||||
* Revision 1.13 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.12 2001/12/29 20:16:31 alex
|
||||
* - Log-Funktionen fuer Resolver-Sub-Prozess implementiert.
|
||||
*
|
||||
* Revision 1.11 2001/12/29 03:08:49 alex
|
||||
* - neue configure-Option "--enable-strict-rfc".
|
||||
*
|
||||
* Revision 1.10 2001/12/27 01:44:49 alex
|
||||
* - die Verwendung von syslog kann nun abgeschaltet werden.
|
||||
*
|
||||
* Revision 1.9 2001/12/26 03:22:16 alex
|
||||
* - string.h wird nun includiert.
|
||||
*
|
||||
* Revision 1.8 2001/12/25 23:13:00 alex
|
||||
* - Versionsstring bei Programmstart verbessert.
|
||||
*
|
||||
* Revision 1.7 2001/12/25 22:04:26 alex
|
||||
* - Aenderungen an den Debug- und Logging-Funktionen.
|
||||
*
|
||||
* Revision 1.6 2001/12/25 19:20:39 alex
|
||||
* - es wird nun die Facility LOG_LOCAL5 zum Loggen verwendet.
|
||||
*
|
||||
* Revision 1.5 2001/12/15 00:07:56 alex
|
||||
* - Log-Level der Start- und Stop-Meldungen angehoben.
|
||||
*
|
||||
* Revision 1.4 2001/12/13 02:04:16 alex
|
||||
* - boesen "Speicherschiesser" in Log() gefixt.
|
||||
*
|
||||
* Revision 1.3 2001/12/12 23:31:24 alex
|
||||
* - Zum Loggen wird nun auch syslog verwendet.
|
||||
*
|
||||
* Revision 1.2 2001/12/12 17:19:12 alex
|
||||
* - in Log-Meldungen wird nun auch der Level der Meldung ausgegeben.
|
||||
*
|
||||
* Revision 1.1.1.1 2001/12/11 21:53:04 alex
|
||||
* - Imported sources to CVS.
|
||||
* Logging functions
|
||||
*/
|
||||
|
||||
|
||||
#define MAX_LOG_MSG_LEN 256
|
||||
#include "portab.h"
|
||||
|
||||
static char UNUSED id[] = "$Id: log.c,v 1.41 2002/12/12 12:24:18 alex Exp $";
|
||||
|
||||
#include <portab.h>
|
||||
#include "global.h"
|
||||
|
||||
#include <imp.h>
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
#include "global.h"
|
||||
#include "ngircd.h"
|
||||
#include "defines.h"
|
||||
#include "conn.h"
|
||||
#include "client.h"
|
||||
#include "channel.h"
|
||||
#include "irc-write.h"
|
||||
|
||||
#include <exp.h>
|
||||
#include "exp.h"
|
||||
#include "log.h"
|
||||
|
||||
|
||||
GLOBAL VOID Log_Init( VOID )
|
||||
LOCAL CHAR Error_File[FNAME_LEN];
|
||||
LOCAL CHAR Init_Txt[127];
|
||||
|
||||
|
||||
LOCAL VOID Wall_ServerNotice PARAMS(( CHAR *Msg ));
|
||||
|
||||
|
||||
GLOBAL VOID
|
||||
Log_Init( VOID )
|
||||
{
|
||||
#ifdef USE_SYSLOG
|
||||
/* Syslog initialisieren */
|
||||
openlog( PACKAGE, LOG_CONS|LOG_PID, LOG_LOCAL5 );
|
||||
#endif
|
||||
|
||||
/* Hello World! */
|
||||
Log( LOG_NOTICE, "%s started.", NGIRCd_Version( ));
|
||||
|
||||
/* Informationen uebern den "Operation Mode" */
|
||||
strcpy( Init_Txt, "" );
|
||||
#ifdef DEBUG
|
||||
if( NGIRCd_Debug )
|
||||
{
|
||||
if( Init_Txt[0] ) strcat( Init_Txt, ", " );
|
||||
strcat( Init_Txt, "debug-mode" );
|
||||
}
|
||||
#endif
|
||||
if( NGIRCd_NoDaemon )
|
||||
{
|
||||
if( Init_Txt[0] ) strcat( Init_Txt, ", " );
|
||||
strcat( Init_Txt, "no-daemon-mode" );
|
||||
}
|
||||
if( NGIRCd_Passive )
|
||||
{
|
||||
if( Init_Txt[0] ) strcat( Init_Txt, ", " );
|
||||
strcat( Init_Txt, "passive-mode" );
|
||||
}
|
||||
#ifdef SNIFFER
|
||||
if( NGIRCd_Sniffer )
|
||||
{
|
||||
if( Init_Txt[0] ) strcat( Init_Txt, ", " );
|
||||
strcat( Init_Txt, "network sniffer" );
|
||||
}
|
||||
#endif
|
||||
if( Init_Txt[0] ) Log( LOG_INFO, "Activating: %s.", Init_Txt );
|
||||
} /* Log_Init */
|
||||
|
||||
|
||||
GLOBAL VOID Log_Exit( VOID )
|
||||
GLOBAL VOID
|
||||
Log_InitErrorfile( VOID )
|
||||
{
|
||||
Log( LOG_NOTICE, PACKAGE" done.");
|
||||
/* "Error-Log" initialisieren: stderr in Datei umlenken. Dort
|
||||
* landen z.B. alle Ausgaben von assert()-Aufrufen. */
|
||||
|
||||
/* Dateiname zusammen bauen */
|
||||
sprintf( Error_File, "%s/%s-%ld.err", ERROR_DIR, PACKAGE, (LONG)getpid( ));
|
||||
|
||||
/* stderr umlenken */
|
||||
fflush( stderr );
|
||||
if( ! freopen( Error_File, "w", stderr ))
|
||||
{
|
||||
Log( LOG_ERR, "Can't reopen stderr (\"%s\"): %s", Error_File, strerror( errno ));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Einige Infos in das Error-File schreiben */
|
||||
fputs( ctime( &NGIRCd_Start ), stderr );
|
||||
fprintf( stderr, "%s started.\n", NGIRCd_Version( ));
|
||||
fprintf( stderr, "Activating: %s\n\n", Init_Txt[0] ? Init_Txt : "-" );
|
||||
fflush( stderr );
|
||||
|
||||
Log( LOG_DEBUG, "Redirected stderr to \"%s\".", Error_File );
|
||||
} /* Log_InitErrfile */
|
||||
|
||||
|
||||
GLOBAL VOID
|
||||
Log_Exit( VOID )
|
||||
{
|
||||
/* Good Bye! */
|
||||
if( NGIRCd_Restart ) Log( LOG_NOTICE, "%s done (restarting).", PACKAGE );
|
||||
else Log( LOG_NOTICE, "%s done.", PACKAGE );
|
||||
|
||||
/* Error-File (stderr) loeschen */
|
||||
if( unlink( Error_File ) != 0 ) Log( LOG_ERR, "Can't delete \"%s\": %s", Error_File, strerror( errno ));
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
/* syslog abmelden */
|
||||
closelog( );
|
||||
#endif
|
||||
} /* Log_Exit */
|
||||
|
||||
|
||||
GLOBAL VOID Log( CONST 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 */
|
||||
|
||||
CHAR msg[MAX_LOG_MSG_LEN];
|
||||
BOOLEAN snotice;
|
||||
va_list ap;
|
||||
|
||||
assert( Format != NULL );
|
||||
|
||||
if( Level & LOG_snotice )
|
||||
{
|
||||
/* Notice an User mit "s" Mode */
|
||||
snotice = TRUE;
|
||||
Level &= ~LOG_snotice;
|
||||
}
|
||||
else snotice = FALSE;
|
||||
|
||||
#ifdef DEBUG
|
||||
if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
|
||||
#else
|
||||
@@ -126,21 +166,45 @@ GLOBAL VOID Log( CONST INT Level, CONST CHAR *Format, ... )
|
||||
#endif
|
||||
|
||||
/* String mit variablen Argumenten zusammenbauen ... */
|
||||
#ifdef PROTOTYPES
|
||||
va_start( ap, Format );
|
||||
vsnprintf( msg, MAX_LOG_MSG_LEN - 1, Format, ap );
|
||||
msg[MAX_LOG_MSG_LEN - 1] = '\0';
|
||||
#else
|
||||
va_start( ap );
|
||||
#endif
|
||||
vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
|
||||
va_end( ap );
|
||||
|
||||
/* ... und ausgeben */
|
||||
if( NGIRCd_NoDaemon ) printf( "[%d] %s\n", Level, msg );
|
||||
if( NGIRCd_NoDaemon )
|
||||
{
|
||||
/* auf Konsole ausgeben */
|
||||
fprintf( stdout, "[%d] %s\n", Level, msg );
|
||||
fflush( stdout );
|
||||
}
|
||||
#ifdef USE_SYSLOG
|
||||
syslog( Level, msg );
|
||||
else
|
||||
{
|
||||
/* Syslog */
|
||||
syslog( Level, "%s", msg );
|
||||
}
|
||||
#endif
|
||||
|
||||
va_end( ap );
|
||||
if( Level <= LOG_CRIT )
|
||||
{
|
||||
/* Kritische Meldungen in Error-File (stderr) */
|
||||
fprintf( stderr, "%s\n", msg );
|
||||
fflush( stderr );
|
||||
}
|
||||
|
||||
if( snotice )
|
||||
{
|
||||
/* NOTICE an lokale User mit "s"-Mode */
|
||||
Wall_ServerNotice( msg );
|
||||
}
|
||||
} /* Log */
|
||||
|
||||
|
||||
GLOBAL VOID Log_Init_Resolver( VOID )
|
||||
GLOBAL VOID
|
||||
Log_Init_Resolver( VOID )
|
||||
{
|
||||
#ifdef USE_SYSLOG
|
||||
openlog( PACKAGE, LOG_CONS|LOG_PID, LOG_LOCAL5 );
|
||||
@@ -148,7 +212,8 @@ GLOBAL VOID Log_Init_Resolver( VOID )
|
||||
} /* Log_Init_Resolver */
|
||||
|
||||
|
||||
GLOBAL VOID Log_Exit_Resolver( VOID )
|
||||
GLOBAL VOID
|
||||
Log_Exit_Resolver( VOID )
|
||||
{
|
||||
#ifdef USE_SYSLOG
|
||||
closelog( );
|
||||
@@ -156,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 */
|
||||
|
||||
@@ -169,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
|
||||
@@ -176,16 +252,37 @@ GLOBAL VOID Log_Resolver( CONST INT Level, CONST CHAR *Format, ... )
|
||||
#endif
|
||||
|
||||
/* String mit variablen Argumenten zusammenbauen ... */
|
||||
#ifdef PROTOTYPES
|
||||
va_start( ap, Format );
|
||||
vsnprintf( msg, MAX_LOG_MSG_LEN - 1, Format, ap );
|
||||
msg[MAX_LOG_MSG_LEN - 1] = '\0';
|
||||
#else
|
||||
va_start( ap );
|
||||
#endif
|
||||
vsnprintf( msg, MAX_LOG_MSG_LEN, Format, ap );
|
||||
va_end( ap );
|
||||
|
||||
/* ... und ausgeben */
|
||||
syslog( Level, msg );
|
||||
|
||||
va_end( ap );
|
||||
#endif
|
||||
} /* Log_Resolver */
|
||||
|
||||
|
||||
LOCAL VOID
|
||||
Wall_ServerNotice( CHAR *Msg )
|
||||
{
|
||||
/* Server-Notice an entsprechende User verschicken */
|
||||
|
||||
CLIENT *c;
|
||||
|
||||
assert( Msg != NULL );
|
||||
|
||||
c = Client_First( );
|
||||
while( c )
|
||||
{
|
||||
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 */
|
||||
|
||||
|
||||
/* -eof- */
|
||||
|
||||
@@ -2,40 +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.7 2002/01/02 02:42:58 alex Exp $
|
||||
* $Id: log.h,v 1.13 2002/12/12 12:23:43 alex Exp $
|
||||
*
|
||||
* log.h: Logging-Funktionen (Header)
|
||||
*
|
||||
* $Log: log.h,v $
|
||||
* Revision 1.7 2002/01/02 02:42:58 alex
|
||||
* - Copyright-Texte aktualisiert.
|
||||
*
|
||||
* Revision 1.6 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.5 2001/12/29 20:16:31 alex
|
||||
* - Log-Funktionen fuer Resolver-Sub-Prozess implementiert.
|
||||
*
|
||||
* Revision 1.4 2001/12/27 01:44:49 alex
|
||||
* - die Verwendung von syslog kann nun abgeschaltet werden.
|
||||
*
|
||||
* Revision 1.3 2001/12/12 23:31:24 alex
|
||||
* - Zum Loggen wird nun auch syslog verwendet.
|
||||
*
|
||||
* Revision 1.2 2001/12/12 17:19:29 alex
|
||||
* - LOG_ERR heisst nun LOG_ERROR.
|
||||
*
|
||||
* Revision 1.1.1.1 2001/12/11 21:53:04 alex
|
||||
* - Imported sources to CVS.
|
||||
* Logging functions (header)
|
||||
*/
|
||||
|
||||
|
||||
@@ -57,15 +32,19 @@
|
||||
#endif
|
||||
|
||||
|
||||
GLOBAL VOID Log_Init( VOID );
|
||||
GLOBAL VOID Log_Exit( VOID );
|
||||
#define LOG_snotice 1024
|
||||
|
||||
GLOBAL VOID Log( CONST INT Level, CONST CHAR *Format, ... );
|
||||
|
||||
GLOBAL VOID Log_Init_Resolver( VOID );
|
||||
GLOBAL VOID Log_Exit_Resolver( VOID );
|
||||
GLOBAL VOID Log_Init PARAMS((VOID ));
|
||||
GLOBAL VOID Log_Exit PARAMS((VOID ));
|
||||
|
||||
GLOBAL VOID Log_Resolver( CONST 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 PARAMS((VOID ));
|
||||
GLOBAL VOID Log_Exit_Resolver PARAMS((VOID ));
|
||||
|
||||
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- */
|
||||
@@ -2,92 +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: messages.h,v 1.23 2002/01/29 00:14:05 alex Exp $
|
||||
* $Id: messages.h,v 1.59.2.1 2002/12/22 23:42:28 alex Exp $
|
||||
*
|
||||
* irc.h: IRC-Befehle (Header)
|
||||
*
|
||||
* $Log: messages.h,v $
|
||||
* Revision 1.23 2002/01/29 00:14:05 alex
|
||||
* - RPL_WHOISCHANNELS_MSG korrigiert.
|
||||
*
|
||||
* Revision 1.22 2002/01/28 13:06:19 alex
|
||||
* - RPL_NAMREPLY_MSG an tatsaechliche Implementierung angepasst ;-)
|
||||
*
|
||||
* Revision 1.21 2002/01/27 17:13:37 alex
|
||||
* - neue Defines fuer RPL_TOPIC und RPL_NOTOPIC.
|
||||
*
|
||||
* Revision 1.20 2002/01/21 00:02:34 alex
|
||||
* - ERR_NOSUCHCHANNEL hinzugefuegt.
|
||||
*
|
||||
* Revision 1.19 2002/01/16 22:09:52 alex
|
||||
* - RPL_LUSERME_MSG erweitert, kleinere Aenderungen.
|
||||
*
|
||||
* Revision 1.18 2002/01/11 23:50:55 alex
|
||||
* - LINKS implementiert, LUSERS begonnen.
|
||||
*
|
||||
* Revision 1.17 2002/01/05 23:23:44 alex
|
||||
* - neue Nachricht ERR_NOSUCHSERVER_MSG definiert.
|
||||
*
|
||||
* Revision 1.16 2002/01/03 02:24:21 alex
|
||||
* - neue Message ERR_NOTREGISTEREDSERVER_MSG.
|
||||
*
|
||||
* Revision 1.15 2002/01/02 02:42:58 alex
|
||||
* - Copyright-Texte aktualisiert.
|
||||
*
|
||||
* Revision 1.14 2001/12/31 16:00:57 alex
|
||||
* - "o" zu den unterstuetzten Modes hinzugefuegt.
|
||||
*
|
||||
* Revision 1.13 2001/12/31 15:33:13 alex
|
||||
* - neuer Befehl NAMES, kleinere Bugfixes.
|
||||
* - Bug bei PING behoben: war zu restriktiv implementiert :-)
|
||||
*
|
||||
* Revision 1.12 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.11 2001/12/30 19:25:39 alex
|
||||
* - RPL_MYINFO_MSG um unterstuetzte User-Modes ergaengz.
|
||||
*
|
||||
* Revision 1.10 2001/12/30 11:42:00 alex
|
||||
* - der Server meldet nun eine ordentliche "Start-Zeit".
|
||||
*
|
||||
* Revision 1.9 2001/12/29 03:06:56 alex
|
||||
* - Texte ergaenzt, einige Bugs behoben (Leerzeichen falsch gesetzt, z.B.)
|
||||
*
|
||||
* Revision 1.8 2001/12/27 19:17:26 alex
|
||||
* - neue Befehle PRIVMSG, NOTICE, PING.
|
||||
*
|
||||
* Revision 1.7 2001/12/27 16:56:06 alex
|
||||
* - RPL_WELCOME an Client_GetID() angepasst.
|
||||
*
|
||||
* Revision 1.6 2001/12/26 22:48:53 alex
|
||||
* - MOTD-Datei ist nun konfigurierbar und wird gelesen.
|
||||
*
|
||||
* Revision 1.5 2001/12/26 03:51:13 alex
|
||||
* - in ERR_NOTREGISTERED_MSG fehlte ein "%s" - jetzt steht auch hier der Nick.
|
||||
*
|
||||
* Revision 1.4 2001/12/26 03:22:40 alex
|
||||
* - Format der Meldungen ueberarbeitet: fast immer ist nun der Nick enthalten.
|
||||
*
|
||||
* Revision 1.3 2001/12/25 19:20:11 alex
|
||||
* - neue Message: ERR_NICKNAMEINUSE[_MSG].
|
||||
*
|
||||
* Revision 1.2 2001/12/24 01:30:46 alex
|
||||
* - einige Messages korrigiert, andere ergaenzt (u.a. fuer MOTD).
|
||||
*
|
||||
* Revision 1.1 2001/12/23 21:53:32 alex
|
||||
* - Ich habe diesen Header begonnen.
|
||||
*
|
||||
* Revision 1.1 2001/12/14 08:13:43 alex
|
||||
* - neues Modul begonnen :-)
|
||||
* IRC numerics (Header)
|
||||
*/
|
||||
|
||||
|
||||
@@ -95,148 +18,102 @@
|
||||
#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_FEATURE_MSG "005 %s NICKLEN=%d TOPICLEN=%d AWAYLEN=%d MAXCHANNELS=%d :are supported on this server"
|
||||
#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_LOCALUSERS_MSG "265 %s :Current local users: %ld, Max: %ld"
|
||||
#define RPL_NETUSERS_MSG "266 %s :Current global users: %ld, Max: %ld"
|
||||
|
||||
#define RPL_YOURHOST "002"
|
||||
#define RPL_YOURHOST_MSG RPL_YOURHOST" %s :Your host is %s, running ngircd "VERSION"-"P_OSNAME"/"P_ARCHNAME
|
||||
#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_CREATED "003"
|
||||
#define RPL_CREATED_MSG RPL_CREATED" %s :This server was started %s"
|
||||
#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_RESTRICTED_MSG "484 %s :Your connection is restricted"
|
||||
#define ERR_NOOPERHOST_MSG "491 %s :Not configured for your host"
|
||||
|
||||
#define RPL_MYINFO "004"
|
||||
#define RPL_MYINFO_MSG RPL_MYINFO" %s %s ngircd-"VERSION" ior +"
|
||||
#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_MOTDSTART "375"
|
||||
#define RPL_MOTDSTART_MSG RPL_MOTDSTART" %s :- %s message of the day"
|
||||
|
||||
#define RPL_MOTD "372"
|
||||
#define RPL_MOTD_MSG RPL_MOTD" %s :- %s"
|
||||
|
||||
#define RPL_ENDOFMOTD "376"
|
||||
#define RPL_ENDOFMOTD_MSG RPL_ENDOFMOTD" %s :End of MOTD command"
|
||||
|
||||
#define RPL_UMODEIS "211"
|
||||
#define RPL_UMODEIS_MSG RPL_UMODEIS" %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_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_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_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_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_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_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_NOPRIVILEGES "481"
|
||||
#define ERR_NOPRIVILEGES_MSG ERR_NOPRIVILEGES" %s :Permission denied"
|
||||
|
||||
#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 flag"
|
||||
|
||||
#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,147 +1,81 @@
|
||||
/*
|
||||
* 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.22 2002/01/22 17:15:39 alex Exp $
|
||||
*
|
||||
* ngircd.c: Hier beginnt alles ;-)
|
||||
*
|
||||
* $Log: ngircd.c,v $
|
||||
* Revision 1.22 2002/01/22 17:15:39 alex
|
||||
* - die Fehlermeldung "interrupted system call" sollte nicht mehr auftreten.
|
||||
*
|
||||
* Revision 1.21 2002/01/21 00:02:11 alex
|
||||
* - Hilfetexte korrigiert und ergaenzt (Sniffer).
|
||||
*
|
||||
* Revision 1.20 2002/01/18 11:12:11 alex
|
||||
* - der Sniffer wird nun nur noch aktiviert, wenn auf Kommandozeile angegeben.
|
||||
*
|
||||
* Revision 1.19 2002/01/12 00:17:28 alex
|
||||
* - ngIRCd wandelt sich nun selber in einen Daemon (Hintergrundprozess) um.
|
||||
*
|
||||
* Revision 1.18 2002/01/11 14:45:18 alex
|
||||
* - Kommandozeilen-Parser implementiert: Debug- und No-Daemon-Modus, Hilfe.
|
||||
*
|
||||
* Revision 1.17 2002/01/02 02:51:16 alex
|
||||
* - Signal-Handler fuer SIGCHLD: so sollten Zombies nicht mehr vorkommen.
|
||||
*
|
||||
* Revision 1.15 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.14 2001/12/30 19:26:12 alex
|
||||
* - Unterstuetzung fuer die Konfigurationsdatei eingebaut.
|
||||
*
|
||||
* Revision 1.13 2001/12/30 11:42:00 alex
|
||||
* - der Server meldet nun eine ordentliche "Start-Zeit".
|
||||
*
|
||||
* Revision 1.12 2001/12/29 03:07:36 alex
|
||||
* - einige Loglevel geaendert.
|
||||
*
|
||||
* Revision 1.11 2001/12/26 14:45:37 alex
|
||||
* - "Code Cleanups".
|
||||
*
|
||||
* Revision 1.10 2001/12/24 01:34:38 alex
|
||||
* - Signal-Handler aufgeraeumt; u.a. SIGPIPE wird nun korrekt ignoriert.
|
||||
*
|
||||
* Revision 1.9 2001/12/21 22:24:50 alex
|
||||
* - neues Modul "parse" wird initialisiert und abgemeldet.
|
||||
*
|
||||
* Revision 1.8 2001/12/14 08:15:26 alex
|
||||
* - neue Module (irc, client, channel) werden an- und abgemeldet.
|
||||
* - zweiter Listen-Socket wird zu Testzwecken konfiguriert.
|
||||
*
|
||||
* Revision 1.7 2001/12/13 01:31:46 alex
|
||||
* - Conn_Handler() wird nun mit einem Timeout aufgerufen.
|
||||
*
|
||||
* Revision 1.6 2001/12/12 23:30:42 alex
|
||||
* - Log-Meldungen an syslog angepasst.
|
||||
* - NGIRCd_Quit ist nun das Flag zum Beenden des ngircd.
|
||||
*
|
||||
* Revision 1.5 2001/12/12 17:21:21 alex
|
||||
* - mehr Unterfunktionen eingebaut, Modul besser strukturiert & dokumentiert.
|
||||
* - Anpassungen an neue Module.
|
||||
*
|
||||
* Revision 1.4 2001/12/12 01:58:53 alex
|
||||
* - Test auf socklen_t verbessert.
|
||||
*
|
||||
* Revision 1.3 2001/12/12 01:40:39 alex
|
||||
* - ein paar mehr Kommentare; Variablennamen verstaendlicher gemacht.
|
||||
* - fehlenden Header <arpa/inet.h> ergaenz.
|
||||
* - SIGINT und SIGQUIT werden nun ebenfalls behandelt.
|
||||
*
|
||||
* Revision 1.2 2001/12/11 22:04:21 alex
|
||||
* - Test auf stdint.h (HAVE_STDINT_H) hinzugefuegt.
|
||||
*
|
||||
* Revision 1.1.1.1 2001/12/11 21:53:04 alex
|
||||
* - Imported sources to CVS.
|
||||
* Main program -- main()
|
||||
*/
|
||||
|
||||
|
||||
#define PORTAB_CHECK_TYPES /* Prueffunktion einbinden, s.u. */
|
||||
#include "portab.h"
|
||||
|
||||
static char UNUSED id[] = "$Id: ngircd.c,v 1.64.2.1 2003/01/01 13:47:42 alex Exp $";
|
||||
|
||||
#include <portab.h>
|
||||
#include "global.h"
|
||||
|
||||
#include <imp.h>
|
||||
|
||||
#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 "irc.h"
|
||||
#include "client.h"
|
||||
#include "channel.h"
|
||||
#include "conf.h"
|
||||
#include "cvs-version.h"
|
||||
#include "defines.h"
|
||||
#include "lists.h"
|
||||
#include "log.h"
|
||||
#include "parse.h"
|
||||
#include "irc.h"
|
||||
|
||||
#include <exp.h>
|
||||
#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[] )
|
||||
{
|
||||
BOOLEAN ok;
|
||||
INT pid, i, n;
|
||||
struct passwd *pwd;
|
||||
struct group *grp;
|
||||
BOOLEAN ok, configtest = FALSE;
|
||||
LONG pid, n;
|
||||
INT i;
|
||||
|
||||
/* Datentypen der portab-Library ueberpruefen */
|
||||
portab_check_types( );
|
||||
umask( 0077 );
|
||||
|
||||
NGIRCd_Restart = FALSE;
|
||||
NGIRCd_Quit = FALSE;
|
||||
NGIRCd_NoDaemon = FALSE;
|
||||
NGIRCd_Passive = FALSE;
|
||||
#ifdef DEBUG
|
||||
NGIRCd_Debug = FALSE;
|
||||
#endif
|
||||
#ifdef SNIFFER
|
||||
NGIRCd_Sniffer = FALSE;
|
||||
#endif
|
||||
strcpy( NGIRCd_ConfFile, CONFIG_FILE );
|
||||
|
||||
/* Kommandozeile parsen */
|
||||
for( i = 1; i < argc; i++ )
|
||||
@@ -151,16 +85,22 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
|
||||
{
|
||||
/* Lange Option */
|
||||
|
||||
if( strcmp( argv[i], "--help" ) == 0 )
|
||||
if( strcmp( argv[i], "--config" ) == 0 )
|
||||
{
|
||||
Show_Version( ); puts( "" );
|
||||
Show_Help( ); puts( "" );
|
||||
exit( 1 );
|
||||
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';
|
||||
|
||||
/* zum uebernaechsten Parameter */
|
||||
i++; ok = TRUE;
|
||||
}
|
||||
}
|
||||
if( strcmp( argv[i], "--version" ) == 0 )
|
||||
if( strcmp( argv[i], "--configtest" ) == 0 )
|
||||
{
|
||||
Show_Version( );
|
||||
exit( 1 );
|
||||
configtest = TRUE;
|
||||
ok = TRUE;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if( strcmp( argv[i], "--debug" ) == 0 )
|
||||
@@ -169,6 +109,22 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
|
||||
ok = TRUE;
|
||||
}
|
||||
#endif
|
||||
if( strcmp( argv[i], "--help" ) == 0 )
|
||||
{
|
||||
Show_Version( );
|
||||
puts( "" ); Show_Help( ); puts( "" );
|
||||
exit( 1 );
|
||||
}
|
||||
if( strcmp( argv[i], "--nodaemon" ) == 0 )
|
||||
{
|
||||
NGIRCd_NoDaemon = TRUE;
|
||||
ok = TRUE;
|
||||
}
|
||||
if( strcmp( argv[i], "--passive" ) == 0 )
|
||||
{
|
||||
NGIRCd_Passive = TRUE;
|
||||
ok = TRUE;
|
||||
}
|
||||
#ifdef SNIFFER
|
||||
if( strcmp( argv[i], "--sniffer" ) == 0 )
|
||||
{
|
||||
@@ -176,17 +132,17 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
|
||||
ok = TRUE;
|
||||
}
|
||||
#endif
|
||||
if( strcmp( argv[i], "--nodaemon" ) == 0 )
|
||||
if( strcmp( argv[i], "--version" ) == 0 )
|
||||
{
|
||||
NGIRCd_NoDaemon = TRUE;
|
||||
ok = TRUE;
|
||||
Show_Version( );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
else if(( argv[i][0] == '-' ) && ( argv[i][1] != '-' ))
|
||||
{
|
||||
/* Kurze Option */
|
||||
|
||||
for( n = 1; n < strlen( argv[i] ); n++ )
|
||||
for( n = 1; n < (LONG)strlen( argv[i] ); n++ )
|
||||
{
|
||||
ok = FALSE;
|
||||
#ifdef DEBUG
|
||||
@@ -196,6 +152,29 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
|
||||
ok = TRUE;
|
||||
}
|
||||
#endif
|
||||
if( argv[i][n] == 'f' )
|
||||
{
|
||||
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';
|
||||
|
||||
/* zum uebernaechsten Parameter */
|
||||
i++; n = (LONG)strlen( argv[i] );
|
||||
ok = TRUE;
|
||||
}
|
||||
}
|
||||
if( argv[i][n] == 'n' )
|
||||
{
|
||||
NGIRCd_NoDaemon = TRUE;
|
||||
ok = TRUE;
|
||||
}
|
||||
if( argv[i][n] == 'p' )
|
||||
{
|
||||
NGIRCd_Passive = TRUE;
|
||||
ok = TRUE;
|
||||
}
|
||||
#ifdef SNIFFER
|
||||
if( argv[i][n] == 's' )
|
||||
{
|
||||
@@ -203,16 +182,11 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
|
||||
ok = TRUE;
|
||||
}
|
||||
#endif
|
||||
if( argv[i][n] == 'n' )
|
||||
{
|
||||
NGIRCd_NoDaemon = TRUE;
|
||||
ok = TRUE;
|
||||
}
|
||||
|
||||
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, argv[i][n] );
|
||||
printf( "Try \"%s --help\" for more information.\n", PACKAGE );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
@@ -220,12 +194,32 @@ 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, argv[i] );
|
||||
printf( "Try \"%s --help\" for more information.\n", PACKAGE );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Debug-Level (fuer IRC-Befehl "VERSION") ermitteln */
|
||||
strcpy( NGIRCd_DebugLevel, "" );
|
||||
#ifdef DEBUG
|
||||
if( NGIRCd_Debug ) strcpy( NGIRCd_DebugLevel, "1" );
|
||||
#endif
|
||||
#ifdef SNIFFER
|
||||
if( NGIRCd_Sniffer )
|
||||
{
|
||||
NGIRCd_Debug = TRUE;
|
||||
strcpy( NGIRCd_DebugLevel, "2" );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Soll nur die Konfigurations ueberprueft und ausgegeben werden? */
|
||||
if( configtest )
|
||||
{
|
||||
Show_Version( ); puts( "" );
|
||||
exit( Conf_Test( ));
|
||||
}
|
||||
|
||||
while( ! NGIRCd_Quit )
|
||||
{
|
||||
/* In der Regel wird ein Sub-Prozess ge-fork()'t, der
|
||||
@@ -235,7 +229,7 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
|
||||
if( ! NGIRCd_NoDaemon )
|
||||
{
|
||||
/* Daemon im Hintergrund erzeugen */
|
||||
pid = fork( );
|
||||
pid = (LONG)fork( );
|
||||
if( pid > 0 )
|
||||
{
|
||||
/* "alter" Prozess */
|
||||
@@ -244,112 +238,238 @@ 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, strerror( errno ));
|
||||
exit( 1 );
|
||||
}
|
||||
setsid( );
|
||||
|
||||
/* Child-Prozess initialisieren */
|
||||
(VOID)setsid( );
|
||||
chdir( "/" );
|
||||
}
|
||||
|
||||
/* Globale Variablen initialisieren */
|
||||
NGIRCd_Start = time( NULL );
|
||||
strftime( NGIRCd_StartStr, 64, "%a %b %d %Y at %H:%M:%S (%Z)", localtime( &NGIRCd_Start ));
|
||||
(VOID)strftime( NGIRCd_StartStr, 64, "%a %b %d %Y at %H:%M:%S (%Z)", localtime( &NGIRCd_Start ));
|
||||
NGIRCd_Restart = FALSE;
|
||||
NGIRCd_Quit = FALSE;
|
||||
|
||||
/* Module initialisieren */
|
||||
Log_Init( );
|
||||
Resolve_Init( );
|
||||
Conf_Init( );
|
||||
Parse_Init( );
|
||||
IRC_Init( );
|
||||
Lists_Init( );
|
||||
Channel_Init( );
|
||||
Client_Init( );
|
||||
Conn_Init( );
|
||||
|
||||
/* Wenn als root ausgefuehrt und eine andere UID
|
||||
* konfiguriert ist, jetzt zu dieser wechseln */
|
||||
if( getuid( ) == 0 )
|
||||
{
|
||||
if( Conf_GID != 0 )
|
||||
{
|
||||
/* Neue Group-ID setzen */
|
||||
if( setgid( Conf_GID ) != 0 ) Log( LOG_ERR, "Can't change Group-ID to %u: %s", Conf_GID, strerror( errno ));
|
||||
}
|
||||
if( Conf_UID != 0 )
|
||||
{
|
||||
/* Neue User-ID setzen */
|
||||
if( setuid( Conf_UID ) != 0 ) Log( LOG_ERR, "Can't change User-ID to %u: %s", Conf_UID, strerror( errno ));
|
||||
}
|
||||
}
|
||||
|
||||
/* 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, 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, 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 );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* Hauptschleife */
|
||||
Conn_Handler( );
|
||||
|
||||
/* Alles abmelden */
|
||||
Conn_Exit( );
|
||||
Client_Exit( );
|
||||
Channel_Exit( );
|
||||
IRC_Exit( );
|
||||
Parse_Exit( );
|
||||
Conf_Exit( );
|
||||
Lists_Exit( );
|
||||
Log_Exit( );
|
||||
}
|
||||
|
||||
return 0;
|
||||
} /* main */
|
||||
|
||||
|
||||
GLOBAL CHAR *NGIRCd_Version( VOID )
|
||||
GLOBAL CHAR *
|
||||
NGIRCd_Version( VOID )
|
||||
{
|
||||
STATIC CHAR version[126];
|
||||
CHAR txt[64];
|
||||
|
||||
#ifdef CVSDATE
|
||||
sprintf( version, "%s %s(%s)-%s", PACKAGE, VERSION, CVSDATE, NGIRCd_VersionAddition( ));
|
||||
#else
|
||||
sprintf( version, "%s %s-%s", PACKAGE, VERSION, NGIRCd_VersionAddition( ));
|
||||
#endif
|
||||
return version;
|
||||
} /* NGIRCd_Version */
|
||||
|
||||
|
||||
GLOBAL CHAR *
|
||||
NGIRCd_VersionAddition( VOID )
|
||||
{
|
||||
STATIC CHAR txt[64];
|
||||
|
||||
strcpy( txt, "" );
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
if( txt[0] ) strcat( txt, "+" );
|
||||
else strcat( txt, "-" );
|
||||
strcat( txt, "SYSLOG" );
|
||||
#endif
|
||||
#ifdef STRICT_RFC
|
||||
#ifdef USE_ZLIB
|
||||
if( txt[0] ) strcat( txt, "+" );
|
||||
else strcat( txt, "-" );
|
||||
strcat( txt, "RFC" );
|
||||
strcat( txt, "ZLIB" );
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
if( txt[0] ) strcat( txt, "+" );
|
||||
else strcat( txt, "-" );
|
||||
strcat( txt, "DEBUG" );
|
||||
#endif
|
||||
#ifdef SNIFFER
|
||||
if( txt[0] ) strcat( txt, "+" );
|
||||
else strcat( txt, "-" );
|
||||
strcat( txt, "SNIFFER" );
|
||||
#endif
|
||||
#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] ) strcat( txt, "-" );
|
||||
strcat( txt, TARGET_CPU );
|
||||
strcat( txt, "/" );
|
||||
strcat( txt, TARGET_VENDOR );
|
||||
strcat( txt, "/" );
|
||||
strcat( txt, TARGET_OS );
|
||||
|
||||
sprintf( version, PACKAGE" version "VERSION"%s-"P_OSNAME"/"P_ARCHNAME, txt );
|
||||
return version;
|
||||
} /* NGIRCd_Version */
|
||||
return txt;
|
||||
} /* NGIRCd_VersionAddition */
|
||||
|
||||
|
||||
LOCAL VOID Initialize_Signal_Handler( VOID )
|
||||
GLOBAL VOID
|
||||
NGIRCd_Rehash( VOID )
|
||||
{
|
||||
CHAR old_name[CLIENT_ID_LEN];
|
||||
|
||||
/* Alle Listen-Sockets schliessen */
|
||||
Conn_ExitListeners( );
|
||||
|
||||
/* Alten Server-Namen merken */
|
||||
strcpy( old_name, Conf_ServerName );
|
||||
|
||||
/* Konfiguration neu lesen ... */
|
||||
Conf_Init( );
|
||||
|
||||
/* 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( );
|
||||
|
||||
Log( LOG_INFO, "Re-reading of configuration done." );
|
||||
} /* NGIRCd_Rehash */
|
||||
|
||||
|
||||
LOCAL VOID
|
||||
Initialize_Signal_Handler( VOID )
|
||||
{
|
||||
/* Signal-Handler initialisieren: einige Signale
|
||||
* werden ignoriert, andere speziell behandelt. */
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
/* sigaction() ist vorhanden */
|
||||
|
||||
struct sigaction saction;
|
||||
|
||||
/* Signal-Struktur initialisieren */
|
||||
memset( &saction, 0, sizeof( saction ));
|
||||
saction.sa_handler = Signal_Handler;
|
||||
saction.sa_flags = SA_RESTART;
|
||||
#ifdef SA_RESTART
|
||||
saction.sa_flags |= SA_RESTART;
|
||||
#endif
|
||||
#ifdef SA_NOCLDWAIT
|
||||
saction.sa_flags |= SA_NOCLDWAIT;
|
||||
#endif
|
||||
|
||||
/* Signal-Handler einhaengen */
|
||||
sigaction( SIGINT, &saction, NULL );
|
||||
sigaction( SIGQUIT, &saction, NULL );
|
||||
sigaction( SIGTERM, &saction, NULL);
|
||||
sigaction( SIGHUP, &saction, NULL);
|
||||
sigaction( SIGCHLD, &saction, NULL);
|
||||
|
||||
/* einige Signale ignorieren */
|
||||
saction.sa_handler = SIG_IGN;
|
||||
sigaction( SIGPIPE, &saction, NULL );
|
||||
#else
|
||||
/* kein sigaction() vorhanden */
|
||||
|
||||
/* Signal-Handler einhaengen */
|
||||
signal( SIGINT, Signal_Handler );
|
||||
signal( SIGQUIT, Signal_Handler );
|
||||
signal( SIGTERM, Signal_Handler );
|
||||
signal( SIGHUP, Signal_Handler );
|
||||
signal( SIGCHLD, Signal_Handler );
|
||||
|
||||
/* einige Signale ignorieren */
|
||||
signal( SIGPIPE, SIG_IGN );
|
||||
#endif
|
||||
} /* 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
|
||||
@@ -361,9 +481,16 @@ LOCAL VOID Signal_Handler( INT Signal )
|
||||
case SIGINT:
|
||||
case SIGQUIT:
|
||||
/* wir soll(t)en uns wohl beenden ... */
|
||||
Log( LOG_WARNING, "Got signal %d, terminating now ...", Signal );
|
||||
if( Signal == SIGTERM ) Log( LOG_WARNING|LOG_snotice, "Got TERM signal, terminating now ..." );
|
||||
else if( Signal == SIGINT ) Log( LOG_WARNING|LOG_snotice, "Got INT signal, terminating now ..." );
|
||||
else if( Signal == SIGQUIT ) Log( LOG_WARNING|LOG_snotice, "Got QUIT signal, terminating now ..." );
|
||||
NGIRCd_Quit = TRUE;
|
||||
break;
|
||||
case SIGHUP:
|
||||
/* Konfiguration neu einlesen: */
|
||||
Log( LOG_WARNING|LOG_snotice, "Got HUP signal, re-reading configuration ..." );
|
||||
NGIRCd_Rehash( );
|
||||
break;
|
||||
case SIGCHLD:
|
||||
/* Child-Prozess wurde beendet. Zombies vermeiden: */
|
||||
while( waitpid( -1, NULL, WNOHANG ) > 0);
|
||||
@@ -375,49 +502,32 @@ LOCAL VOID Signal_Handler( INT Signal )
|
||||
} /* Signal_Handler */
|
||||
|
||||
|
||||
LOCAL VOID Initialize_Listen_Ports( VOID )
|
||||
{
|
||||
/* Ports, auf denen der Server Verbindungen entgegennehmen
|
||||
* soll, initialisieren */
|
||||
|
||||
INT 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 %d!", 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" );
|
||||
puts( " -d, --debug log extra debug messages" );
|
||||
#endif
|
||||
puts( " -n, --nodaemon don't fork and don't detatch from controlling terminal" );
|
||||
puts( " -f, --config <f> use file <f> as configuration file" );
|
||||
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" );
|
||||
puts( " -s, --sniffer enable network sniffer and display all IRC traffic" );
|
||||
#endif
|
||||
puts( " --version output version information and exit" );
|
||||
puts( " --help display this help and exit" );
|
||||
puts( " --configtest read, validate and display configuration; then exit" );
|
||||
puts( " --version output version information and exit" );
|
||||
puts( " --help display this help and exit" );
|
||||
} /* Show_Help */
|
||||
|
||||
|
||||
|
||||
@@ -2,43 +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.8 2002/01/18 11:12:11 alex Exp $
|
||||
* $Id: ngircd.h,v 1.17 2002/12/12 11:30:23 alex Exp $
|
||||
*
|
||||
* ngircd.h: Prototypen aus dem "Haupt-Modul"
|
||||
*
|
||||
* $Log: ngircd.h,v $
|
||||
* Revision 1.8 2002/01/18 11:12:11 alex
|
||||
* - der Sniffer wird nun nur noch aktiviert, wenn auf Kommandozeile angegeben.
|
||||
*
|
||||
* Revision 1.7 2002/01/11 14:45:18 alex
|
||||
* - Kommandozeilen-Parser implementiert: Debug- und No-Daemon-Modus, Hilfe.
|
||||
*
|
||||
* Revision 1.6 2002/01/02 02:44:37 alex
|
||||
* - neue Defines fuer max. Anzahl Server und Operatoren.
|
||||
*
|
||||
* Revision 1.5 2001/12/31 03:06:03 alex
|
||||
* - das #include fuer time.h hat noch gefehlt.
|
||||
*
|
||||
* Revision 1.4 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.3 2001/12/30 11:42:00 alex
|
||||
* - der Server meldet nun eine ordentliche "Start-Zeit".
|
||||
*
|
||||
* Revision 1.2 2001/12/12 23:30:01 alex
|
||||
* - NGIRCd_Quit ist nun das globale Flag zum Beenden des ngircd.
|
||||
*
|
||||
* Revision 1.1.1.1 2001/12/11 21:53:04 alex
|
||||
* - Imported sources to CVS.
|
||||
* Prototypes of the "main module".
|
||||
*/
|
||||
|
||||
|
||||
@@ -47,6 +19,8 @@
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
|
||||
GLOBAL time_t NGIRCd_Start; /* Startzeitpunkt des Daemon */
|
||||
GLOBAL CHAR NGIRCd_StartStr[64];
|
||||
@@ -61,11 +35,22 @@ GLOBAL BOOLEAN NGIRCd_Sniffer; /* Sniffer aktivieren */
|
||||
|
||||
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 CHAR NGIRCd_DebugLevel[2]; /* Debug-Level fuer IRC_VERSION() */
|
||||
|
||||
GLOBAL CHAR *NGIRCd_Version( VOID );
|
||||
GLOBAL CHAR NGIRCd_ConfFile[FNAME_LEN]; /* Konfigurationsdatei */
|
||||
|
||||
GLOBAL CHAR NGIRCd_ProtoID[1024]; /* Protokoll- und Server-Identifikation */
|
||||
|
||||
|
||||
GLOBAL CHAR *NGIRCd_Version PARAMS((VOID ));
|
||||
GLOBAL CHAR *NGIRCd_VersionAddition PARAMS((VOID ));
|
||||
|
||||
GLOBAL VOID NGIRCd_Rehash PARAMS(( VOID ));
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,138 +2,118 @@
|
||||
* 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.22 2002/01/21 00:01:37 alex Exp $
|
||||
*
|
||||
* parse.c: Parsen der Client-Anfragen
|
||||
*
|
||||
* $Log: parse.c,v $
|
||||
* Revision 1.22 2002/01/21 00:01:37 alex
|
||||
* - neue Befehle JOIN und PART.
|
||||
*
|
||||
* Revision 1.21 2002/01/18 11:12:11 alex
|
||||
* - der Sniffer wird nun nur noch aktiviert, wenn auf Kommandozeile angegeben.
|
||||
*
|
||||
* Revision 1.20 2002/01/11 23:50:55 alex
|
||||
* - LINKS implementiert, LUSERS begonnen.
|
||||
*
|
||||
* Revision 1.19 2002/01/09 01:08:42 alex
|
||||
* - Parses handhabt Leerzeichen zw. Parametern nun etwas "lockerer".
|
||||
*
|
||||
* Revision 1.18 2002/01/07 15:29:11 alex
|
||||
* - Status-Codes an den Server selber werden ignoriert, besseres Logging.
|
||||
*
|
||||
* Revision 1.17 2002/01/06 17:41:44 alex
|
||||
* - die Fehlermeldung "unbekannter Befehl" hatte ein falsches Format.
|
||||
*
|
||||
* Revision 1.16 2002/01/05 23:23:20 alex
|
||||
* - generisches Forwarding von Zahlen-Statuscodes implementiert.
|
||||
*
|
||||
* Revision 1.15 2002/01/05 01:42:08 alex
|
||||
* - an Server werden keine ERRORS mehr wegen unbekannter Befehle geschickt.
|
||||
*
|
||||
* Revision 1.14 2002/01/04 17:56:45 alex
|
||||
* - neuer Befehl SQUIT.
|
||||
*
|
||||
* Revision 1.13 2002/01/04 01:20:02 alex
|
||||
* - Client-Strukruren werden nur noch ueber Funktionen angesprochen.
|
||||
*
|
||||
* Revision 1.12 2002/01/03 02:24:49 alex
|
||||
* - neue Befehle NJOIN und SERVER begonnen.
|
||||
*
|
||||
* Revision 1.11 2002/01/02 02:43:22 alex
|
||||
* - Copyright-Texte aktualisiert.
|
||||
* - neuer Befehl ERROR.
|
||||
*
|
||||
* Revision 1.10 2001/12/31 15:33:13 alex
|
||||
* - neuer Befehl NAMES, kleinere Bugfixes.
|
||||
* - Bug bei PING behoben: war zu restriktiv implementiert :-)
|
||||
*
|
||||
* Revision 1.9 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.8 2001/12/29 03:08:19 alex
|
||||
* - Fuehrende und folgende Leerzeichen etc. in Requests werden geloescht.
|
||||
* - Logmeldungen (mal wieder) ein wenig angepasst.
|
||||
*
|
||||
* Revision 1.7 2001/12/27 19:13:21 alex
|
||||
* - neue Befehle NOTICE und PRIVMSG.
|
||||
* - Debug-Logging ein wenig reduziert.
|
||||
*
|
||||
* Revision 1.6 2001/12/26 14:45:37 alex
|
||||
* - "Code Cleanups".
|
||||
*
|
||||
* Revision 1.5 2001/12/26 03:23:03 alex
|
||||
* - PING/PONG-Befehle implementiert.
|
||||
*
|
||||
* Revision 1.4 2001/12/25 22:04:26 alex
|
||||
* - Aenderungen an den Debug- und Logging-Funktionen.
|
||||
*
|
||||
* Revision 1.3 2001/12/25 19:18:36 alex
|
||||
* - Gross- und Kleinschreibung der IRC-Befehle wird ignoriert.
|
||||
* - bessere Debug-Ausgaben.
|
||||
*
|
||||
* Revision 1.2 2001/12/23 21:56:47 alex
|
||||
* - bessere Debug-Ausgaben,
|
||||
* - Bug im Parameter-Parser behoben (bei "langem" Parameter)
|
||||
* - erste IRC-Befehle werden erkannt :-)
|
||||
*
|
||||
* Revision 1.1 2001/12/21 23:53:16 alex
|
||||
* - Modul zum Parsen von Client-Requests begonnen.
|
||||
* IRC command parser and validator
|
||||
*/
|
||||
|
||||
|
||||
#include <portab.h>
|
||||
#include "global.h"
|
||||
#include "portab.h"
|
||||
|
||||
#include <imp.h>
|
||||
static char UNUSED id[] = "$Id: parse.c,v 1.52 2002/12/18 13:53:20 alex Exp $";
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ngircd.h"
|
||||
#include "client.h"
|
||||
#include "defines.h"
|
||||
#include "conn.h"
|
||||
#include "irc.h"
|
||||
#include "client.h"
|
||||
#include "channel.h"
|
||||
#include "log.h"
|
||||
#include "messages.h"
|
||||
#include "tool.h"
|
||||
|
||||
#include <exp.h>
|
||||
#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 VOID Parse_Init( VOID )
|
||||
COMMAND My_Commands[] =
|
||||
{
|
||||
} /* Parse_Init */
|
||||
{ "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 },
|
||||
{ "ERROR", IRC_ERROR, 0xFFFF, 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 },
|
||||
{ "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 */
|
||||
};
|
||||
|
||||
|
||||
GLOBAL VOID Parse_Exit( VOID )
|
||||
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 )
|
||||
{
|
||||
} /* Parse_Exit */
|
||||
return My_Commands;
|
||||
} /* Parse_GetCommandStruct */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
|
||||
GLOBAL BOOLEAN
|
||||
Parse_Request( CONN_ID Idx, CHAR *Request )
|
||||
{
|
||||
/* Client-Request parsen. Bei einem schwerwiegenden Fehler wird
|
||||
* die Verbindung geschlossen und FALSE geliefert.
|
||||
@@ -141,6 +121,7 @@ GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
|
||||
|
||||
REQUEST req;
|
||||
CHAR *start, *ptr;
|
||||
BOOLEAN closed;
|
||||
|
||||
assert( Idx >= 0 );
|
||||
assert( Request != NULL );
|
||||
@@ -148,7 +129,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 */
|
||||
@@ -160,7 +141,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
|
||||
@@ -171,8 +156,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 )
|
||||
@@ -186,8 +169,6 @@ GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
|
||||
}
|
||||
req.command = start;
|
||||
|
||||
if( ! Validate_Command( &req )) return Parse_Error( Idx, "Invalid command" );
|
||||
|
||||
/* Argumente, Parameter */
|
||||
if( ptr )
|
||||
{
|
||||
@@ -215,29 +196,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;
|
||||
@@ -247,48 +232,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 );
|
||||
@@ -304,12 +332,12 @@ LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *Req )
|
||||
/* Befehl ist ein Statuscode */
|
||||
|
||||
/* Zielserver ermitteln */
|
||||
if(( Client_Type( client ) == CLIENT_SERVER ) && ( Req->argc > 0 )) target = Client_GetFromID( Req->argv[0] );
|
||||
if(( Client_Type( client ) == CLIENT_SERVER ) && ( Req->argc > 0 )) target = Client_Search( Req->argv[0] );
|
||||
else target = NULL;
|
||||
if( ! target )
|
||||
{
|
||||
if( target ) Log( LOG_WARNING, "Unknown target for status code: \"%s\"", Req->argv[0] );
|
||||
else Log( LOG_WARNING, "Unknown target for status code!" );
|
||||
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( ))
|
||||
@@ -324,7 +352,7 @@ LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *Req )
|
||||
Log( LOG_WARNING, "Got status code without prefix!?" );
|
||||
return TRUE;
|
||||
}
|
||||
else prefix = Client_GetFromID( Req->prefix );
|
||||
else prefix = Client_Search( Req->prefix );
|
||||
if( ! prefix )
|
||||
{
|
||||
Log( LOG_WARNING, "Got status code from unknown source: \"%s\"", Req->prefix );
|
||||
@@ -339,40 +367,42 @@ LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *Req )
|
||||
else strcat( str, " :" );
|
||||
strcat( str, Req->argv[i] );
|
||||
}
|
||||
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 );
|
||||
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,39 +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.4 2002/01/02 02:43:50 alex Exp $
|
||||
* $Id: parse.h,v 1.9 2002/12/18 13:53:20 alex Exp $
|
||||
*
|
||||
* parse.h: Parsen der Client-Anfragen (Header)
|
||||
*
|
||||
* $Log: parse.h,v $
|
||||
* Revision 1.4 2002/01/02 02:43:50 alex
|
||||
* - Copyright-Text ergaenzt bzw. aktualisiert.
|
||||
*
|
||||
* Revision 1.3 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.2 2001/12/26 14:45:37 alex
|
||||
* - "Code Cleanups".
|
||||
*
|
||||
* Revision 1.1 2001/12/21 23:53:16 alex
|
||||
* - Modul zum Parsen von Client-Requests begonnen.
|
||||
* IRC command parser and validator (header)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __parse_h__
|
||||
#define __parse_h__
|
||||
|
||||
#include "conn.h"
|
||||
|
||||
|
||||
typedef struct _REQUEST /* vgl. RFC 2812, 2.3 */
|
||||
{
|
||||
@@ -45,10 +27,19 @@ typedef struct _REQUEST /* vgl. RFC 2812, 2.3 */
|
||||
} REQUEST;
|
||||
|
||||
|
||||
GLOBAL VOID Parse_Init( VOID );
|
||||
GLOBAL VOID Parse_Exit( VOID );
|
||||
typedef struct _COMMAND
|
||||
{
|
||||
CHAR *name; /* command name */
|
||||
BOOLEAN (*function)( 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( CONN_ID Idx, CHAR *Request );
|
||||
|
||||
GLOBAL BOOLEAN Parse_Request PARAMS((CONN_ID Idx, CHAR *Request ));
|
||||
|
||||
GLOBAL COMMAND *Parse_GetCommandStruct PARAMS(( VOID ));
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
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.4 2002/12/12 12:24:18 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 ) strcpy( hostname, h->h_name );
|
||||
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
|
||||
strcpy( hostname, inet_ntoa( Addr->sin_addr ));
|
||||
}
|
||||
|
||||
/* Antwort an Parent schreiben */
|
||||
if( write( w_fd, hostname, strlen( hostname ) + 1 ) != ( 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;
|
||||
strcpy( ip, inet_ntoa( *addr ));
|
||||
}
|
||||
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( write( w_fd, ip, strlen( ip ) + 1 ) != ( 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.3 2002/12/12 12:23:43 alex Exp $
|
||||
*
|
||||
* Asynchronous resolver (header)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __resolve_h__
|
||||
#define __resolve_h__
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
#endif
|
||||
|
||||
|
||||
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- */
|
||||
@@ -2,54 +2,32 @@
|
||||
* 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: tool.c,v 1.6 2002/01/02 02:42:58 alex Exp $
|
||||
*
|
||||
* tool.c: Hilfsfunktionen, ggf. Platformabhaengig
|
||||
*
|
||||
* $Log: tool.c,v $
|
||||
* Revision 1.6 2002/01/02 02:42:58 alex
|
||||
* - Copyright-Texte aktualisiert.
|
||||
*
|
||||
* Revision 1.5 2001/12/31 02:44:36 alex
|
||||
* - ngt_TrimStr() hatte noch einen boesen Bug: evtl. wurde ueber den Start
|
||||
* des Strings nach vorne(!) hinaus gelesen. Hopsa!
|
||||
*
|
||||
* Revision 1.4 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.3 2001/12/29 03:05:34 alex
|
||||
* - Funktionsnamen etwas konsequenter umbenannt :-)
|
||||
*
|
||||
* Revision 1.2 2001/12/12 17:20:33 alex
|
||||
* - Tool-Funktionen haben nun das Praefix "ngt_".
|
||||
*
|
||||
* Revision 1.1.1.1 2001/12/11 21:53:04 alex
|
||||
* - Imported sources to CVS.
|
||||
* Tool functions
|
||||
*/
|
||||
|
||||
|
||||
#include <portab.h>
|
||||
#include "global.h"
|
||||
#include "portab.h"
|
||||
|
||||
#include <imp.h>
|
||||
static char UNUSED id[] = "$Id: tool.c,v 1.10 2002/12/12 12:24:18 alex Exp $";
|
||||
|
||||
#include "imp.h"
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <exp.h>
|
||||
#include "exp.h"
|
||||
#include "tool.h"
|
||||
|
||||
|
||||
GLOBAL VOID ngt_TrimStr( CHAR *String )
|
||||
GLOBAL VOID
|
||||
ngt_TrimStr( CHAR *String )
|
||||
{
|
||||
/* Mit ngt_TrimStr() werden fuehrende und folgende Leerzeichen,
|
||||
* Tabulatoren und Zeilenumbrueche (ASCII 10 und ASCII 13) aus
|
||||
@@ -73,4 +51,27 @@ GLOBAL VOID ngt_TrimStr( CHAR *String )
|
||||
} /* ngt_TrimStr */
|
||||
|
||||
|
||||
GLOBAL CHAR *
|
||||
ngt_LowerStr( CHAR *String )
|
||||
{
|
||||
/* String in Kleinbuchstaben konvertieren. Der uebergebene
|
||||
* Speicherbereich wird durch das Ergebnis ersetzt, zusaetzlich
|
||||
* wird dieser auch als Pointer geliefert. */
|
||||
|
||||
CHAR *ptr;
|
||||
|
||||
assert( String != NULL );
|
||||
|
||||
/* Zeichen konvertieren */
|
||||
ptr = String;
|
||||
while( *ptr )
|
||||
{
|
||||
*ptr = tolower( *ptr );
|
||||
ptr++;
|
||||
}
|
||||
|
||||
return String;
|
||||
} /* ngt_LowerStr */
|
||||
|
||||
|
||||
/* -eof- */
|
||||
|
||||
@@ -2,34 +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: tool.h,v 1.5 2002/01/02 02:42:58 alex Exp $
|
||||
* $Id: tool.h,v 1.9 2002/12/12 12:23:43 alex Exp $
|
||||
*
|
||||
* log.h: Hilfsfunktionen (Header)
|
||||
*
|
||||
* $Log: tool.h,v $
|
||||
* Revision 1.5 2002/01/02 02:42:58 alex
|
||||
* - Copyright-Texte aktualisiert.
|
||||
*
|
||||
* Revision 1.4 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
|
||||
*
|
||||
* Revision 1.3 2001/12/26 14:45:37 alex
|
||||
* - "Code Cleanups".
|
||||
*
|
||||
* Revision 1.2 2001/12/12 17:20:33 alex
|
||||
* - Tool-Funktionen haben nun das Praefix "ngt_".
|
||||
*
|
||||
* Revision 1.1.1.1 2001/12/11 21:53:04 alex
|
||||
* - Imported sources to CVS.
|
||||
* Tool functions (Header)
|
||||
*/
|
||||
|
||||
|
||||
@@ -37,7 +18,9 @@
|
||||
#define __tool_h__
|
||||
|
||||
|
||||
GLOBAL VOID ngt_TrimStr( CHAR *String );
|
||||
GLOBAL VOID ngt_TrimStr PARAMS((CHAR *String ));
|
||||
|
||||
GLOBAL CHAR *ngt_LowerStr PARAMS((CHAR *String ));
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
32
src/portab/Makefile.am
Normal file
32
src/portab/Makefile.am
Normal file
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# 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.4 2002/05/22 09:09:43 alex Exp $
|
||||
#
|
||||
|
||||
AUTOMAKE_OPTIONS = ansi2knr
|
||||
|
||||
noinst_LIBRARIES = libngportab.a
|
||||
|
||||
libngportab_a_SOURCES = vsnprintf.c
|
||||
|
||||
check_PROGRAMS = portabtest
|
||||
|
||||
portabtest_SOURCES = portabtest.c
|
||||
|
||||
noinst_HEADERS = imp.h exp.h portab.h
|
||||
|
||||
maintainer-clean-local:
|
||||
rm -f Makefile Makefile.in
|
||||
|
||||
TESTS = portabtest
|
||||
|
||||
# -eof-
|
||||
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;
|
||||
}
|
||||
22
src/portab/exp.h
Normal file
22
src/portab/exp.h
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: exp.h,v 1.1 2002/03/12 14:36:44 alex Exp $
|
||||
*
|
||||
* exp.h: "Export Header"
|
||||
*/
|
||||
|
||||
|
||||
#undef GLOBAL
|
||||
#define GLOBAL
|
||||
|
||||
|
||||
/* -eof- */
|
||||
22
src/portab/imp.h
Normal file
22
src/portab/imp.h
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: imp.h,v 1.1 2002/03/12 14:36:44 alex Exp $
|
||||
*
|
||||
* imp.h: "Import Header"
|
||||
*/
|
||||
|
||||
|
||||
#undef GLOBAL
|
||||
#define GLOBAL extern
|
||||
|
||||
|
||||
/* -eof- */
|
||||
137
src/portab/portab.h
Normal file
137
src/portab/portab.h
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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: portab.h,v 1.9 2002/12/12 11:26:08 alex Exp $
|
||||
*
|
||||
* portab.h: "Portabilitaets-Definitionen"
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __PORTAB__
|
||||
#define __PORTAB__
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
/* 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 */
|
||||
|
||||
#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;
|
||||
typedef unsigned short UINT16;
|
||||
typedef signed long INT32;
|
||||
typedef unsigned long UINT32;
|
||||
|
||||
typedef double DOUBLE;
|
||||
typedef float FLOAT;
|
||||
|
||||
typedef char CHAR;
|
||||
|
||||
typedef UINT8 BOOLEAN;
|
||||
|
||||
#undef TRUE
|
||||
#define TRUE (BOOLEAN)1
|
||||
|
||||
#undef FALSE
|
||||
#define FALSE (BOOLEAN)0
|
||||
|
||||
#undef NULL
|
||||
#ifdef PROTOTYPES
|
||||
# define NULL (VOID *)0
|
||||
#else
|
||||
# define NULL 0L
|
||||
#endif
|
||||
|
||||
#undef GLOBAL
|
||||
#define GLOBAL
|
||||
|
||||
|
||||
/* SPLint */
|
||||
|
||||
|
||||
#ifdef S_SPLINT_S
|
||||
#include "splint.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* configure-Optionen */
|
||||
|
||||
#ifndef HAVE_socklen_t
|
||||
#define socklen_t int /* u.a. fuer Mac OS X */
|
||||
#endif
|
||||
|
||||
#if OS_UNIX_AUX
|
||||
#define _POSIX_SOURCE /* muss unter A/UX definiert sein */
|
||||
#endif
|
||||
|
||||
|
||||
/* Konstanten */
|
||||
|
||||
#ifndef TARGET_OS
|
||||
#define TARGET_OS "unknown"
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_CPU
|
||||
#define TARGET_CPU "unknown"
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_VENDOR
|
||||
#define TARGET_VENDOR "unknown"
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* -eof- */
|
||||
43
src/portab/portabtest.c
Normal file
43
src/portab/portabtest.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* test program for portab.h and friends ;-)
|
||||
*/
|
||||
|
||||
|
||||
#include "portab.h"
|
||||
|
||||
static char UNUSED id[] = "$Id: portabtest.c,v 1.9 2002/12/12 11:38:46 alex Exp $";
|
||||
|
||||
#include "imp.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "exp.h"
|
||||
|
||||
|
||||
GLOBAL int
|
||||
main( VOID )
|
||||
{
|
||||
/* Datentypen pruefen */
|
||||
if( FALSE != 0 ) return 1;
|
||||
if( TRUE != 1 ) return 1;
|
||||
if( sizeof( INT8 ) != 1 ) return 1;
|
||||
if( sizeof( UINT8 ) != 1 ) return 1;
|
||||
if( sizeof( INT16 ) != 2 ) return 1;
|
||||
if( sizeof( UINT16 ) != 2 ) return 1;
|
||||
if( sizeof( INT32 ) != 4 ) return 1;
|
||||
if( sizeof( UINT32 ) != 4 ) return 1;
|
||||
|
||||
/* kein Fehler */
|
||||
return 0;
|
||||
} /* portab_check_types */
|
||||
|
||||
|
||||
/* -eof- */
|
||||
43
src/portab/splint.h
Normal file
43
src/portab/splint.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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: splint.h,v 1.1 2002/03/25 19:13:19 alex Exp $
|
||||
*
|
||||
* splint.h: spezieller Header fuer SPLint Code-Check
|
||||
*
|
||||
* Dieser Header wird von portab.h nur dann includiert, wenn ein Code-Check
|
||||
* mit SPLint laeufr (d.h. S_SPLINT_S definiert ist).
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __splint__
|
||||
#define __splint__
|
||||
|
||||
|
||||
#define SYSCONFDIR "/"
|
||||
#define LOCALSTATEDIR "/"
|
||||
|
||||
#define LOG_EMERG 0
|
||||
#define LOG_ALERT 1
|
||||
#define LOG_CRIT 2
|
||||
#define LOG_ERR 3
|
||||
#define LOG_WARNING 4
|
||||
#define LOG_NOTICE 5
|
||||
#define LOG_INFO 6
|
||||
#define LOG_DEBUG 7
|
||||
|
||||
#define WNOHANG 0
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* -eof- */
|
||||
926
src/portab/vsnprintf.c
Normal file
926
src/portab/vsnprintf.c
Normal file
@@ -0,0 +1,926 @@
|
||||
/*
|
||||
* 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.4 2002/12/12 11:37:11 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 )) { }
|
||||
#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-
|
||||
30
src/testsuite/getpid.sh
Executable file
30
src/testsuite/getpid.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
# ngIRCd Test Suite
|
||||
# $Id: getpid.sh,v 1.2 2002/11/10 14:28:06 alex Exp $
|
||||
|
||||
# wurde ein Name uebergeben?
|
||||
[ $# -ne 1 ] && exit 1
|
||||
|
||||
# Flags fuer "ps" ermitteln
|
||||
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"
|
||||
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
|
||||
|
||||
# PID ermitteln
|
||||
ps $PS_FLAGS > procs.tmp
|
||||
pid=$( cat procs.tmp | grep "$1" | awk "{print \$$PS_PIDCOL}" | sort -n | head $HEAD_FLAGS )
|
||||
|
||||
# ermittelte PID validieren
|
||||
[ "$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-
|
||||
14
src/testsuite/ngircd-test.conf
Normal file
14
src/testsuite/ngircd-test.conf
Normal file
@@ -0,0 +1,14 @@
|
||||
# $Id: ngircd-test.conf,v 1.3 2002/10/21 13:45:23 alex Exp $
|
||||
|
||||
[Global]
|
||||
Name = ngircd.test.server
|
||||
Info = ngIRCd Test-Server
|
||||
Ports = 6789
|
||||
MotdFile = ngircd-test.motd
|
||||
AdminEMail = admin@irc.server
|
||||
|
||||
[Operator]
|
||||
Name = TestOp
|
||||
Password = 123
|
||||
|
||||
# -eof-
|
||||
32
src/testsuite/start-server.sh
Executable file
32
src/testsuite/start-server.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
# ngIRCd Test Suite
|
||||
# $Id: start-server.sh,v 1.10 2002/11/10 14:28:06 alex Exp $
|
||||
|
||||
[ -z "$srcdir" ] && srcdir=`dirname $0`
|
||||
|
||||
echo " starting server ..."
|
||||
|
||||
# alte Logfiles loeschen
|
||||
rm -rf logs *.log
|
||||
|
||||
# pruefen, ob getpid.sh gueltige PID's liefert. Wenn dem nicht so ist,
|
||||
# wird kein ngIRCd gestartet, da dieser ansonsten nicht mehr am Ende
|
||||
# des Testlaufs beendet werden koennte!
|
||||
./getpid.sh sh > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " error: getpid.sh FAILED!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# MOTD fuer Test-Server erzeugen
|
||||
echo "This is an ngIRCd Test Server" > ngircd-test.motd
|
||||
|
||||
# Test-Server starten ...
|
||||
./T-ngircd -np -f ${srcdir}/ngircd-test.conf > ngircd-test.log 2>&1 &
|
||||
sleep 1
|
||||
|
||||
# validieren, dass Server laeuft
|
||||
pid=`./getpid.sh T-ngircd`
|
||||
[ -n "$pid" ] && kill -0 $pid > /dev/null 2>&1 || exit 1
|
||||
|
||||
# -eof-
|
||||
17
src/testsuite/stop-server.sh
Executable file
17
src/testsuite/stop-server.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
# ngIRCd Test Suite
|
||||
# $Id: stop-server.sh,v 1.9 2002/11/10 14:28:06 alex Exp $
|
||||
|
||||
[ -z "$srcdir" ] && srcdir=`dirname $0`
|
||||
|
||||
echo " stopping server ..."
|
||||
|
||||
# Test-Server stoppen ...
|
||||
pid=`./getpid.sh T-ngircd`
|
||||
[ -n "$pid" ] && kill $pid > /dev/null 2>&1 || exit 1
|
||||
sleep 1
|
||||
|
||||
# jetzt duerfte der Prozess nicht mehr laufen
|
||||
kill -0 $pid > /dev/null 2>&1 && exit 1 || exit 0
|
||||
|
||||
# -eof-
|
||||
9
src/testsuite/stress-A.e
Normal file
9
src/testsuite/stress-A.e
Normal file
@@ -0,0 +1,9 @@
|
||||
# $Id: stress-A.e,v 1.1 2002/09/09 22:56:07 alex Exp $
|
||||
|
||||
spawn telnet localhost 6789
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"Connected"
|
||||
}
|
||||
|
||||
# -eof-
|
||||
69
src/testsuite/stress-B.e
Normal file
69
src/testsuite/stress-B.e
Normal file
@@ -0,0 +1,69 @@
|
||||
# $Id: stress-B.e,v 1.1 2002/09/09 22:56:07 alex Exp $
|
||||
|
||||
send "user user . . :User\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"376"
|
||||
}
|
||||
|
||||
send "oper TestOp 123\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"MODE test* :+o"
|
||||
}
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"381 test*"
|
||||
}
|
||||
|
||||
send "join #channel\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":test*!~user@* JOIN :#channel"
|
||||
}
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"366"
|
||||
}
|
||||
|
||||
send "mode #channel\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"324 test* #channel"
|
||||
}
|
||||
|
||||
send "join #channel2\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":test*!~user@* JOIN :#channel2"
|
||||
}
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"366"
|
||||
}
|
||||
|
||||
send "names\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"366"
|
||||
}
|
||||
|
||||
send "part #channel2\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":test*!~user@* PART #channel2"
|
||||
}
|
||||
|
||||
send "part #channel\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
":test*!~user@* PART #channel"
|
||||
}
|
||||
|
||||
send "quit\r"
|
||||
expect {
|
||||
timeout { exit 1 }
|
||||
"Connection closed"
|
||||
}
|
||||
|
||||
# -eof-
|
||||
46
src/testsuite/stress-server.sh
Executable file
46
src/testsuite/stress-server.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/sh
|
||||
# ngIRCd Test Suite
|
||||
# $Id: stress-server.sh,v 1.6 2002/09/23 22:07:43 alex Exp $
|
||||
|
||||
[ -z "$srcdir" ] && srcdir=`dirname $0`
|
||||
|
||||
[ $1 -gt 0 ] 2> /dev/null && CLIENTS=$1 || CLIENTS=5
|
||||
|
||||
name=`basename $0`
|
||||
test=`echo ${name} | cut -d '.' -f 1`
|
||||
mkdir -p logs tests
|
||||
|
||||
type expect > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "SKIP: ${name} -- \"expect\" not found."; exit 77
|
||||
fi
|
||||
type telnet > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "SKIP: ${name} -- \"telnet\" not found."; exit 77
|
||||
fi
|
||||
|
||||
echo " stressing server with $CLIENTS clients (be patient!) ..."
|
||||
no=0
|
||||
while [ ${no} -lt $CLIENTS ]; do
|
||||
cat ${srcdir}/stress-A.e > tests/${no}.e
|
||||
echo "send \"nick test${no}\\r\"" >> tests/${no}.e
|
||||
cat ${srcdir}/stress-B.e >> tests/${no}.e
|
||||
no=`expr ${no} + 1`
|
||||
done
|
||||
no=0
|
||||
while [ ${no} -lt $CLIENTS ]; do
|
||||
expect tests/${no}.e > logs/stress-${no}.log 2> /dev/null &
|
||||
no=`expr ${no} + 1`
|
||||
done
|
||||
|
||||
touch logs/check-idle.log
|
||||
while true; do
|
||||
expect ${srcdir}/check-idle.e >> logs/check-idle.log
|
||||
res=$?
|
||||
[ $res -eq 0 ] && exit 0
|
||||
[ $res -eq 1 ] && exit 1
|
||||
sleep 1
|
||||
echo "====================" >> logs/check-idle.log
|
||||
done
|
||||
|
||||
# -eof-
|
||||
21
src/testsuite/tests.sh
Executable file
21
src/testsuite/tests.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
# ngIRCd Test Suite
|
||||
# $Id: tests.sh,v 1.3 2002/09/12 02:29:03 alex Exp $
|
||||
|
||||
name=`basename $0`
|
||||
test=`echo ${name} | cut -d '.' -f 1`
|
||||
mkdir -p logs
|
||||
|
||||
type expect > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "SKIP: ${name} -- \"expect\" not found."; exit 77
|
||||
fi
|
||||
type telnet > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "SKIP: ${name} -- \"telnet\" not found."; exit 77
|
||||
fi
|
||||
|
||||
echo " doing ${test} ..."
|
||||
expect ${srcdir}/${test}.e > logs/${test}.log
|
||||
|
||||
# -eof-
|
||||
Reference in New Issue
Block a user