1
0
mirror of https://github.com/osmarks/ngircd.git synced 2025-11-01 14:33:00 +00:00

Compare commits

...

152 Commits

Author SHA1 Message Date
Alexander Barton
621a3ca102 - Version 0.2.0 2002-02-15 14:35:55 +00:00
Alexander Barton
57f36fc883 *** empty log message *** 2002-02-13 23:06:07 +00:00
Alexander Barton
213fa0994f - Nach Connect eines Users werden LUSERS-Informationen angezeigt. 2002-02-13 23:05:29 +00:00
Alexander Barton
b10d05f2d2 - RPL_MYINFO_MSG korrigiert. 2002-02-13 23:04:50 +00:00
Alexander Barton
645aeacf0a - CHANMODES um Operator (o) und Voiced User (v) ergaenzt. 2002-02-13 23:04:27 +00:00
Alexander Barton
70ac29b253 *** empty log message *** 2002-02-13 17:52:37 +00:00
Alexander Barton
f3f121b8f8 - es werden nun Channel- und User-Modes von Usern angenommen. 2002-02-13 17:52:27 +00:00
Alexander Barton
f908e78118 - unterstuetzte User- und Channel-Modes stehen nun in Konstanten. 2002-02-13 17:45:57 +00:00
Alexander Barton
e1a1e7ecf4 - via NJOIN gemeldete Benutzer wurden nicht in Channels bekannt gemacht. 2002-02-12 14:40:37 +00:00
Alexander Barton
6610d6e4ba - weitere Anpassungen an Channel-Modes und Channel-User-Modes. 2002-02-11 23:33:35 +00:00
Alexander Barton
207937da2a - neue Message ERR_CHANOPRIVSNEEDED_MSG definiert. 2002-02-11 23:33:12 +00:00
Alexander Barton
84a2f8ab26 - Die Quelle von MODE-Aenderungen wird nun korrekt weitergegeben. 2002-02-11 16:06:21 +00:00
Alexander Barton
5ef9ff5b2d - PONG an den Server selber wurde faelschlicherweise versucht zu forwarden.
- Channel-Modes wurden falsch geliefert (als User-Modes).
2002-02-11 15:52:21 +00:00
Alexander Barton
617cdf068e - neue Nachricht RPL_CHANNELMODEIS definiert. 2002-02-11 15:48:39 +00:00
Alexander Barton
d2d6dcbb1f - PING und PONG werden nun auch korrekt an andere Server geforwarded.
- bei MODE-Meldungen wird der letzte Parameter nicht mehr mit ":" getrennt.
2002-02-11 15:15:53 +00:00
Alexander Barton
0595f42fbe - Aenderungen und Anpassungen an Channel-Modes und Channel-User-Modes:
Modes werden besser geforwarded, lokale User, fuer die ein Channel
  angelegt wird, werden Channel-Operator, etc. pp. ...
- NJOIN's von Servern werden nun korrekt an andere Server weitergeleitet.
2002-02-11 01:03:20 +00:00
Alexander Barton
b9f005af75 - neue Funktion Conn_LastPing(). 2002-02-11 01:00:50 +00:00
Alexander Barton
2184b3615b - neue Funktionen Channel_ModeAdd(), Channel_ModeDel(), Channel_UserModes(),
Channel_UserModeAdd(), Channel_UserModeDel().
2002-02-11 01:00:22 +00:00
Alexander Barton
d72c55a09d - neue Funktionen Channel_ModeAdd(), Channel_ModeDel(), Channel_UserModes(),
Channel_UserModeAdd(), Channel_UserModeDel().
- Modes in CL2CHAN-Struktur werden nun korrekt initialisiert.
2002-02-11 01:00:12 +00:00
Alexander Barton
4da8fc54ac - Aktualisierungen ... 2002-02-11 00:58:12 +00:00
Alexander Barton
5c48cbff1d - neue Text-Konstante RPL_UMODEISCHAN_MSG. 2002-02-06 16:51:39 +00:00
Alexander Barton
f29ae5ae0e - neue Funktion zur MODE-Behandlung, fuer Channel-Modes vorbereitet. 2002-02-06 16:51:22 +00:00
Alexander Barton
175b20bbb5 - neue Funktion Client_IsValidNick(). 2002-02-06 16:49:56 +00:00
Alexander Barton
33944e8cdb - neue Funktion Client_IsValidNick(), Nicknames werden besser validiert. 2002-02-06 16:49:41 +00:00
Alexander Barton
40c9f5c332 - neue Funktionen Channel_Modes() und Channel_IsValidName(). 2002-02-06 16:49:10 +00:00
Alexander Barton
f53914b17a - neue Funktion Channel_Modes() und Channel_IsValidName().
- Channel-Namen werden (besser) validiert.
2002-02-06 16:48:48 +00:00
Alexander Barton
6e9ec92974 - Version auf 0.1.1-pre im CVS angehoben. 2002-01-29 01:07:15 +00:00
Alexander Barton
1e56fb35ab - Version 0.0.1 2002-01-29 00:24:17 +00:00
Alexander Barton
408793c2ca - README, NEWS und ChangeLog aktualisiert. 2002-01-29 00:17:39 +00:00
Alexander Barton
1ab92bb9cb - neue Funktion Client_TopServer(), Client_NewXXX() angepasst. 2002-01-29 00:14:49 +00:00
Alexander Barton
5a0f118df0 - RPL_WHOISCHANNELS_MSG korrigiert. 2002-01-29 00:14:05 +00:00
Alexander Barton
eab20beefc - WHOIS zeigt nun auch die Channels an, in denen der jeweilige User Mitglied ist.
- zu jedem Server wird nun der "Top-Server" gespeichert, somit funktioniert
  LINKS wieder korrekt.
2002-01-29 00:13:45 +00:00
Alexander Barton
0bb9db1aa0 - neue Funktionen Channel_FirstChannelOf() und Channel_NextChannelOf(). 2002-01-29 00:11:10 +00:00
Alexander Barton
8316d98b16 - RPL_NAMREPLY_MSG an tatsaechliche Implementierung angepasst ;-) 2002-01-28 13:06:19 +00:00
Alexander Barton
a0123e424c - nach einem JOIN wird die Liste der Mitglieder an den Client geschickt.
- MODE fuer Channels wird nun komplett ignoriert (keine Fehlermeldung mehr).
2002-01-28 13:05:48 +00:00
Alexander Barton
ff25b7291f - SERVER-Meldungen an neue Server sind nun in der richtigen Reihenfolge. 2002-01-28 01:45:43 +00:00
Alexander Barton
eba8d4d553 - connectierenden Servern werden Channels nun mit NJOIN bekannt gemacht. 2002-01-28 01:18:14 +00:00
Alexander Barton
71c7a6fcc0 - neue Funktionen Channel_Name(), Channel_First() und Channel_Next(). 2002-01-28 01:16:15 +00:00
Alexander Barton
3b38d3ca0d - ein neu connectierender Server wird nun korrekt im Netz bekannt gemacht. 2002-01-28 00:55:08 +00:00
Alexander Barton
6491b9843f - PART wird nicht mehr an den Server verschickt, von dem es empfangen wurde. 2002-01-27 22:47:11 +00:00
Alexander Barton
40c9fd26d6 - Client_GetFromID() besser dokumentiert, kleinere Aenderungen. 2002-01-27 22:07:36 +00:00
Alexander Barton
b5ee4552c1 - weitere Anpassungen an Chennals, v.a. ueber Server-Links. 2002-01-27 21:56:54 +00:00
Alexander Barton
8f521aa8bf - IRC_WriteStrServersPrefixID() und IRC_WriteStrClientPrefixID() wieder entfernt.
- einige kleinere Fixes bezueglich Channels ...
2002-01-27 21:56:39 +00:00
Alexander Barton
b28dab3632 - IRC_WriteStrServersPrefixID() und IRC_WriteStrClientPrefixID() wieder entfernt. 2002-01-27 21:53:57 +00:00
Alexander Barton
9f9e9a496f - bei NICK wurde das falsche Prefix an andere Server weitergegeben. 2002-01-27 18:28:01 +00:00
Alexander Barton
d17748e978 - Client_GetFromID() kommt nun auch mit Host-Masken zurecht. 2002-01-27 18:27:12 +00:00
Alexander Barton
d14588f368 - anderungen an den Funktions-Prototypen von IRC_WriteStrChannel() und
IRC_WriteStrChannelPrefix(),
- neue: IRC_WriteStrClientPrefixID() und IRC_WriteStrServersPrefixID().
2002-01-27 17:15:49 +00:00
Alexander Barton
d569c9246e - diverse Aenderungen fuer Channels ueber mehrere Server. 2002-01-27 17:14:33 +00:00
Alexander Barton
791301dc7d - neue Defines fuer RPL_TOPIC und RPL_NOTOPIC. 2002-01-27 17:13:37 +00:00
Alexander Barton
92fb409fe2 - 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.
2002-01-26 18:43:11 +00:00
Alexander Barton
8a324b6d9c - CHANNEL- und CL2CHAN-Strukturen in Header verlegt,
- einige neue Funktionen (Channel_GetChannel(), Channel_FirstMember(), ...)
2002-01-26 18:41:55 +00:00
Alexander Barton
7709acf754 - CVS-ID's ergaenzt ... 2002-01-23 18:20:04 +00:00
Alexander Barton
077b610eb0 - FAQ begonnen. 2002-01-23 14:05:20 +00:00
Alexander Barton
23253edb54 - die Fehlermeldung "interrupted system call" sollte nicht mehr auftreten. 2002-01-22 17:15:39 +00:00
Alexander Barton
bb19cfda95 - begonnen, Channels zu implementieren :-) 2002-01-21 00:12:29 +00:00
Alexander Barton
4b0c9849d6 - Definition der CHANNEL-Struktur aus Header entfernt,
- neue Funktionen Channel_Join(), Channel_Part() und Channel_RemoveClient().
2002-01-21 00:11:59 +00:00
Alexander Barton
fc3c82f7df - wird ein Client entfernt, so wird er auch aus allen Channels geloescht. 2002-01-21 00:08:50 +00:00
Alexander Barton
5999fcea4e - Channel-Pointer aus Client-Struktur entfernt. Wird nun dynamisch verwaltet :-) 2002-01-21 00:06:49 +00:00
Alexander Barton
87fc9566b0 - neue Funktionen IRC_JOIN und IRC_PART begonnen, ebenso die Funktionen
IRC_WriteStrRelatedPrefix und IRC_WriteStrRelatedChannelPrefix().
- diverse Aenderungen im Zusammenhang mit Channels.
2002-01-21 00:05:11 +00:00
Alexander Barton
85ac414908 - neue Funktionen IRC_JOIN, IRC_PART, IRC_WriteStrRelatedPrefix und
IRC_WriteStrRelatedChannelPrefix().
2002-01-21 00:04:13 +00:00
Alexander Barton
01999cfdb1 - neue Konstante CHANNEL_MODE_LEN. 2002-01-21 00:03:16 +00:00
Alexander Barton
4c32a6cebd - ERR_NOSUCHCHANNEL hinzugefuegt. 2002-01-21 00:02:34 +00:00
Alexander Barton
9951e13510 - Hilfetexte korrigiert und ergaenzt (Sniffer). 2002-01-21 00:02:11 +00:00
Alexander Barton
d3e0d78d4d - neue Befehle JOIN und PART. 2002-01-21 00:01:37 +00:00
Alexander Barton
20640e1a90 *** empty log message *** 2002-01-21 00:00:54 +00:00
Alexander Barton
6debfc3123 - Server-Verbinungen werden beim Start erst nach kurzer Pause aufgebaut. 2002-01-18 15:51:44 +00:00
Alexander Barton
49ed223c1b - bei Client_SetModes() wurde das NULL-Byte falsch gesetzt. Opsa. 2002-01-18 15:32:01 +00:00
Alexander Barton
00f86465ef - die User-Modes bei einem NICK von einem Server wurden falsch uebernommen. 2002-01-18 15:31:32 +00:00
Alexander Barton
d79a7d287a - der Sniffer wird nun nur noch aktiviert, wenn auf Kommandozeile angegeben. 2002-01-18 11:12:11 +00:00
Alexander Barton
5829be2944 - Version auf 0.0.4-pre im CVS angehoben. 2002-01-16 23:06:16 +00:00
Alexander Barton
bd923fc757 - Version 0.0.3 2002-01-16 22:55:45 +00:00
Alexander Barton
6600c90890 *** empty log message *** 2002-01-16 22:35:28 +00:00
Alexander Barton
b9d701dbeb - neue Funktionen Client_xxxCount(). 2002-01-16 22:10:35 +00:00
Alexander Barton
b3ccaa76b6 - IRC_LUSERS() implementiert. 2002-01-16 22:10:18 +00:00
Alexander Barton
8d48f07de1 - RPL_LUSERME_MSG erweitert, kleinere Aenderungen. 2002-01-16 22:09:52 +00:00
Alexander Barton
568239244f - neue Funktion Channel_Count(). 2002-01-16 22:09:07 +00:00
Alexander Barton
22cf0c5def - ngIRCd wandelt sich nun selber in einen Daemon (Hintergrundprozess) um. 2002-01-12 00:17:28 +00:00
Alexander Barton
c2ee5437da - LINKS implementiert, LUSERS begonnen. 2002-01-11 23:50:55 +00:00
Alexander Barton
4fe7e9d6f1 - Hop-Count fuer den Server selber (0) wird korrekt initialisiert. 2002-01-11 23:50:40 +00:00
Alexander Barton
006c0328b4 - Anpassungen an neue Kommandozeilen-Optionen "--debug" und "--nodaemon". 2002-01-11 14:45:37 +00:00
Alexander Barton
52424b49cb - Kommandozeilen-Parser implementiert: Debug- und No-Daemon-Modus, Hilfe. 2002-01-11 14:45:18 +00:00
Alexander Barton
baf845ddeb - WHOIS wurde faelschlicherweise an User geforwarded statt vom Server beantwortet. 2002-01-09 21:30:45 +00:00
Alexander Barton
428cc6258f - WHOIS wird im "Strict-RFC-Mode" nicht mehr automatisch geforwarded,
- andere Server werden nun ueber bisherige Server und User informiert.
2002-01-09 01:09:58 +00:00
Alexander Barton
3543c2220a - Parses handhabt Leerzeichen zw. Parametern nun etwas "lockerer". 2002-01-09 01:08:42 +00:00
Alexander Barton
8f7e7d666a - wird ein Server abgemeldet, so wird anderen Server ein SQUIT geschickt. 2002-01-09 01:08:08 +00:00
Alexander Barton
a53857b4c7 - 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.
2002-01-07 23:42:12 +00:00
Alexander Barton
2714a94f43 - Loglevel von Remote-Mode-Aenderungen angepasst (nun Debug).
- Im Debug-Mode werden nun auch PING's protokolliert.
2002-01-07 16:02:36 +00:00
Alexander Barton
6359ec48f0 - Server nimmt nun Server-Links an: PASS und SERVER entsprechend angepasst.
- MODE und NICK melden nun die Aenderungen an andere Server.
2002-01-07 15:39:46 +00:00
Alexander Barton
b89c310891 - Bei Log-Meldungen ueber Clients wird nun immer die "Client Mask" verwendet. 2002-01-07 15:31:00 +00:00
Alexander Barton
bf92db85a6 - PASSSERVERADD definiert, wird beim PASS-Befehl an Server verwendet. 2002-01-07 15:29:52 +00:00
Alexander Barton
9e18ec30ff - Status-Codes an den Server selber werden ignoriert, besseres Logging. 2002-01-07 15:29:11 +00:00
Alexander Barton
a56776892b - die Fehlermeldung "unbekannter Befehl" hatte ein falsches Format. 2002-01-06 17:41:44 +00:00
Alexander Barton
969e5f1c12 - Beispiel-Konfigurationsdatei aktualisiert. 2002-01-06 16:54:05 +00:00
Alexander Barton
81afb0cb31 - CVS-Version auf "0.0.3-pre" angehoben. 2002-01-06 16:21:09 +00:00
Alexander Barton
85d7e12a0f - Version 0.0.2 2002-01-06 16:09:37 +00:00
Alexander Barton
018cffbb5f *** empty log message *** 2002-01-06 15:40:01 +00:00
Alexander Barton
8b162c0ecd - Loglevel und Meldungen nochmals ueberarbeitet.
- QUIT und SQUIT forwarden nun den Grund der Trennung,
- WHOIS wird nun immer an den "Original-Server" weitergeleitet.
2002-01-06 15:21:29 +00:00
Alexander Barton
79809118a3 - Loglevel und Meldungen nochmals geaendert. Level passen nun besser. 2002-01-06 15:18:14 +00:00
Alexander Barton
dbd0a23994 - Fehlermeldungen korrigiert. 2002-01-05 23:26:24 +00:00
Alexander Barton
904d5e5b09 - Vorbereitungen fuer Ident-Abfragen in Client-Strukturen. 2002-01-05 23:26:05 +00:00
Alexander Barton
2e4d085df5 - Vorbereitungen fuer Ident-Abfragen bei neuen Client-Strukturen. 2002-01-05 23:25:25 +00:00
Alexander Barton
e44988f23d - WHOIS erweitert: Anfragen koennen an andere Server weitergeleitet werden.
- Vorbereitungen fuer Ident-Abfragen bei neuen Client-Strukturen.
2002-01-05 23:24:54 +00:00
Alexander Barton
0b15709e4c - neue Nachricht ERR_NOSUCHSERVER_MSG definiert. 2002-01-05 23:23:44 +00:00
Alexander Barton
1c8c92af42 - generisches Forwarding von Zahlen-Statuscodes implementiert. 2002-01-05 23:23:20 +00:00
Alexander Barton
adcf68be90 *** empty log message *** 2002-01-05 20:08:34 +00:00
Alexander Barton
e7be3a01f3 - neue Funktion Client_NextHop(). 2002-01-05 20:08:17 +00:00
Alexander Barton
a5e92ba180 - Div. Aenderungen fuer die Server-Links (u.a. WHOIS, QUIT, NICK angepasst).
- Neue Funktionen IRC_WriteStrServer() und IRC_WriteStrServerPrefix().
2002-01-05 20:08:02 +00:00
Alexander Barton
db58d34797 - Fehlerpruefung bei select() in der "Hauptschleife" korrigiert. 2002-01-05 19:15:03 +00:00
Alexander Barton
2e289b5084 - Bug bei Remote-Server-Namen entfernt: diese wurden falsch gekuerzt. 2002-01-05 16:51:49 +00:00
Alexander Barton
b20d2df064 - das Passwort von Servern wird nun ueberprueft (PASS- und SERVER-Befehl). 2002-01-05 16:51:18 +00:00
Alexander Barton
bcc0cdc3ab - "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.
2002-01-05 15:56:23 +00:00
Alexander Barton
bb2143aabc - Wrapper fuer inet_aton(): liefert immer Fehler. 2002-01-05 15:55:11 +00:00
Alexander Barton
03783eea35 - syslog() etc. wurde verwendet, auch wenn USE_SYSLOG nicht definiert war. 2002-01-05 15:54:40 +00:00
Alexander Barton
406ac2c8c2 - Test auf Header "arpa/inet.h" und Funktion inet_aton() hinzugefuegt (BeOS). 2002-01-05 15:53:20 +00:00
Alexander Barton
3d2e944856 - an Server werden keine ERRORS mehr wegen unbekannter Befehle geschickt. 2002-01-05 01:42:08 +00:00
Alexander Barton
a19c9ed5c7 - bei SQUIT wurde immer die Verbindung getrennt, auch bei Remote-Servern. 2002-01-05 00:48:33 +00:00
Alexander Barton
bed4005ed0 - IRC_WriteStrXXX()-Funktionen eingefuehrt, groessere Anpassungen daran.
- neuer Befehl SQUIT, QUIT an Server-Links angepasst.
2002-01-04 17:58:44 +00:00
Alexander Barton
165d165b63 - IRC_WriteStrXXX()-Funktionen angepasst; neuer Befehl SQUIT. 2002-01-04 17:58:21 +00:00
Alexander Barton
c48544703d - Client_Destroy() an Server-Links angepasst. 2002-01-04 17:57:08 +00:00
Alexander Barton
5ff42762cd - neuer Befehl SQUIT. 2002-01-04 17:56:45 +00:00
Alexander Barton
4d4f2d4ffb - Loglevel ein wenig angepasst. 2002-01-04 01:36:40 +00:00
Alexander Barton
bf1c59c61c - Client-Strukruren werden nur noch ueber Funktionen angesprochen.
- Weitere Anpassungen und Erweiterungen der Server-Links.
2002-01-04 01:21:47 +00:00
Alexander Barton
f755190093 - Client-Strukturen koennen von anderen Modulen nun nur noch ueber die
enstprechenden (zum Teil neuen) Funktionen angesprochen werden.
2002-01-04 01:21:22 +00:00
Alexander Barton
356683ff6e - Client-Strukruren werden nur noch ueber Funktionen angesprochen. 2002-01-04 01:20:02 +00:00
Alexander Barton
d29ac98938 *** empty log message *** 2002-01-04 01:18:38 +00:00
Alexander Barton
0c4e71da9c *** empty log message *** 2002-01-03 02:28:20 +00:00
Alexander Barton
07903baa61 - neue Funktion Client_CheckID(), diverse Aenderungen fuer Server-Links. 2002-01-03 02:28:06 +00:00
Alexander Barton
ed406b4a93 - das Server-Passwort kann nun konfiguriert werden. 2002-01-03 02:27:20 +00:00
Alexander Barton
b9bf012e83 - neue Befehle SERVER und NJOIN begonnen,
- begonnen, diverse IRC-Befehle an Server-Links anzupassen.
2002-01-03 02:26:51 +00:00
Alexander Barton
d1574f872f - neue Befehle SERVER und NJOIN begonnen. 2002-01-03 02:26:07 +00:00
Alexander Barton
54e487d424 - diverse Aenderungen und Umsetellungen fuer Server-Links. 2002-01-03 02:25:36 +00:00
Alexander Barton
93aa0dbfb8 - neue Befehle NJOIN und SERVER begonnen. 2002-01-03 02:24:49 +00:00
Alexander Barton
0d2c0db71a - neue Message ERR_NOTREGISTEREDSERVER_MSG. 2002-01-03 02:24:21 +00:00
Alexander Barton
f4dc4ae7ba - Protokollversion und Suffix definiert. 2002-01-03 02:24:00 +00:00
Alexander Barton
4a8fd02f99 - CFLAGS wird nur noch gesetzt, wenn der GCC verwendet wird. 2002-01-02 13:41:36 +00:00
Alexander Barton
cb7931cc27 - die Gross- und Kleinschreibung des Nicks kann mit NICK nun geaendert werden. 2002-01-02 12:46:41 +00:00
Alexander Barton
64218c161c - Copyright-Texte angepasst ;-) 2002-01-02 02:52:09 +00:00
Alexander Barton
32b29d6956 - Copyright-Texte angepasst.
- neuer Befehl "ERROR".
2002-01-02 02:51:39 +00:00
Alexander Barton
71f297097b - Signal-Handler fuer SIGCHLD: so sollten Zombies nicht mehr vorkommen. 2002-01-02 02:51:16 +00:00
Alexander Barton
ef8c58c43b - 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.
2002-01-02 02:50:47 +00:00
Alexander Barton
21a8a278fb - Konfigurationsdatei "Samba like" umgestellt.
- es koennen nun mehrere Server und Oprtatoren konfiguriert werden.
2002-01-02 02:49:15 +00:00
Alexander Barton
03d971d994 - neue Defines fuer max. Anzahl Server und Operatoren. 2002-01-02 02:44:36 +00:00
Alexander Barton
020c6d8bb3 - Copyright-Text ergaenzt bzw. aktualisiert. 2002-01-02 02:43:50 +00:00
Alexander Barton
b6254bbbb3 - Copyright-Texte aktualisiert.
- neuer Befehl ERROR.
2002-01-02 02:43:22 +00:00
Alexander Barton
1547f76cfd - Copyright-Texte aktualisiert. 2002-01-02 02:42:58 +00:00
Alexander Barton
e42fae3918 - fehlenden Copyright-Text ergaenzt. 2002-01-02 02:41:11 +00:00
Alexander Barton
55aa0f221c - Copyright-Text aktualisiert. 2002-01-02 02:40:50 +00:00
Alexander Barton
0b5e853138 - Copyright-Text ergaenzt. 2002-01-02 02:40:31 +00:00
Alexander Barton
667a621ed6 - Copyright-Texte ergaenzt und aktualisiert,
- fehlende Dateien in Projekt aufgenommen.
2002-01-02 02:40:15 +00:00
Alexander Barton
b20fa7c6e6 - #include's fuer stdlib.h ergaenzt. 2002-01-01 18:25:44 +00:00
Alexander Barton
71939cf513 - Architektur und Betriebssystem in Start-Meldung aufgenommen. 2002-01-01 18:01:43 +00:00
Alexander Barton
b169f0c524 - CVS-Version auf "0.0.2-pre" angehoben. 2001-12-31 16:11:13 +00:00
39 changed files with 4763 additions and 670 deletions

View File

@@ -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

View File

@@ -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 $

View File

@@ -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

View File

@@ -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.
#

View File

@@ -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.
#

View File

@@ -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,

View File

@@ -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
View File

@@ -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
View File

@@ -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 $

View File

@@ -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.
*

View File

@@ -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([ \

View File

@@ -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
View 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 $

View File

@@ -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

View File

@@ -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 $

View File

@@ -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-

View File

@@ -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

View File

@@ -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

View File

@@ -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- */

View File

@@ -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

View File

@@ -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- */

View File

@@ -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

View File

@@ -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 );
}

View File

@@ -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 );

View File

@@ -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- */

View File

@@ -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

View File

@@ -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

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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 */

View File

@@ -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.

View File

@@ -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"

View File

@@ -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- */

View File

@@ -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

View File

@@ -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 */

View File

@@ -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.

View File

@@ -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!

View File

@@ -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.