mirror of
https://github.com/osmarks/ngircd.git
synced 2025-11-01 14:33:00 +00:00
Compare commits
152 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
1e56fb35ab | ||
|
|
408793c2ca | ||
|
|
1ab92bb9cb | ||
|
|
5a0f118df0 | ||
|
|
eab20beefc | ||
|
|
0bb9db1aa0 | ||
|
|
8316d98b16 | ||
|
|
a0123e424c | ||
|
|
ff25b7291f | ||
|
|
eba8d4d553 | ||
|
|
71c7a6fcc0 | ||
|
|
3b38d3ca0d | ||
|
|
6491b9843f | ||
|
|
40c9fd26d6 | ||
|
|
b5ee4552c1 | ||
|
|
8f521aa8bf | ||
|
|
b28dab3632 | ||
|
|
9f9e9a496f | ||
|
|
d17748e978 | ||
|
|
d14588f368 | ||
|
|
d569c9246e | ||
|
|
791301dc7d | ||
|
|
92fb409fe2 | ||
|
|
8a324b6d9c | ||
|
|
7709acf754 | ||
|
|
077b610eb0 | ||
|
|
23253edb54 | ||
|
|
bb19cfda95 | ||
|
|
4b0c9849d6 | ||
|
|
fc3c82f7df | ||
|
|
5999fcea4e | ||
|
|
87fc9566b0 | ||
|
|
85ac414908 | ||
|
|
01999cfdb1 | ||
|
|
4c32a6cebd | ||
|
|
9951e13510 | ||
|
|
d3e0d78d4d | ||
|
|
20640e1a90 | ||
|
|
6debfc3123 | ||
|
|
49ed223c1b | ||
|
|
00f86465ef | ||
|
|
d79a7d287a | ||
|
|
5829be2944 | ||
|
|
bd923fc757 | ||
|
|
6600c90890 | ||
|
|
b9d701dbeb | ||
|
|
b3ccaa76b6 | ||
|
|
8d48f07de1 | ||
|
|
568239244f | ||
|
|
22cf0c5def | ||
|
|
c2ee5437da | ||
|
|
4fe7e9d6f1 | ||
|
|
006c0328b4 | ||
|
|
52424b49cb | ||
|
|
baf845ddeb | ||
|
|
428cc6258f | ||
|
|
3543c2220a | ||
|
|
8f7e7d666a | ||
|
|
a53857b4c7 | ||
|
|
2714a94f43 | ||
|
|
6359ec48f0 | ||
|
|
b89c310891 | ||
|
|
bf92db85a6 | ||
|
|
9e18ec30ff | ||
|
|
a56776892b | ||
|
|
969e5f1c12 | ||
|
|
81afb0cb31 | ||
|
|
85d7e12a0f | ||
|
|
018cffbb5f | ||
|
|
8b162c0ecd | ||
|
|
79809118a3 | ||
|
|
dbd0a23994 | ||
|
|
904d5e5b09 | ||
|
|
2e4d085df5 | ||
|
|
e44988f23d | ||
|
|
0b15709e4c | ||
|
|
1c8c92af42 | ||
|
|
adcf68be90 | ||
|
|
e7be3a01f3 | ||
|
|
a5e92ba180 | ||
|
|
db58d34797 | ||
|
|
2e289b5084 | ||
|
|
b20d2df064 | ||
|
|
bcc0cdc3ab | ||
|
|
bb2143aabc | ||
|
|
03783eea35 | ||
|
|
406ac2c8c2 | ||
|
|
3d2e944856 | ||
|
|
a19c9ed5c7 | ||
|
|
bed4005ed0 | ||
|
|
165d165b63 | ||
|
|
c48544703d | ||
|
|
5ff42762cd | ||
|
|
4d4f2d4ffb | ||
|
|
bf1c59c61c | ||
|
|
f755190093 | ||
|
|
356683ff6e | ||
|
|
d29ac98938 | ||
|
|
0c4e71da9c | ||
|
|
07903baa61 | ||
|
|
ed406b4a93 | ||
|
|
b9bf012e83 | ||
|
|
d1574f872f | ||
|
|
54e487d424 | ||
|
|
93aa0dbfb8 | ||
|
|
0d2c0db71a | ||
|
|
f4dc4ae7ba | ||
|
|
4a8fd02f99 | ||
|
|
cb7931cc27 | ||
|
|
64218c161c | ||
|
|
32b29d6956 | ||
|
|
71f297097b | ||
|
|
ef8c58c43b | ||
|
|
21a8a278fb | ||
|
|
03d971d994 | ||
|
|
020c6d8bb3 | ||
|
|
b6254bbbb3 | ||
|
|
1547f76cfd | ||
|
|
e42fae3918 | ||
|
|
55aa0f221c | ||
|
|
0b5e853138 | ||
|
|
667a621ed6 | ||
|
|
b20fa7c6e6 | ||
|
|
71939cf513 | ||
|
|
b169f0c524 |
2
AUTHORS
2
AUTHORS
@@ -1,7 +1,7 @@
|
||||
|
||||
ngIRCd - Next Generation IRC Server
|
||||
|
||||
(c)2001 by Alexander Barton,
|
||||
(c)2001,2002 by Alexander Barton,
|
||||
alex@barton.de, http://www.barton.de/
|
||||
|
||||
ngIRCd ist freie Software und steht unter
|
||||
|
||||
90
ChangeLog
90
ChangeLog
@@ -1,7 +1,7 @@
|
||||
|
||||
ngIRCd - Next Generation IRC Server
|
||||
|
||||
(c)2001 by Alexander Barton,
|
||||
(c)2001,2002 by Alexander Barton,
|
||||
alex@barton.de, http://www.barton.de/
|
||||
|
||||
ngIRCd ist freie Software und steht unter
|
||||
@@ -10,5 +10,89 @@
|
||||
-- ChangeLog / Aenderungen --
|
||||
|
||||
|
||||
[Zur Zeit ist kein "ChangeLog" vorhanden. Bitte ziehe die CVS-Kommentare in
|
||||
den einzelnen Dateien zu Rate ...]
|
||||
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)
|
||||
wurden falsch uebernommen. Zudem wurden die Modes falsch gekuerzt.
|
||||
- Server-Verbindungen werden nun nach dem Start erst nach einer kurzen
|
||||
Pause aufgebaut (zur Zeit drei Sekunden).
|
||||
- Hilfetext korrigiert: --help und --version waren vertauscht, die
|
||||
Option --sniffer wurde gar nicht erwaehnt.
|
||||
- FAQ.txt in doc/ begonnen.
|
||||
- der IRC-Sniffer wird nur noch aktiviert, wenn die Option auf der
|
||||
Kommandozeile angegeben wurde (bei entsprechend compiliertem Server).
|
||||
- Channels implementiert, bisher jedoch noch ohne Channel-Modes, d.h.
|
||||
es gibt keine Channel-Ops, kein Topic, kein "topic lock" etc. pp.
|
||||
Chatten in Channels ist aber natuerlich moeglich ;-)
|
||||
- neue Befehle fuer Channles: JOIN, PART und NJOIN.
|
||||
- durch die Channels einige Aenderungen an PRIVMSG, WHOIS, MODE etc.
|
||||
- neu connectierenden Servern werden nun Channels mit NJOIN angekuendigt.
|
||||
- Signal-Hander geaendert: die Fehlermeldung "interrupted system call"
|
||||
sollte so nicht mehr auftreten.
|
||||
- "spaeter" neu connectierende Server werden nun im Netz angekuendigt.
|
||||
- SERVER-Meldungen an andere Server sind nun korrekt sortiert.
|
||||
- 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
|
||||
"Sub-Server" haben, also sowohl als Leaf-Node als auch Hub in einem
|
||||
IRC-Netzwerk arbeiten.
|
||||
- MODE und NICK melden nun die Aenderungen an andere Server, ebenso
|
||||
die Befehle QUIT und SQUIT.
|
||||
- WHOIS wird nun immer an den "Original-Server" weitergeleitet.
|
||||
- Parses handhabt Leerzeichen zw. Parametern nun etwas "lockerer".
|
||||
- Status-Codes an den Server selber werden ignorier.
|
||||
- Log-Meldungen und Log-Level ueberarbeitet und korrigiert.
|
||||
- Kommandozeilen-Parser: Debug- und No-Daemon-Modus, Hilfe.
|
||||
- ngIRCd wandelt sich nun in einen Daemon (Hintergrundprozess) um.
|
||||
- WHOIS korrigiert: Anfrage wurde u.U. an User geforwarded anstatt vom
|
||||
Server beantwortet zu werden.
|
||||
- neue Befehle: LUSERS, LINKS
|
||||
- Client-Modes von Remote-Servern wurden nicht korrekt uerbernommen.
|
||||
|
||||
ngIRCd 0.0.2, 06.01.2002
|
||||
|
||||
- Struktur der Konfigurationsdatei geaendert: sie ist nun "Samba like",
|
||||
d.h. sie besteht aus Abschnitten (siehe "doc/sample-ngircd.conf").
|
||||
- Es koennen mehrere IRC-Server-Opertatoren konfiguriert werden.
|
||||
- Zombies der Resolver-Prozesse werden nun ordentlich "getoetet".
|
||||
- NICK kann nun die Gross- und Kleinschreibung eines Nicks aendern.
|
||||
- ein Server-Passwort ist nun konfigurierbar.
|
||||
- neue Befehle: ERROR, SERVER, NJOIN (nur als "Fake"), SQUIT.
|
||||
- Asyncroner Resolver Hostname->IP implementiert.
|
||||
- Server-Links teilweise implementiert: bisher kann der ngIRCd jedoch
|
||||
nur "leafed server" sein, d.h. keine "Client-Server" haben. Einige
|
||||
Befehle sind auch noch nicht (optimal) angepasst: PRIVMSG funktioniert
|
||||
aber bereits, ebenso wie WHOIS (letzterer wird immer an den Server,
|
||||
auf dem der User registriert ist, weitergegeben).
|
||||
- "arpa/inet.h" wird nur noch includiert, wenn vorhanden.
|
||||
- Fehler bei select() fuerhen nun zum Abbruch von ngIRCd, bisher landete
|
||||
der Server zumeist in einer Endlosschleife.
|
||||
- Logmeldungen und Level an vielen Stellen verbessert.
|
||||
- lokalen Usernamen wird nun ein "~" vorangestellt, da bisher noch keine
|
||||
Ident-Anfragen gemacht werden.
|
||||
|
||||
ngIRCd 0.0.1, 31.12.2001
|
||||
|
||||
- erste oeffentliche Version von ngIRCd als "public preview" :-)
|
||||
|
||||
|
||||
--
|
||||
$Id: ChangeLog,v 1.17 2002/02/15 14:35:55 alex Exp $
|
||||
|
||||
2
INSTALL
2
INSTALL
@@ -1,7 +1,7 @@
|
||||
|
||||
ngIRCd - Next Generation IRC Server
|
||||
|
||||
(c)2001 by Alexander Barton,
|
||||
(c)2001,2002 by Alexander Barton,
|
||||
alex@barton.de, http://www.barton.de/
|
||||
|
||||
ngIRCd ist freie Software und steht unter
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
# $Id: Makefile.am,v 1.2 2001/12/31 16:02:12 alex Exp $
|
||||
|
||||
#
|
||||
# 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.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.
|
||||
#
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
# $Id: Makefile.am,v 1.1 2001/12/31 16:02:12 alex Exp $
|
||||
|
||||
#
|
||||
# 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/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.
|
||||
#
|
||||
|
||||
@@ -141,9 +141,9 @@
|
||||
F52162DD01C7BCDD012300F4,
|
||||
F52162E501C7C79E012300F4,
|
||||
F51D17FF01C8F5B701E11C2E,
|
||||
F51D180601C8FDD001E11C2E,
|
||||
F51D180701C8FDD001E11C2E,
|
||||
F576ABFD01D5E77301A85B03,
|
||||
F5263AEE01E263D201CE8F8F,
|
||||
);
|
||||
isa = PBXSourcesBuildPhase;
|
||||
name = Sources;
|
||||
@@ -250,12 +250,6 @@
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F51D180601C8FDD001E11C2E = {
|
||||
fileRef = F51D180001C8FDD001E11C2E;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F51D180701C8FDD001E11C2E = {
|
||||
fileRef = F51D180201C8FDD001E11C2E;
|
||||
isa = PBXBuildFile;
|
||||
@@ -276,6 +270,7 @@
|
||||
};
|
||||
F51F791401DFD0DE01D13771 = {
|
||||
children = (
|
||||
F5263AEF01E2A9B801CE8F8F,
|
||||
F51F791501DFD0DE01D13771,
|
||||
F51F791601DFD0DE01D13771,
|
||||
F51F791701DFD0DE01D13771,
|
||||
@@ -553,6 +548,18 @@
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5263AEE01E263D201CE8F8F = {
|
||||
fileRef = F51D180001C8FDD001E11C2E;
|
||||
isa = PBXBuildFile;
|
||||
settings = {
|
||||
};
|
||||
};
|
||||
F5263AEF01E2A9B801CE8F8F = {
|
||||
isa = PBXFileReference;
|
||||
name = Makefile.am;
|
||||
path = ../doc/Makefile.am;
|
||||
refType = 2;
|
||||
};
|
||||
F56D8B9E01E0BFA00155ADA7 = {
|
||||
children = (
|
||||
F56D8B9F01E0BFA00155ADA7,
|
||||
|
||||
18
Makefile.am
18
Makefile.am
@@ -1,6 +1,20 @@
|
||||
# $Id: Makefile.am,v 1.4 2001/12/31 02:20:20 alex Exp $
|
||||
|
||||
#
|
||||
# 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/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.
|
||||
#
|
||||
|
||||
47
NEWS
47
NEWS
@@ -1,7 +1,7 @@
|
||||
|
||||
ngIRCd - Next Generation IRC Server
|
||||
|
||||
(c)2001 by Alexander Barton,
|
||||
(c)2001,2002 by Alexander Barton,
|
||||
alex@barton.de, http://www.barton.de/
|
||||
|
||||
ngIRCd ist freie Software und steht unter
|
||||
@@ -10,5 +10,46 @@
|
||||
-- NEWS / Neuigkeiten --
|
||||
|
||||
|
||||
[Zur Zeit nicht vorhanden. Bitte die CVS-Kommentare in den einzelnen Dateien
|
||||
zu Rate ziehen -- oder das ChangeLog, so es existent sein sollte ;-)]
|
||||
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.
|
||||
es gibt keine Channel-Ops, kein Topic, kein "topic lock" etc. pp.
|
||||
Chatten in Channels ist aber natuerlich moeglich ;-)
|
||||
Dadurch zum Teil groessere Aenderungen an bisherigen Funktionen.
|
||||
- neue Befehle fuer Channles: JOIN, PART und NJOIN.
|
||||
- FAQ.txt in doc/ begonnen.
|
||||
|
||||
ngIRCd 0.0.3, 16.01.2002
|
||||
|
||||
- Server-Links vollstaendig implementiert: der ngIRCd kann nun auch
|
||||
"Sub-Server" haben, also sowohl als Leaf-Node als auch Hub in einem
|
||||
IRC-Netzwerk arbeiten.
|
||||
- WHOIS wird nun immer an den "Original-Server" weitergeleitet.
|
||||
- Parser handhabt Leerzeichen zw. Parametern nun etwas "lockerer".
|
||||
- Kommandozeilen-Parser: Debug- und No-Daemon-Modus, Hilfe.
|
||||
- ngIRCd wandelt sich nun in einen Daemon (Hintergrundprozess) um.
|
||||
- neue Befehle: LUSERS, LINKS.
|
||||
|
||||
ngIRCd 0.0.2, 06.01.2002
|
||||
|
||||
- neuer Aufbau der Konfigurationsdatei,
|
||||
- mehrere IRC-Operatoren koennen konfiguriert werden,
|
||||
- Server-Links teilweise implementiert. Bisher kann der ngIRCd jedoch
|
||||
nur "leafed server" sein, d.h. keine "Client-Server" haben.
|
||||
|
||||
ngIRCd 0.0.1, 31.12.2001
|
||||
|
||||
- erste oeffentliche Version von ngIRCd als "public preview" :-)
|
||||
|
||||
|
||||
--
|
||||
$Id: NEWS,v 1.10 2002/02/15 14:35:55 alex Exp $
|
||||
|
||||
13
README
13
README
@@ -1,7 +1,7 @@
|
||||
|
||||
ngIRCd - Next Generation IRC Server
|
||||
|
||||
(c)2001 by Alexander Barton,
|
||||
(c)2001,2002 by Alexander Barton,
|
||||
alex@barton.de, http://www.barton.de/
|
||||
|
||||
ngIRCd ist freie Software und steht unter
|
||||
@@ -20,12 +20,11 @@ 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 ;-)
|
||||
|
||||
Diese Version ist aber auf jeden Fall als "Preview" anzusehen!
|
||||
|
||||
Bisher (mehr oder wenig vollstaendig) implementierte IRC-Befehle:
|
||||
|
||||
DIE, ISON, MODE, MOTD, NAMES, NICK, NOTICE, OPER, PASS, PING, PONG, PRIVMSG,
|
||||
QUIT, RESTART, USER, USERHOST, WHOIS.
|
||||
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! :-))
|
||||
@@ -40,3 +39,7 @@ 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 ,-)
|
||||
|
||||
|
||||
--
|
||||
$Id: README,v 1.4 2002/01/29 00:17:39 alex Exp $
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,9 +9,12 @@
|
||||
* 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.6 2001/12/31 02:21:00 alex Exp $
|
||||
* $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.
|
||||
*
|
||||
|
||||
75
configure.in
75
configure.in
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# ngIRCd -- The Next Generation IRC Daemon
|
||||
# Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
# 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
|
||||
@@ -9,9 +9,42 @@
|
||||
# Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
# der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
#
|
||||
# $Id: configure.in,v 1.13 2001/12/31 16:02:30 alex Exp $
|
||||
# $Id: configure.in,v 1.24 2002/02/15 14:35:55 alex Exp $
|
||||
#
|
||||
# $Log: configure.in,v $
|
||||
# Revision 1.24 2002/02/15 14:35:55 alex
|
||||
# - Version 0.2.0
|
||||
#
|
||||
# Revision 1.23 2002/01/29 01:07:15 alex
|
||||
# - Version auf 0.1.1-pre im CVS angehoben.
|
||||
#
|
||||
# Revision 1.22 2002/01/29 00:24:17 alex
|
||||
# - Version 0.1.0
|
||||
#
|
||||
# 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
|
||||
#
|
||||
@@ -56,13 +89,11 @@
|
||||
|
||||
AC_INIT
|
||||
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
|
||||
AM_INIT_AUTOMAKE(ngircd,0.0.1)
|
||||
AM_INIT_AUTOMAKE(ngircd,0.2.0)
|
||||
AM_CONFIG_HEADER(src/config.h)
|
||||
|
||||
# -- Variablen --
|
||||
|
||||
CFLAGS="-Wall -g $CFLAGS"
|
||||
|
||||
# -- C Compiler --
|
||||
|
||||
AC_PROG_CC
|
||||
@@ -108,10 +139,12 @@ AC_ARG_WITH(portab,
|
||||
)
|
||||
|
||||
AC_CHECK_HEADERS([ \
|
||||
arpa/inet.h errno.h fcntl.h netinet/in.h string.h \
|
||||
errno.h fcntl.h netinet/in.h string.h \
|
||||
sys/socket.h sys/time.h unistd.h \
|
||||
],,AC_MSG_ERROR([required C header missing!]))
|
||||
|
||||
AC_CHECK_HEADERS(arpa/inet.h)
|
||||
|
||||
# -- Datentypen --
|
||||
|
||||
AC_MSG_CHECKING(whether socklen_t exists)
|
||||
@@ -133,9 +166,11 @@ AC_FUNC_MALLOC
|
||||
|
||||
AC_CHECK_FUNCS([ \
|
||||
gethostname inet_ntoa memmove memset select \
|
||||
socket strcasecmp strchr strerror strstr \
|
||||
socket strcasecmp strchr strerror strstr waitpid \
|
||||
],,AC_MSG_ERROR([required function missing!]))
|
||||
|
||||
AC_CHECK_FUNCS(inet_aton)
|
||||
|
||||
# -- Libraries --
|
||||
|
||||
# -- Konfigurationsoptionen --
|
||||
@@ -160,24 +195,30 @@ AC_ARG_ENABLE(strict-rfc,
|
||||
fi
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug show additional debug output],
|
||||
if test "$enableval" = "yes"; then
|
||||
AC_DEFINE(DEBUG, 1)
|
||||
AC_MSG_RESULT([enabling additional debug output])
|
||||
fi
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(sniffer,
|
||||
[ --enable-sniffer enable network traffic monitor (enables debug mode!)],
|
||||
if test "$enableval" = "yes"; then
|
||||
AC_DEFINE(DEBUG, 1)
|
||||
AC_MSG_RESULT([enabling additional debug output])
|
||||
AC_DEFINE(SNIFFER, 1)
|
||||
AC_MSG_RESULT([enabling network traffic monitor])
|
||||
x_debug_on=yes
|
||||
fi
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
[ --enable-debug show additional debug output],
|
||||
if test "$enableval" = "yes"; then x_debug_on=yes; fi
|
||||
)
|
||||
if test "$x_debug_on" = "yes"; then
|
||||
AC_DEFINE(DEBUG, 1)
|
||||
AC_MSG_RESULT([enabling additional debug output])
|
||||
fi
|
||||
|
||||
# -- Variablen II --
|
||||
|
||||
if test "$GCC" = "yes"; then
|
||||
CFLAGS="-Wall $CFLAGS"
|
||||
fi
|
||||
|
||||
# -- Ausgabe --
|
||||
|
||||
AC_OUTPUT([ \
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
ngIRCd - Next Generation IRC Server
|
||||
|
||||
(c)2001 by Alexander Barton,
|
||||
(c)2001,2002 by Alexander Barton,
|
||||
alex@barton.de, http://www.barton.de/
|
||||
|
||||
ngIRCd ist freie Software und steht unter
|
||||
@@ -19,3 +19,7 @@ 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 ... ]
|
||||
|
||||
|
||||
--
|
||||
$Id: CVS.txt,v 1.4 2002/01/23 18:20:04 alex Exp $
|
||||
|
||||
46
doc/FAQ.txt
Normal file
46
doc/FAQ.txt
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
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.
|
||||
|
||||
-- FAQ: Frequently Asked Questions --
|
||||
|
||||
|
||||
I. Allgemein
|
||||
~~~~~~~~~~~~
|
||||
Q: Kann der ngIRCd im Netz zusammen mit "normalen" Servern betrieben werden?
|
||||
A: Ja. ngIRCd ist zum Original kompatibel, getestet wird dies zur Zeit mit
|
||||
der Version 2.10.3p3 des ircd.
|
||||
|
||||
Q: Gibt es eine Homepage mit Informationen und Downloads?
|
||||
A: Ja. Die URL ist <http://arthur.ath.cx/~alex/ngircd/>.
|
||||
|
||||
|
||||
II. Compilieren
|
||||
~~~~~~~~~~~~~~~
|
||||
Q: Ich habe die Sourcen von ngIRCd ueber CVS installiert. Nun kann ich
|
||||
./configure nicht ausfuehren, da es nicht existiert!?
|
||||
A: Bei Builds direkt aus dem CVS-Tree muss das configure-Script zunaechst
|
||||
durch GNU autoconf sowie die Makefile.in's durch GNU automake generiert
|
||||
werden. Um dies zu vereinfachen existiert das Script "./autogen.sh".
|
||||
GNU automake und GNU autoconf werden -- im Gegensatz zu Builds aus den
|
||||
Sourcen eines .tar.gz-Archivs -- hierbei benoetigt!
|
||||
|
||||
Q: ./autogen.sh bricht mit der Meldung "autoheader: command not found" ab.
|
||||
A: GNU autoconf ist nicht installiert, wird jedoch bei Builds direkt aus
|
||||
dem CVS-Tree benoetigt.
|
||||
|
||||
Q: ./autogen.sh bricht mit der Meldung "autoconf: Undefined macros:
|
||||
AC_FUNC_MALLOC" bzw. "AC_CONFIG_SRCDIR" ab.
|
||||
A: Auf dem System ist eine zu alte Version von GNU autoconf installiert.
|
||||
Ein Update auf z.B. Version 2.52 loest dieses Problem (eine installiete
|
||||
alte Version sollte ggf. zunaechst entfernt werden, bei RPM-Paketen z.B.
|
||||
mit dem Befehl "rpm -e autoconf").
|
||||
|
||||
|
||||
--
|
||||
$Id: FAQ.txt,v 1.1 2002/01/23 14:05:20 alex Exp $
|
||||
@@ -1,11 +1,26 @@
|
||||
# $Id: Makefile.am,v 1.2 2001/12/31 02:45:24 alex Exp $
|
||||
|
||||
#
|
||||
# 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.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.
|
||||
#
|
||||
|
||||
EXTRA_DIST = CVS.txt RFC.txt sample-ngircd.conf
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
ngIRCd - Next Generation IRC Server
|
||||
|
||||
(c)2001 by Alexander Barton,
|
||||
(c)2001,2002 by Alexander Barton,
|
||||
alex@barton.de, http://www.barton.de/
|
||||
|
||||
ngIRCd ist freie Software und steht unter
|
||||
@@ -27,3 +27,6 @@ Das IRC-Protokoll ist in diesen RFC's (Request For Comments) dokumentiert:
|
||||
2813 Kalt, C., "Internet Relay Chat: Server Protocol",
|
||||
April 2000, [IRC-SERVER].
|
||||
|
||||
|
||||
--
|
||||
$Id: RFC.txt,v 1.4 2002/01/23 18:20:04 alex Exp $
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
# ngircd.conf
|
||||
# $Id: sample-ngircd.conf,v 1.2 2002/01/06 16:54:05 alex Exp $
|
||||
|
||||
ServerName = thor.my.net
|
||||
ServerInfo = [thor.my.net] Experimental ngIRCd Test Server
|
||||
[Global]
|
||||
Name = irc.the.net
|
||||
Info = Server Info Text
|
||||
Ports = 6667, 6668, 6669
|
||||
MotdFile = /usr/local/etc/ngircd.motd
|
||||
PingTimeout = 120
|
||||
PongTimeout = 10
|
||||
ConnectRetry = 60
|
||||
|
||||
# Operator = Alex
|
||||
# OperatorPwd = 123
|
||||
[Operator]
|
||||
; Name = TheOper
|
||||
; Password = ThePwd
|
||||
|
||||
ListenPorts = 6668
|
||||
|
||||
MotdFile = /usr/local/etc/ngircd.motd
|
||||
|
||||
PingTimeout = 120
|
||||
PongTimeout = 10
|
||||
[Server]
|
||||
; Host = host2.the.net
|
||||
; Name = irc2.the.net
|
||||
; Port = 6666
|
||||
; Password = ThePwd
|
||||
|
||||
# -eof-
|
||||
|
||||
@@ -1,8 +1,22 @@
|
||||
# $Id: Makefile.am,v 1.1 2001/12/11 21:53:04 alex Exp $
|
||||
|
||||
#
|
||||
# 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/01/02 02:41:11 alex Exp $
|
||||
#
|
||||
# $Log: Makefile.am,v $
|
||||
# Revision 1.1 2001/12/11 21:53:04 alex
|
||||
# Initial revision
|
||||
# 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.
|
||||
#
|
||||
|
||||
SUBDIRS = ngircd
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
# $Id: Makefile.am,v 1.9 2001/12/31 02:18:51 alex Exp $
|
||||
|
||||
#
|
||||
# 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.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.
|
||||
@@ -29,6 +43,7 @@
|
||||
#
|
||||
# Revision 1.1.1.1 2001/12/11 21:53:04 alex
|
||||
# - Imported sources to CVS.
|
||||
#
|
||||
|
||||
sbin_PROGRAMS = ngircd
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,48 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: channel.c,v 1.2 2001/12/31 02:18:51 alex Exp $
|
||||
* $Id: channel.c,v 1.13 2002/02/11 01:00:12 alex Exp $
|
||||
*
|
||||
* channel.c: Management der Channels
|
||||
*
|
||||
* $Log: channel.c,v $
|
||||
* Revision 1.13 2002/02/11 01:00:12 alex
|
||||
* - neue Funktionen Channel_ModeAdd(), Channel_ModeDel(), Channel_UserModes(),
|
||||
* Channel_UserModeAdd(), Channel_UserModeDel().
|
||||
* - Modes in CL2CHAN-Struktur werden nun korrekt initialisiert.
|
||||
*
|
||||
* Revision 1.12 2002/02/06 16:48:48 alex
|
||||
* - neue Funktion Channel_Modes() und Channel_IsValidName().
|
||||
* - Channel-Namen werden (besser) validiert.
|
||||
*
|
||||
* 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.
|
||||
@@ -21,32 +58,541 @@
|
||||
*
|
||||
* Revision 1.1 2001/12/14 08:13:43 alex
|
||||
* - neues Modul begonnen :-)
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define __channel_c__
|
||||
|
||||
|
||||
#include <portab.h>
|
||||
#include "global.h"
|
||||
|
||||
#include <imp.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "client.h"
|
||||
#include "irc.h"
|
||||
#include "log.h"
|
||||
#include "messages.h"
|
||||
|
||||
#include <exp.h>
|
||||
#include "channel.h"
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
|
||||
GLOBAL VOID Channel_Init( VOID )
|
||||
{
|
||||
My_Channels = NULL;
|
||||
My_Cl2Chan = NULL;
|
||||
} /* Channel_Init */
|
||||
|
||||
|
||||
GLOBAL VOID Channel_Exit( VOID )
|
||||
{
|
||||
CHANNEL *c, *c_next;
|
||||
CL2CHAN *cl2chan, *cl2chan_next;
|
||||
|
||||
/* Channel-Strukturen freigeben */
|
||||
c = My_Channels;
|
||||
while( c )
|
||||
{
|
||||
c_next = c->next;
|
||||
free( c );
|
||||
c = c_next;
|
||||
}
|
||||
|
||||
/* Channel-Zuordnungstabelle freigeben */
|
||||
cl2chan = My_Cl2Chan;
|
||||
while( c )
|
||||
{
|
||||
cl2chan_next = cl2chan->next;
|
||||
free( cl2chan );
|
||||
cl2chan = cl2chan_next;
|
||||
}
|
||||
} /* Channel_Exit */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN Channel_Join( CLIENT *Client, CHAR *Name )
|
||||
{
|
||||
CHANNEL *chan;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Name != NULL );
|
||||
|
||||
/* Valider Channel-Name? */
|
||||
if( ! Channel_IsValidName( Name ))
|
||||
{
|
||||
IRC_WriteStrClient( Client, ERR_NOSUCHCHANNEL_MSG, Client_ID( Client ), Name );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Channel suchen */
|
||||
chan = Channel_Search( Name );
|
||||
if( chan )
|
||||
{
|
||||
/* Ist der Client bereits Mitglied? */
|
||||
if( Get_Cl2Chan( chan, Client )) return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Gibt es noch nicht? Dann neu anlegen: */
|
||||
chan = New_Chan( Name );
|
||||
if( ! chan ) return FALSE;
|
||||
|
||||
/* Verketten */
|
||||
chan->next = My_Channels;
|
||||
My_Channels = chan;
|
||||
}
|
||||
|
||||
/* User dem Channel hinzufuegen */
|
||||
if( ! Add_Client( chan, Client )) return FALSE;
|
||||
else return TRUE;
|
||||
} /* Channel_Join */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN Channel_Part( CLIENT *Client, CLIENT *Origin, CHAR *Name, CHAR *Reason )
|
||||
{
|
||||
CHANNEL *chan;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Name != NULL );
|
||||
|
||||
/* Channel suchen */
|
||||
chan = Channel_Search( Name );
|
||||
if(( ! chan ) || ( ! Get_Cl2Chan( chan, Client )))
|
||||
{
|
||||
IRC_WriteStrClient( Client, ERR_NOSUCHCHANNEL_MSG, Client_ID( Client ), Name );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* User aus Channel entfernen */
|
||||
if( ! Remove_Client( chan, Client, Origin, Reason, TRUE )) return FALSE;
|
||||
else return TRUE;
|
||||
} /* Channel_Part */
|
||||
|
||||
|
||||
GLOBAL VOID Channel_RemoveClient( CLIENT *Client, CHAR *Reason )
|
||||
{
|
||||
CHANNEL *c, *next_c;
|
||||
|
||||
assert( Client != NULL );
|
||||
|
||||
c = My_Channels;
|
||||
while( c )
|
||||
{
|
||||
next_c = c->next;
|
||||
Remove_Client( c, Client, Client_ThisServer( ), Reason, FALSE );
|
||||
c = next_c;
|
||||
}
|
||||
} /* Channel_RemoveClient */
|
||||
|
||||
|
||||
GLOBAL INT Channel_Count( VOID )
|
||||
{
|
||||
CHANNEL *c;
|
||||
INT count;
|
||||
|
||||
count = 0;
|
||||
c = My_Channels;
|
||||
while( c )
|
||||
{
|
||||
count++;
|
||||
c = c->next;
|
||||
}
|
||||
return count;
|
||||
} /* Channel_Count */
|
||||
|
||||
|
||||
GLOBAL CHAR *Channel_Name( CHANNEL *Chan )
|
||||
{
|
||||
assert( Chan != NULL );
|
||||
return Chan->name;
|
||||
} /* Channel_Name */
|
||||
|
||||
|
||||
GLOBAL CHAR *Channel_Modes( CHANNEL *Chan )
|
||||
{
|
||||
assert( Chan != NULL );
|
||||
return Chan->modes;
|
||||
} /* Channel_Modes */
|
||||
|
||||
|
||||
GLOBAL CHANNEL *Channel_First( VOID )
|
||||
{
|
||||
return My_Channels;
|
||||
} /* Channel_First */
|
||||
|
||||
|
||||
GLOBAL CHANNEL *Channel_Next( CHANNEL *Chan )
|
||||
{
|
||||
assert( Chan != NULL );
|
||||
return Chan->next;
|
||||
} /* Channel_Next */
|
||||
|
||||
|
||||
GLOBAL CHANNEL *Channel_Search( CHAR *Name )
|
||||
{
|
||||
/* Channel-Struktur suchen */
|
||||
|
||||
CHANNEL *c;
|
||||
|
||||
assert( Name != NULL );
|
||||
c = My_Channels;
|
||||
while( c )
|
||||
{
|
||||
if( strcasecmp( Name, c->name ) == 0 ) return c;
|
||||
c = c->next;
|
||||
}
|
||||
return NULL;
|
||||
} /* Channel_Search */
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
assert( Chan != NULL );
|
||||
assert( Cl2Chan != NULL );
|
||||
return Get_Next_Cl2Chan( Cl2Chan->next, NULL, Chan );
|
||||
} /* Channel_NextMember */
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
assert( Cl2Chan != NULL );
|
||||
return Get_Next_Cl2Chan( Cl2Chan->next, Client, NULL );
|
||||
} /* Channel_NextChannelOf */
|
||||
|
||||
|
||||
GLOBAL CLIENT *Channel_GetClient( CL2CHAN *Cl2Chan )
|
||||
{
|
||||
assert( Cl2Chan != NULL );
|
||||
return Cl2Chan->client;
|
||||
} /* Channel_GetClient */
|
||||
|
||||
|
||||
GLOBAL CHANNEL *Channel_GetChannel( CL2CHAN *Cl2Chan )
|
||||
{
|
||||
assert( Cl2Chan != NULL );
|
||||
return Cl2Chan->channel;
|
||||
} /* Channel_GetChannel */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN Channel_IsValidName( CHAR *Name )
|
||||
{
|
||||
/* Pr<50>fen, ob Name als Channelname gueltig */
|
||||
|
||||
assert( Name != NULL );
|
||||
|
||||
if(( Name[0] != '#' ) || ( strlen( Name ) >= CHANNEL_NAME_LEN )) return FALSE;
|
||||
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 */
|
||||
|
||||
|
||||
LOCAL CHANNEL *New_Chan( CHAR *Name )
|
||||
{
|
||||
/* Neue Channel-Struktur anlegen */
|
||||
|
||||
CHANNEL *c;
|
||||
|
||||
assert( Name != NULL );
|
||||
|
||||
c = malloc( sizeof( CHANNEL ));
|
||||
if( ! c )
|
||||
{
|
||||
Log( LOG_EMERG, "Can't allocate memory!" );
|
||||
return NULL;
|
||||
}
|
||||
c->next = NULL;
|
||||
strncpy( c->name, Name, CHANNEL_NAME_LEN );
|
||||
c->name[CHANNEL_NAME_LEN - 1] = '\0';
|
||||
strcpy( c->modes, "" );
|
||||
|
||||
Log( LOG_DEBUG, "Created new channel structure for \"%s\".", Name );
|
||||
|
||||
return c;
|
||||
} /* New_Chan */
|
||||
|
||||
|
||||
LOCAL CL2CHAN *Get_Cl2Chan( CHANNEL *Chan, CLIENT *Client )
|
||||
{
|
||||
CL2CHAN *cl2chan;
|
||||
|
||||
assert( Chan != NULL );
|
||||
assert( Client != NULL );
|
||||
|
||||
cl2chan = My_Cl2Chan;
|
||||
while( cl2chan )
|
||||
{
|
||||
if(( cl2chan->channel == Chan ) && ( cl2chan->client == Client )) return cl2chan;
|
||||
cl2chan = cl2chan->next;
|
||||
}
|
||||
return NULL;
|
||||
} /* Get_Cl2Chan */
|
||||
|
||||
|
||||
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!" );
|
||||
return NULL;
|
||||
}
|
||||
cl2chan->channel = Chan;
|
||||
cl2chan->client = Client;
|
||||
strcpy( cl2chan->modes, "" );
|
||||
|
||||
/* Verketten */
|
||||
cl2chan->next = My_Cl2Chan;
|
||||
My_Cl2Chan = cl2chan;
|
||||
|
||||
Log( LOG_DEBUG, "User \"%s\" joined channel \"%s\".", Client_Mask( Client ), Chan->name );
|
||||
|
||||
return cl2chan;
|
||||
} /* Add_Client */
|
||||
|
||||
|
||||
LOCAL BOOLEAN Remove_Client( CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, CHAR *Reason, BOOLEAN ServerPART )
|
||||
{
|
||||
CL2CHAN *cl2chan, *last_cl2chan;
|
||||
CHANNEL *c;
|
||||
|
||||
assert( Chan != NULL );
|
||||
assert( Client != NULL );
|
||||
assert( Origin != NULL );
|
||||
assert( Reason != NULL );
|
||||
|
||||
last_cl2chan = NULL;
|
||||
cl2chan = My_Cl2Chan;
|
||||
while( cl2chan )
|
||||
{
|
||||
if(( cl2chan->channel == Chan ) && ( cl2chan->client == Client )) break;
|
||||
last_cl2chan = cl2chan;
|
||||
cl2chan = cl2chan->next;
|
||||
}
|
||||
if( ! cl2chan ) return FALSE;
|
||||
|
||||
c = cl2chan->channel;
|
||||
assert( c != NULL );
|
||||
|
||||
/* Aus Verkettung loesen und freigeben */
|
||||
if( last_cl2chan ) last_cl2chan->next = cl2chan->next;
|
||||
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 );
|
||||
|
||||
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 );
|
||||
|
||||
return TRUE;
|
||||
} /* Remove_Client */
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
CL2CHAN *cl2chan;
|
||||
|
||||
assert( Client != NULL || Channel != NULL );
|
||||
|
||||
cl2chan = Start;
|
||||
while( cl2chan )
|
||||
{
|
||||
if(( Client ) && ( cl2chan->client == Client )) return cl2chan;
|
||||
if(( Channel ) && ( cl2chan->channel == Channel )) return cl2chan;
|
||||
cl2chan = cl2chan->next;
|
||||
}
|
||||
return NULL;
|
||||
} /* Get_Next_Cl2Chan */
|
||||
|
||||
|
||||
LOCAL BOOLEAN Delete_Channel( CHANNEL *Chan )
|
||||
{
|
||||
/* Channel-Struktur loeschen */
|
||||
|
||||
CHANNEL *chan, *last_chan;
|
||||
|
||||
last_chan = NULL;
|
||||
chan = My_Channels;
|
||||
while( chan )
|
||||
{
|
||||
if( chan == Chan ) break;
|
||||
last_chan = chan;
|
||||
chan = chan->next;
|
||||
}
|
||||
if( ! chan ) return FALSE;
|
||||
|
||||
Log( LOG_DEBUG, "Freed channel structure for \"%s\".", Chan->name );
|
||||
|
||||
/* Neu verketten und freigeben */
|
||||
if( last_chan ) last_chan->next = chan->next;
|
||||
else My_Channels = chan->next;
|
||||
free( chan );
|
||||
|
||||
return TRUE;
|
||||
} /* Delete_Channel */
|
||||
|
||||
|
||||
/* -eof- */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,38 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: channel.h,v 1.3 2001/12/31 02:18:51 alex Exp $
|
||||
* $Id: channel.h,v 1.11 2002/02/11 01:00:22 alex Exp $
|
||||
*
|
||||
* channel.h: Management der Channels (Header)
|
||||
*
|
||||
* $Log: channel.h,v $
|
||||
* Revision 1.11 2002/02/11 01:00:22 alex
|
||||
* - neue Funktionen Channel_ModeAdd(), Channel_ModeDel(), Channel_UserModes(),
|
||||
* Channel_UserModeAdd(), Channel_UserModeDel().
|
||||
*
|
||||
* Revision 1.10 2002/02/06 16:49:10 alex
|
||||
* - neue Funktionen Channel_Modes() und Channel_IsValidName().
|
||||
*
|
||||
* 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.
|
||||
@@ -24,23 +51,75 @@
|
||||
*
|
||||
* Revision 1.1 2001/12/14 08:13:43 alex
|
||||
* - neues Modul begonnen :-)
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __channel_h__
|
||||
#define __channel_h__
|
||||
|
||||
#include "client.h"
|
||||
|
||||
|
||||
#ifdef __channel_c__
|
||||
|
||||
typedef struct _CHANNEL
|
||||
{
|
||||
CHAR name[CHANNEL_NAME_LEN]; /* Name */
|
||||
struct _CHANNEL *next;
|
||||
CHAR name[CHANNEL_NAME_LEN]; /* Name des Channel */
|
||||
CHAR modes[CHANNEL_MODE_LEN]; /* Channel-Modes */
|
||||
} CHANNEL;
|
||||
|
||||
typedef struct _CLIENT2CHAN
|
||||
{
|
||||
struct _CLIENT2CHAN *next;
|
||||
CLIENT *client;
|
||||
CHANNEL *channel;
|
||||
CHAR modes[CHANNEL_MODE_LEN]; /* User-Modes in dem Channel */
|
||||
} CL2CHAN;
|
||||
|
||||
#else
|
||||
|
||||
typedef POINTER CHANNEL;
|
||||
typedef POINTER CL2CHAN;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
GLOBAL VOID Channel_Init( VOID );
|
||||
GLOBAL VOID Channel_Exit( VOID );
|
||||
|
||||
GLOBAL BOOLEAN Channel_Join( CLIENT *Client, CHAR *Name );
|
||||
GLOBAL BOOLEAN Channel_Part( CLIENT *Client, CLIENT *Origin, CHAR *Name, CHAR *Reason );
|
||||
|
||||
GLOBAL VOID Channel_RemoveClient( CLIENT *Client, CHAR *Reason );
|
||||
|
||||
GLOBAL INT Channel_Count( VOID );
|
||||
|
||||
GLOBAL CHAR *Channel_Name( CHANNEL *Chan );
|
||||
GLOBAL CHAR *Channel_Modes( CHANNEL *Chan );
|
||||
|
||||
GLOBAL CHANNEL *Channel_Search( CHAR *Name );
|
||||
|
||||
GLOBAL CHANNEL *Channel_First( VOID );
|
||||
GLOBAL CHANNEL *Channel_Next( CHANNEL *Chan );
|
||||
|
||||
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 CLIENT *Channel_GetClient( CL2CHAN *Cl2Chan );
|
||||
GLOBAL CHANNEL *Channel_GetChannel( CL2CHAN *Cl2Chan );
|
||||
|
||||
GLOBAL BOOLEAN Channel_IsValidName( CHAR *Name );
|
||||
|
||||
GLOBAL BOOLEAN Channel_ModeAdd( CHANNEL *Chan, CHAR Mode );
|
||||
GLOBAL BOOLEAN Channel_ModeDel( CHANNEL *Chan, CHAR Mode );
|
||||
|
||||
GLOBAL BOOLEAN Channel_UserModeAdd( CHANNEL *Chan, CLIENT *Client, CHAR Mode );
|
||||
GLOBAL BOOLEAN Channel_UserModeDel( CHANNEL *Chan, CLIENT *Client, CHAR Mode );
|
||||
GLOBAL CHAR *Channel_UserModes( CHANNEL *Chan, CLIENT *Client );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,7 +9,7 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: client.c,v 1.15 2001/12/31 15:33:13 alex Exp $
|
||||
* $Id: client.c,v 1.36 2002/02/06 16:49:41 alex Exp $
|
||||
*
|
||||
* client.c: Management aller Clients
|
||||
*
|
||||
@@ -21,6 +21,72 @@
|
||||
* Server gewesen, so existiert eine entsprechende CONNECTION-Struktur.
|
||||
*
|
||||
* $Log: client.c,v $
|
||||
* Revision 1.36 2002/02/06 16:49:41 alex
|
||||
* - neue Funktion Client_IsValidNick(), Nicknames werden besser validiert.
|
||||
*
|
||||
* Revision 1.35 2002/01/29 00:14:49 alex
|
||||
* - neue Funktion Client_TopServer(), Client_NewXXX() angepasst.
|
||||
*
|
||||
* Revision 1.34 2002/01/27 22:07:36 alex
|
||||
* - Client_GetFromID() besser dokumentiert, kleinere Aenderungen.
|
||||
*
|
||||
* Revision 1.33 2002/01/27 21:56:54 alex
|
||||
* - weitere Anpassungen an Chennals, v.a. ueber Server-Links.
|
||||
*
|
||||
* Revision 1.32 2002/01/27 18:27:12 alex
|
||||
* - Client_GetFromID() kommt nun auch mit Host-Masken zurecht.
|
||||
*
|
||||
* Revision 1.31 2002/01/21 00:08:50 alex
|
||||
* - wird ein Client entfernt, so wird er auch aus allen Channels geloescht.
|
||||
*
|
||||
* Revision 1.30 2002/01/18 15:32:01 alex
|
||||
* - bei Client_SetModes() wurde das NULL-Byte falsch gesetzt. Opsa.
|
||||
*
|
||||
* Revision 1.29 2002/01/16 22:10:35 alex
|
||||
* - neue Funktionen Client_xxxCount().
|
||||
*
|
||||
* Revision 1.28 2002/01/11 23:50:40 alex
|
||||
* - Hop-Count fuer den Server selber (0) wird korrekt initialisiert.
|
||||
*
|
||||
* Revision 1.27 2002/01/09 01:08:08 alex
|
||||
* - wird ein Server abgemeldet, so wird anderen Server ein SQUIT geschickt.
|
||||
*
|
||||
* Revision 1.26 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.25 2002/01/07 15:31:00 alex
|
||||
* - Bei Log-Meldungen ueber Clients wird nun immer die "Client Mask" verwendet.
|
||||
*
|
||||
* Revision 1.24 2002/01/06 15:18:14 alex
|
||||
* - Loglevel und Meldungen nochmals geaendert. Level passen nun besser.
|
||||
*
|
||||
* Revision 1.23 2002/01/05 23:26:05 alex
|
||||
* - Vorbereitungen fuer Ident-Abfragen in Client-Strukturen.
|
||||
*
|
||||
* Revision 1.22 2002/01/05 20:08:17 alex
|
||||
* - neue Funktion Client_NextHop().
|
||||
*
|
||||
* Revision 1.21 2002/01/05 19:15:03 alex
|
||||
* - Fehlerpruefung bei select() in der "Hauptschleife" korrigiert.
|
||||
*
|
||||
* Revision 1.20 2002/01/04 17:57:08 alex
|
||||
* - Client_Destroy() an Server-Links angepasst.
|
||||
*
|
||||
* Revision 1.19 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.18 2002/01/03 02:28:06 alex
|
||||
* - neue Funktion Client_CheckID(), diverse Aenderungen fuer Server-Links.
|
||||
*
|
||||
* Revision 1.17 2002/01/02 02:42:58 alex
|
||||
* - Copyright-Texte aktualisiert.
|
||||
*
|
||||
* Revision 1.16 2002/01/01 18:25:44 alex
|
||||
* - #include's fuer stdlib.h ergaenzt.
|
||||
*
|
||||
* Revision 1.15 2001/12/31 15:33:13 alex
|
||||
* - neuer Befehl NAMES, kleinere Bugfixes.
|
||||
* - Bug bei PING behoben: war zu restriktiv implementiert :-)
|
||||
@@ -72,6 +138,9 @@
|
||||
*/
|
||||
|
||||
|
||||
#define __client_c__
|
||||
|
||||
|
||||
#include <portab.h>
|
||||
#include "global.h"
|
||||
|
||||
@@ -79,6 +148,7 @@
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
|
||||
@@ -86,6 +156,7 @@
|
||||
#include "client.h"
|
||||
|
||||
#include <imp.h>
|
||||
#include "ngircd.h"
|
||||
#include "channel.h"
|
||||
#include "conf.h"
|
||||
#include "conn.h"
|
||||
@@ -96,11 +167,15 @@
|
||||
#include <exp.h>
|
||||
|
||||
|
||||
LOCAL CLIENT *My_Clients;
|
||||
LOCAL CLIENT *This_Server, *My_Clients;
|
||||
LOCAL CHAR GetID_Buffer[CLIENT_ID_LEN];
|
||||
|
||||
|
||||
LOCAL INT Count( CLIENT_TYPE Type );
|
||||
LOCAL INT MyCount( CLIENT_TYPE Type );
|
||||
|
||||
LOCAL CLIENT *New_Client_Struct( VOID );
|
||||
LOCAL VOID Generate_MyToken( CLIENT *Client );
|
||||
|
||||
|
||||
GLOBAL VOID Client_Init( VOID )
|
||||
@@ -120,12 +195,14 @@ GLOBAL VOID Client_Init( VOID )
|
||||
This_Server->type = CLIENT_SERVER;
|
||||
This_Server->conn_id = NONE;
|
||||
This_Server->introducer = This_Server;
|
||||
This_Server->mytoken = 1;
|
||||
This_Server->hops = 0;
|
||||
|
||||
gethostname( This_Server->host, CLIENT_HOST_LEN );
|
||||
h = gethostbyname( This_Server->host );
|
||||
if( h ) strcpy( This_Server->host, h->h_name );
|
||||
|
||||
strcpy( This_Server->nick, Conf_ServerName );
|
||||
strcpy( This_Server->id, Conf_ServerName );
|
||||
strcpy( This_Server->info, Conf_ServerInfo );
|
||||
|
||||
My_Clients = This_Server;
|
||||
@@ -137,7 +214,7 @@ GLOBAL VOID Client_Exit( VOID )
|
||||
CLIENT *c, *next;
|
||||
INT cnt;
|
||||
|
||||
Client_Destroy( This_Server );
|
||||
Client_Destroy( This_Server, "Server going down.", NULL );
|
||||
|
||||
cnt = 0;
|
||||
c = My_Clients;
|
||||
@@ -149,52 +226,132 @@ GLOBAL VOID Client_Exit( VOID )
|
||||
c = next;
|
||||
}
|
||||
if( cnt ) Log( LOG_INFO, "Freed %d client structure%s.", cnt, cnt == 1 ? "" : "s" );
|
||||
} /* Client Exit */
|
||||
} /* Client_Exit */
|
||||
|
||||
|
||||
GLOBAL CLIENT *Client_NewLocal( CONN_ID Idx, CHAR *Hostname )
|
||||
GLOBAL CLIENT *Client_ThisServer( VOID )
|
||||
{
|
||||
return This_Server;
|
||||
} /* Client_ThisServer */
|
||||
|
||||
|
||||
GLOBAL CLIENT *Client_NewLocal( CONN_ID Idx, CHAR *Hostname, INT Type, BOOLEAN Idented )
|
||||
{
|
||||
/* Neuen lokalen Client erzeugen: Wrapper-Funktion fuer Client_New(). */
|
||||
return Client_New( Idx, This_Server, NULL, Type, NULL, NULL, Hostname, NULL, 0, 0, NULL, Idented );
|
||||
} /* Client_NewLocal */
|
||||
|
||||
|
||||
GLOBAL CLIENT *Client_NewRemoteServer( CLIENT *Introducer, CHAR *Hostname, CLIENT *TopServer, INT Hops, INT Token, CHAR *Info, BOOLEAN Idented )
|
||||
{
|
||||
/* Neuen Remote-Client erzeugen: Wrapper-Funktion fuer Client_New (). */
|
||||
return Client_New( NONE, Introducer, TopServer, CLIENT_SERVER, Hostname, NULL, Hostname, Info, Hops, Token, NULL, Idented );
|
||||
} /* Client_NewRemoteServer */
|
||||
|
||||
|
||||
GLOBAL CLIENT *Client_NewRemoteUser( CLIENT *Introducer, CHAR *Nick, INT Hops, CHAR *User, CHAR *Hostname, INT Token, CHAR *Modes, CHAR *Info, BOOLEAN Idented )
|
||||
{
|
||||
/* Neuen Remote-Client erzeugen: Wrapper-Funktion fuer Client_New (). */
|
||||
return Client_New( NONE, Introducer, NULL, CLIENT_USER, Nick, User, Hostname, Info, Hops, Token, Modes, Idented );
|
||||
} /* Client_NewRemoteUser */
|
||||
|
||||
|
||||
GLOBAL CLIENT *Client_New( CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, INT Type, CHAR *ID, CHAR *User, CHAR *Hostname, CHAR *Info, INT Hops, INT Token, CHAR *Modes, BOOLEAN Idented )
|
||||
{
|
||||
/* Neuen lokalen Client erzeugen. */
|
||||
|
||||
CLIENT *client;
|
||||
|
||||
assert( Idx >= 0 );
|
||||
assert( Idx >= NONE );
|
||||
assert( Introducer != NULL );
|
||||
assert( Hostname != NULL );
|
||||
|
||||
|
||||
client = New_Client_Struct( );
|
||||
if( ! client ) return NULL;
|
||||
|
||||
/* Initialisieren */
|
||||
client->conn_id = Idx;
|
||||
client->introducer = This_Server;
|
||||
Client_SetHostname( client, Hostname );
|
||||
client->introducer = Introducer;
|
||||
client->topserver = TopServer;
|
||||
client->type = Type;
|
||||
if( ID ) Client_SetID( client, ID );
|
||||
if( User ) Client_SetUser( client, User, Idented );
|
||||
if( Hostname ) Client_SetHostname( client, Hostname );
|
||||
if( Info ) Client_SetInfo( client, Info );
|
||||
client->hops = Hops;
|
||||
client->token = Token;
|
||||
if( Modes ) Client_SetModes( client, Modes );
|
||||
if( Type == CLIENT_SERVER ) Generate_MyToken( client );
|
||||
|
||||
/* Verketten */
|
||||
client->next = My_Clients;
|
||||
My_Clients = client;
|
||||
|
||||
|
||||
return client;
|
||||
} /* Client_NewLocal */
|
||||
} /* Client_New */
|
||||
|
||||
|
||||
GLOBAL VOID Client_Destroy( CLIENT *Client )
|
||||
GLOBAL VOID Client_Destroy( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg )
|
||||
{
|
||||
/* Client entfernen. */
|
||||
|
||||
CLIENT *last, *c;
|
||||
CHAR *txt;
|
||||
|
||||
assert( Client != NULL );
|
||||
|
||||
|
||||
if( LogMsg ) txt = LogMsg;
|
||||
else txt = FwdMsg;
|
||||
if( ! txt ) txt = "Reason unknown.";
|
||||
|
||||
last = NULL;
|
||||
c = My_Clients;
|
||||
while( c )
|
||||
{
|
||||
if(( Client->type == CLIENT_SERVER ) && ( c->introducer == Client ) && ( c != Client ))
|
||||
{
|
||||
Client_Destroy( c, LogMsg, FwdMsg );
|
||||
last = NULL;
|
||||
c = My_Clients;
|
||||
continue;
|
||||
}
|
||||
if( c == Client )
|
||||
{
|
||||
if( last ) last->next = c->next;
|
||||
else My_Clients = c->next;
|
||||
|
||||
if( c->type == CLIENT_USER ) Log( LOG_NOTICE, "User \"%s!%s@%s\" (%s) exited (connection %d).", c->nick, c->user, c->host, c->name, c->conn_id );
|
||||
if( c->type == CLIENT_USER )
|
||||
{
|
||||
if( c->conn_id != NONE )
|
||||
{
|
||||
/* Ein lokaler User. Alle andere Server informieren! */
|
||||
Log( LOG_NOTICE, "User \"%s\" unregistered (connection %d): %s", Client_Mask( c ), c->conn_id, txt );
|
||||
|
||||
if( FwdMsg ) IRC_WriteStrServersPrefix( NULL, c, "QUIT :%s", FwdMsg );
|
||||
else IRC_WriteStrServersPrefix( NULL, c, "QUIT :" );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remote User. Andere Server informieren, ausser denen,
|
||||
* die "in Richtung dem liegen", auf dem der User registriert
|
||||
* ist. Von denen haben wir das QUIT ja wohl bekommen. */
|
||||
Log( LOG_DEBUG, "User \"%s\" unregistered: %s", Client_Mask( c ), txt );
|
||||
|
||||
if( FwdMsg ) IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "QUIT :%s", FwdMsg );
|
||||
else IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "QUIT :" );
|
||||
}
|
||||
Channel_RemoveClient( c, FwdMsg ? FwdMsg : c->id );
|
||||
}
|
||||
else if( c->type == CLIENT_SERVER )
|
||||
{
|
||||
if( c != This_Server ) Log( LOG_NOTICE, "Server \"%s\" unregistered: %s", c->id, txt );
|
||||
|
||||
/* andere Server informieren */
|
||||
if( ! NGIRCd_Quit )
|
||||
{
|
||||
if( FwdMsg ) IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "SQUIT %s :%s", c->id, FwdMsg );
|
||||
else IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "SQUIT %s :", c->id );
|
||||
}
|
||||
}
|
||||
else Log( LOG_NOTICE, "Unknown client \"%s\" unregistered: %s", c->id, txt );
|
||||
|
||||
free( c );
|
||||
break;
|
||||
@@ -215,6 +372,143 @@ GLOBAL VOID Client_SetHostname( CLIENT *Client, CHAR *Hostname )
|
||||
} /* Client_SetHostname */
|
||||
|
||||
|
||||
GLOBAL VOID Client_SetID( CLIENT *Client, CHAR *ID )
|
||||
{
|
||||
/* Hostname eines Clients setzen */
|
||||
|
||||
assert( Client != NULL );
|
||||
strncpy( Client->id, ID, CLIENT_ID_LEN );
|
||||
Client->id[CLIENT_ID_LEN - 1] = '\0';
|
||||
} /* Client_SetID */
|
||||
|
||||
|
||||
GLOBAL VOID Client_SetUser( CLIENT *Client, CHAR *User, BOOLEAN Idented )
|
||||
{
|
||||
/* Username eines Clients setzen */
|
||||
|
||||
assert( Client != NULL );
|
||||
if( Idented ) strncpy( Client->user, User, CLIENT_USER_LEN );
|
||||
else
|
||||
{
|
||||
Client->user[0] = '~';
|
||||
strncpy( Client->user + 1, User, CLIENT_USER_LEN - 1 );
|
||||
}
|
||||
Client->user[CLIENT_USER_LEN - 1] = '\0';
|
||||
} /* Client_SetUser */
|
||||
|
||||
|
||||
GLOBAL VOID Client_SetInfo( CLIENT *Client, CHAR *Info )
|
||||
{
|
||||
/* Hostname eines Clients setzen */
|
||||
|
||||
assert( Client != NULL );
|
||||
strncpy( Client->info, Info, CLIENT_INFO_LEN );
|
||||
Client->info[CLIENT_INFO_LEN - 1] = '\0';
|
||||
} /* Client_SetInfo */
|
||||
|
||||
|
||||
GLOBAL VOID Client_SetModes( CLIENT *Client, CHAR *Modes )
|
||||
{
|
||||
/* Hostname eines Clients setzen */
|
||||
|
||||
assert( Client != NULL );
|
||||
strncpy( Client->modes, Modes, CLIENT_MODE_LEN );
|
||||
Client->modes[CLIENT_MODE_LEN - 1] = '\0';
|
||||
} /* Client_SetModes */
|
||||
|
||||
|
||||
GLOBAL VOID Client_SetPassword( CLIENT *Client, CHAR *Pwd )
|
||||
{
|
||||
/* Von einem Client geliefertes Passwort */
|
||||
|
||||
assert( Client != NULL );
|
||||
strncpy( Client->pwd, Pwd, CLIENT_PASS_LEN );
|
||||
Client->pwd[CLIENT_PASS_LEN - 1] = '\0';
|
||||
} /* Client_SetPassword */
|
||||
|
||||
|
||||
GLOBAL VOID Client_SetType( CLIENT *Client, INT Type )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
Client->type = Type;
|
||||
if( Type == CLIENT_SERVER ) Generate_MyToken( Client );
|
||||
} /* Client_SetType */
|
||||
|
||||
|
||||
GLOBAL VOID Client_SetHops( CLIENT *Client, INT Hops )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
Client->hops = Hops;
|
||||
} /* Client_SetHops */
|
||||
|
||||
|
||||
GLOBAL VOID Client_SetToken( CLIENT *Client, INT Token )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
Client->token = Token;
|
||||
} /* Client_SetToken */
|
||||
|
||||
|
||||
GLOBAL VOID Client_SetIntroducer( CLIENT *Client, CLIENT *Introducer )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
Client->introducer = Introducer;
|
||||
} /* Client_SetIntroducer */
|
||||
|
||||
|
||||
GLOBAL VOID Client_SetOperByMe( CLIENT *Client, BOOLEAN OperByMe )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
Client->oper_by_me = OperByMe;
|
||||
} /* Client_SetOperByMe */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN Client_ModeAdd( CLIENT *Client, CHAR Mode )
|
||||
{
|
||||
/* Mode soll gesetzt werden. TRUE wird geliefert, wenn der
|
||||
* Mode neu gesetzt wurde, FALSE, wenn der Client den Mode
|
||||
* bereits hatte. */
|
||||
|
||||
CHAR x[2];
|
||||
|
||||
assert( Client != NULL );
|
||||
|
||||
x[0] = Mode; x[1] = '\0';
|
||||
if( ! strchr( Client->modes, x[0] ))
|
||||
{
|
||||
/* Client hat den Mode noch nicht -> setzen */
|
||||
strcat( Client->modes, x );
|
||||
return TRUE;
|
||||
}
|
||||
else return FALSE;
|
||||
} /* Client_ModeAdd */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN Client_ModeDel( CLIENT *Client, CHAR Mode )
|
||||
{
|
||||
/* Mode soll geloescht werden. TRUE wird geliefert, wenn der
|
||||
* Mode entfernt wurde, FALSE, wenn der Client den Mode
|
||||
* ueberhaupt nicht hatte. */
|
||||
|
||||
CHAR x[2], *p;
|
||||
|
||||
assert( Client != NULL );
|
||||
|
||||
x[0] = Mode; x[1] = '\0';
|
||||
|
||||
p = strchr( Client->modes, x[0] );
|
||||
if( ! p ) return FALSE;
|
||||
|
||||
/* Client hat den Mode -> loeschen */
|
||||
while( *p )
|
||||
{
|
||||
*p = *(p + 1);
|
||||
p++;
|
||||
}
|
||||
return TRUE;
|
||||
} /* Client_ModeDel */
|
||||
|
||||
|
||||
GLOBAL CLIENT *Client_GetFromConn( CONN_ID Idx )
|
||||
{
|
||||
/* Client-Struktur, die zur lokalen Verbindung Idx gehoert,
|
||||
@@ -234,32 +528,185 @@ GLOBAL CLIENT *Client_GetFromConn( CONN_ID Idx )
|
||||
} /* Client_GetFromConn */
|
||||
|
||||
|
||||
GLOBAL CLIENT *Client_GetFromNick( CHAR *Nick )
|
||||
GLOBAL CLIENT *Client_GetFromID( CHAR *Nick )
|
||||
{
|
||||
/* Client-Struktur, die den entsprechenden Nick hat,
|
||||
* liefern. Wird keine gefunden, so wird NULL geliefert. */
|
||||
* liefern. Wird keine gefunden, so wird NULL geliefert. */
|
||||
|
||||
CLIENT *c;
|
||||
CHAR n[CLIENT_ID_LEN + 1], *ptr;
|
||||
CLIENT *c = NULL;
|
||||
|
||||
assert( Nick != NULL );
|
||||
|
||||
/* Nick kopieren und ggf. Host-Mask abschneiden */
|
||||
strncpy( n, Nick, CLIENT_ID_LEN );
|
||||
n[CLIENT_ID_LEN] = '\0';
|
||||
ptr = strchr( n, '!' );
|
||||
if( ptr ) *ptr = '\0';
|
||||
|
||||
c = My_Clients;
|
||||
while( c )
|
||||
{
|
||||
if( strcasecmp( c->nick, Nick ) == 0 ) return c;
|
||||
if( strcasecmp( c->id, n ) == 0 ) return c;
|
||||
c = c->next;
|
||||
}
|
||||
return NULL;
|
||||
} /* Client_GetFromNick */
|
||||
} /* Client_GetFromID */
|
||||
|
||||
|
||||
GLOBAL CHAR *Client_Nick( CLIENT *Client )
|
||||
GLOBAL CLIENT *Client_GetFromToken( CLIENT *Client, INT Token )
|
||||
{
|
||||
/* Client-Struktur, die den entsprechenden Introducer (=Client)
|
||||
* und das gegebene Token hat, liefern. Wird keine gefunden,
|
||||
* so wird NULL geliefert. */
|
||||
|
||||
CLIENT *c;
|
||||
|
||||
assert( Client != NULL );
|
||||
assert( Token > 0 );
|
||||
|
||||
c = My_Clients;
|
||||
while( c )
|
||||
{
|
||||
if(( c->type == CLIENT_SERVER ) && ( c->introducer == Client ) && ( c->token == Token )) return c;
|
||||
c = c->next;
|
||||
}
|
||||
return NULL;
|
||||
} /* Client_GetFromToken */
|
||||
|
||||
|
||||
GLOBAL INT Client_Type( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
return Client->type;
|
||||
} /* Client_Type */
|
||||
|
||||
|
||||
GLOBAL CONN_ID Client_Conn( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
return Client->conn_id;
|
||||
} /* Client_Conn */
|
||||
|
||||
|
||||
GLOBAL CHAR *Client_ID( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
|
||||
if( Client->nick[0] ) return Client->nick;
|
||||
if( Client->id[0] ) return Client->id;
|
||||
else return "*";
|
||||
} /* Client_Name */
|
||||
} /* Client_ID */
|
||||
|
||||
|
||||
GLOBAL CHAR *Client_Info( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
return Client->info;
|
||||
} /* Client_Info */
|
||||
|
||||
|
||||
GLOBAL CHAR *Client_User( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
if( Client->user ) return Client->user;
|
||||
else return "~";
|
||||
} /* Client_User */
|
||||
|
||||
|
||||
GLOBAL CHAR *Client_Hostname( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
return Client->host;
|
||||
} /* Client_Hostname */
|
||||
|
||||
|
||||
GLOBAL CHAR *Client_Password( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
return Client->pwd;
|
||||
} /* Client_Password */
|
||||
|
||||
|
||||
GLOBAL CHAR *Client_Modes( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
return Client->modes;
|
||||
} /* Client_Modes */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN Client_OperByMe( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
return Client->oper_by_me;
|
||||
} /* Client_OperByMe */
|
||||
|
||||
|
||||
GLOBAL INT Client_Hops( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
return Client->hops;
|
||||
} /* Client_Hops */
|
||||
|
||||
|
||||
GLOBAL INT Client_Token( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
return Client->token;
|
||||
} /* Client_Token */
|
||||
|
||||
|
||||
GLOBAL INT Client_MyToken( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
return Client->mytoken;
|
||||
} /* Client_MyToken */
|
||||
|
||||
|
||||
GLOBAL CLIENT *Client_NextHop( CLIENT *Client )
|
||||
{
|
||||
CLIENT *c;
|
||||
|
||||
assert( Client != NULL );
|
||||
|
||||
c = Client;
|
||||
while( c->introducer && ( c->introducer != c ) && ( c->introducer != This_Server )) c = c->introducer;
|
||||
return c;
|
||||
} /* Client_NextHop */
|
||||
|
||||
|
||||
GLOBAL CHAR *Client_Mask( CLIENT *Client )
|
||||
{
|
||||
/* Client-"ID" liefern, wie sie z.B. fuer
|
||||
* Prefixe benoetigt wird. */
|
||||
|
||||
assert( Client != NULL );
|
||||
|
||||
if( Client->type == CLIENT_SERVER ) return Client->id;
|
||||
|
||||
sprintf( GetID_Buffer, "%s!%s@%s", Client->id, Client->user, Client->host );
|
||||
return GetID_Buffer;
|
||||
} /* Client_Mask */
|
||||
|
||||
|
||||
GLOBAL CLIENT *Client_Introducer( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
return Client->introducer;
|
||||
} /* Client_Introducer */
|
||||
|
||||
|
||||
GLOBAL CLIENT *Client_TopServer( CLIENT *Client )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
return Client->topserver;
|
||||
} /* Client_TopServer */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN Client_HasMode( CLIENT *Client, CHAR Mode )
|
||||
{
|
||||
assert( Client != NULL );
|
||||
return strchr( Client->modes, Mode ) != NULL;
|
||||
} /* Client_HasMode */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN Client_CheckNick( CLIENT *Client, CHAR *Nick )
|
||||
@@ -271,17 +718,17 @@ GLOBAL BOOLEAN Client_CheckNick( CLIENT *Client, CHAR *Nick )
|
||||
assert( Client != NULL );
|
||||
assert( Nick != NULL );
|
||||
|
||||
/* Nick zu lang? */
|
||||
if( strlen( Nick ) > CLIENT_NICK_LEN ) return IRC_WriteStrClient( Client, This_Server, ERR_ERRONEUSNICKNAME_MSG, Client_Nick( Client ), Nick );
|
||||
/* Nick ungueltig? */
|
||||
if( ! Client_IsValidNick( Nick )) return IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), Nick );
|
||||
|
||||
/* Nick bereits vergeben? */
|
||||
c = My_Clients;
|
||||
while( c )
|
||||
{
|
||||
if( strcasecmp( c->nick, Nick ) == 0 )
|
||||
if( strcasecmp( c->id, Nick ) == 0 )
|
||||
{
|
||||
/* den Nick gibt es bereits */
|
||||
IRC_WriteStrClient( Client, This_Server, ERR_NICKNAMEINUSE_MSG, Client_Nick( Client ), Nick );
|
||||
IRC_WriteStrClient( Client, ERR_NICKNAMEINUSE_MSG, Client_ID( Client ), Nick );
|
||||
return FALSE;
|
||||
}
|
||||
c = c->next;
|
||||
@@ -291,18 +738,37 @@ GLOBAL BOOLEAN Client_CheckNick( CLIENT *Client, CHAR *Nick )
|
||||
} /* Client_CheckNick */
|
||||
|
||||
|
||||
GLOBAL CHAR *Client_GetID( CLIENT *Client )
|
||||
GLOBAL BOOLEAN Client_CheckID( CLIENT *Client, CHAR *ID )
|
||||
{
|
||||
/* Client-"ID" liefern, wie sie z.B. fuer
|
||||
* Prefixe benoetigt wird. */
|
||||
/* Nick ueberpruefen */
|
||||
|
||||
CHAR str[COMMAND_LEN];
|
||||
CLIENT *c;
|
||||
|
||||
assert( Client != NULL );
|
||||
|
||||
if( Client->type == CLIENT_SERVER ) return Client->nick;
|
||||
assert( Client->conn_id > NONE );
|
||||
assert( ID != NULL );
|
||||
|
||||
sprintf( GetID_Buffer, "%s!%s@%s", Client->nick, Client->user, Client->host );
|
||||
return GetID_Buffer;
|
||||
} /* Client_GetID */
|
||||
/* Nick zu lang? */
|
||||
if( strlen( ID ) > CLIENT_ID_LEN ) return IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), ID );
|
||||
|
||||
/* ID bereits vergeben? */
|
||||
c = My_Clients;
|
||||
while( c )
|
||||
{
|
||||
if( strcasecmp( c->id, ID ) == 0 )
|
||||
{
|
||||
/* die Server-ID gibt es bereits */
|
||||
sprintf( str, "ID \"%s\" already registered!", ID );
|
||||
Log( LOG_ERR, "%s (on connection %d)", str, Client->conn_id );
|
||||
Conn_Close( Client->conn_id, str, str, TRUE );
|
||||
return FALSE;
|
||||
}
|
||||
c = c->next;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
} /* Client_CheckID */
|
||||
|
||||
|
||||
GLOBAL CLIENT *Client_Search( CHAR *ID )
|
||||
@@ -316,7 +782,7 @@ GLOBAL CLIENT *Client_Search( CHAR *ID )
|
||||
c = My_Clients;
|
||||
while( c )
|
||||
{
|
||||
if( strcasecmp( c->nick, ID ) == 0 ) return c;
|
||||
if( strcasecmp( c->id, ID ) == 0 ) return c;
|
||||
c = c->next;
|
||||
}
|
||||
|
||||
@@ -342,12 +808,123 @@ GLOBAL CLIENT *Client_Next( CLIENT *c )
|
||||
} /* Client_Next */
|
||||
|
||||
|
||||
GLOBAL INT Client_UserCount( VOID )
|
||||
{
|
||||
return Count( CLIENT_USER );
|
||||
} /* Client_UserCount */
|
||||
|
||||
|
||||
GLOBAL INT Client_ServiceCount( VOID )
|
||||
{
|
||||
return Count( CLIENT_SERVICE );;
|
||||
} /* Client_ServiceCount */
|
||||
|
||||
|
||||
GLOBAL INT Client_ServerCount( VOID )
|
||||
{
|
||||
return Count( CLIENT_SERVER );
|
||||
} /* Client_ServerCount */
|
||||
|
||||
|
||||
GLOBAL INT Client_MyUserCount( VOID )
|
||||
{
|
||||
return MyCount( CLIENT_USER );
|
||||
} /* Client_MyUserCount */
|
||||
|
||||
|
||||
GLOBAL INT Client_MyServiceCount( VOID )
|
||||
{
|
||||
return MyCount( CLIENT_SERVICE );
|
||||
} /* Client_MyServiceCount */
|
||||
|
||||
|
||||
GLOBAL INT Client_MyServerCount( VOID )
|
||||
{
|
||||
return MyCount( CLIENT_SERVER );
|
||||
} /* Client_MyServerCount */
|
||||
|
||||
|
||||
GLOBAL INT Client_OperCount( VOID )
|
||||
{
|
||||
CLIENT *c;
|
||||
INT cnt;
|
||||
|
||||
cnt = 0;
|
||||
c = My_Clients;
|
||||
while( c )
|
||||
{
|
||||
if( c && ( c->type == CLIENT_USER ) && ( strchr( c->modes, 'o' ))) cnt++;
|
||||
c = c->next;
|
||||
}
|
||||
return cnt;
|
||||
} /* Client_OperCount */
|
||||
|
||||
|
||||
GLOBAL INT Client_UnknownCount( VOID )
|
||||
{
|
||||
CLIENT *c;
|
||||
INT cnt;
|
||||
|
||||
cnt = 0;
|
||||
c = My_Clients;
|
||||
while( c )
|
||||
{
|
||||
if( c && ( c->type != CLIENT_USER ) && ( c->type != CLIENT_SERVICE ) && ( c->type != CLIENT_SERVER )) cnt++;
|
||||
c = c->next;
|
||||
}
|
||||
return cnt;
|
||||
} /* Client_UnknownCount */
|
||||
|
||||
|
||||
GLOBAL BOOLEAN Client_IsValidNick( CHAR *Nick )
|
||||
{
|
||||
/* Ist der Nick gueltig? */
|
||||
|
||||
assert( Nick != NULL );
|
||||
|
||||
if( Nick[0] == '#' ) return FALSE;
|
||||
if( strlen( Nick ) > CLIENT_NICK_LEN ) return FALSE;
|
||||
return TRUE;
|
||||
} /* Client_IsValidNick */
|
||||
|
||||
|
||||
LOCAL INT Count( CLIENT_TYPE Type )
|
||||
{
|
||||
CLIENT *c;
|
||||
INT cnt;
|
||||
|
||||
cnt = 0;
|
||||
c = My_Clients;
|
||||
while( c )
|
||||
{
|
||||
if( c && ( c->type == Type )) cnt++;
|
||||
c = c->next;
|
||||
}
|
||||
return cnt;
|
||||
} /* Count */
|
||||
|
||||
|
||||
LOCAL INT MyCount( CLIENT_TYPE Type )
|
||||
{
|
||||
CLIENT *c;
|
||||
INT cnt;
|
||||
|
||||
cnt = 0;
|
||||
c = My_Clients;
|
||||
while( c )
|
||||
{
|
||||
if( c && ( c->introducer == This_Server ) && ( c->type == Type )) cnt++;
|
||||
c = c->next;
|
||||
}
|
||||
return cnt;
|
||||
} /* MyCount */
|
||||
|
||||
|
||||
LOCAL CLIENT *New_Client_Struct( VOID )
|
||||
{
|
||||
/* Neue CLIENT-Struktur pre-initialisieren */
|
||||
|
||||
CLIENT *c;
|
||||
INT i;
|
||||
|
||||
c = malloc( sizeof( CLIENT ));
|
||||
if( ! c )
|
||||
@@ -360,18 +937,43 @@ LOCAL CLIENT *New_Client_Struct( VOID )
|
||||
c->type = CLIENT_UNKNOWN;
|
||||
c->conn_id = NONE;
|
||||
c->introducer = NULL;
|
||||
strcpy( c->nick, "" );
|
||||
strcpy( c->pass, "" );
|
||||
c->topserver = NULL;
|
||||
strcpy( c->id, "" );
|
||||
strcpy( c->pwd, "" );
|
||||
strcpy( c->host, "" );
|
||||
strcpy( c->user, "" );
|
||||
strcpy( c->name, "" );
|
||||
strcpy( c->info, "" );
|
||||
for( i = 0; i < MAX_CHANNELS; c->channels[i++] = NULL );
|
||||
strcpy( c->modes, "" );
|
||||
c->oper_by_me = FALSE;
|
||||
c->hops = -1;
|
||||
c->token = -1;
|
||||
c->mytoken = -1;
|
||||
|
||||
return c;
|
||||
} /* New_Client */
|
||||
|
||||
|
||||
LOCAL VOID Generate_MyToken( CLIENT *Client )
|
||||
{
|
||||
CLIENT *c;
|
||||
INT token;
|
||||
|
||||
c = My_Clients;
|
||||
token = 2;
|
||||
while( c )
|
||||
{
|
||||
if( c->mytoken == token )
|
||||
{
|
||||
/* Das Token wurde bereits vergeben */
|
||||
token++;
|
||||
c = My_Clients;
|
||||
continue;
|
||||
}
|
||||
else c = c->next;
|
||||
}
|
||||
Client->mytoken = token;
|
||||
Log( LOG_DEBUG, "Assigned token %d to server \"%s\".", token, Client->id );
|
||||
} /* Generate_MyToken */
|
||||
|
||||
|
||||
/* -eof- */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,47 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: client.h,v 1.11 2001/12/31 15:33:13 alex Exp $
|
||||
* $Id: client.h,v 1.22 2002/02/06 16:49:56 alex Exp $
|
||||
*
|
||||
* client.h: Konfiguration des ngircd (Header)
|
||||
*
|
||||
* $Log: client.h,v $
|
||||
* Revision 1.22 2002/02/06 16:49:56 alex
|
||||
* - neue Funktion Client_IsValidNick().
|
||||
*
|
||||
* 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 :-)
|
||||
@@ -56,7 +92,6 @@
|
||||
#ifndef __client_h__
|
||||
#define __client_h__
|
||||
|
||||
#include "channel.h"
|
||||
#include "conn.h"
|
||||
|
||||
|
||||
@@ -67,47 +102,103 @@ typedef enum
|
||||
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;
|
||||
|
||||
|
||||
#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 */
|
||||
CHAR nick[CLIENT_ID_LEN]; /* Nick (bzw. Server-ID, daher auch IDLEN!) */
|
||||
CHAR pass[CLIENT_PASS_LEN]; /* Passwort, welches der Client angegeben 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 name[CLIENT_NAME_LEN]; /* Langer Benutzername */
|
||||
CHAR info[CLIENT_INFO_LEN]; /* Infotext (Server) */
|
||||
CHANNEL *channels[MAX_CHANNELS];/* IDs der Channel, bzw. NULL */
|
||||
CHAR info[CLIENT_INFO_LEN]; /* Langer Benutzername (User) bzw. Infotext (Server) */
|
||||
CHAR modes[CLIENT_MODE_LEN]; /* Client Modes */
|
||||
BOOLEAN oper_by_me; /* Operator-Status durch diesen Server? */
|
||||
INT hops, token, mytoken; /* "Hops" und "Token" (-> SERVER-Befehl) */
|
||||
BOOLEAN oper_by_me; /* IRC-Operator-Status durch diesen Server? */
|
||||
} CLIENT;
|
||||
|
||||
|
||||
GLOBAL CLIENT *This_Server;
|
||||
#else
|
||||
typedef POINTER CLIENT;
|
||||
#endif
|
||||
|
||||
|
||||
GLOBAL VOID Client_Init( VOID );
|
||||
GLOBAL VOID Client_Exit( VOID );
|
||||
|
||||
GLOBAL CLIENT *Client_NewLocal( CONN_ID Idx, CHAR *Hostname );
|
||||
GLOBAL VOID Client_Destroy( CLIENT *Client );
|
||||
GLOBAL VOID Client_SetHostname( CLIENT *Client, CHAR *Hostname );
|
||||
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 VOID Client_Destroy( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg );
|
||||
|
||||
GLOBAL CLIENT *Client_ThisServer( VOID );
|
||||
|
||||
GLOBAL CLIENT *Client_GetFromConn( CONN_ID Idx );
|
||||
GLOBAL CLIENT *Client_GetFromNick( CHAR *Nick );
|
||||
GLOBAL CHAR *Client_Nick( CLIENT *Client );
|
||||
GLOBAL BOOLEAN Client_CheckNick( CLIENT *Client, CHAR *Nick );
|
||||
GLOBAL CHAR *Client_GetID( CLIENT *Client );
|
||||
GLOBAL CLIENT *Client_GetFromID( CHAR *Nick );
|
||||
GLOBAL CLIENT *Client_GetFromToken( CLIENT *Client, INT Token );
|
||||
|
||||
GLOBAL CLIENT *Client_Search( CHAR *ID );
|
||||
GLOBAL CLIENT *Client_First( VOID );
|
||||
GLOBAL CLIENT *Client_Next( 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 BOOLEAN Client_HasMode( 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 BOOLEAN Client_ModeAdd( CLIENT *Client, CHAR Mode );
|
||||
GLOBAL BOOLEAN Client_ModeDel( CLIENT *Client, CHAR Mode );
|
||||
|
||||
GLOBAL BOOLEAN Client_CheckNick( CLIENT *Client, CHAR *Nick );
|
||||
GLOBAL BOOLEAN Client_CheckID( 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 BOOLEAN Client_IsValidNick( CHAR *Nick );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,30 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: conf.c,v 1.6 2001/12/31 02:18:51 alex Exp $
|
||||
* $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.
|
||||
@@ -43,6 +62,7 @@
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "client.h"
|
||||
@@ -54,6 +74,11 @@
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
|
||||
@@ -66,9 +91,7 @@ GLOBAL VOID Conf_Init( VOID )
|
||||
|
||||
strcpy( Conf_ServerName, "" );
|
||||
strcpy( Conf_ServerInfo, PACKAGE" "VERSION );
|
||||
|
||||
strcpy( Conf_Oper, "" );
|
||||
strcpy( Conf_OperPwd, "" );
|
||||
strcpy( Conf_ServerPwd, "" );
|
||||
|
||||
strcpy( Conf_MotdFile, "/usr/local/etc/ngircd.motd" );
|
||||
|
||||
@@ -77,6 +100,12 @@ GLOBAL VOID Conf_Init( VOID )
|
||||
Conf_PingTimeout = 120;
|
||||
Conf_PongTimeout = 10;
|
||||
|
||||
Conf_ConnectRetry = 60;
|
||||
|
||||
Conf_Oper_Count = 0;
|
||||
|
||||
Conf_Server_Count = 0;
|
||||
|
||||
/* Konfigurationsdatei einlesen und validieren */
|
||||
Read_Config( );
|
||||
Validate_Config( );
|
||||
@@ -93,9 +122,7 @@ LOCAL VOID Read_Config( VOID )
|
||||
{
|
||||
/* Konfigurationsdatei einlesen. */
|
||||
|
||||
CHAR str[LINE_LEN], *var, *arg, *ptr;
|
||||
BOOLEAN ok;
|
||||
INT32 port;
|
||||
CHAR section[LINE_LEN], str[LINE_LEN], *var, *arg, *ptr;
|
||||
INT line;
|
||||
FILE *fd;
|
||||
|
||||
@@ -109,10 +136,9 @@ LOCAL VOID Read_Config( VOID )
|
||||
}
|
||||
|
||||
line = 0;
|
||||
strcpy( section, "" );
|
||||
while( TRUE )
|
||||
{
|
||||
ok = FALSE;
|
||||
|
||||
if( ! fgets( str, LINE_LEN, fd )) break;
|
||||
ngt_TrimStr( str );
|
||||
line++;
|
||||
@@ -120,6 +146,46 @@ LOCAL VOID Read_Config( VOID )
|
||||
/* Kommentarzeilen und leere Zeilen ueberspringen */
|
||||
if( str[0] == ';' || str[0] == '#' || str[0] == '\0' ) continue;
|
||||
|
||||
/* Anfang eines Abschnittes? */
|
||||
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." );
|
||||
else
|
||||
{
|
||||
/* neuen Operator initialisieren */
|
||||
strcpy( Conf_Oper[Conf_Oper_Count].name, "" );
|
||||
strcpy( Conf_Oper[Conf_Oper_Count].pwd, "" );
|
||||
Conf_Oper_Count++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if( strcasecmp( section, "[SERVER]" ) == 0 )
|
||||
{
|
||||
if( Conf_Server_Count + 1 > MAX_SERVERS ) Log( LOG_ERR, "Too many servers configured." );
|
||||
else
|
||||
{
|
||||
/* neuen Server ("Peer") initialisieren */
|
||||
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, "" );
|
||||
Conf_Server[Conf_Server_Count].port = 0;
|
||||
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 );
|
||||
section[0] = 0x1;
|
||||
}
|
||||
if( section[0] == 0x1 ) continue;
|
||||
|
||||
/* In Variable und Argument zerlegen */
|
||||
ptr = strchr( str, '=' );
|
||||
if( ! ptr )
|
||||
{
|
||||
@@ -127,83 +193,169 @@ LOCAL VOID Read_Config( VOID )
|
||||
continue;
|
||||
}
|
||||
*ptr = '\0';
|
||||
|
||||
var = str; ngt_TrimStr( var );
|
||||
arg = ptr + 1; ngt_TrimStr( arg );
|
||||
|
||||
if( strcasecmp( str, "ServerName" ) == 0 )
|
||||
{
|
||||
/* Der Server-Name */
|
||||
strncpy( Conf_ServerName, arg, CLIENT_ID_LEN );
|
||||
Conf_ServerName[CLIENT_ID_LEN - 1] = '\0';
|
||||
ok = TRUE;
|
||||
}
|
||||
else if( strcasecmp( str, "ServerInfo" ) == 0 )
|
||||
{
|
||||
/* Server-Info-Text */
|
||||
strncpy( Conf_ServerInfo, arg, CLIENT_INFO_LEN );
|
||||
Conf_ServerInfo[CLIENT_INFO_LEN - 1] = '\0';
|
||||
ok = TRUE;
|
||||
}
|
||||
else if( strcasecmp( str, "Operator" ) == 0 )
|
||||
{
|
||||
/* Name des IRC Operator */
|
||||
strncpy( Conf_Oper, arg, CLIENT_PASS_LEN );
|
||||
Conf_Oper[CLIENT_PASS_LEN - 1] = '\0';
|
||||
ok = TRUE;
|
||||
}
|
||||
else if( strcasecmp( str, "OperatorPwd" ) == 0 )
|
||||
{
|
||||
/* Passwort des IRC Operator */
|
||||
strncpy( Conf_OperPwd, arg, CLIENT_PASS_LEN );
|
||||
Conf_OperPwd[CLIENT_PASS_LEN - 1] = '\0';
|
||||
ok = TRUE;
|
||||
}
|
||||
else if( strcasecmp( str, "ListenPorts" ) == 0 )
|
||||
{
|
||||
/* Ports, durch "," getrennt, auf denen der Server
|
||||
* Verbindungen annehmen soll */
|
||||
ptr = strtok( arg, "," );
|
||||
while( ptr )
|
||||
{
|
||||
ngt_TrimStr( ptr );
|
||||
port = atol( ptr );
|
||||
if( Conf_ListenPorts_Count + 1 > LISTEN_PORTS ) Log( LOG_ERR, "Too many listen ports configured. Port %ld ignored.", port );
|
||||
if( port > 0 && port < 0xFFFF ) Conf_ListenPorts[Conf_ListenPorts_Count++] = port;
|
||||
else Log( LOG_ERR, "Illegal port number: %ld. Ignored.", port );
|
||||
ptr = strtok( NULL, "," );
|
||||
}
|
||||
ok = TRUE;
|
||||
}
|
||||
else if( strcasecmp( str, "MotdFile" ) == 0 )
|
||||
{
|
||||
/* Datei mit der "message of the day" (MOTD) */
|
||||
strncpy( Conf_MotdFile, arg, FNAME_LEN );
|
||||
Conf_MotdFile[FNAME_LEN - 1] = '\0';
|
||||
ok = TRUE;
|
||||
}
|
||||
else if( strcasecmp( str, "PingTimeout" ) == 0 )
|
||||
{
|
||||
/* PING-Timeout */
|
||||
Conf_PingTimeout = atoi( arg );
|
||||
if(( Conf_PingTimeout ) < 5 ) Conf_PingTimeout = 5;
|
||||
ok = TRUE;
|
||||
}
|
||||
else if( strcasecmp( str, "PongTimeout" ) == 0 )
|
||||
{
|
||||
/* PONG-Timeout */
|
||||
Conf_PongTimeout = atoi( arg );
|
||||
if(( Conf_PongTimeout ) < 5 ) Conf_PongTimeout = 5;
|
||||
ok = TRUE;
|
||||
}
|
||||
|
||||
if( ! ok ) Log( LOG_ERR, "%s, line %d: Unknown variable \"%s\"!", Conf_File, line, var );
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
fclose( fd );
|
||||
} /* Read_Config */
|
||||
|
||||
|
||||
GLOBAL VOID Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
|
||||
{
|
||||
CHAR *ptr;
|
||||
INT port;
|
||||
|
||||
assert( Line > 0 );
|
||||
assert( Var != NULL );
|
||||
assert( Arg != NULL );
|
||||
|
||||
if( strcasecmp( Var, "Name" ) == 0 )
|
||||
{
|
||||
/* Der Server-Name */
|
||||
strncpy( Conf_ServerName, Arg, CLIENT_ID_LEN );
|
||||
Conf_ServerName[CLIENT_ID_LEN - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Info" ) == 0 )
|
||||
{
|
||||
/* Server-Info-Text */
|
||||
strncpy( Conf_ServerInfo, Arg, CLIENT_INFO_LEN );
|
||||
Conf_ServerInfo[CLIENT_INFO_LEN - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Password" ) == 0 )
|
||||
{
|
||||
/* Der Server-Name */
|
||||
strncpy( Conf_ServerPwd, Arg, CLIENT_PASS_LEN );
|
||||
Conf_ServerPwd[CLIENT_PASS_LEN - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Ports" ) == 0 )
|
||||
{
|
||||
/* Ports, durch "," getrennt, auf denen der Server
|
||||
* Verbindungen annehmen soll */
|
||||
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 );
|
||||
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 );
|
||||
}
|
||||
ptr = strtok( NULL, "," );
|
||||
}
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "MotdFile" ) == 0 )
|
||||
{
|
||||
/* Datei mit der "message of the day" (MOTD) */
|
||||
strncpy( Conf_MotdFile, Arg, FNAME_LEN );
|
||||
Conf_MotdFile[FNAME_LEN - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "PingTimeout" ) == 0 )
|
||||
{
|
||||
/* PING-Timeout */
|
||||
Conf_PingTimeout = atoi( Arg );
|
||||
if(( Conf_PingTimeout ) < 5 ) Conf_PingTimeout = 5;
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "PongTimeout" ) == 0 )
|
||||
{
|
||||
/* PONG-Timeout */
|
||||
Conf_PongTimeout = atoi( Arg );
|
||||
if(( Conf_PongTimeout ) < 5 ) Conf_PongTimeout = 5;
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "ConnectRetry" ) == 0 )
|
||||
{
|
||||
/* Sekunden zwischen Verbindungsversuchen zu anderen Servern */
|
||||
Conf_ConnectRetry = atoi( Arg );
|
||||
if(( Conf_ConnectRetry ) < 5 ) Conf_ConnectRetry = 5;
|
||||
return;
|
||||
}
|
||||
|
||||
Log( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", Conf_File, Line, Var );
|
||||
} /* Handle_GLOBAL */
|
||||
|
||||
|
||||
GLOBAL VOID Handle_OPERATOR( INT Line, CHAR *Var, CHAR *Arg )
|
||||
{
|
||||
assert( Line > 0 );
|
||||
assert( Var != NULL );
|
||||
assert( Arg != NULL );
|
||||
assert( Conf_Oper_Count > 0 );
|
||||
|
||||
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';
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Password" ) == 0 )
|
||||
{
|
||||
/* Passwort des IRC Operator */
|
||||
strncpy( Conf_Oper[Conf_Oper_Count - 1].pwd, Arg, CLIENT_PASS_LEN );
|
||||
Conf_Oper[Conf_Oper_Count - 1].pwd[CLIENT_PASS_LEN - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
Log( LOG_ERR, "%s, line %d (section \"Operator\"): Unknown variable \"%s\"!", Conf_File, Line, Var );
|
||||
} /* Handle_OPERATOR */
|
||||
|
||||
|
||||
GLOBAL VOID Handle_SERVER( INT Line, CHAR *Var, CHAR *Arg )
|
||||
{
|
||||
INT port;
|
||||
|
||||
assert( Line > 0 );
|
||||
assert( Var != NULL );
|
||||
assert( Arg != NULL );
|
||||
|
||||
if( strcasecmp( Var, "Host" ) == 0 )
|
||||
{
|
||||
/* Hostname des Servers */
|
||||
strncpy( Conf_Server[Conf_Server_Count - 1].host, Arg, HOST_LEN );
|
||||
Conf_Server[Conf_Server_Count - 1].host[HOST_LEN - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Name" ) == 0 )
|
||||
{
|
||||
/* Name des Servers ("Nick") */
|
||||
strncpy( Conf_Server[Conf_Server_Count - 1].name, Arg, CLIENT_ID_LEN );
|
||||
Conf_Server[Conf_Server_Count - 1].name[CLIENT_ID_LEN - 1] = '\0';
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Password" ) == 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';
|
||||
return;
|
||||
}
|
||||
if( strcasecmp( Var, "Port" ) == 0 )
|
||||
{
|
||||
/* Port, zu dem Verbunden werden soll */
|
||||
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 );
|
||||
return;
|
||||
}
|
||||
|
||||
Log( LOG_ERR, "%s, line %d (section \"Server\"): Unknown variable \"%s\"!", Conf_File, Line, Var );
|
||||
} /* Handle_SERVER */
|
||||
|
||||
|
||||
LOCAL VOID Validate_Config( VOID )
|
||||
{
|
||||
/* Konfiguration ueberpruefen */
|
||||
@@ -211,7 +363,7 @@ LOCAL VOID Validate_Config( VOID )
|
||||
if( ! Conf_ServerName[0] )
|
||||
{
|
||||
/* Kein Servername konfiguriert */
|
||||
Log( LOG_ALERT, "No server name configured (use \"ServerName\")!", Conf_File, strerror( errno ));
|
||||
Log( LOG_ALERT, "No server name configured in \"%s\"!", Conf_File );
|
||||
Log( LOG_ALERT, PACKAGE" exiting due to fatal errors!" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,18 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: conf.h,v 1.6 2001/12/31 02:18:51 alex Exp $
|
||||
* $Id: conf.h,v 1.9 2002/01/03 02:27:20 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.
|
||||
@@ -39,22 +46,60 @@
|
||||
#ifndef __conf_h__
|
||||
#define __conf_h__
|
||||
|
||||
#include <time.h>
|
||||
|
||||
GLOBAL CHAR Conf_File[FNAME_LEN]; /* Konfigurationsdatei */
|
||||
|
||||
GLOBAL CHAR Conf_ServerName[CLIENT_ID_LEN]; /* Name ("Nick") des Servers */
|
||||
GLOBAL CHAR Conf_ServerInfo[CLIENT_INFO_LEN]; /* Servers-Info-Text */
|
||||
typedef struct _Conf_Oper
|
||||
{
|
||||
CHAR name[CLIENT_PASS_LEN];
|
||||
CHAR pwd[CLIENT_PASS_LEN];
|
||||
} CONF_OPER;
|
||||
|
||||
GLOBAL CHAR Conf_MotdFile[FNAME_LEN]; /* Datei mit MOTD-Text */
|
||||
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;
|
||||
} CONF_SERVER;
|
||||
|
||||
GLOBAL INT Conf_ListenPorts[LISTEN_PORTS]; /* Ports, auf denen der Server Verbindungen */
|
||||
GLOBAL INT Conf_ListenPorts_Count; /* entgegen nimmt sowie deren Anzahl */
|
||||
|
||||
GLOBAL CHAR Conf_Oper[CLIENT_PASS_LEN]; /* Operator Name */
|
||||
GLOBAL CHAR Conf_OperPwd[CLIENT_PASS_LEN]; /* Operator Passwort */
|
||||
/* Konfigurationsdatei */
|
||||
GLOBAL CHAR Conf_File[FNAME_LEN];
|
||||
|
||||
GLOBAL INT Conf_PingTimeout; /* Ping Timeout */
|
||||
GLOBAL INT Conf_PongTimeout; /* Pong Timeout */
|
||||
/* Name ("Nick") des Servers */
|
||||
GLOBAL CHAR Conf_ServerName[CLIENT_ID_LEN];
|
||||
|
||||
/* Servers-Info-Text */
|
||||
GLOBAL CHAR Conf_ServerInfo[CLIENT_INFO_LEN];
|
||||
|
||||
/* Server-Passwort */
|
||||
GLOBAL CHAR Conf_ServerPwd[CLIENT_PASS_LEN];
|
||||
|
||||
/* Datei mit MOTD-Text */
|
||||
GLOBAL CHAR Conf_MotdFile[FNAME_LEN];
|
||||
|
||||
/* Ports, auf denen der Server Verbindungen entgegen nimmt */
|
||||
GLOBAL INT Conf_ListenPorts[MAX_LISTEN_PORTS];
|
||||
GLOBAL INT Conf_ListenPorts_Count;
|
||||
|
||||
/* Timeouts fuer PING und PONG */
|
||||
GLOBAL INT Conf_PingTimeout;
|
||||
GLOBAL INT Conf_PongTimeout;
|
||||
|
||||
/* Sekunden zwischen Verbindungsversuchen zu anderen Servern */
|
||||
GLOBAL INT Conf_ConnectRetry;
|
||||
|
||||
/* Operatoren */
|
||||
GLOBAL CONF_OPER Conf_Oper[MAX_OPERATORS];
|
||||
GLOBAL INT Conf_Oper_Count;
|
||||
|
||||
/* Server */
|
||||
GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS];
|
||||
GLOBAL INT Conf_Server_Count;
|
||||
|
||||
|
||||
GLOBAL VOID Conf_Init( VOID );
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,52 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: conn.c,v 1.23 2001/12/31 02:18:51 alex Exp $
|
||||
* $Id: conn.c,v 1.36 2002/02/11 01:00:50 alex Exp $
|
||||
*
|
||||
* connect.h: Verwaltung aller Netz-Verbindungen ("connections")
|
||||
*
|
||||
* $Log: conn.c,v $
|
||||
* Revision 1.36 2002/02/11 01:00:50 alex
|
||||
* - neue Funktion Conn_LastPing().
|
||||
*
|
||||
* Revision 1.35 2002/01/18 11:12:11 alex
|
||||
* - der Sniffer wird nun nur noch aktiviert, wenn auf Kommandozeile angegeben.
|
||||
*
|
||||
* Revision 1.34 2002/01/07 15:29:52 alex
|
||||
* - PASSSERVERADD definiert, wird beim PASS-Befehl an Server verwendet.
|
||||
*
|
||||
* Revision 1.33 2002/01/06 15:18:14 alex
|
||||
* - Loglevel und Meldungen nochmals geaendert. Level passen nun besser.
|
||||
*
|
||||
* Revision 1.32 2002/01/05 23:25:25 alex
|
||||
* - Vorbereitungen fuer Ident-Abfragen bei neuen Client-Strukturen.
|
||||
*
|
||||
* Revision 1.31 2002/01/05 19:15:03 alex
|
||||
* - Fehlerpruefung bei select() in der "Hauptschleife" korrigiert.
|
||||
*
|
||||
* Revision 1.30 2002/01/05 15:56:23 alex
|
||||
* - "arpa/inet.h" wird nur noch includiert, wenn vorhanden.
|
||||
* - Ein Fehler bei select() fuerht nun zum Abbruch von ngIRCd.
|
||||
* - NO_ADDRESS durch NO_DATA ersetzt: ist wohl portabler.
|
||||
*
|
||||
* Revision 1.29 2002/01/04 01:36:40 alex
|
||||
* - Loglevel ein wenig angepasst.
|
||||
*
|
||||
* Revision 1.28 2002/01/04 01:20:23 alex
|
||||
* - Client-Strukruren werden nur noch ueber Funktionen angesprochen.
|
||||
*
|
||||
* Revision 1.27 2002/01/03 02:25:36 alex
|
||||
* - diverse Aenderungen und Umsetellungen fuer Server-Links.
|
||||
*
|
||||
* Revision 1.26 2002/01/02 02:50:47 alex
|
||||
* - Asyncroner Resolver Hostname->IP.
|
||||
* - Server-Links begonnen zu implementieren. Die Verbindung wird aufgebaut,
|
||||
* jedoch noch keine SERVER-Befehle verschickt.
|
||||
* - Diverse Bug-Fixes und kleinere Erweiterungen.
|
||||
*
|
||||
* Revision 1.24 2002/01/01 18:25:44 alex
|
||||
* - #include's fuer stdlib.h ergaenzt.
|
||||
*
|
||||
* Revision 1.23 2001/12/31 02:18:51 alex
|
||||
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
|
||||
* - neuen Header "defines.h" mit (fast) allen Konstanten.
|
||||
@@ -104,6 +145,7 @@
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
@@ -113,9 +155,14 @@
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#else
|
||||
#define PF_INET AF_INET
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h> /* u.a. fuer Mac OS X */
|
||||
#endif
|
||||
@@ -131,11 +178,7 @@
|
||||
#include "conn.h"
|
||||
|
||||
|
||||
typedef struct _Res_Stat
|
||||
{
|
||||
INT pid; /* PID des Child-Prozess */
|
||||
INT pipe[2]; /* Pipe fuer IPC */
|
||||
} RES_STAT;
|
||||
#define SERVER_WAIT NONE - 1
|
||||
|
||||
|
||||
typedef struct _Connection
|
||||
@@ -148,6 +191,7 @@ typedef struct _Connection
|
||||
INT rdatalen; /* Laenge der Daten im Lesepuffer */
|
||||
CHAR wbuf[WRITEBUFFER_LEN]; /* Schreibpuffer */
|
||||
INT wdatalen; /* Laenge der Daten im Schreibpuffer */
|
||||
INT our_server; /* wenn von uns zu connectender Server: ID */
|
||||
time_t lastdata; /* Letzte Aktivitaet */
|
||||
time_t lastping; /* Letzter PING */
|
||||
time_t lastprivmsg; /* Letzte PRIVMSG */
|
||||
@@ -162,11 +206,16 @@ LOCAL VOID Read_Request( CONN_ID Idx );
|
||||
LOCAL BOOLEAN Try_Write( CONN_ID Idx );
|
||||
LOCAL VOID Handle_Buffer( CONN_ID Idx );
|
||||
LOCAL VOID Check_Connections( VOID );
|
||||
LOCAL VOID Check_Servers( VOID );
|
||||
LOCAL VOID Init_Conn_Struct( INT Idx );
|
||||
LOCAL VOID New_Server( INT Server, CONN_ID Idx );
|
||||
|
||||
LOCAL RES_STAT *Resolve( struct sockaddr_in *Addr );
|
||||
LOCAL RES_STAT *ResolveAddr( struct sockaddr_in *Addr );
|
||||
LOCAL RES_STAT *ResolveName( CHAR *Host );
|
||||
LOCAL VOID Do_ResolveAddr( struct sockaddr_in *Addr, INT w_fd );
|
||||
LOCAL VOID Do_ResolveName( CHAR *Host, INT w_fd );
|
||||
LOCAL VOID Read_Resolver_Result( INT r_fd );
|
||||
LOCAL VOID Do_Resolve( struct sockaddr_in *Addr, INT w_fd );
|
||||
LOCAL CHAR *Resolv_Error( INT H_Error );
|
||||
|
||||
|
||||
LOCAL fd_set My_Listeners;
|
||||
@@ -205,6 +254,7 @@ GLOBAL VOID Conn_Exit( VOID )
|
||||
INT i;
|
||||
|
||||
/* Sockets schliessen */
|
||||
Log( LOG_DEBUG, "Shutting down all connections ..." );
|
||||
for( i = 0; i < My_Max_Fd + 1; i++ )
|
||||
{
|
||||
if( FD_ISSET( i, &My_Sockets ))
|
||||
@@ -213,11 +263,11 @@ GLOBAL VOID Conn_Exit( VOID )
|
||||
{
|
||||
if( My_Connections[idx].sock == i ) break;
|
||||
}
|
||||
if( idx < MAX_CONNECTIONS ) Conn_Close( idx, "Server going down ..." );
|
||||
if( idx < MAX_CONNECTIONS ) Conn_Close( idx, NULL, "Server going down", TRUE );
|
||||
else if( FD_ISSET( i, &My_Listeners ))
|
||||
{
|
||||
close( i );
|
||||
Log( LOG_INFO, "Listening socket %d closed.", i );
|
||||
Log( LOG_DEBUG, "Listening socket %d closed.", i );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -248,27 +298,27 @@ GLOBAL BOOLEAN Conn_NewListener( CONST INT Port )
|
||||
sock = socket( PF_INET, SOCK_STREAM, 0);
|
||||
if( sock < 0 )
|
||||
{
|
||||
Log( LOG_ALERT, "Can't create socket: %s!", strerror( errno ));
|
||||
Log( LOG_CRIT, "Can't create socket: %s!", strerror( errno ));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Socket-Optionen setzen */
|
||||
if( fcntl( sock, F_SETFL, O_NONBLOCK ) != 0 )
|
||||
{
|
||||
Log( LOG_ALERT, "Can't enable non-blocking mode: %s!", strerror( errno ));
|
||||
Log( LOG_CRIT, "Can't enable non-blocking mode: %s!", strerror( errno ));
|
||||
close( sock );
|
||||
return FALSE;
|
||||
}
|
||||
if( setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &on, (socklen_t)sizeof( on )) != 0)
|
||||
{
|
||||
Log( LOG_CRIT, "Can't set socket options: %s!", strerror( errno ));
|
||||
Log( LOG_ERR, "Can't set socket options: %s!", strerror( errno ));
|
||||
/* dieser Fehler kann ignoriert werden. */
|
||||
}
|
||||
|
||||
/* an Port binden */
|
||||
if( bind( sock, (struct sockaddr *)&addr, (socklen_t)sizeof( addr )) != 0 )
|
||||
{
|
||||
Log( LOG_ALERT, "Can't bind socket: %s!", strerror( errno ));
|
||||
Log( LOG_CRIT, "Can't bind socket: %s!", strerror( errno ));
|
||||
close( sock );
|
||||
return FALSE;
|
||||
}
|
||||
@@ -276,7 +326,7 @@ GLOBAL BOOLEAN Conn_NewListener( CONST INT Port )
|
||||
/* in "listen mode" gehen :-) */
|
||||
if( listen( sock, 10 ) != 0 )
|
||||
{
|
||||
Log( LOG_ALERT, "Can't listen on soecket: %s!", strerror( errno ));
|
||||
Log( LOG_CRIT, "Can't listen on soecket: %s!", strerror( errno ));
|
||||
close( sock );
|
||||
return FALSE;
|
||||
}
|
||||
@@ -299,6 +349,7 @@ GLOBAL VOID Conn_Handler( INT Timeout )
|
||||
* Sekunden wird die Funktion verlassen. Folgende Aktionen
|
||||
* werden durchgefuehrt:
|
||||
* - neue Verbindungen annehmen,
|
||||
* - Server-Verbindungen aufbauen,
|
||||
* - geschlossene Verbindungen loeschen,
|
||||
* - volle Schreibpuffer versuchen zu schreiben,
|
||||
* - volle Lesepuffer versuchen zu verarbeiten,
|
||||
@@ -313,6 +364,8 @@ GLOBAL VOID Conn_Handler( INT Timeout )
|
||||
start = time( NULL );
|
||||
while(( time( NULL ) - start < Timeout ) && ( ! NGIRCd_Quit ))
|
||||
{
|
||||
Check_Servers( );
|
||||
|
||||
Check_Connections( );
|
||||
|
||||
/* Timeout initialisieren */
|
||||
@@ -322,7 +375,7 @@ GLOBAL VOID Conn_Handler( INT Timeout )
|
||||
/* noch volle Lese-Buffer suchen */
|
||||
for( i = 0; i < MAX_CONNECTIONS; i++ )
|
||||
{
|
||||
if(( My_Connections[i].sock >= 0 ) && ( My_Connections[i].rdatalen > 0 ))
|
||||
if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].rdatalen > 0 ))
|
||||
{
|
||||
/* Kann aus dem Buffer noch ein Befehl extrahiert werden? */
|
||||
Handle_Buffer( i );
|
||||
@@ -333,7 +386,7 @@ GLOBAL VOID Conn_Handler( INT Timeout )
|
||||
FD_ZERO( &write_sockets );
|
||||
for( i = 0; i < MAX_CONNECTIONS; i++ )
|
||||
{
|
||||
if(( My_Connections[i].sock >= 0 ) && ( My_Connections[i].wdatalen > 0 ))
|
||||
if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].wdatalen > 0 ))
|
||||
{
|
||||
/* Socket der Verbindung in Set aufnehmen */
|
||||
FD_SET( My_Connections[i].sock, &write_sockets );
|
||||
@@ -344,7 +397,7 @@ GLOBAL VOID Conn_Handler( INT Timeout )
|
||||
read_sockets = My_Sockets;
|
||||
for( i = 0; i < MAX_CONNECTIONS; i++ )
|
||||
{
|
||||
if(( My_Connections[i].sock >= 0 ) && ( My_Connections[i].host[0] == '\0' ))
|
||||
if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].host[0] == '\0' ))
|
||||
{
|
||||
/* Hier muss noch auf den Resolver Sub-Prozess gewartet werden */
|
||||
FD_CLR( My_Connections[i].sock, &read_sockets );
|
||||
@@ -362,8 +415,13 @@ GLOBAL VOID Conn_Handler( INT Timeout )
|
||||
/* Auf Aktivitaet warten */
|
||||
if( select( My_Max_Fd + 1, &read_sockets, &write_sockets, NULL, &tv ) == -1 )
|
||||
{
|
||||
if( errno != EINTR ) Log( LOG_ALERT, "select(): %s!", strerror( errno ));
|
||||
return;
|
||||
if( errno != EINTR )
|
||||
{
|
||||
Log( LOG_EMERG, "select(): %s!", strerror( errno ));
|
||||
Log( LOG_ALERT, PACKAGE" exiting due to fatal errors!" );
|
||||
exit( 1 );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Koennen Daten geschrieben werden? */
|
||||
@@ -394,13 +452,13 @@ GLOBAL BOOLEAN Conn_WriteStr( CONN_ID Idx, CHAR *Format, ... )
|
||||
va_start( ap, Format );
|
||||
if( vsnprintf( buffer, COMMAND_LEN - 2, Format, ap ) == COMMAND_LEN - 2 )
|
||||
{
|
||||
Log( LOG_ALERT, "String too long to send (connection %d)!", Idx );
|
||||
Conn_Close( Idx, "Server error: String too long to send!" );
|
||||
Log( LOG_CRIT, "Text too long to send (connection %d)!", Idx );
|
||||
Conn_Close( Idx, "Text too long to send!", NULL, FALSE );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef SNIFFER
|
||||
Log( LOG_DEBUG, " -> connection %d: '%s'.", Idx, buffer );
|
||||
if( NGIRCd_Sniffer ) Log( LOG_DEBUG, " -> connection %d: '%s'.", Idx, buffer );
|
||||
#endif
|
||||
|
||||
strcat( buffer, "\r\n" );
|
||||
@@ -417,7 +475,7 @@ GLOBAL BOOLEAN Conn_Write( CONN_ID Idx, CHAR *Data, INT Len )
|
||||
* der Client disconnectiert und FALSE geliefert. */
|
||||
|
||||
assert( Idx >= 0 );
|
||||
assert( My_Connections[Idx].sock >= 0 );
|
||||
assert( My_Connections[Idx].sock > NONE );
|
||||
assert( Data != NULL );
|
||||
assert( Len > 0 );
|
||||
|
||||
@@ -433,7 +491,7 @@ GLOBAL BOOLEAN Conn_Write( CONN_ID Idx, CHAR *Data, INT Len )
|
||||
{
|
||||
/* der Puffer ist dummerweise voll ... */
|
||||
Log( LOG_NOTICE, "Write buffer overflow (connection %d)!", Idx );
|
||||
Conn_Close( Idx, NULL );
|
||||
Conn_Close( Idx, "Write buffer overflow!", NULL, FALSE );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -451,27 +509,34 @@ GLOBAL BOOLEAN Conn_Write( CONN_ID Idx, CHAR *Data, INT Len )
|
||||
} /* Conn_Write */
|
||||
|
||||
|
||||
GLOBAL VOID Conn_Close( CONN_ID Idx, CHAR *Msg )
|
||||
GLOBAL VOID Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient )
|
||||
{
|
||||
/* Verbindung schliessen. Evtl. noch von Resolver
|
||||
* Sub-Prozessen offene Pipes werden geschlossen. */
|
||||
|
||||
CLIENT *c;
|
||||
|
||||
assert( Idx >= 0 );
|
||||
assert( My_Connections[Idx].sock >= 0 );
|
||||
assert( My_Connections[Idx].sock > NONE );
|
||||
|
||||
if( Msg ) Conn_WriteStr( Idx, "ERROR :%s", Msg );
|
||||
if( InformClient )
|
||||
{
|
||||
if( FwdMsg ) Conn_WriteStr( Idx, "ERROR :%s", FwdMsg );
|
||||
else Conn_WriteStr( Idx, "ERROR :Closing connection." );
|
||||
if( My_Connections[Idx].sock == NONE ) return;
|
||||
}
|
||||
|
||||
if( close( My_Connections[Idx].sock ) != 0 )
|
||||
{
|
||||
Log( LOG_ERR, "Error closing connection %d with %s:%d - %s!", Idx, inet_ntoa( My_Connections[Idx].addr.sin_addr ), ntohs( My_Connections[Idx].addr.sin_port), strerror( errno ));
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log( LOG_NOTICE, "Connection %d with %s:%d closed.", Idx, inet_ntoa( My_Connections[Idx].addr.sin_addr ), ntohs( My_Connections[Idx].addr.sin_port ));
|
||||
Log( LOG_INFO, "Connection %d with %s:%d closed.", Idx, inet_ntoa( My_Connections[Idx].addr.sin_addr ), ntohs( My_Connections[Idx].addr.sin_port ));
|
||||
}
|
||||
|
||||
Client_Destroy( Client_GetFromConn( Idx ));
|
||||
c = Client_GetFromConn( Idx );
|
||||
if( c ) Client_Destroy( c, LogMsg, FwdMsg );
|
||||
|
||||
if( My_Connections[Idx].res_stat )
|
||||
{
|
||||
@@ -481,7 +546,10 @@ GLOBAL VOID Conn_Close( CONN_ID Idx, CHAR *Msg )
|
||||
close( My_Connections[Idx].res_stat->pipe[1] );
|
||||
free( My_Connections[Idx].res_stat );
|
||||
}
|
||||
|
||||
|
||||
/* Bei Server-Verbindungen lasttry-Zeitpunkt auf "jetzt" setzen */
|
||||
if( My_Connections[Idx].our_server >= 0 ) Conf_Server[My_Connections[Idx].our_server].lasttry = time( NULL );
|
||||
|
||||
FD_CLR( My_Connections[Idx].sock, &My_Sockets );
|
||||
My_Connections[Idx].sock = NONE;
|
||||
} /* Conn_Close */
|
||||
@@ -505,6 +573,15 @@ GLOBAL INT32 Conn_GetIdle( CONN_ID Idx )
|
||||
} /* Conn_GetIdle */
|
||||
|
||||
|
||||
GLOBAL INT32 Conn_LastPing( CONN_ID Idx )
|
||||
{
|
||||
/* Zeitpunkt des letzten PING liefern */
|
||||
|
||||
assert( Idx >= 0 );
|
||||
return My_Connections[Idx].lastping;
|
||||
} /* Conn_LastPing */
|
||||
|
||||
|
||||
LOCAL BOOLEAN Try_Write( CONN_ID Idx )
|
||||
{
|
||||
/* Versuchen, Daten aus dem Schreib-Puffer in den
|
||||
@@ -513,7 +590,7 @@ LOCAL BOOLEAN Try_Write( CONN_ID Idx )
|
||||
fd_set write_socket;
|
||||
|
||||
assert( Idx >= 0 );
|
||||
assert( My_Connections[Idx].sock >= 0 );
|
||||
assert( My_Connections[Idx].sock > NONE );
|
||||
assert( My_Connections[Idx].wdatalen > 0 );
|
||||
|
||||
FD_ZERO( &write_socket );
|
||||
@@ -523,8 +600,8 @@ LOCAL BOOLEAN Try_Write( CONN_ID Idx )
|
||||
/* Fehler! */
|
||||
if( errno != EINTR )
|
||||
{
|
||||
Log( LOG_ALERT, "select(): %s!", strerror( errno ));
|
||||
Conn_Close( Idx, NULL );
|
||||
Log( LOG_ALERT, "select() failed: %s!", strerror( errno ));
|
||||
Conn_Close( Idx, "Server error!", NULL, FALSE );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -575,7 +652,7 @@ LOCAL BOOLEAN Handle_Write( CONN_ID Idx )
|
||||
INT len;
|
||||
|
||||
assert( Idx >= 0 );
|
||||
assert( My_Connections[Idx].sock >= 0 );
|
||||
assert( My_Connections[Idx].sock > NONE );
|
||||
assert( My_Connections[Idx].wdatalen > 0 );
|
||||
|
||||
/* Daten schreiben */
|
||||
@@ -583,8 +660,8 @@ LOCAL BOOLEAN Handle_Write( CONN_ID Idx )
|
||||
if( len < 0 )
|
||||
{
|
||||
/* Oops, ein Fehler! */
|
||||
Log( LOG_ALERT, "Write error (buffer) on connection %d: %s!", Idx, strerror( errno ));
|
||||
Conn_Close( Idx, NULL );
|
||||
Log( LOG_ERR, "Write error (buffer) on connection %d: %s!", Idx, strerror( errno ));
|
||||
Conn_Close( Idx, "Write error (buffer)!", NULL, FALSE );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -605,7 +682,7 @@ LOCAL VOID New_Connection( INT Sock )
|
||||
INT new_sock, new_sock_len;
|
||||
RES_STAT *s;
|
||||
CONN_ID idx;
|
||||
|
||||
|
||||
assert( Sock >= 0 );
|
||||
|
||||
new_sock_len = sizeof( new_addr );
|
||||
@@ -617,7 +694,7 @@ LOCAL VOID New_Connection( INT Sock )
|
||||
}
|
||||
|
||||
/* Freie Connection-Struktur suschen */
|
||||
for( idx = 0; idx < MAX_CONNECTIONS; idx++ ) if( My_Connections[idx].sock < 0 ) break;
|
||||
for( idx = 0; idx < MAX_CONNECTIONS; idx++ ) if( My_Connections[idx].sock == NONE ) break;
|
||||
if( idx >= MAX_CONNECTIONS )
|
||||
{
|
||||
Log( LOG_ALERT, "Can't accept connection: limit reached (%d)!", MAX_CONNECTIONS );
|
||||
@@ -626,7 +703,7 @@ LOCAL VOID New_Connection( INT Sock )
|
||||
}
|
||||
|
||||
/* Client-Struktur initialisieren */
|
||||
if( ! Client_NewLocal( idx, inet_ntoa( new_addr.sin_addr )))
|
||||
if( ! Client_NewLocal( idx, inet_ntoa( new_addr.sin_addr ), CLIENT_UNKNOWN, FALSE ))
|
||||
{
|
||||
Log( LOG_ALERT, "Can't accept connection: can't create client structure!" );
|
||||
close( new_sock );
|
||||
@@ -642,10 +719,10 @@ LOCAL VOID New_Connection( INT Sock )
|
||||
FD_SET( new_sock, &My_Sockets );
|
||||
if( new_sock > My_Max_Fd ) My_Max_Fd = new_sock;
|
||||
|
||||
Log( LOG_NOTICE, "Accepted connection %d from %s:%d on socket %d.", idx, inet_ntoa( new_addr.sin_addr ), ntohs( new_addr.sin_port), Sock );
|
||||
Log( LOG_INFO, "Accepted connection %d from %s:%d on socket %d.", idx, inet_ntoa( new_addr.sin_addr ), ntohs( new_addr.sin_port), Sock );
|
||||
|
||||
/* Hostnamen ermitteln */
|
||||
s = Resolve( &new_addr );
|
||||
s = ResolveAddr( &new_addr );
|
||||
if( s )
|
||||
{
|
||||
/* Sub-Prozess wurde asyncron gestartet */
|
||||
@@ -682,42 +759,39 @@ LOCAL VOID Read_Request( CONN_ID Idx )
|
||||
INT len;
|
||||
|
||||
assert( Idx >= 0 );
|
||||
assert( My_Connections[Idx].sock >= 0 );
|
||||
assert( My_Connections[Idx].sock > NONE );
|
||||
|
||||
len = recv( My_Connections[Idx].sock, My_Connections[Idx].rbuf + My_Connections[Idx].rdatalen, READBUFFER_LEN - My_Connections[Idx].rdatalen - 1, 0 );
|
||||
My_Connections[Idx].rbuf[READBUFFER_LEN - 1] = '\0';
|
||||
if( READBUFFER_LEN - My_Connections[Idx].rdatalen - 2 < 0 )
|
||||
{
|
||||
/* Der Lesepuffer ist voll */
|
||||
Log( LOG_ERR, "Read buffer overflow (connection %d): %d bytes!", Idx, My_Connections[Idx].rdatalen );
|
||||
Conn_Close( Idx, "Read buffer overflow!", NULL, FALSE );
|
||||
return;
|
||||
}
|
||||
|
||||
len = recv( My_Connections[Idx].sock, My_Connections[Idx].rbuf + My_Connections[Idx].rdatalen, READBUFFER_LEN - My_Connections[Idx].rdatalen - 2, 0 );
|
||||
|
||||
if( len == 0 )
|
||||
{
|
||||
/* Socket wurde geschlossen */
|
||||
Log( LOG_INFO, "%s:%d is closing the connection ...", inet_ntoa( My_Connections[Idx].addr.sin_addr ), ntohs( My_Connections[Idx].addr.sin_port));
|
||||
Conn_Close( Idx, NULL );
|
||||
Conn_Close( Idx, "Socket closed.", NULL, FALSE );
|
||||
return;
|
||||
}
|
||||
|
||||
if( len < 0 )
|
||||
{
|
||||
/* Fehler beim Lesen */
|
||||
Log( LOG_ALERT, "Read error on connection %d: %s!", Idx, strerror( errno ));
|
||||
Conn_Close( Idx, NULL );
|
||||
Log( LOG_ERR, "Read error on connection %d: %s!", Idx, strerror( errno ));
|
||||
Conn_Close( Idx, "Read error!", NULL, FALSE );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Lesebuffer updaten */
|
||||
My_Connections[Idx].rdatalen += len;
|
||||
assert( My_Connections[Idx].rdatalen <= READBUFFER_LEN );
|
||||
assert( My_Connections[Idx].rdatalen < READBUFFER_LEN );
|
||||
My_Connections[Idx].rbuf[My_Connections[Idx].rdatalen] = '\0';
|
||||
|
||||
if( My_Connections[Idx].rdatalen > COMMAND_LEN )
|
||||
{
|
||||
/* Eine Anfrage darf(!) nicht laenger als 512 Zeichen
|
||||
* (incl. CR+LF!) werden; vgl. RFC 2812. Wenn soetwas
|
||||
* empfangen wird, wird der Client disconnectiert. */
|
||||
Log( LOG_ALERT, "Request too long (connection %d)!", Idx );
|
||||
Conn_Close( Idx, "Request too long!" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Timestamp aktualisieren */
|
||||
My_Connections[Idx].lastdata = time( NULL );
|
||||
|
||||
@@ -737,6 +811,7 @@ LOCAL VOID Handle_Buffer( CONN_ID Idx )
|
||||
ptr = strstr( My_Connections[Idx].rbuf, "\r\n" );
|
||||
|
||||
if( ptr ) delta = 2;
|
||||
#ifndef STRICT_RFC
|
||||
else
|
||||
{
|
||||
/* Nicht RFC-konforme Anfrage mit nur CR oder LF? Leider
|
||||
@@ -748,12 +823,23 @@ LOCAL VOID Handle_Buffer( CONN_ID Idx )
|
||||
else if( ptr1 ) ptr = ptr1;
|
||||
else if( ptr2 ) ptr = ptr2;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if( ptr )
|
||||
{
|
||||
/* Ende der Anfrage wurde gefunden */
|
||||
*ptr = '\0';
|
||||
len = ( ptr - My_Connections[Idx].rbuf ) + delta;
|
||||
if( len > COMMAND_LEN )
|
||||
{
|
||||
/* Eine Anfrage darf(!) nicht laenger als 512 Zeichen
|
||||
* (incl. CR+LF!) werden; vgl. RFC 2812. Wenn soetwas
|
||||
* empfangen wird, wird der Client disconnectiert. */
|
||||
Log( LOG_ERR, "Request too long (connection %d): %d bytes!", Idx, My_Connections[Idx].rdatalen );
|
||||
Conn_Close( Idx, NULL, "Request too long", TRUE );
|
||||
return;
|
||||
}
|
||||
|
||||
if( len > delta )
|
||||
{
|
||||
/* Es wurde ein Request gelesen */
|
||||
@@ -773,20 +859,25 @@ LOCAL VOID Check_Connections( VOID )
|
||||
* nicht der Fall, zunaechst PING-PONG spielen und, wenn
|
||||
* auch das nicht "hilft", Client disconnectieren. */
|
||||
|
||||
CLIENT *c;
|
||||
INT i;
|
||||
|
||||
for( i = 0; i < MAX_CONNECTIONS; i++ )
|
||||
{
|
||||
if( My_Connections[i].sock != NONE )
|
||||
if( My_Connections[i].sock == NONE ) continue;
|
||||
|
||||
c = Client_GetFromConn( i );
|
||||
if( c && (( Client_Type( c ) == CLIENT_USER ) || ( Client_Type( c ) == CLIENT_SERVER ) || ( Client_Type( c ) == CLIENT_SERVICE )))
|
||||
{
|
||||
/* verbundener User, Server oder Service */
|
||||
if( My_Connections[i].lastping > My_Connections[i].lastdata )
|
||||
{
|
||||
/* es wurde bereits ein PING gesendet */
|
||||
if( My_Connections[i].lastping < time( NULL ) - Conf_PongTimeout )
|
||||
{
|
||||
/* Timeout */
|
||||
Log( LOG_INFO, "Connection %d: Ping timeout.", i );
|
||||
Conn_Close( i, "Ping timeout" );
|
||||
Log( LOG_DEBUG, "Connection %d: Ping timeout.", i );
|
||||
Conn_Close( i, NULL, "Ping timeout", TRUE );
|
||||
}
|
||||
}
|
||||
else if( My_Connections[i].lastdata < time( NULL ) - Conf_PingTimeout )
|
||||
@@ -794,11 +885,161 @@ LOCAL VOID Check_Connections( VOID )
|
||||
/* es muss ein PING gesendet werden */
|
||||
Log( LOG_DEBUG, "Connection %d: sending PING ...", i );
|
||||
My_Connections[i].lastping = time( NULL );
|
||||
Conn_WriteStr( i, "PING :%s", This_Server->nick );
|
||||
Conn_WriteStr( i, "PING :%s", Client_ID( Client_ThisServer( )));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* noch nicht vollstaendig aufgebaute Verbindung */
|
||||
if( My_Connections[i].lastdata < time( NULL ) - Conf_PingTimeout )
|
||||
{
|
||||
/* Timeout */
|
||||
Log( LOG_INFO, "Connection %d: Timeout.", i );
|
||||
Conn_Close( i, NULL, "Timeout", TRUE );
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* Conn_Check */
|
||||
} /* Check_Connections */
|
||||
|
||||
|
||||
LOCAL VOID Check_Servers( VOID )
|
||||
{
|
||||
/* Pruefen, ob Server-Verbindungen aufgebaut werden
|
||||
* muessen bzw. koennen */
|
||||
|
||||
INT idx, i, n;
|
||||
RES_STAT *s;
|
||||
|
||||
for( i = 0; i < Conf_Server_Count; i++ )
|
||||
{
|
||||
/* Ist ein Hostname und Port definiert? */
|
||||
if(( ! Conf_Server[i].host[0] ) || ( ! Conf_Server[i].port > 0 )) continue;
|
||||
|
||||
/* Haben wir schon eine Verbindung? */
|
||||
for( n = 0; n < MAX_CONNECTIONS; n++ )
|
||||
{
|
||||
if(( My_Connections[n].sock != NONE ) && ( My_Connections[n].our_server == i ))
|
||||
{
|
||||
/* Komplett aufgebaute Verbindung? */
|
||||
if( My_Connections[n].sock > NONE ) break;
|
||||
|
||||
/* IP schon aufgeloest? */
|
||||
if( My_Connections[n].res_stat == NULL ) New_Server( i, n );
|
||||
}
|
||||
}
|
||||
if( n < MAX_CONNECTIONS ) continue;
|
||||
|
||||
/* Wann war der letzte Connect-Versuch? */
|
||||
if( Conf_Server[i].lasttry > time( NULL ) - Conf_ConnectRetry ) continue;
|
||||
|
||||
/* Okay, Verbindungsaufbau versuchen */
|
||||
Conf_Server[i].lasttry = time( NULL );
|
||||
|
||||
/* Freie Connection-Struktur suschen */
|
||||
for( idx = 0; idx < MAX_CONNECTIONS; idx++ ) if( My_Connections[idx].sock == NONE ) break;
|
||||
if( idx >= MAX_CONNECTIONS )
|
||||
{
|
||||
Log( LOG_ALERT, "Can't establist server connection: connection limit reached (%d)!", MAX_CONNECTIONS );
|
||||
return;
|
||||
}
|
||||
Log( LOG_DEBUG, "Preparing connection %d for \"%s\" ...", idx, Conf_Server[i].host );
|
||||
|
||||
/* Verbindungs-Struktur initialisieren */
|
||||
Init_Conn_Struct( idx );
|
||||
My_Connections[idx].sock = SERVER_WAIT;
|
||||
My_Connections[idx].our_server = i;
|
||||
|
||||
/* Hostnamen in IP aufloesen */
|
||||
s = ResolveName( Conf_Server[i].host );
|
||||
if( s )
|
||||
{
|
||||
/* Sub-Prozess wurde asyncron gestartet */
|
||||
My_Connections[idx].res_stat = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* kann Namen nicht aufloesen: Connection-Struktur freigeben */
|
||||
Init_Conn_Struct( idx );
|
||||
}
|
||||
}
|
||||
} /* Check_Servers */
|
||||
|
||||
|
||||
LOCAL VOID New_Server( INT Server, CONN_ID Idx )
|
||||
{
|
||||
/* Neue Server-Verbindung aufbauen */
|
||||
|
||||
struct sockaddr_in new_addr;
|
||||
struct in_addr inaddr;
|
||||
INT new_sock;
|
||||
CLIENT *c;
|
||||
|
||||
assert( Server >= 0 );
|
||||
assert( Idx >= 0 );
|
||||
|
||||
/* Wurde eine gueltige IP-Adresse gefunden? */
|
||||
if( ! Conf_Server[Server].ip[0] )
|
||||
{
|
||||
/* Nein. Verbindung wieder freigeben: */
|
||||
Init_Conn_Struct( Idx );
|
||||
Log( LOG_ERR, "Can't connect to \"%s\" (connection %d): ip address unknown!", Conf_Server[Server].host, Idx );
|
||||
return;
|
||||
}
|
||||
|
||||
Log( LOG_INFO, "Establishing connection to \"%s\", %s (connection %d) ... ", Conf_Server[Server].host, Conf_Server[Server].ip, Idx );
|
||||
|
||||
if( inet_aton( Conf_Server[Server].ip, &inaddr ) == 0 )
|
||||
{
|
||||
/* Konnte Adresse nicht konvertieren */
|
||||
Init_Conn_Struct( Idx );
|
||||
Log( LOG_ERR, "Can't connect to \"%s\" (connection %d): can't convert ip address %s!", Conf_Server[Server].host, Idx, Conf_Server[Server].ip );
|
||||
return;
|
||||
}
|
||||
|
||||
memset( &new_addr, 0, sizeof( new_addr ));
|
||||
new_addr.sin_family = AF_INET;
|
||||
new_addr.sin_addr = inaddr;
|
||||
new_addr.sin_port = htons( Conf_Server[Server].port );
|
||||
|
||||
new_sock = socket( PF_INET, SOCK_STREAM, 0 );
|
||||
if ( new_sock < 0 )
|
||||
{
|
||||
Init_Conn_Struct( Idx );
|
||||
Log( LOG_CRIT, "Can't create socket: %s!", strerror( errno ));
|
||||
return;
|
||||
}
|
||||
if( connect( new_sock, (struct sockaddr *)&new_addr, sizeof( new_addr )) < 0)
|
||||
{
|
||||
close( new_sock );
|
||||
Init_Conn_Struct( Idx );
|
||||
Log( LOG_CRIT, "Can't connect socket: %s!", strerror( errno ));
|
||||
return;
|
||||
}
|
||||
|
||||
/* Client-Struktur initialisieren */
|
||||
c = Client_NewLocal( Idx, inet_ntoa( new_addr.sin_addr ), CLIENT_UNKNOWNSERVER, FALSE );
|
||||
if( ! c )
|
||||
{
|
||||
close( new_sock );
|
||||
Init_Conn_Struct( Idx );
|
||||
Log( LOG_ALERT, "Can't establish connection: can't create client structure!" );
|
||||
return;
|
||||
}
|
||||
Client_SetIntroducer( c, c );
|
||||
|
||||
/* Verbindung registrieren */
|
||||
My_Connections[Idx].sock = new_sock;
|
||||
My_Connections[Idx].addr = new_addr;
|
||||
strcpy( My_Connections[Idx].host, Conf_Server[Server].host );
|
||||
|
||||
/* Neuen Socket registrieren */
|
||||
FD_SET( new_sock, &My_Sockets );
|
||||
if( new_sock > My_Max_Fd ) My_Max_Fd = new_sock;
|
||||
|
||||
/* PASS und SERVER verschicken */
|
||||
Conn_WriteStr( Idx, "PASS %s "PASSSERVERADD, Conf_Server[Server].pwd );
|
||||
Conn_WriteStr( Idx, "SERVER %s :%s", Conf_ServerName, Conf_ServerInfo );
|
||||
} /* New_Server */
|
||||
|
||||
|
||||
LOCAL VOID Init_Conn_Struct( INT Idx )
|
||||
@@ -812,15 +1053,16 @@ LOCAL VOID Init_Conn_Struct( INT Idx )
|
||||
My_Connections[Idx].rdatalen = 0;
|
||||
My_Connections[Idx].wbuf[0] = '\0';
|
||||
My_Connections[Idx].wdatalen = 0;
|
||||
My_Connections[Idx].our_server = -1;
|
||||
My_Connections[Idx].lastdata = time( NULL );
|
||||
My_Connections[Idx].lastping = 0;
|
||||
My_Connections[Idx].lastprivmsg = time( NULL );
|
||||
} /* Init_Conn_Struct */
|
||||
|
||||
|
||||
LOCAL RES_STAT *Resolve( struct sockaddr_in *Addr )
|
||||
LOCAL RES_STAT *ResolveAddr( struct sockaddr_in *Addr )
|
||||
{
|
||||
/* Hostnamen (asyncron!) aufloesen. Bei Fehler, z.B. wenn der
|
||||
/* 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. */
|
||||
|
||||
@@ -831,7 +1073,7 @@ LOCAL RES_STAT *Resolve( struct sockaddr_in *Addr )
|
||||
s = malloc( sizeof( RES_STAT ));
|
||||
if( ! s )
|
||||
{
|
||||
Log( LOG_ALERT, "Resolver: Can't alloc memory!" );
|
||||
Log( LOG_EMERG, "Resolver: Can't allocate memory!" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -858,7 +1100,7 @@ LOCAL RES_STAT *Resolve( struct sockaddr_in *Addr )
|
||||
{
|
||||
/* Sub-Prozess */
|
||||
Log_Init_Resolver( );
|
||||
Do_Resolve( Addr, s->pipe[1] );
|
||||
Do_ResolveAddr( Addr, s->pipe[1] );
|
||||
Log_Exit_Resolver( );
|
||||
exit( 0 );
|
||||
}
|
||||
@@ -866,63 +1108,69 @@ LOCAL RES_STAT *Resolve( struct sockaddr_in *Addr )
|
||||
{
|
||||
/* Fehler */
|
||||
free( s );
|
||||
Log( LOG_ALERT, "Resolver: Can't fork: %s!", strerror( errno ));
|
||||
Log( LOG_CRIT, "Resolver: Can't fork: %s!", strerror( errno ));
|
||||
return NULL;
|
||||
}
|
||||
} /* Resolve */
|
||||
} /* ResolveAddr */
|
||||
|
||||
|
||||
LOCAL VOID Read_Resolver_Result( INT r_fd )
|
||||
LOCAL RES_STAT *ResolveName( CHAR *Host )
|
||||
{
|
||||
/* Ergebnis von Resolver Sub-Prozess aus Pipe lesen
|
||||
* und entsprechende Connection aktualisieren */
|
||||
/* 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. */
|
||||
|
||||
CHAR hostname[HOST_LEN];
|
||||
CLIENT *c;
|
||||
INT i;
|
||||
RES_STAT *s;
|
||||
INT pid;
|
||||
|
||||
FD_CLR( r_fd, &My_Resolvers );
|
||||
|
||||
/* Anfrage vom Parent lesen */
|
||||
if( read( r_fd, hostname, HOST_LEN) < 0 )
|
||||
/* Speicher anfordern */
|
||||
s = malloc( sizeof( RES_STAT ));
|
||||
if( ! s )
|
||||
{
|
||||
/* Fehler beim Lesen aus der Pipe */
|
||||
close( r_fd );
|
||||
Log( LOG_ALERT, "Resolver: Can't read result: %s!", strerror( errno ));
|
||||
return;
|
||||
Log( LOG_EMERG, "Resolver: Can't allocate memory!" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* zugehoerige Connection suchen */
|
||||
for( i = 0; i < MAX_CONNECTIONS; i++ )
|
||||
/* Pipe fuer Antwort initialisieren */
|
||||
if( pipe( s->pipe ) != 0 )
|
||||
{
|
||||
if(( My_Connections[i].sock >= 0 ) && ( My_Connections[i].res_stat ) && ( My_Connections[i].res_stat->pipe[0] == r_fd )) break;
|
||||
free( s );
|
||||
Log( LOG_ALERT, "Resolver: Can't create output pipe: %s!", strerror( errno ));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( i >= MAX_CONNECTIONS )
|
||||
/* Sub-Prozess erzeugen */
|
||||
pid = fork( );
|
||||
if( pid > 0 )
|
||||
{
|
||||
/* Opsa! Keine passende Connection gefunden!? */
|
||||
close( r_fd );
|
||||
Log( LOG_ALERT, "Resolver: Got result for unknown connection!?" );
|
||||
return;
|
||||
/* Haupt-Prozess */
|
||||
Log( LOG_DEBUG, "Resolver for \"%s\" created (PID %d).", Host, pid );
|
||||
FD_SET( s->pipe[0], &My_Resolvers );
|
||||
if( s->pipe[0] > My_Max_Fd ) My_Max_Fd = s->pipe[0];
|
||||
s->pid = pid;
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Aufraeumen */
|
||||
close( My_Connections[i].res_stat->pipe[0] );
|
||||
close( My_Connections[i].res_stat->pipe[1] );
|
||||
free( My_Connections[i].res_stat );
|
||||
My_Connections[i].res_stat = NULL;
|
||||
|
||||
/* Hostnamen setzen */
|
||||
strcpy( My_Connections[i].host, hostname );
|
||||
c = Client_GetFromConn( i );
|
||||
if( c ) Client_SetHostname( c, hostname );
|
||||
} /* Read_Resolver_Result */
|
||||
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;
|
||||
}
|
||||
} /* ResolveName */
|
||||
|
||||
|
||||
LOCAL VOID Do_Resolve( struct sockaddr_in *Addr, INT w_fd )
|
||||
LOCAL VOID Do_ResolveAddr( struct sockaddr_in *Addr, INT w_fd )
|
||||
{
|
||||
/* Resolver Sub-Prozess: aufzuloesenden Namen aus
|
||||
* der Pipe lesen, Ergebnis in Pipe schreiben. */
|
||||
/* Resolver Sub-Prozess: IP aufloesen und Ergebnis in Pipe schreiben. */
|
||||
|
||||
CHAR hostname[HOST_LEN];
|
||||
struct hostent *h;
|
||||
@@ -934,20 +1182,134 @@ LOCAL VOID Do_Resolve( struct sockaddr_in *Addr, INT w_fd )
|
||||
if( h ) strcpy( hostname, h->h_name );
|
||||
else
|
||||
{
|
||||
Log_Resolver( LOG_WARNING, "Resolver: Can't resolve host name (code %d)!", h_errno );
|
||||
Log_Resolver( LOG_WARNING, "Can't resolve address %s: code %s!", inet_ntoa( Addr->sin_addr ), Resolv_Error( h_errno ));
|
||||
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_ALERT, "Resolver: Can't write to parent: %s!", strerror( errno ));
|
||||
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_Resolve */
|
||||
} /* 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
|
||||
{
|
||||
Log_Resolver( LOG_WARNING, "Can't resolve \"%s\": %s!", Host, Resolv_Error( h_errno ));
|
||||
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 */
|
||||
|
||||
|
||||
LOCAL VOID Read_Resolver_Result( INT r_fd )
|
||||
{
|
||||
/* Ergebnis von Resolver Sub-Prozess aus Pipe lesen
|
||||
* und entsprechende Connection aktualisieren */
|
||||
|
||||
CHAR result[HOST_LEN];
|
||||
CLIENT *c;
|
||||
INT len, i;
|
||||
|
||||
FD_CLR( r_fd, &My_Resolvers );
|
||||
|
||||
/* Anfrage vom Parent lesen */
|
||||
len = read( r_fd, result, HOST_LEN);
|
||||
if( len < 0 )
|
||||
{
|
||||
/* Fehler beim Lesen aus der Pipe */
|
||||
close( r_fd );
|
||||
Log( LOG_CRIT, "Resolver: Can't read result: %s!", strerror( errno ));
|
||||
return;
|
||||
}
|
||||
result[len] = '\0';
|
||||
|
||||
/* zugehoerige Connection suchen */
|
||||
for( i = 0; i < MAX_CONNECTIONS; i++ )
|
||||
{
|
||||
if(( My_Connections[i].sock != NONE ) && ( My_Connections[i].res_stat ) && ( My_Connections[i].res_stat->pipe[0] == r_fd )) break;
|
||||
}
|
||||
if( i >= MAX_CONNECTIONS )
|
||||
{
|
||||
/* Opsa! Keine passende Connection gefunden!? Vermutlich
|
||||
* wurde sie schon wieder geschlossen. */
|
||||
close( r_fd );
|
||||
Log( LOG_DEBUG, "Resolver: Got result for unknown connection!?" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Aufraeumen */
|
||||
close( My_Connections[i].res_stat->pipe[0] );
|
||||
close( My_Connections[i].res_stat->pipe[1] );
|
||||
free( My_Connections[i].res_stat );
|
||||
My_Connections[i].res_stat = NULL;
|
||||
|
||||
if( My_Connections[i].sock > NONE )
|
||||
{
|
||||
/* Eingehende Verbindung: Hostnamen setzen */
|
||||
c = Client_GetFromConn( i );
|
||||
assert( c != NULL );
|
||||
strcpy( My_Connections[i].host, result );
|
||||
Client_SetHostname( c, result );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Ausgehende Verbindung (=Server): IP setzen */
|
||||
assert( My_Connections[i].our_server >= 0 );
|
||||
strcpy( Conf_Server[My_Connections[i].our_server].ip, result );
|
||||
}
|
||||
} /* Read_Resolver_Result */
|
||||
|
||||
|
||||
LOCAL CHAR *Resolv_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";
|
||||
}
|
||||
} /* Resolv_Error */
|
||||
|
||||
|
||||
/* -eof- */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,20 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: conn.h,v 1.8 2001/12/31 02:18:51 alex Exp $
|
||||
* $Id: conn.h,v 1.11 2002/02/11 01:00:50 alex Exp $
|
||||
*
|
||||
* conn.h: Verwaltung aller Netz-Verbindungen ("connections") (Header)
|
||||
*
|
||||
* $Log: conn.h,v $
|
||||
* Revision 1.11 2002/02/11 01:00:50 alex
|
||||
* - neue Funktion Conn_LastPing().
|
||||
*
|
||||
* 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.
|
||||
@@ -48,6 +57,12 @@
|
||||
|
||||
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( VOID );
|
||||
GLOBAL VOID Conn_Exit( VOID );
|
||||
@@ -59,10 +74,11 @@ 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 *Msg );
|
||||
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 INT32 Conn_LastPing( CONN_ID Idx );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,16 +9,39 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: defines.h,v 1.1 2001/12/31 02:18:51 alex Exp $
|
||||
* $Id: defines.h,v 1.9 2002/02/13 23:04:27 alex Exp $
|
||||
*
|
||||
* defines.h: (globale) Konstanten
|
||||
*
|
||||
* $Log: defines.h,v $
|
||||
* Revision 1.9 2002/02/13 23:04:27 alex
|
||||
* - CHANMODES um Operator (o) und Voiced User (v) ergaenzt.
|
||||
*
|
||||
* Revision 1.8 2002/02/13 17:45:57 alex
|
||||
* - unterstuetzte User- und Channel-Modes stehen nun in Konstanten.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __defines_h__
|
||||
@@ -29,15 +52,17 @@
|
||||
|
||||
#define FNAME_LEN 256 /* max. Laenge eines Dateinamen */
|
||||
|
||||
#define LISTEN_PORTS 16 /* max. Anzahl von Listen-Ports */
|
||||
|
||||
#define LINE_LEN 256 /* max. Laenge einer Konfigurationszeile */
|
||||
|
||||
#define HOST_LEN 256 /* max. Laenge eines Hostnamen */
|
||||
|
||||
#define MAX_CONNECTIONS 100 /* max. Anzahl von Verbindungen an diesem Server */
|
||||
#define MAX_LISTEN_PORTS 16 /* max. Anzahl von Listen-Ports */
|
||||
|
||||
#define MAX_CHANNELS 32 /* max. Anzahl Channels pro Nick */
|
||||
#define MAX_OPERATORS 8 /* max. Anzahl konfigurierbarer Operatoren */
|
||||
|
||||
#define MAX_SERVERS 8 /* max. Anzahl konfigurierbarer Server ("Peers") */
|
||||
|
||||
#define MAX_CONNECTIONS 100 /* max. Anzahl von Verbindungen an diesem Server */
|
||||
|
||||
#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 */
|
||||
@@ -48,13 +73,25 @@
|
||||
#define CLIENT_MODE_LEN 8 /* max. Laenge der Client-Modes */
|
||||
#define CLIENT_INFO_LEN 64 /* max. Infotext-Laenge (Server) */
|
||||
|
||||
#define COMMAND_LEN 513 /* max. Laenge eines Befehls, vgl. RFC 2812, 3.2 */
|
||||
|
||||
#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 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 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) */
|
||||
|
||||
#define PASSSERVERADD PROTOVER""PROTOSUFFIX" IRC|"PACKAGE"-"VERSION" P"
|
||||
|
||||
#define STARTUP_DELAY 1 /* Erst n Sek. nach Start zu anderen Servern verbinden */
|
||||
|
||||
#define USERMODES "io" /* unterstuetzte User-Modes */
|
||||
#define CHANMODES "amnopqstv" /* unterstuetzte Channel-Modes */
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,17 @@
|
||||
* 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.4 2001/12/31 02:18:51 alex Exp $
|
||||
* $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.
|
||||
@@ -41,6 +47,10 @@
|
||||
#define socklen_t int /* u.a. fuer Mac OS X */
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_INET_ATON
|
||||
#define inet_aton( opt, bind ) 0
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
1833
src/ngircd/irc.c
1833
src/ngircd/irc.c
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,44 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: irc.h,v 1.11 2001/12/31 15:33:13 alex Exp $
|
||||
* $Id: irc.h,v 1.21 2002/01/27 21:53:57 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 :-)
|
||||
@@ -59,22 +92,32 @@
|
||||
#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, CLIENT *Prefix, CHAR *Format, ... );
|
||||
GLOBAL BOOLEAN IRC_WriteStrRelated( CLIENT *Client, CHAR *Format, ... );
|
||||
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 );
|
||||
@@ -90,6 +133,11 @@ 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 );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,23 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: log.c,v 1.13 2001/12/31 02:18:51 alex Exp $
|
||||
* $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.
|
||||
@@ -73,41 +85,19 @@
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
#include "global.h"
|
||||
#include "ngircd.h"
|
||||
|
||||
#include <exp.h>
|
||||
#include "log.h"
|
||||
|
||||
|
||||
GLOBAL VOID Log_Init( VOID )
|
||||
{
|
||||
CHAR txt[64];
|
||||
|
||||
strcpy( txt, "" );
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
if( txt[0] ) strcat( txt, "+" );
|
||||
else strcat( txt, "-" );
|
||||
strcat( txt, "SYSLOG" );
|
||||
#endif
|
||||
#ifdef STRICT_RFC
|
||||
if( txt[0] ) strcat( txt, "+" );
|
||||
else strcat( txt, "-" );
|
||||
strcat( txt, "RFC" );
|
||||
#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 USE_SYSLOG
|
||||
openlog( PACKAGE, LOG_CONS|LOG_PID, LOG_LOCAL5 );
|
||||
#endif
|
||||
Log( LOG_NOTICE, PACKAGE" version "VERSION"%s started.", txt );
|
||||
Log( LOG_NOTICE, "%s started.", NGIRCd_Version( ));
|
||||
} /* Log_Init */
|
||||
|
||||
|
||||
@@ -129,7 +119,9 @@ GLOBAL VOID Log( CONST INT Level, CONST CHAR *Format, ... )
|
||||
|
||||
assert( Format != NULL );
|
||||
|
||||
#ifndef DEBUG
|
||||
#ifdef DEBUG
|
||||
if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
|
||||
#else
|
||||
if( Level == LOG_DEBUG ) return;
|
||||
#endif
|
||||
|
||||
@@ -139,7 +131,7 @@ GLOBAL VOID Log( CONST INT Level, CONST CHAR *Format, ... )
|
||||
msg[MAX_LOG_MSG_LEN - 1] = '\0';
|
||||
|
||||
/* ... und ausgeben */
|
||||
printf( "[%d] %s\n", Level, msg );
|
||||
if( NGIRCd_NoDaemon ) printf( "[%d] %s\n", Level, msg );
|
||||
#ifdef USE_SYSLOG
|
||||
syslog( Level, msg );
|
||||
#endif
|
||||
@@ -168,16 +160,18 @@ GLOBAL VOID Log_Resolver( CONST INT Level, CONST CHAR *Format, ... )
|
||||
{
|
||||
/* Eintrag des Resolver in Logfile(s) schreiben */
|
||||
|
||||
#ifndef USE_SYSLOG
|
||||
return;
|
||||
#else
|
||||
|
||||
CHAR msg[MAX_LOG_MSG_LEN];
|
||||
va_list ap;
|
||||
|
||||
assert( Format != NULL );
|
||||
|
||||
#ifndef USE_SYSLOG
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG
|
||||
#ifdef DEBUG
|
||||
if(( Level == LOG_DEBUG ) && ( ! NGIRCd_Debug )) return;
|
||||
#else
|
||||
if( Level == LOG_DEBUG ) return;
|
||||
#endif
|
||||
|
||||
@@ -190,6 +184,7 @@ GLOBAL VOID Log_Resolver( CONST INT Level, CONST CHAR *Format, ... )
|
||||
syslog( Level, msg );
|
||||
|
||||
va_end( ap );
|
||||
#endif
|
||||
} /* Log_Resolver */
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,14 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: log.h,v 1.6 2001/12/31 02:18:51 alex Exp $
|
||||
* $Id: log.h,v 1.7 2002/01/02 02:42:58 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.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,53 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: messages.h,v 1.14 2001/12/31 16:00:57 alex Exp $
|
||||
* $Id: messages.h,v 1.28 2002/02/13 23:04:50 alex Exp $
|
||||
*
|
||||
* irc.h: IRC-Befehle (Header)
|
||||
*
|
||||
* $Log: messages.h,v $
|
||||
* Revision 1.28 2002/02/13 23:04:50 alex
|
||||
* - RPL_MYINFO_MSG korrigiert.
|
||||
*
|
||||
* Revision 1.27 2002/02/13 17:45:57 alex
|
||||
* - unterstuetzte User- und Channel-Modes stehen nun in Konstanten.
|
||||
*
|
||||
* Revision 1.26 2002/02/11 23:33:12 alex
|
||||
* - neue Message ERR_CHANOPRIVSNEEDED_MSG definiert.
|
||||
*
|
||||
* Revision 1.25 2002/02/11 15:48:39 alex
|
||||
* - neue Nachricht RPL_CHANNELMODEIS definiert.
|
||||
*
|
||||
* Revision 1.24 2002/02/06 16:51:39 alex
|
||||
* - neue Text-Konstante RPL_UMODEISCHAN_MSG.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
@@ -78,7 +120,22 @@
|
||||
#define RPL_CREATED_MSG RPL_CREATED" %s :This server was started %s"
|
||||
|
||||
#define RPL_MYINFO "004"
|
||||
#define RPL_MYINFO_MSG RPL_MYINFO" %s %s ngircd-"VERSION" ior +"
|
||||
#define RPL_MYINFO_MSG RPL_MYINFO" %s :%s ngircd-"VERSION" "USERMODES" "CHANMODES
|
||||
|
||||
#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"
|
||||
@@ -114,14 +171,30 @@
|
||||
#define RPL_ENDOFWHOIS_MSG RPL_ENDOFWHOIS" %s %s :End of WHOIS list"
|
||||
|
||||
#define RPL_WHOISCHANNELS "319"
|
||||
#define RPL_WHOISCHANNELS_MSG RPL_WHOISCHANNELS" %s :"
|
||||
#define RPL_WHOISCHANNELS_MSG RPL_WHOISCHANNELS" %s %s :"
|
||||
|
||||
#define RPL_CHANNELMODEIS "324"
|
||||
#define RPL_CHANNELMODEIS_MSG RPL_CHANNELMODEIS" %s %s +%s"
|
||||
|
||||
#define RPL_NOTOPIC "331"
|
||||
#define RPL_NOTOPIC_MSG RPL_NOTOPIC" %s %s :No topic is set"
|
||||
|
||||
#define RPL_TOPIC "332"
|
||||
#define RPL_TOPIC_MSG RPL_TOPIC" %s %s :%s"
|
||||
|
||||
#define RPL_NAMREPLY "353"
|
||||
#define RPL_NAMREPLY_MSG RPL_NAMREPLY" %s %s %s :%s"
|
||||
#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"
|
||||
|
||||
@@ -129,6 +202,12 @@
|
||||
#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"
|
||||
|
||||
@@ -161,10 +240,14 @@
|
||||
|
||||
#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_CHANOPRIVSNEEDED "482"
|
||||
#define ERR_CHANOPRIVSNEEDED_MSG ERR_CHANOPRIVSNEEDED" %s %s :You are not channel operator"
|
||||
|
||||
#define ERR_RESTRICTED "484"
|
||||
#define ERR_RESTRICTED_MSG ERR_RESTRICTED" %s :Your connection is restricted"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,29 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: ngircd.c,v 1.15 2001/12/31 02:18:51 alex Exp $
|
||||
* $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.
|
||||
@@ -77,8 +95,13 @@
|
||||
#include <imp.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "channel.h"
|
||||
@@ -98,14 +121,136 @@ LOCAL VOID Signal_Handler( INT Signal );
|
||||
|
||||
LOCAL VOID Initialize_Listen_Ports( VOID );
|
||||
|
||||
LOCAL VOID Show_Version( VOID );
|
||||
LOCAL VOID Show_Help( VOID );
|
||||
|
||||
|
||||
GLOBAL INT main( INT argc, CONST CHAR *argv[] )
|
||||
{
|
||||
BOOLEAN ok;
|
||||
INT pid, i, n;
|
||||
|
||||
/* Datentypen der portab-Library ueberpruefen */
|
||||
portab_check_types( );
|
||||
|
||||
NGIRCd_Restart = FALSE;
|
||||
NGIRCd_Quit = FALSE;
|
||||
NGIRCd_NoDaemon = FALSE;
|
||||
#ifdef DEBUG
|
||||
NGIRCd_Debug = FALSE;
|
||||
#endif
|
||||
#ifdef SNIFFER
|
||||
NGIRCd_Sniffer = FALSE;
|
||||
#endif
|
||||
|
||||
/* Kommandozeile parsen */
|
||||
for( i = 1; i < argc; i++ )
|
||||
{
|
||||
ok = FALSE;
|
||||
if(( argv[i][0] == '-' ) && ( argv[i][1] == '-' ))
|
||||
{
|
||||
/* Lange Option */
|
||||
|
||||
if( strcmp( argv[i], "--help" ) == 0 )
|
||||
{
|
||||
Show_Version( ); puts( "" );
|
||||
Show_Help( ); puts( "" );
|
||||
exit( 1 );
|
||||
}
|
||||
if( strcmp( argv[i], "--version" ) == 0 )
|
||||
{
|
||||
Show_Version( );
|
||||
exit( 1 );
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if( strcmp( argv[i], "--debug" ) == 0 )
|
||||
{
|
||||
NGIRCd_Debug = TRUE;
|
||||
ok = TRUE;
|
||||
}
|
||||
#endif
|
||||
#ifdef SNIFFER
|
||||
if( strcmp( argv[i], "--sniffer" ) == 0 )
|
||||
{
|
||||
NGIRCd_Sniffer = TRUE;
|
||||
ok = TRUE;
|
||||
}
|
||||
#endif
|
||||
if( strcmp( argv[i], "--nodaemon" ) == 0 )
|
||||
{
|
||||
NGIRCd_NoDaemon = TRUE;
|
||||
ok = TRUE;
|
||||
}
|
||||
}
|
||||
else if(( argv[i][0] == '-' ) && ( argv[i][1] != '-' ))
|
||||
{
|
||||
/* Kurze Option */
|
||||
|
||||
for( n = 1; n < strlen( argv[i] ); n++ )
|
||||
{
|
||||
ok = FALSE;
|
||||
#ifdef DEBUG
|
||||
if( argv[i][n] == 'd' )
|
||||
{
|
||||
NGIRCd_Debug = TRUE;
|
||||
ok = TRUE;
|
||||
}
|
||||
#endif
|
||||
#ifdef SNIFFER
|
||||
if( argv[i][n] == 's' )
|
||||
{
|
||||
NGIRCd_Sniffer = TRUE;
|
||||
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." );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if( ! ok )
|
||||
{
|
||||
printf( PACKAGE": invalid option \"%s\"!\n", argv[i] );
|
||||
puts( "Try \""PACKAGE" --help\" for more information." );
|
||||
exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
while( ! NGIRCd_Quit )
|
||||
{
|
||||
/* In der Regel wird ein Sub-Prozess ge-fork()'t, der
|
||||
* nicht mehr mit dem Terminal verbunden ist. Mit der
|
||||
* Option "--nodaemon" kann dies (z.B. zum Debuggen)
|
||||
* verhindert werden. */
|
||||
if( ! NGIRCd_NoDaemon )
|
||||
{
|
||||
/* Daemon im Hintergrund erzeugen */
|
||||
pid = fork( );
|
||||
if( pid > 0 )
|
||||
{
|
||||
/* "alter" Prozess */
|
||||
exit( 0 );
|
||||
}
|
||||
if( pid < 0 )
|
||||
{
|
||||
/* Fehler */
|
||||
printf( PACKAGE": Can't fork: %s!\nFatal error, exiting now ...", strerror( errno ));
|
||||
exit( 1 );
|
||||
}
|
||||
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 ));
|
||||
@@ -147,6 +292,39 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
|
||||
} /* main */
|
||||
|
||||
|
||||
GLOBAL CHAR *NGIRCd_Version( VOID )
|
||||
{
|
||||
STATIC CHAR version[126];
|
||||
CHAR txt[64];
|
||||
|
||||
strcpy( txt, "" );
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
if( txt[0] ) strcat( txt, "+" );
|
||||
else strcat( txt, "-" );
|
||||
strcat( txt, "SYSLOG" );
|
||||
#endif
|
||||
#ifdef STRICT_RFC
|
||||
if( txt[0] ) strcat( txt, "+" );
|
||||
else strcat( txt, "-" );
|
||||
strcat( txt, "RFC" );
|
||||
#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
|
||||
|
||||
sprintf( version, PACKAGE" version "VERSION"%s-"P_OSNAME"/"P_ARCHNAME, txt );
|
||||
return version;
|
||||
} /* NGIRCd_Version */
|
||||
|
||||
|
||||
LOCAL VOID Initialize_Signal_Handler( VOID )
|
||||
{
|
||||
/* Signal-Handler initialisieren: einige Signale
|
||||
@@ -156,12 +334,14 @@ LOCAL VOID Initialize_Signal_Handler( VOID )
|
||||
|
||||
/* Signal-Struktur initialisieren */
|
||||
memset( &saction, 0, sizeof( saction ));
|
||||
saction.sa_handler = Signal_Handler;
|
||||
saction.sa_flags = SA_RESTART;
|
||||
|
||||
/* Signal-Handler einhaengen */
|
||||
saction.sa_handler = Signal_Handler;
|
||||
sigaction( SIGINT, &saction, NULL );
|
||||
sigaction( SIGQUIT, &saction, NULL );
|
||||
sigaction( SIGTERM, &saction, NULL);
|
||||
sigaction( SIGCHLD, &saction, NULL);
|
||||
|
||||
/* einige Signale ignorieren */
|
||||
saction.sa_handler = SIG_IGN;
|
||||
@@ -184,6 +364,10 @@ LOCAL VOID Signal_Handler( INT Signal )
|
||||
Log( LOG_WARNING, "Got signal %d, terminating now ...", Signal );
|
||||
NGIRCd_Quit = TRUE;
|
||||
break;
|
||||
case SIGCHLD:
|
||||
/* Child-Prozess wurde beendet. Zombies vermeiden: */
|
||||
while( waitpid( -1, NULL, WNOHANG ) > 0);
|
||||
break;
|
||||
default:
|
||||
/* unbekanntes bzw. unbehandeltes Signal */
|
||||
Log( LOG_NOTICE, "Got signal %d! Ignored.", Signal );
|
||||
@@ -213,4 +397,28 @@ LOCAL VOID Initialize_Listen_Ports( VOID )
|
||||
}
|
||||
} /* Initialize_Listen_Ports */
|
||||
|
||||
|
||||
LOCAL VOID Show_Version( VOID )
|
||||
{
|
||||
puts( NGIRCd_Version( ));
|
||||
puts( "Copyright (c)2001,2002 by Alexander Barton (alex@barton.de).\n" );
|
||||
puts( "This is free software; see the source for copying conditions. There is NO" );
|
||||
puts( "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." );
|
||||
} /* Show_Version */
|
||||
|
||||
|
||||
LOCAL VOID Show_Help( VOID )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
puts( " -d, --debug log extra debug messages" );
|
||||
#endif
|
||||
puts( " -n, --nodaemon don't fork and don't detatch from controlling terminal" );
|
||||
#ifdef SNIFFER
|
||||
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" );
|
||||
} /* Show_Help */
|
||||
|
||||
|
||||
/* -eof- */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,20 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: ngircd.h,v 1.5 2001/12/31 03:06:03 alex Exp $
|
||||
* $Id: ngircd.h,v 1.8 2002/01/18 11:12:11 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.
|
||||
*
|
||||
@@ -42,10 +51,23 @@
|
||||
GLOBAL time_t NGIRCd_Start; /* Startzeitpunkt des Daemon */
|
||||
GLOBAL CHAR NGIRCd_StartStr[64];
|
||||
|
||||
#ifdef DEBUG
|
||||
GLOBAL BOOLEAN NGIRCd_Debug; /* Debug-Modus aktivieren */
|
||||
#endif
|
||||
|
||||
#ifdef SNIFFER
|
||||
GLOBAL BOOLEAN NGIRCd_Sniffer; /* Sniffer aktivieren */
|
||||
#endif
|
||||
|
||||
GLOBAL BOOLEAN NGIRCd_NoDaemon; /* nicht im Hintergrund laufen */
|
||||
|
||||
GLOBAL BOOLEAN NGIRCd_Quit; /* TRUE: ngIRCd beenden */
|
||||
GLOBAL BOOLEAN NGIRCd_Restart; /* TRUE: neu starten */
|
||||
|
||||
|
||||
GLOBAL CHAR *NGIRCd_Version( VOID );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,48 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: parse.c,v 1.10 2001/12/31 15:33:13 alex Exp $
|
||||
* $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 :-)
|
||||
@@ -59,9 +96,11 @@
|
||||
|
||||
#include <imp.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ngircd.h"
|
||||
#include "client.h"
|
||||
#include "conn.h"
|
||||
#include "irc.h"
|
||||
@@ -107,7 +146,7 @@ GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
|
||||
assert( Request != NULL );
|
||||
|
||||
#ifdef SNIFFER
|
||||
Log( LOG_DEBUG, " <- connection %d: '%s'.", Idx, Request );
|
||||
if( NGIRCd_Sniffer ) Log( LOG_DEBUG, " <- connection %d: '%s'.", Idx, Request );
|
||||
#endif
|
||||
|
||||
Init_Request( &req );
|
||||
@@ -121,8 +160,13 @@ GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
|
||||
/* Prefix vorhanden */
|
||||
req.prefix = Request + 1;
|
||||
ptr = strchr( Request, ' ' );
|
||||
if( ! ptr ) return Parse_Error( Idx, "Invalid prefix (command missing!?)" );
|
||||
if( ! ptr ) return Parse_Error( Idx, "Prefix without command!?" );
|
||||
*ptr = '\0';
|
||||
#ifndef STRICT_RFC
|
||||
/* multiple Leerzeichen als Trenner zwischen
|
||||
* Prefix und Befehl ignorieren */
|
||||
while( *(ptr + 1) == ' ' ) ptr++;
|
||||
#endif
|
||||
start = ptr + 1;
|
||||
}
|
||||
else start = Request;
|
||||
@@ -131,7 +175,15 @@ GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
|
||||
|
||||
/* Befehl */
|
||||
ptr = strchr( start, ' ' );
|
||||
if( ptr ) *ptr = '\0';
|
||||
if( ptr )
|
||||
{
|
||||
*ptr = '\0';
|
||||
#ifndef STRICT_RFC
|
||||
/* multiple Leerzeichen als Trenner vor
|
||||
*Parametertrennern ignorieren */
|
||||
while( *(ptr + 1) == ' ' ) ptr++;
|
||||
#endif
|
||||
}
|
||||
req.command = start;
|
||||
|
||||
if( ! Validate_Command( &req )) return Parse_Error( Idx, "Invalid command" );
|
||||
@@ -153,7 +205,15 @@ GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
|
||||
{
|
||||
req.argv[req.argc] = start;
|
||||
ptr = strchr( start, ' ' );
|
||||
if( ptr ) *ptr = '\0';
|
||||
if( ptr )
|
||||
{
|
||||
*ptr = '\0';
|
||||
#ifndef STRICT_RFC
|
||||
/* multiple Leerzeichen als
|
||||
* Parametertrenner ignorieren */
|
||||
while( *(ptr + 1) == ' ' ) ptr++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
req.argc++;
|
||||
@@ -167,7 +227,7 @@ GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
|
||||
}
|
||||
|
||||
if( ! Validate_Args( &req )) return Parse_Error( Idx, "Invalid argument(s)" );
|
||||
|
||||
|
||||
return Handle_Request( Idx, &req );
|
||||
} /* Parse_Request */
|
||||
|
||||
@@ -193,13 +253,11 @@ LOCAL BOOLEAN Parse_Error( CONN_ID Idx, CHAR *Error )
|
||||
* TRUE: Connection wurde durch diese Funktion nicht geschlossen,
|
||||
* FALSE: Connection wurde terminiert. */
|
||||
|
||||
CHAR msg[256];
|
||||
|
||||
assert( Idx >= 0 );
|
||||
assert( Error != NULL );
|
||||
|
||||
sprintf( msg, "Parse error: %s!", Error );
|
||||
return Conn_WriteStr( Idx, msg );
|
||||
Log( LOG_DEBUG, "Connection %d: Parse error: %s", Idx, Error );
|
||||
return Conn_WriteStr( Idx, "ERROR :Parse error: %s", Error );
|
||||
} /* Parse_Error */
|
||||
|
||||
|
||||
@@ -229,7 +287,9 @@ 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;
|
||||
CLIENT *client, *target, *prefix;
|
||||
CHAR str[LINE_LEN];
|
||||
INT i;
|
||||
|
||||
assert( Idx >= 0 );
|
||||
assert( Req != NULL );
|
||||
@@ -238,10 +298,57 @@ LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *Req )
|
||||
client = Client_GetFromConn( Idx );
|
||||
assert( client != NULL );
|
||||
|
||||
/* Statuscode, der geforwarded werden muss? */
|
||||
if(( strlen( Req->command ) == 3 ) && ( atoi( Req->command ) > 100 ))
|
||||
{
|
||||
/* Befehl ist ein Statuscode */
|
||||
|
||||
/* Zielserver ermitteln */
|
||||
if(( Client_Type( client ) == CLIENT_SERVER ) && ( Req->argc > 0 )) target = Client_GetFromID( 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!" );
|
||||
return TRUE;
|
||||
}
|
||||
if( target == Client_ThisServer( ))
|
||||
{
|
||||
Log( LOG_DEBUG, "Ignored status code %s from \"%s\".", Req->command, Client_ID( client ));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Quell-Client ermitteln */
|
||||
if( ! Req->prefix[0] )
|
||||
{
|
||||
Log( LOG_WARNING, "Got status code without prefix!?" );
|
||||
return TRUE;
|
||||
}
|
||||
else prefix = Client_GetFromID( Req->prefix );
|
||||
if( ! prefix )
|
||||
{
|
||||
Log( LOG_WARNING, "Got status code from unknown source: \"%s\"", Req->prefix );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Statuscode weiterleiten */
|
||||
strcpy( str, Req->command );
|
||||
for( i = 0; i < Req->argc; i++ )
|
||||
{
|
||||
if( i < Req->argc - 1 ) strcat( str, " " );
|
||||
else strcat( str, " :" );
|
||||
strcat( str, Req->argv[i] );
|
||||
}
|
||||
return IRC_WriteStrClientPrefix( target, prefix, 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 );
|
||||
@@ -255,10 +362,15 @@ LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *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 );
|
||||
|
||||
/* Unbekannter Befehl */
|
||||
IRC_WriteStrClient( client, This_Server, ERR_UNKNOWNCOMMAND_MSG, Client_Nick( client ), Req->command );
|
||||
Log( LOG_DEBUG, "User \"%s!%s@%s\": Unknown command \"%s\", %d %s,%s prefix.", client->nick, client->user, client->host, Req->command, Req->argc, Req->argc == 1 ? "parameter" : "parameters", Req->prefix ? "" : " no" );
|
||||
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;
|
||||
} /* Handle_Request */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,14 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: parse.h,v 1.3 2001/12/31 02:18:51 alex Exp $
|
||||
* $Id: parse.h,v 1.4 2002/01/02 02:43:50 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.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,14 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: tool.c,v 1.5 2001/12/31 02:44:36 alex Exp $
|
||||
* $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!
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* ngIRCd -- The Next Generation IRC Daemon
|
||||
* Copyright (c)2001 by Alexander Barton (alex@barton.de)
|
||||
* 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
|
||||
@@ -9,11 +9,14 @@
|
||||
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
|
||||
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
|
||||
*
|
||||
* $Id: tool.h,v 1.4 2001/12/31 02:18:51 alex Exp $
|
||||
* $Id: tool.h,v 1.5 2002/01/02 02:42:58 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.
|
||||
|
||||
Reference in New Issue
Block a user