1
0
mirror of https://github.com/osmarks/ngircd.git synced 2025-12-25 23:16:04 +00:00

Compare commits

...

195 Commits

Author SHA1 Message Date
Alexander Barton
6878d25d04 - INSTALL um Hinweise auf portab.h etc. ergaenzt. 2002-03-02 03:47:28 +00:00
Alexander Barton
250ef1ab55 - Version 0.3.0 2002-03-02 03:36:14 +00:00
Alexander Barton
7b8b542396 - Aenderung des Idle-Verhalten revidiert: das war ein Schnellschuss :-/ 2002-03-02 03:32:08 +00:00
Alexander Barton
5457e0788a - Timeouts ausgehender Verbindungen werden besser erkannt (z.B. unter Cygwin).
- Idle-Time der Hauptschleife [Conn_Handle()] erhoeht: weniger Last.
2002-03-02 02:44:01 +00:00
Alexander Barton
09da2c9afd - Aktualisierungen. 2002-03-02 01:36:35 +00:00
Alexander Barton
7157d93651 - Channel- und Nicknames werden nun ordentlich validiert. 2002-03-02 01:35:50 +00:00
Alexander Barton
0370c4843f - Bei der USER-Registrierung wird NICK nicht mehr sofort geforwarded,
sondern erst dann, wenn auch ein gueltiges USER empfangen wurde.
2002-03-02 00:49:11 +00:00
Alexander Barton
a3ee1a9a26 - bei abgebrochene ausgehende Server-Verbindungen wird der naechste Ver-
bindungsversuch in RECONNECT_DELAY Sekunden (3) unternommen und nicht
  mehr "ConnectRetry" Sekunden gewartet.
2002-03-02 00:43:31 +00:00
Alexander Barton
cbce54e0fc - der Wert der Konfigurations-Variable "ConnectRetry" wird besser beachtet. 2002-03-02 00:29:11 +00:00
Alexander Barton
5facc989c5 Aktualisierung. 2002-03-02 00:29:04 +00:00
Alexander Barton
02f394f0ce - ChangeLog aktualisiert. 2002-03-02 00:25:44 +00:00
Alexander Barton
6da91c34b4 - ausgehende Verbindungen werden nun asyncron connectiert und blockieren
nicht mehr den Server. Dadurch waren einige Aenderungen noetig.
- diverse Log-Meldungen ueberarbeitet.
2002-03-02 00:23:32 +00:00
Alexander Barton
40f07f2f5c - Forwarding von TOPIC an andere Server gefixed. Hoffentlich ;-) 2002-02-28 00:48:26 +00:00
Alexander Barton
ef7f7a90f4 - einige Funktionen in irc-xxx-Module ausgegliedert. 2002-02-27 23:26:36 +00:00
Alexander Barton
c23199d971 - Modul aus irc.c bzw. irc.h ausgegliedert. 2002-02-27 23:26:21 +00:00
Alexander Barton
b56eb4d8d4 - Anpassungen an Aufteilung von irc.d, Init- und Exit-Funktionen entfernt. 2002-02-27 23:25:31 +00:00
Alexander Barton
d022c1bf4e - CONNECTED und DISCONNECTED fuer die irc-xxx-Module wird nun hier definiert. 2002-02-27 23:24:58 +00:00
Alexander Barton
fc186d77c1 - ueberfluessige Init- und Exit-Funktionen entfernt. 2002-02-27 23:24:29 +00:00
Alexander Barton
ff54198f43 - Includes fuer einige Header bereinigt. 2002-02-27 23:23:53 +00:00
Alexander Barton
a22a3d5f29 - einige Header umgestellt, neue Source-Dateien irc-xxx.c 2002-02-27 23:22:09 +00:00
Alexander Barton
070da48826 - NEWS und ChangeLog aktualisiert. 2002-02-27 20:55:56 +00:00
Alexander Barton
9780ed1f21 - Channel-Topics werden nun auch korrekt von anderen Server angenommen. 2002-02-27 20:55:44 +00:00
Alexander Barton
d59f029043 - Channel-Topics implementiert. 2002-02-27 20:33:13 +00:00
Alexander Barton
d58e22a3ea - neue Text-Konstante: ERR_NOTONCHANNEL_MSG 2002-02-27 20:33:01 +00:00
Alexander Barton
8975c7a204 - neue Konstante: CHANNEL_TOPIC_LEN 2002-02-27 20:32:34 +00:00
Alexander Barton
52548bd3e3 - neue Funktionen Channel_Topic() und Channel_SetTopic(). 2002-02-27 20:32:10 +00:00
Alexander Barton
caf41e5bba - Aktualisierungen. 2002-02-27 19:02:47 +00:00
Alexander Barton
3c01ac4e33 - PRIVMSG zeugt nun bei Texten an User an, wenn diese "away" sind. 2002-02-27 18:57:21 +00:00
Alexander Barton
949977e878 - IRC-Befehl "AWAY" implementert. 2002-02-27 18:23:45 +00:00
Alexander Barton
83177581e4 - neue Text-Konstanten RPL_UNAWAY_MSG und RPL_NOWAWAY_MSG. 2002-02-27 18:23:24 +00:00
Alexander Barton
18d881876d - Mode "a" (away) in USERMODES aufgenommen. 2002-02-27 18:22:45 +00:00
Alexander Barton
c48501245e - neue Funktion Client_SetAway() und Client_Away() implementiert. 2002-02-27 18:22:09 +00:00
Alexander Barton
b53b5728a6 - ChangeLog aktualisiert. 2002-02-27 17:07:02 +00:00
Alexander Barton
cd6e40493c - PRIVMSG beachtet nun die Channel-Modes "n" und "m". 2002-02-27 17:05:41 +00:00
Alexander Barton
82da6d2ff1 - neue Text-Konstante ERR_CANNOTSENDTOCHAN_MSG eingefuehrt. 2002-02-27 17:05:13 +00:00
Alexander Barton
f99a8ed18f - ChangeLog aktualisiert. 2002-02-27 16:05:31 +00:00
Alexander Barton
a7bbcef6e0 - Bug bei belegtem Nickname bei User-Registrierung (NICK-Befehl) behoben. 2002-02-27 16:04:14 +00:00
Alexander Barton
c147ebef0d - NAMES beachtet nun das "invisible" Flag ("i") von Usern. 2002-02-27 15:23:27 +00:00
Alexander Barton
153aa0aac8 - neue Funktion Channel_IsMemberOf() implementiert. 2002-02-27 15:21:21 +00:00
Alexander Barton
28d5898617 - Logging beim Abmelden von Clients (erneut) geaendert: nun ist's aber gut ;-) 2002-02-27 14:47:53 +00:00
Alexander Barton
140d1aa505 - Logging bei Timeout von Verbindungen geaendert. 2002-02-27 14:47:04 +00:00
Alexander Barton
d360137d94 - gerade eben in SQUIT eingefuehrten Bug behoben: entfernte Server werden nun
nur noch geloescht, die Verbindung, von der SQUIT kam, bleibt wieder offen.
2002-02-27 03:44:53 +00:00
Alexander Barton
805096d173 *** empty log message *** 2002-02-27 03:08:38 +00:00
Alexander Barton
70e3c6b50a - Log-Meldungen bei SQUIT erneut ueberarbeitet ... 2002-02-27 03:08:05 +00:00
Alexander Barton
b181f1bd3c - SQUIT wird auf jeden Fall geforwarded, zudem besseres Logging. 2002-02-27 02:26:58 +00:00
Alexander Barton
1575e30d77 - an Conn_Close() werden zwei weitere Fehlermeldungen zum Forwarden uebergeben. 2002-02-27 02:26:23 +00:00
Alexander Barton
e4754c3447 *** empty log message *** 2002-02-27 00:51:31 +00:00
Alexander Barton
180095be32 - einige unnoetige Client_NextHop()-Aufrufe entfernt.
- NAMES korrigiert und komplett implementiert.
2002-02-27 00:50:05 +00:00
Alexander Barton
93a52dfab8 - Nick-Aenderungen werden nun wieder korrekt ins Logfile geschrieben. 2002-02-26 22:06:40 +00:00
Alexander Barton
08d43d5f67 - VERSION wurde falsch weitergeleitet und beantwortet (Prefix nicht beachtet) 2002-02-26 20:52:40 +00:00
Alexander Barton
1ff2fceb22 - Fehler bei Fehlermeldung wg. unbekanntem Prefix behoben. 2002-02-26 20:52:15 +00:00
Alexander Barton
8c956d5989 *** empty log message *** 2002-02-25 17:47:41 +00:00
Alexander Barton
6817e293c5 - an User wird nun immer ein "komplettes" Prefix verschickt. 2002-02-25 17:46:27 +00:00
Alexander Barton
67295c48ca - die neuen Texte werden nun auch in Archive ("make dist") aufgenommen ;-) 2002-02-25 14:10:38 +00:00
Alexander Barton
b7a6bf27cc - etwas mehr Doku ;-) 2002-02-25 14:02:32 +00:00
Alexander Barton
abe6a2c107 *** empty log message *** 2002-02-25 13:23:31 +00:00
Alexander Barton
c90cf7c9ed - WHOIS wird nicht mehr automatisch an den "Original-Server" weiterge-
leitet: war eh nicht RFC-konform und machte Probleme mit Clients.
2002-02-25 13:21:25 +00:00
Alexander Barton
ed1dac585d *** empty log message *** 2002-02-25 11:47:30 +00:00
Alexander Barton
a809fe36c7 - es wird auf sigaction() geprueft (u.a. fuer A/UX, welches das nicht kennt). 2002-02-25 11:45:28 +00:00
Alexander Barton
62266a8d46 - wenn ein System sigaction() nicht kennt, so wird nun signal() verwendet. 2002-02-25 11:42:47 +00:00
Alexander Barton
498e6e0d22 - unter A/UX wird _POSIX_SOURCE definiert: fuer Systemheader notwendig. 2002-02-25 11:42:15 +00:00
Alexander Barton
5d306a1dc9 - es werden ein paar Funktionen mehr getestet: u.a. vsnprintf() und setsockopt().
- libUTIL wird eingebunden, so vorhanden (unter A/UX notwendig!)
2002-02-25 11:41:43 +00:00
Alexander Barton
aaa682fb24 - IRC-Befehl KILL sowie Kills bei Nick Collsisions implementiert. 2002-02-23 21:39:48 +00:00
Alexander Barton
6f955d2a34 - fuer SIGCHLD wird nun auch SA_NOCLDWAIT gesetzt, wenn vorhanden. 2002-02-23 19:06:47 +00:00
Alexander Barton
8465653c6e - Ergebnistyp von Conn_GetIdle() und Conn_LastPing() auf "time_t" geaendert. 2002-02-23 00:03:54 +00:00
Alexander Barton
2a69ee905a *** empty log message *** 2002-02-21 23:59:52 +00:00
Alexander Barton
3c233aa9c5 - die Rechte der check-Scripts wurde nicht gesetzt. 2002-02-21 18:47:49 +00:00
Alexander Barton
0253bcc8af - "check"-Target fr "make check" und "make distcheck" begonnen ... 2002-02-21 17:25:16 +00:00
Alexander Barton
367657fd36 *** empty log message *** 2002-02-19 20:36:40 +00:00
Alexander Barton
944352717a - Bei ausgehenden Verbindungen wird der Ziel-Port ins Log geschrieben. 2002-02-19 20:34:31 +00:00
Alexander Barton
1b30228caa *** empty log message *** 2002-02-19 20:32:11 +00:00
Alexander Barton
9919f38dae - SA_RESTART wird fuer Signale nur noch gesetzt, wenn es definiert ist. 2002-02-19 20:30:47 +00:00
Alexander Barton
2617d21336 *** empty log message *** 2002-02-19 20:15:17 +00:00
Alexander Barton
c66702c6d4 *** empty log message *** 2002-02-19 20:08:54 +00:00
Alexander Barton
eea1a88b24 - "Passive-Mode" implementiert: kein Auto-Conect zu anderen Servern.
- NGIRCd_DebugLevel wird (fuer VERSION-Befehl) ermittelt.
2002-02-19 20:08:24 +00:00
Alexander Barton
d1382fab5c - Neue Variablen NGIRCd_DebugVersion und NGIRCd_Passive. 2002-02-19 20:07:48 +00:00
Alexander Barton
fcb47ae64b - direkt nach dem Start werden die aktiven "Modes" ins Log geschrieben. 2002-02-19 20:07:13 +00:00
Alexander Barton
1fe8355fcf - User-Registrierung wird nicht mehr als Nick-Aenderung protokolliert,
- VERSION liefert nun doch wieder den Debug-Status im Reply.
2002-02-19 20:06:45 +00:00
Alexander Barton
26ffbc7850 - "Passive-Mode" implementiert: kein Auto-Conect zu anderen Servern. 2002-02-19 20:05:37 +00:00
Alexander Barton
b0482db966 - FAQ um Hinweise auf den Bugtracker ergaenzt. 2002-02-19 20:05:02 +00:00
Alexander Barton
0470cdfdcc - der Debug-Level wird bei VERSION nicht mehr geliefert. Grund: a) absolut
unnoetig und b) Compiler-Fehler, wenn ohne Debug-Code configure'd ;-))
2002-02-19 02:21:17 +00:00
Alexander Barton
b80fc259d8 - auf die "libbe" wird nur noch getestet, wenn syslog ueberhaupt verwendet wird. 2002-02-19 02:11:26 +00:00
Alexander Barton
efe152336c - Neue Funktion NGIRCd_VersionAddition(). 2002-02-17 23:40:32 +00:00
Alexander Barton
3fbbfe44ed - neue Funktion NGIRCd_VersionAddition(). NGIRCd_Version() aufgespaltet. 2002-02-17 23:40:21 +00:00
Alexander Barton
5a8a789511 - Konstanten sortiert, neue Konstante RPL_VERSION und RPL_VERSION_MSG. 2002-02-17 23:39:24 +00:00
Alexander Barton
458174ffb0 - neuer IRC-Befehl VERSION implementiert: IRC_VERSION(). 2002-02-17 23:38:58 +00:00
Alexander Barton
00529c8fbd *** empty log message *** 2002-02-17 23:38:13 +00:00
Alexander Barton
71fa0781d4 - Versionsnummer im CVS auf 0.2.2-pre angehoben ... 2002-02-17 22:17:33 +00:00
Alexander Barton
8fdb46361d *** empty log message *** 2002-02-17 21:59:56 +00:00
Alexander Barton
3232c7d245 - Version 0.2.1. 2002-02-17 21:50:38 +00:00
Alexander Barton
2c0a42e935 *** empty log message *** 2002-02-17 19:08:19 +00:00
Alexander Barton
a233adfbd8 - NICK-Aenderungen wurden dem User selber mit dem falschen Prefix geliefert. 2002-02-17 19:03:12 +00:00
Alexander Barton
9f3a9df24a - Client_CheckNick() und Client_CheckID() lieferten u.U. falsche Ergebnisse. 2002-02-17 19:02:49 +00:00
Alexander Barton
44b396d9a5 - Tests auf netdb.h, stdlib.h, sys/wait.h, gethostbyaddr, gethostbyname,
strftime und die "libbe" unter BeOS (fuer syslog) ergaenzt.
2002-02-17 18:47:26 +00:00
Alexander Barton
25e1e8b690 *** empty log message *** 2002-02-17 17:47:01 +00:00
Alexander Barton
b60f369266 - Fehlerhafte Modes werden nun ausfuehrlicher an den Client gemeldet. 2002-02-17 17:43:14 +00:00
Alexander Barton
1b1b718e7e - neue Text-Konstante ERR_UMODEUNKNOWNFLAG2_MSG. 2002-02-17 17:42:53 +00:00
Alexander Barton
ce2738c984 - Beispiel-Konfiguration etwas erweitert. Doku fehlt immer noch ... 2002-02-17 17:34:50 +00:00
Alexander Barton
bec7783ec9 - NICK-Aenderungen werden an alle Server und betroffene Clients gemeldet.
- Neue Funktion IRC_WriteStrRelatedPrefix().
2002-02-17 17:30:21 +00:00
Alexander Barton
db7ea9c4b3 - NICK korrigiert. 2002-02-17 17:18:59 +00:00
anonymous
2d87beed3d *** empty log message *** 2002-02-15 15:15:48 +00:00
Alexander Barton
05a493e1d0 - CVS-Doku um anonymen Zugang ergaenzt. 2002-02-15 15:15:22 +00:00
Alexander Barton
825711973a - Version auf 0.2.1-pre im CVS angehoben ... 2002-02-15 14:57:21 +00:00
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
39 changed files with 4602 additions and 1045 deletions

103
ChangeLog
View File

@@ -10,6 +10,107 @@
-- ChangeLog / Aenderungen --
ngIRCd 0.2.x, xx.xx.2002
- bekommt der Server ein HUP-Signal, so startet er neu -- genau so, wie
er auf den IRC-Befehl RESTART reagiert.
- FAQ um Hinweise auf den Bugtracker erweitert.
- neuer Kommandozeilen-Schalter "--passive" (-p): wird er angegeben, so
verbindet sich der ngIRCd nicht mehr automatisch zu anderen Servern.
Zum Debuggen manchmal ganz praktisch :-)
- direkt nach dem Start schreibt der ngIRCd nun die aktiven Kommando-
zeilenschalter in's Logfile (Passive, Debug, Sniffer ...).
- das Signal-Flag SA_RESTART wird nur noch gesetzt, wenn es auf dem
jeweiligen System auch definiert ist.
- bei ausgehenden Verbindungen wird nun der Ziel-Port protokolliert.
- neue Befehle VERSION und KILL implementiert.
- make-Target "check" (und "distcheck") mit Sinn erfuellt :-)
(die Tests sind aber bisher nicht all zu tiefgehend ...)
- Durch einen Ueberlauf konnte die Idle-Time bei WHOIS negativ werden ...
- Anpassungen an A/UX: gehoert nun auch zu den unterstuetzten Platformen.
- WHOIS wird nicht mehr automatisch an den "Original-Server" weiterge-
leitet: war eh nicht RFC-konform und machte mit Clients Probleme.
- an User wird nun immer ein "komplettes" Prefix (mit Host-Mask) ver-
schickt, Server bekommen nach wie vor kurze: das "Original" hat bei
bestimmten Befehlen (PRIVMSG) ansonsten evtl. Probleme ...
- NAMES korrigiert und vollstaendig implementiert.
- SQUIT wird auf jeden Fall geforwarded, zudem besseres Logging.
- Ist ein Nick bei der User-Registrierung bereits belegt, nimmt der
Server nun korrekt weitere NICK-Befehle an und verwendet diese.
- PRIVMSG beachtet nun die Channel-Modes "n" und "m".
- AWAY implementiert. PRIVMSG, MODE, USERHOST und WHOIS angepasst.
- der ngIRCd unterstuetzt nun Channel-Topics (TOPIC-Befehl).
- ausgehende Server-Verbindungen werden nun asyncron connectiert und
blockieren nicht mehr den ganzen Server, wenn die Gegenseite nicht
erreicht werden kann (bis zum Timeout konnten Minuten vergehen!).
- Wert der Konfigurations-Variable "ConnectRetry" wird besser beachtet.
- Channel- und Nicknames werden nun ordentlich validiert.
ngIRCd 0.2.1, 17.02.2002
- NICK korrigiert: es werden nun auch alle "betroffenen" User informiert.
- configure-Script erweitert, u.a. bessere Anpassung an BeOS: dort wird
nun die "libbe" zum ngIRCd gelinkt, somit funktioniert auch syslog.
- Fehlerhafte bzw. noch nicht verstandene Modes werden nun ausfuehrlicher
an den Client geliefert.
ngIRCd 0.2.0, 15.02.2002
- Nicknames und Channel-Namen werden etwas besser auf Gueltigkeit ueber-
prueft; ist aber nach wie vor noch nicht ausreichend.
- NJOINS von Servern wurden nicht an andere Server weitergeleitet.
- Begonnen Channel-Modes und User-Channel-Modes zu implementieren: der
Server versteht an User-Modes o und v, beachtet letzteres allerdings
noch nirgends. Bekannte (aber nicht beachtete!) Channel-Modes sind
bisher a, m, n, p, q, s und t. Diese Modes werden von Usern ange-
nommen, von anderen Servern werden auch unbekannte Modes uebernommen.
- Benutzer von connectierenden Servern wurden nicht in den Channels ange-
kuendigt, es wurden nur die internen Strukturen angepasst.
- Nach dem Connect eines Users werden LUSERS-Informationen angezeigt.
ngIRCd 0.1.0, 29.01.2002
- User-Modes bei User-Registrierungen von andere Servern (NICK-Befehl)
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",
@@ -38,4 +139,4 @@ ngIRCd 0.0.1, 31.12.2001
--
$Id: ChangeLog,v 1.7 2002/01/06 15:40:01 alex Exp $
$Id: ChangeLog,v 1.39 2002/03/02 01:36:35 alex Exp $

20
INSTALL
View File

@@ -15,8 +15,20 @@ ngIRCd ist fuer UNIXoide-Systeme konzipiert. Dieser Text beschreibt den
und GNU autoconf ("configure") unterstuetzt wird.
I. Quick Start
~~~~~~~~~~~~~~
I. Voraussetzungen
~~~~~~~~~~~~~~~~~~
ngIRCd benoetigt "Alex' Portability Headers" (portab.h). Diese koennen von
der Homepage heruntergeladen werden:
<http://arthur.ath.cx/~alex/ngircd/#download>
Vor dem configure-Lauf des ngIRCd muessen dies Header auf dem System in-
stalliert sein, anonsten bricht configure ab.
II. Quick Start
~~~~~~~~~~~~~~~
In der Regel sind folgende Schritte ausreichend:
@@ -58,8 +70,8 @@ Der make-Befehl bearbeitet die vom configure-Script erzeugten Makefile's und
uebersetzt die comBase-Library und die Testprogramme.
II. Nuetzliche make-Targets
~~~~~~~~~~~~~~~~~~~~~~~~~~~
III. Nuetzliche make-Targets
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Die vom configure-Script erzeugten Makefile's enthalten immer die folgenden
nuetzlichen Targets:

View File

@@ -128,6 +128,9 @@
F576ABFC01D5E77301A85B03,
F576ABFF01D61D7401A85B03,
F51F791301DFC95301D13771,
F51DBB15022D95E801A85B04,
F51DBB19022D995501A85B04,
F51DBB1D022D9D8F01A85B04,
);
isa = PBXHeadersBuildPhase;
name = Headers;
@@ -144,6 +147,9 @@
F51D180701C8FDD001E11C2E,
F576ABFD01D5E77301A85B03,
F5263AEE01E263D201CE8F8F,
F51DBB16022D95E801A85B04,
F51DBB1A022D995501A85B04,
F51DBB1E022D9D8F01A85B04,
);
isa = PBXSourcesBuildPhase;
name = Sources;
@@ -256,6 +262,72 @@
settings = {
};
};
F51DBB13022D95E801A85B04 = {
isa = PBXFileReference;
path = "irc-write.c";
refType = 4;
};
F51DBB14022D95E801A85B04 = {
isa = PBXFileReference;
path = "irc-write.h";
refType = 4;
};
F51DBB15022D95E801A85B04 = {
fileRef = F51DBB14022D95E801A85B04;
isa = PBXBuildFile;
settings = {
};
};
F51DBB16022D95E801A85B04 = {
fileRef = F51DBB13022D95E801A85B04;
isa = PBXBuildFile;
settings = {
};
};
F51DBB17022D995501A85B04 = {
isa = PBXFileReference;
path = "irc-mode.c";
refType = 4;
};
F51DBB18022D995501A85B04 = {
isa = PBXFileReference;
path = "irc-mode.h";
refType = 4;
};
F51DBB19022D995501A85B04 = {
fileRef = F51DBB18022D995501A85B04;
isa = PBXBuildFile;
settings = {
};
};
F51DBB1A022D995501A85B04 = {
fileRef = F51DBB17022D995501A85B04;
isa = PBXBuildFile;
settings = {
};
};
F51DBB1B022D9D8F01A85B04 = {
isa = PBXFileReference;
path = "irc-login.c";
refType = 4;
};
F51DBB1C022D9D8F01A85B04 = {
isa = PBXFileReference;
path = "irc-login.h";
refType = 4;
};
F51DBB1D022D9D8F01A85B04 = {
fileRef = F51DBB1C022D9D8F01A85B04;
isa = PBXBuildFile;
settings = {
};
};
F51DBB1E022D9D8F01A85B04 = {
fileRef = F51DBB1B022D9D8F01A85B04;
isa = PBXBuildFile;
settings = {
};
};
F51F791201DFC95301D13771 = {
isa = PBXFileReference;
name = defines.h;
@@ -327,6 +399,12 @@
F52162DB01C7BCDC012300F4,
F51D180201C8FDD001E11C2E,
F51D180301C8FDD001E11C2E,
F51DBB1B022D9D8F01A85B04,
F51DBB1C022D9D8F01A85B04,
F51DBB17022D995501A85B04,
F51DBB18022D995501A85B04,
F51DBB13022D95E801A85B04,
F51DBB14022D95E801A85B04,
F52162BB01C7B904012300F4,
F52162BC01C7B904012300F4,
F576ABFA01D5E77301A85B03,

44
NEWS
View File

@@ -10,6 +10,48 @@
-- NEWS / Neuigkeiten --
ngIRCd 0.2.x, xx.xx.2002
- bekommt der Server ein HUP-Signal, so startet er neu -- genau so, wie
er auf den IRC-Befehl RESTART reagiert.
- neuer Kommandozeilen-Schalter "--passive" (-p): wird er angegeben, so
verbindet sich der ngIRCd nicht mehr automatisch zu anderen Servern.
Zum Debuggen manchmal ganz praktisch :-)
- neue Befehle VERSION und KILL implementiert. NAMES korrigiert.
- Anpassungen an A/UX: gehoert nun auch zu den unterstuetzten Platformen.
- AWAY (und der User-Mode 'a') ist nun implementiert.
- der ngIRCd unterstuetzt nun Channel-Topics (TOPIC-Befehl).
- Channel- und Nicknames werden nun ordentlich validiert.
ngIRCd 0.2.0, 15.02.2002
- Begonnen Channel-Modes und User-Channel-Modes zu implementieren: der
Server versteht an User-Modes o und v, beachtet letzteres allerdings
noch nirgends. Bekannte (aber nicht beachtete!) Channel-Modes sind
bisher a, m, n, p, q, s und t. Diese Modes werden von Usern ange-
nommen, von anderen Servern werden auch unbekannte Modes uebernommen.
- Nach dem Connect eines Users werden LUSERS-Informationen angezeigt.
ngIRCd 0.1.0, 29.01.2002
- Channels implementiert, bisher jedoch noch ohne Channel-Modes, d.h.
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,
@@ -23,4 +65,4 @@ ngIRCd 0.0.1, 31.12.2001
--
$Id: NEWS,v 1.4 2002/01/06 15:40:01 alex Exp $
$Id: NEWS,v 1.16 2002/03/02 01:36:35 alex Exp $

13
README
View File

@@ -1,4 +1,4 @@
ngIRCd - Next Generation IRC Server
(c)2001,2002 by Alexander Barton,
@@ -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.5 2002/02/15 15:15:48 anonymous Exp $

View File

@@ -9,9 +9,50 @@
# 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.19 2002/01/06 16:21:09 alex Exp $
# $Id: configure.in,v 1.32 2002/03/02 03:36:14 alex Exp $
#
# $Log: configure.in,v $
# Revision 1.32 2002/03/02 03:36:14 alex
# - Version 0.3.0
#
# Revision 1.31 2002/02/25 11:45:28 alex
# - es wird auf sigaction() geprueft (u.a. fuer A/UX, welches das nicht kennt).
#
# Revision 1.30 2002/02/25 11:41:43 alex
# - es werden ein paar Funktionen mehr getestet: u.a. vsnprintf() und setsockopt().
# - libUTIL wird eingebunden, so vorhanden (unter A/UX notwendig!)
#
# Revision 1.29 2002/02/19 02:11:26 alex
# - auf die "libbe" wird nur noch getestet, wenn syslog ueberhaupt verwendet wird.
#
# Revision 1.28 2002/02/17 22:17:33 alex
# - Versionsnummer im CVS auf 0.2.2-pre angehoben ...
#
# Revision 1.27 2002/02/17 21:50:38 alex
# - Version 0.2.1.
#
# Revision 1.26 2002/02/17 18:47:26 alex
# - Tests auf netdb.h, stdlib.h, sys/wait.h, gethostbyaddr, gethostbyname,
# strftime und die "libbe" unter BeOS (fuer syslog) ergaenzt.
#
# Revision 1.25 2002/02/15 14:57:21 alex
# - Version auf 0.2.1-pre im CVS angehoben ...
#
# 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.
#
@@ -74,11 +115,9 @@
AC_INIT
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
AM_INIT_AUTOMAKE(ngircd,0.0.3-pre)
AM_INIT_AUTOMAKE(ngircd,0.3.0)
AM_CONFIG_HEADER(src/config.h)
# -- Variablen --
# -- C Compiler --
AC_PROG_CC
@@ -123,13 +162,13 @@ AC_ARG_WITH(portab,
]
)
AC_CHECK_HEADERS([ \
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)
AC_CHECK_HEADERS([ \
errno.h fcntl.h netdb.h netinet/in.h stdlib.h string.h \
sys/socket.h sys/time.h sys/wait.h unistd.h \
],,AC_MSG_ERROR([required C header missing!]))
# -- Datentypen --
AC_MSG_CHECKING(whether socklen_t exists)
@@ -145,30 +184,44 @@ AC_TRY_COMPILE([
AC_MSG_RESULT(no)
])
# -- Libraries --
AC_CHECK_LIB(UTIL,memmove)
# -- Funktionen --
AC_FUNC_MALLOC
AC_CHECK_FUNCS([ \
gethostname inet_ntoa memmove memset select \
socket strcasecmp strchr strerror strstr waitpid \
bind gethostbyaddr gethostbyname gethostname inet_ntoa memmove \
memset select setsockopt socket strcasecmp strchr strerror strftime \
strstr vsnprintf waitpid \
],,AC_MSG_ERROR([required function missing!]))
AC_CHECK_FUNCS(inet_aton)
# -- Libraries --
AC_CHECK_FUNCS(sigaction)
# -- Konfigurationsoptionen --
AC_ARG_ENABLE(syslog,
[ --disable-syslog disable syslog (autodetected by default)],
[ if test "$enableval" = "yes"; then
AC_CHECK_HEADER(syslog.h,AC_DEFINE(USE_SYSLOG, 1),AC_MSG_ERROR([Can't enable syslog: syslog.h not found!]))
AC_CHECK_HEADER(syslog.h,
[ AC_DEFINE(USE_SYSLOG, 1)
AC_CHECK_LIB(be,syslog)
],
AC_MSG_ERROR([Can't enable syslog: syslog.h not found!])
)
else
AC_MSG_RESULT([disabling syslog])
fi
],
[ AC_CHECK_HEADER(syslog.h,AC_DEFINE(USE_SYSLOG, 1))
[ AC_CHECK_HEADER(syslog.h,
[ AC_DEFINE(USE_SYSLOG, 1)
AC_CHECK_LIB(be,syslog)
]
)
]
)

27
doc/CC-Speed.txt Normal file
View File

@@ -0,0 +1,27 @@
ngIRCd - Next Generation IRC Server
(c)2001,2002 by Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd ist freie Software und steht unter
der GNU General Public License.
-- CC-Speed.txt --
ngIRCd-0.2.1-pre (2002-02-25):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[nach make-Zeiten sortiert]
Intel PIII, 1 GHz, 256 MB Ram, FreeBSD 4.4: configure: 00:10, make: 00:05
Intel PIII, 1 GHz, 256 MB Ram, Linux 2.4.10: configure: 00:06, make: 00:06
Intel PIII, 1 GHz, 256 MB Ram, BeOS R5: configure: 00:19, make: 00:07
Intel PIII, 1 GHz, 256 MB Ram, Win2k+CygWin: configure: 00:27, make: 00:08
AMD K6/2, 400 Mhz, 256 MB Ram, Linux 2.4.12: configure: 00:14, make: 00:12
PowerMac G4, 400 Mhz, 768 MB Ram, Mac OS X 10.1.2: configure: 00:32, make: 00:19
Macintosh SE/30, 68030 16 MHz, 32 MB, A/UX 3.0.1: configure: 07:33, make: 12:02
--
$Id: CC-Speed.txt,v 1.1 2002/02/25 14:02:32 alex Exp $

View File

@@ -14,8 +14,51 @@ Die Sourcen des ngIRCd werden mit dem "Concurrent Versions System" (CVS)
verwaltet. Somit koennen ohne Probleme mehrere Leute gleichzeitig die Sourcen
bearbeitet.
Dieser Text soll in Zukunft die Grundlagen beschreiben. Tut er aber leider
noch nicht, also frage einfach Alex direkt (siehe AUTHORS-Text), wenn du
daran interessiert bist, Zugriff auf den Quellcode via CVS zu bekommen!
[ ... more to come ... ]
I. Anonymer "Nur-Lesen"-Zugang
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Anonymer Zugriff auf die CVS-Repository von ngIRCd ist im "nur-lesen"-Modus
moeglich. Dazu sind folgende Schritte noetig:
Beim CVS-Server anmelden
$ cvs -d:pserver:anonymous@arthur.ath.cx:/usr/local/CVS/ngircd login
Als Benutzername wird "anonymous" mit einem leeren Passwort verwendet.
Nun ein "Check-Out" der Quellcodes durchfuehren:
$ cvs -d:pserver:anonymous@arthur.ath.cx:/usr/local/CVS/ngircd checkout ngircd
Dadurch wird im aktuellen Verzeichnis der neue Ordner "ngircd" mit allen
Quell-Dateien des ngIRCd erzeugt.
Dieses ist der "Arbeitsordner", alle CVS-Befehle werden in Zukunft aus
diesem Ordner bzw. einem Unterordner davon ausgefuehrt.
Wichtig: wenn ngIRCd "frisch" aus dem CVS compiliert werden soll, so
existiert das configure-Script noch nicht. Dieses muss zunaechst mit dem
Script "autogen.sh" erzeugt werden. Letzteres setzt ein installiertes GNU
automake und GNU autoconf voraus!
CVS-Tree aktualisieren:
$ cvs update
Dieser Befehl aktualisiert alle Dateien im aktuellen Verzeichnis sowie allen
Unterverzeichnissen.
$ cvs update <filename>
So kann eine einzelne Datei aktualisiert werden (auch dann, wenn sie lokal
z.B. geloescht wurde -- praktisch, um eigene "Experimente" rueckgaengig zu
machen ;-))
III. Schreibzugriff
~~~~~~~~~~~~~~~~~~~
Wer Schreibzugriff auf die CVS-Repository wuenscht, der moege sich bitte
mit Alex Barton, <alex@barton.de> in Verbindung setzen.
--
$Id: CVS.txt,v 1.5 2002/02/15 15:15:22 alex Exp $

61
doc/FAQ.txt Normal file
View File

@@ -0,0 +1,61 @@
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").
III. Bugs!?
~~~~~~~~~~~
Q: Gibt es eine Liste der bekannten Bugs bzw. Feature-Wuensche?
A: Ja. Es existiert ein Bug-Tracking-System fuer den ngIRCd (Bugzilla):
URL: <http://arthur.ath.cx/bugzilla/ngircd/>. Dort koennen Bugs ge-
meldet und Feature-Wunsche kundgetan werden. Bekannte Bugs koennen in
der Datenbank gesucht und aufgelistet werden.
Einen Account zum Suchen und Melden von Bugs bzw. Feature-Wuenschen
kannst du dir dort selber anlegen.
Q: Was mache ich, wenn ich einen Bug gefunden habe?
A: Am besten traegst du ihn in das Bug-Tracking-System des ngIRCd ein:
URL: <http://arthur.ath.cx/bugzilla/ngircd/>
--
$Id: FAQ.txt,v 1.2 2002/02/19 20:05:02 alex Exp $

View File

@@ -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: Makefile.am,v 1.3 2002/01/02 02:40:31 alex Exp $
# $Id: Makefile.am,v 1.4 2002/02/25 14:10:38 alex Exp $
#
# $Log: Makefile.am,v $
# Revision 1.4 2002/02/25 14:10:38 alex
# - die neuen Texte werden nun auch in Archive ("make dist") aufgenommen ;-)
#
# Revision 1.3 2002/01/02 02:40:31 alex
# - Copyright-Text ergaenzt.
#
@@ -22,7 +25,8 @@
# - Makefile.am fuer das "doc"-Verzeichnis begonnen.
#
EXTRA_DIST = CVS.txt RFC.txt sample-ngircd.conf
EXTRA_DIST = CC-Speed.txt CVS.txt FAQ.txt README-AUX.txt README-BeOS.txt \
RFC.txt sample-ngircd.conf
maintainer-clean-local:
rm -f Makefile Makefile.in

47
doc/README-AUX.txt Normal file
View File

@@ -0,0 +1,47 @@
ngIRCd - Next Generation IRC Server
(c)2001,2002 by Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd ist freie Software und steht unter
der GNU General Public License.
-- README-AUX.txt --
Seit Version 0.2.2-pre gehoert Apple A/UX zu den offiziell unterstuetzten
Platformen. Er ist im vollen Funktionsumfang nutzbar.
Folgende Software wird jedoch benoetigt:
- GNU C Compiler (gcc)
Bezugsquellen:
http://www.rezepte-im-web.de/appleux/gcc281.tar.gz
ftp://arthur.ath.cx/pub/AUX/Software/Development/gcc281.tar.gz
- GNU make
Bezugsquellen:
http://www.rezepte-im-web.de/appleux/make-3.79.tar.gz
ftp://arthur.ath.cx/pub/AUX/Software/Development/make-3.79.tar.gz
- GNU sed
Bezugsquellen:
http://www.rezepte-im-web.de/appleux/sed-3.02.tar.gz
ftp://arthur.ath.cx/pub/AUX/Software/Tools/sed-3.02.tar.gz
- libUTIL.a
Bezugsquellen:
http://ftp.mayn.de/pub/apple/apple_unix/Sys_stuff/libUTIL-2.1.tar.gz
ftp://arthur.ath.cx/pub/AUX/Software/Libraries/libUTIL-2.1.tar.gz
Nachdem diese Pakete entsprechend installiert sind, reicht ein ganz normales
"./configure" und "make" aus, um den ngIRCd unter A/UX zu compilieren.
Hier die Zeiten von Alex System (Macintosh SE/30, 32 MB, A/UX 3.0.1):
configure: 7:33, make: 12:02
--
$Id: README-AUX.txt,v 1.1 2002/02/25 14:02:32 alex Exp $

36
doc/README-BeOS.txt Normal file
View File

@@ -0,0 +1,36 @@
ngIRCd - Next Generation IRC Server
(c)2001,2002 by Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd ist freie Software und steht unter
der GNU General Public License.
-- README-BeOS.txt --
BeOS gehoert im Moment (noch?) nicht zu den offiziell unterstuetzten Plat-
formen: der ngIRCd enthaelt zwar bereits einige Anpassungen an BeOS und
compiliert auch, jedoch bricht er bei jedem Connect-Versuch eines Clients
mit diesem Fehler ab:
select(): Bad file descriptor!
Es sieht leider so aus, als ob das select() von BeOS nicht mit File-Handles
von Pipes verschiedener Prozesse umgehen kann: sobald der Resolver asyncron
gestartet wird, also Pipe-Handles im select() vorhanden sind, fuehrt das zu
obiger Meldung.
Theoretische "Lösung"/Workaround:
Den Resolver unter BeOS nicht verwenden, sondern mit IP-Adressen arbeiten.
Nachteil: der ngIRCd koennte sich nicht zu Servern verbinden, die dynamische
Adressen benutzen -- dazu muesste er den Namen aufloesen. Ansonsten sollte
es eigentlich zu keinen Beeintraechtigungen kommen ...
Also: wenn es jemand implementieren will ... ;-))
Vielleicht mache ich es auch irgendwann mal selber. Mal sehen.
--
$Id: README-BeOS.txt,v 1.1 2002/02/25 14:02:32 alex Exp $

View File

@@ -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,4 +1,4 @@
# $Id: sample-ngircd.conf,v 1.2 2002/01/06 16:54:05 alex Exp $
# $Id: sample-ngircd.conf,v 1.3 2002/02/17 17:34:50 alex Exp $
[Global]
Name = irc.the.net
@@ -14,9 +14,14 @@
; Password = ThePwd
[Server]
; Host = host2.the.net
; Host = connect-to-host.the.net
; Name = irc2.the.net
; Port = 6666
; Password = ThePwd
; Password = ThePwd1
[Server]
; Host = wait-for-host.the.net
; Name = irc3.the.net
; Password = ThePwd2
# -eof-

View File

@@ -9,9 +9,18 @@
# 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 $
# $Id: Makefile.am,v 1.13 2002/02/27 23:22:09 alex Exp $
#
# $Log: Makefile.am,v $
# Revision 1.13 2002/02/27 23:22:09 alex
# - einige Header umgestellt, neue Source-Dateien irc-xxx.c
#
# Revision 1.12 2002/02/21 18:47:49 alex
# - die Rechte der check-Scripts wurde nicht gesetzt.
#
# Revision 1.11 2002/02/21 17:25:16 alex
# - "check"-Target für "make check" und "make distcheck" begonnen ...
#
# Revision 1.10 2002/01/02 02:43:50 alex
# - Copyright-Text ergaenzt bzw. aktualisiert.
#
@@ -47,13 +56,29 @@
sbin_PROGRAMS = ngircd
ngircd_SOURCES = ngircd.c channel.c client.c conf.c conn.c irc.c log.c \
parse.c tool.c
ngircd_SOURCES = ngircd.c channel.c client.c conf.c conn.c irc.c \
irc-login.c irc-mode.c irc-write.c log.c parse.c tool.c
noinst_HEADERS = ngircd.h channel.h client.h conf.h conn.h irc.h log.h \
parse.h tool.h global.h messages.h defines.h
noinst_HEADERS = ngircd.h channel.h client.h conf.h conn.h irc.h \
irc-login.h irc-mode.h irc-write.h log.h parse.h tool.h \
global.h messages.h defines.h
clean-local:
rm -f check-version check-help
maintainer-clean-local:
rm -f Makefile Makefile.in
check-version: Makefile
echo "#!/bin/sh" > check-version
echo "./ngircd --version | grep version > /dev/null 2>&1" >> check-version
chmod 755 check-version
check-help: Makefile
echo "#!/bin/sh" > check-help
echo "./ngircd --help | grep help > /dev/null 2>&1" >> check-help
chmod 755 check-help
TESTS = check-version check-help
# -eof-

View File

@@ -9,11 +9,57 @@
* 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.3 2002/01/02 02:42:58 alex Exp $
* $Id: channel.c,v 1.17 2002/03/02 01:35:50 alex Exp $
*
* channel.c: Management der Channels
*
* $Log: channel.c,v $
* Revision 1.17 2002/03/02 01:35:50 alex
* - Channel- und Nicknames werden nun ordentlich validiert.
*
* Revision 1.16 2002/02/27 23:23:53 alex
* - Includes fuer einige Header bereinigt.
*
* Revision 1.15 2002/02/27 20:32:10 alex
* - neue Funktionen Channel_Topic() und Channel_SetTopic().
*
* Revision 1.14 2002/02/27 15:21:21 alex
* - neue Funktion Channel_IsMemberOf() implementiert.
*
* 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.
*
@@ -24,32 +70,581 @@
*
* 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-write.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Ÿfen, ob Name als Channelname gueltig */
CHAR *ptr, badchars[] = " ,:\x07";
assert( Name != NULL );
if(( Name[0] != '#' ) || ( strlen( Name ) >= CHANNEL_NAME_LEN )) return FALSE;
ptr = Name;
while( *ptr )
{
if( strchr( badchars, *ptr )) return FALSE;
ptr++;
}
return TRUE;
} /* Channel_IsValidName */
GLOBAL BOOLEAN Channel_ModeAdd( CHANNEL *Chan, CHAR Mode )
{
/* Mode soll gesetzt werden. TRUE wird geliefert, wenn der
* Mode neu gesetzt wurde, FALSE, wenn der Channel den Mode
* bereits hatte. */
CHAR x[2];
assert( Chan != NULL );
x[0] = Mode; x[1] = '\0';
if( ! strchr( Chan->modes, x[0] ))
{
/* Client hat den Mode noch nicht -> setzen */
strcat( Chan->modes, x );
return TRUE;
}
else return FALSE;
} /* Channel_ModeAdd */
GLOBAL BOOLEAN Channel_ModeDel( CHANNEL *Chan, CHAR Mode )
{
/* Mode soll geloescht werden. TRUE wird geliefert, wenn der
* Mode entfernt wurde, FALSE, wenn der Channel den Mode
* ueberhaupt nicht hatte. */
CHAR x[2], *p;
assert( Chan != NULL );
x[0] = Mode; x[1] = '\0';
p = strchr( Chan->modes, x[0] );
if( ! p ) return FALSE;
/* Client hat den Mode -> loeschen */
while( *p )
{
*p = *(p + 1);
p++;
}
return TRUE;
} /* Channel_ModeDel */
GLOBAL BOOLEAN Channel_UserModeAdd( CHANNEL *Chan, CLIENT *Client, CHAR Mode )
{
/* Channel-User-Mode soll gesetzt werden. TRUE wird geliefert,
* wenn der Mode neu gesetzt wurde, FALSE, wenn der User den
* Channel-Mode bereits hatte. */
CL2CHAN *cl2chan;
CHAR x[2];
assert( Chan != NULL );
assert( Client != NULL );
cl2chan = Get_Cl2Chan( Chan, Client );
assert( cl2chan != NULL );
x[0] = Mode; x[1] = '\0';
if( ! strchr( cl2chan->modes, x[0] ))
{
/* Client hat den Mode noch nicht -> setzen */
strcat( cl2chan->modes, x );
return TRUE;
}
else return FALSE;
} /* Channel_UserModeAdd */
GLOBAL BOOLEAN Channel_UserModeDel( CHANNEL *Chan, CLIENT *Client, CHAR Mode )
{
/* Channel-User-Mode soll geloescht werden. TRUE wird geliefert,
* wenn der Mode entfernt wurde, FALSE, wenn der User den Channel-Mode
* ueberhaupt nicht hatte. */
CL2CHAN *cl2chan;
CHAR x[2], *p;
assert( Chan != NULL );
assert( Client != NULL );
cl2chan = Get_Cl2Chan( Chan, Client );
assert( cl2chan != NULL );
x[0] = Mode; x[1] = '\0';
p = strchr( cl2chan->modes, x[0] );
if( ! p ) return FALSE;
/* Client hat den Mode -> loeschen */
while( *p )
{
*p = *(p + 1);
p++;
}
return TRUE;
} /* Channel_UserModeDel */
GLOBAL CHAR *Channel_UserModes( CHANNEL *Chan, CLIENT *Client )
{
/* Channel-Modes eines Users liefern */
CL2CHAN *cl2chan;
assert( Chan != NULL );
assert( Client != NULL );
cl2chan = Get_Cl2Chan( Chan, Client );
assert( cl2chan != NULL );
return cl2chan->modes;
} /* Channel_UserModes */
GLOBAL BOOLEAN Channel_IsMemberOf( CHANNEL *Chan, CLIENT *Client )
{
/* Pruefen, ob Client Mitglied in Channel ist */
assert( Chan != NULL );
assert( Client != NULL );
if( Get_Cl2Chan( Chan, Client )) return TRUE;
else return FALSE;
} /* Channel_IsMemberOf */
GLOBAL CHAR *Channel_Topic( CHANNEL *Chan )
{
assert( Chan != NULL );
return Chan->topic;
} /* Channel_Topic */
GLOBAL VOID Channel_SetTopic( CHANNEL *Chan, CHAR *Topic )
{
assert( Chan != NULL );
assert( Topic != NULL );
strncpy( Chan->topic, Topic, CHANNEL_TOPIC_LEN );
Chan->topic[CHANNEL_TOPIC_LEN - 1] = '\0';
} /* Channel_SetTopic */
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, "" );
strcpy( c->topic, "" );
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

@@ -9,11 +9,41 @@
* 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.4 2002/01/02 02:42:58 alex Exp $
* $Id: channel.h,v 1.13 2002/02/27 20:32:10 alex Exp $
*
* channel.h: Management der Channels (Header)
*
* $Log: channel.h,v $
* Revision 1.13 2002/02/27 20:32:10 alex
* - neue Funktionen Channel_Topic() und Channel_SetTopic().
*
* Revision 1.12 2002/02/27 15:21:21 alex
* - neue Funktion Channel_IsMemberOf() implementiert.
*
* 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.
*
@@ -27,23 +57,81 @@
*
* 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 */
CHAR topic[CHANNEL_TOPIC_LEN]; /* Topic des Channels */
} 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 CHAR *Channel_Topic( CHANNEL *Chan );
GLOBAL VOID Channel_SetTopic( CHANNEL *Chan, CHAR *Topic );
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 );
GLOBAL BOOLEAN Channel_IsMemberOf( CHANNEL *Chan, CLIENT *Client );
#endif

View File

@@ -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.24 2002/01/06 15:18:14 alex Exp $
* $Id: client.c,v 1.41 2002/03/02 01:35:50 alex Exp $
*
* client.c: Management aller Clients
*
@@ -21,6 +21,59 @@
* Server gewesen, so existiert eine entsprechende CONNECTION-Struktur.
*
* $Log: client.c,v $
* Revision 1.41 2002/03/02 01:35:50 alex
* - Channel- und Nicknames werden nun ordentlich validiert.
*
* Revision 1.40 2002/02/27 23:23:53 alex
* - Includes fuer einige Header bereinigt.
*
* Revision 1.39 2002/02/27 18:22:09 alex
* - neue Funktion Client_SetAway() und Client_Away() implementiert.
*
* Revision 1.38 2002/02/27 14:47:53 alex
* - Logging beim Abmelden von Clients (erneut) geaendert: nun ist's aber gut ;-)
*
* Revision 1.37 2002/02/17 19:02:49 alex
* - Client_CheckNick() und Client_CheckID() lieferten u.U. falsche Ergebnisse.
*
* 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.
*
@@ -122,7 +175,7 @@
#include "channel.h"
#include "conf.h"
#include "conn.h"
#include "irc.h"
#include "irc-write.h"
#include "log.h"
#include "messages.h"
@@ -133,7 +186,11 @@ 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 )
@@ -153,6 +210,8 @@ 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 );
@@ -194,25 +253,25 @@ GLOBAL CLIENT *Client_ThisServer( VOID )
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, Type, NULL, NULL, Hostname, NULL, 0, 0, NULL, Idented );
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, INT Hops, INT Token, CHAR *Info, BOOLEAN Idented )
GLOBAL CLIENT *Client_NewRemoteServer( CLIENT *Introducer, CHAR *Hostname, CLIENT *TopServer, INT Hops, INT Token, CHAR *Info, BOOLEAN Idented )
{
/* Neuen Remote-Client erzeugen: Wrapper-Funktion fuer Client_New (). */
return Client_New( NONE, Introducer, CLIENT_SERVER, Hostname, NULL, Hostname, Info, Hops, Token, NULL, Idented );
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, CLIENT_USER, Nick, User, Hostname, Info, Hops, Token, NULL, Idented );
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, INT Type, CHAR *ID, CHAR *User, CHAR *Hostname, CHAR *Info, INT Hops, INT Token, CHAR *Modes, BOOLEAN Idented )
GLOBAL CLIENT *Client_New( CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, INT Type, CHAR *ID, CHAR *User, CHAR *Hostname, CHAR *Info, INT Hops, INT Token, CHAR *Modes, BOOLEAN Idented )
{
CLIENT *client;
@@ -226,6 +285,7 @@ GLOBAL CLIENT *Client_New( CONN_ID Idx, CLIENT *Introducer, INT Type, CHAR *ID,
/* Initialisieren */
client->conn_id = Idx;
client->introducer = Introducer;
client->topserver = TopServer;
client->type = Type;
if( ID ) Client_SetID( client, ID );
if( User ) Client_SetUser( client, User, Idented );
@@ -234,6 +294,7 @@ GLOBAL CLIENT *Client_New( CONN_ID Idx, CLIENT *Introducer, INT Type, CHAR *ID,
client->hops = Hops;
client->token = Token;
if( Modes ) Client_SetModes( client, Modes );
if( Type == CLIENT_SERVER ) Generate_MyToken( client );
/* Verketten */
client->next = My_Clients;
@@ -276,22 +337,52 @@ GLOBAL VOID Client_Destroy( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg )
{
if( c->conn_id != NONE )
{
/* Ein lokaler User. Andere Server informieren! */
Log( LOG_NOTICE, "User \"%s\" unregistered (connection %d): %s", c->id, c->conn_id, txt );
/* 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
{
Log( LOG_DEBUG, "User \"%s\" unregistered: %s", c->id, txt );
/* 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 );
if( c != This_Server )
{
if( c->conn_id != NONE ) Log( LOG_NOTICE, "Server \"%s\" unregistered (connection %d): %s", c->id, c->conn_id, txt );
else 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
{
if( c->conn_id != NONE )
{
if( c->id[0] ) Log( LOG_NOTICE, "Client \"%s\" unregistered (connection %d): %s", c->id, c->conn_id, txt );
else Log( LOG_NOTICE, "Client unregistered (connection %d): %s", c->conn_id, txt );
}
else
{
if( c->id[0] ) Log( LOG_WARNING, "Unregistered unknown client \"%s\": %s", c->id, txt );
else Log( LOG_WARNING, "Unregistered unknown client: %s", c->id, txt );
}
}
else Log( LOG_NOTICE, "Unknown client \"%s\" unregistered: %s", c->id, txt );
free( c );
break;
@@ -353,7 +444,7 @@ GLOBAL VOID Client_SetModes( CLIENT *Client, CHAR *Modes )
assert( Client != NULL );
strncpy( Client->modes, Modes, CLIENT_MODE_LEN );
Client->info[CLIENT_MODE_LEN - 1] = '\0';
Client->modes[CLIENT_MODE_LEN - 1] = '\0';
} /* Client_SetModes */
@@ -367,10 +458,34 @@ GLOBAL VOID Client_SetPassword( CLIENT *Client, CHAR *Pwd )
} /* Client_SetPassword */
GLOBAL VOID Client_SetAway( CLIENT *Client, CHAR *Txt )
{
/* Von einem Client gelieferte AWAY-Nachricht */
assert( Client != NULL );
if( Txt )
{
/* Client AWAY setzen */
strncpy( Client->away, Txt, CLIENT_AWAY_LEN );
Client->away[CLIENT_AWAY_LEN - 1] = '\0';
Client_ModeAdd( Client, 'a' );
Log( LOG_DEBUG, "User \"%s\" is away: %s", Client_Mask( Client ), Txt );
}
else
{
/* AWAY loeschen */
Client_ModeDel( Client, 'a' );
Log( LOG_DEBUG, "User \"%s\" is no longer away.", Client_Mask( Client ));
}
} /* Client_SetAway */
GLOBAL VOID Client_SetType( CLIENT *Client, INT Type )
{
assert( Client != NULL );
Client->type = Type;
if( Type == CLIENT_SERVER ) Generate_MyToken( Client );
} /* Client_SetType */
@@ -470,16 +585,23 @@ GLOBAL CLIENT *Client_GetFromConn( CONN_ID Idx )
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->id, Nick ) == 0 ) return c;
if( strcasecmp( c->id, n ) == 0 ) return c;
c = c->next;
}
return NULL;
@@ -587,6 +709,13 @@ GLOBAL INT Client_Token( CLIENT *Client )
} /* Client_Token */
GLOBAL INT Client_MyToken( CLIENT *Client )
{
assert( Client != NULL );
return Client->mytoken;
} /* Client_MyToken */
GLOBAL CLIENT *Client_NextHop( CLIENT *Client )
{
CLIENT *c;
@@ -620,6 +749,13 @@ GLOBAL CLIENT *Client_Introducer( CLIENT *Client )
} /* 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 );
@@ -627,6 +763,15 @@ GLOBAL BOOLEAN Client_HasMode( CLIENT *Client, CHAR Mode )
} /* Client_HasMode */
GLOBAL CHAR *Client_Away( CLIENT *Client )
{
/* AWAY-Text liefern */
assert( Client != NULL );
return Client->away;
} /* Client_Away */
GLOBAL BOOLEAN Client_CheckNick( CLIENT *Client, CHAR *Nick )
{
/* Nick ueberpruefen */
@@ -636,8 +781,12 @@ 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, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), Nick );
/* Nick ungueltig? */
if( ! Client_IsValidNick( Nick ))
{
IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), Nick );
return FALSE;
}
/* Nick bereits vergeben? */
c = My_Clients;
@@ -668,7 +817,11 @@ GLOBAL BOOLEAN Client_CheckID( CLIENT *Client, CHAR *ID )
assert( ID != NULL );
/* Nick zu lang? */
if( strlen( ID ) > CLIENT_ID_LEN ) return IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), ID );
if( strlen( ID ) > CLIENT_ID_LEN )
{
IRC_WriteStrClient( Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID( Client ), ID );
return FALSE;
}
/* ID bereits vergeben? */
c = My_Clients;
@@ -726,12 +879,135 @@ 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? */
CHAR *ptr, goodchars[] = ";0123456789";
assert( Nick != NULL );
if( Nick[0] == '#' ) return FALSE;
if( strchr( goodchars, Nick[0] )) return FALSE;
if( strlen( Nick ) >= CLIENT_NICK_LEN ) return FALSE;
ptr = Nick;
while( *ptr )
{
if(( *ptr < 'A' ) && ( ! strchr( goodchars, *ptr ))) return FALSE;
if(( *ptr > '}' ) && ( ! strchr( goodchars, *ptr ))) return FALSE;
ptr++;
}
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 )
@@ -744,19 +1020,44 @@ LOCAL CLIENT *New_Client_Struct( VOID )
c->type = CLIENT_UNKNOWN;
c->conn_id = NONE;
c->introducer = NULL;
c->topserver = NULL;
strcpy( c->id, "" );
strcpy( c->pwd, "" );
strcpy( c->host, "" );
strcpy( c->user, "" );
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;
strcpy( c->away, "" );
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

@@ -9,11 +9,31 @@
* 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.17 2002/01/06 15:18:14 alex Exp $
* $Id: client.h,v 1.23 2002/02/27 18:22:09 alex Exp $
*
* client.h: Konfiguration des ngircd (Header)
*
* $Log: client.h,v $
* Revision 1.23 2002/02/27 18:22:09 alex
* - neue Funktion Client_SetAway() und Client_Away() implementiert.
*
* 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.
*
@@ -75,7 +95,6 @@
#ifndef __client_h__
#define __client_h__
#include "channel.h"
#include "conn.h"
@@ -101,14 +120,15 @@ typedef struct _CLIENT
CLIENT_TYPE type; /* Typ des Client, vgl. CLIENT_TYPE */
CONN_ID conn_id; /* ID der Connection (wenn lokal) bzw. NONE (remote) */
struct _CLIENT *introducer; /* ID des Servers, der die Verbindung hat */
struct _CLIENT *topserver; /* Toplevel-Servers (nur gueltig, wenn Client ein Server ist) */
CHAR pwd[CLIENT_PASS_LEN]; /* Passwort, welches der Client angegeben hat */
CHAR host[CLIENT_HOST_LEN]; /* Hostname des Client */
CHAR user[CLIENT_USER_LEN]; /* Benutzername ("Login") */
CHAR info[CLIENT_INFO_LEN]; /* Langer Benutzername (User) bzw. Infotext (Server) */
CHANNEL *channels[MAX_CHANNELS];/* Channel, in denen der Client Mitglied ist */
CHAR modes[CLIENT_MODE_LEN]; /* Client Modes */
INT hops, token; /* "Hops" und "Token" (-> SERVER-Befehl) */
INT hops, token, mytoken; /* "Hops" und "Token" (-> SERVER-Befehl) */
BOOLEAN oper_by_me; /* IRC-Operator-Status durch diesen Server? */
CHAR away[CLIENT_AWAY_LEN]; /* AWAY-Text, wenn Mode 'a' gesetzt */
} CLIENT;
#else
typedef POINTER CLIENT;
@@ -119,9 +139,9 @@ GLOBAL VOID Client_Init( VOID );
GLOBAL VOID Client_Exit( VOID );
GLOBAL CLIENT *Client_NewLocal( CONN_ID Idx, CHAR *Hostname, INT Type, BOOLEAN Idented );
GLOBAL CLIENT *Client_NewRemoteServer( CLIENT *Introducer, CHAR *Hostname, INT Hops, INT Token, CHAR *Info, BOOLEAN Idented );
GLOBAL CLIENT *Client_NewRemoteServer( CLIENT *Introducer, CHAR *Hostname, CLIENT *TopServer, INT Hops, INT Token, CHAR *Info, BOOLEAN Idented );
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, INT Type, CHAR *ID, CHAR *User, CHAR *Hostname, CHAR *Info, INT Hops, INT Token, CHAR *Modes, BOOLEAN Idented );
GLOBAL CLIENT *Client_New( CONN_ID Idx, CLIENT *Introducer, CLIENT *TopServer, INT Type, CHAR *ID, CHAR *User, CHAR *Hostname, CHAR *Info, INT Hops, INT Token, CHAR *Modes, BOOLEAN Idented );
GLOBAL VOID Client_Destroy( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg );
@@ -148,7 +168,10 @@ GLOBAL CLIENT *Client_Introducer( CLIENT *Client );
GLOBAL BOOLEAN Client_OperByMe( CLIENT *Client );
GLOBAL INT Client_Hops( CLIENT *Client );
GLOBAL INT Client_Token( CLIENT *Client );
GLOBAL INT Client_MyToken( CLIENT *Client );
GLOBAL CLIENT *Client_TopServer( CLIENT *Client );
GLOBAL CLIENT *Client_NextHop( CLIENT *Client );
GLOBAL CHAR *Client_Away( CLIENT *Client );
GLOBAL BOOLEAN Client_HasMode( CLIENT *Client, CHAR Mode );
@@ -163,6 +186,7 @@ GLOBAL VOID Client_SetToken( CLIENT *Client, INT Token );
GLOBAL VOID Client_SetOperByMe( CLIENT *Client, BOOLEAN OperByMe );
GLOBAL VOID Client_SetModes( CLIENT *Client, CHAR *Modes );
GLOBAL VOID Client_SetIntroducer( CLIENT *Client, CLIENT *Introducer );
GLOBAL VOID Client_SetAway( CLIENT *Client, CHAR *Txt );
GLOBAL BOOLEAN Client_ModeAdd( CLIENT *Client, CHAR Mode );
GLOBAL BOOLEAN Client_ModeDel( CLIENT *Client, CHAR Mode );
@@ -170,6 +194,18 @@ 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

@@ -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: conf.c,v 1.12 2002/01/05 23:26:24 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.
*
@@ -171,7 +174,7 @@ LOCAL VOID Read_Config( VOID )
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 = 0;
Conf_Server[Conf_Server_Count].lasttry = time( NULL ) - Conf_ConnectRetry + STARTUP_DELAY;
Conf_Server[Conf_Server_Count].res_stat = NULL;
Conf_Server_Count++;
}

View File

@@ -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: conf.h,v 1.9 2002/01/03 02:27:20 alex Exp $
* $Id: conf.h,v 1.10 2002/02/27 23:23:53 alex Exp $
*
* conf.h: Konfiguration des ngircd (Header)
*
* $Log: conf.h,v $
* Revision 1.10 2002/02/27 23:23:53 alex
* - Includes fuer einige Header bereinigt.
*
* Revision 1.9 2002/01/03 02:27:20 alex
* - das Server-Passwort kann nun konfiguriert werden.
*
@@ -48,6 +51,8 @@
#include <time.h>
#include "conn.h"
typedef struct _Conf_Oper
{

View File

@@ -9,11 +9,55 @@
* 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.33 2002/01/06 15:18:14 alex Exp $
* $Id: conn.c,v 1.46 2002/03/02 03:32:08 alex Exp $
*
* connect.h: Verwaltung aller Netz-Verbindungen ("connections")
*
* $Log: conn.c,v $
* Revision 1.46 2002/03/02 03:32:08 alex
* - Aenderung des Idle-Verhalten revidiert: das war ein Schnellschuss :-/
*
* Revision 1.45 2002/03/02 02:44:01 alex
* - Timeouts ausgehender Verbindungen werden besser erkannt (z.B. unter Cygwin).
* - Idle-Time der Hauptschleife [Conn_Handle()] erhoeht: weniger Last.
*
* Revision 1.44 2002/03/02 00:43:31 alex
* - bei abgebrochene ausgehende Server-Verbindungen wird der naechste Ver-
* bindungsversuch in RECONNECT_DELAY Sekunden (3) unternommen und nicht
* mehr "ConnectRetry" Sekunden gewartet.
*
* Revision 1.43 2002/03/02 00:29:11 alex
* - der Wert der Konfigurations-Variable "ConnectRetry" wird besser beachtet.
*
* Revision 1.42 2002/03/02 00:23:32 alex
* - ausgehende Verbindungen werden nun asyncron connectiert und blockieren
* nicht mehr den Server. Dadurch waren einige Aenderungen noetig.
* - diverse Log-Meldungen ueberarbeitet.
*
* Revision 1.41 2002/02/27 14:47:04 alex
* - Logging bei Timeout von Verbindungen geaendert.
*
* Revision 1.40 2002/02/27 02:26:23 alex
* - an Conn_Close() werden zwei weitere Fehlermeldungen zum Forwarden uebergeben.
*
* Revision 1.39 2002/02/23 00:03:54 alex
* - Ergebnistyp von Conn_GetIdle() und Conn_LastPing() auf "time_t" geaendert.
*
* Revision 1.38 2002/02/19 20:34:31 alex
* - Bei ausgehenden Verbindungen wird der Ziel-Port ins Log geschrieben.
*
* Revision 1.37 2002/02/19 20:05:37 alex
* - "Passive-Mode" implementiert: kein Auto-Conect zu anderen Servern.
*
* 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.
*
@@ -199,6 +243,7 @@ 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 BOOLEAN Init_Socket( INT Sock );
LOCAL VOID New_Server( INT Server, CONN_ID Idx );
LOCAL RES_STAT *ResolveAddr( struct sockaddr_in *Addr );
@@ -212,6 +257,7 @@ LOCAL CHAR *Resolv_Error( INT H_Error );
LOCAL fd_set My_Listeners;
LOCAL fd_set My_Sockets;
LOCAL fd_set My_Resolvers;
LOCAL fd_set My_Connects;
LOCAL INT My_Max_Fd;
@@ -228,6 +274,7 @@ GLOBAL VOID Conn_Init( VOID )
FD_ZERO( &My_Listeners );
FD_ZERO( &My_Sockets );
FD_ZERO( &My_Resolvers );
FD_ZERO( &My_Connects );
My_Max_Fd = 0;
@@ -254,16 +301,21 @@ GLOBAL VOID Conn_Exit( VOID )
{
if( My_Connections[idx].sock == i ) break;
}
if( idx < MAX_CONNECTIONS ) Conn_Close( idx, NULL, "Server going down", TRUE );
else if( FD_ISSET( i, &My_Listeners ))
if( FD_ISSET( i, &My_Listeners ))
{
close( i );
Log( LOG_DEBUG, "Listening socket %d closed.", i );
}
else
else if( FD_ISSET( i, &My_Connects ))
{
close( i );
Log( LOG_WARNING, "Unknown connection %d closed.", i );
Log( LOG_DEBUG, "Connection %d closed during creation (socket %d).", idx, i );
}
else if( idx < MAX_CONNECTIONS ) Conn_Close( idx, NULL, "Server going down", TRUE );
else
{
Log( LOG_WARNING, "Closing unknown connection %d ...", i );
close( i );
}
}
}
@@ -277,7 +329,7 @@ GLOBAL BOOLEAN Conn_NewListener( CONST INT Port )
* Socket nicht erteugt werden, so wird NULL geliefert.*/
struct sockaddr_in addr;
INT sock, on = 1;
INT sock;
/* Server-"Listen"-Socket initialisieren */
memset( &addr, 0, sizeof( addr ));
@@ -293,18 +345,7 @@ GLOBAL BOOLEAN Conn_NewListener( CONST INT Port )
return FALSE;
}
/* Socket-Optionen setzen */
if( fcntl( sock, F_SETFL, O_NONBLOCK ) != 0 )
{
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_ERR, "Can't set socket options: %s!", strerror( errno ));
/* dieser Fehler kann ignoriert werden. */
}
if( ! Init_Socket( sock )) return FALSE;
/* an Port binden */
if( bind( sock, (struct sockaddr *)&addr, (socklen_t)sizeof( addr )) != 0 )
@@ -383,6 +424,11 @@ GLOBAL VOID Conn_Handler( INT Timeout )
FD_SET( My_Connections[i].sock, &write_sockets );
}
}
/* Sockets mit im Aufbau befindlichen ausgehenden Verbindungen suchen */
for( i = 0; i < MAX_CONNECTIONS; i++ )
{
if(( My_Connections[i].sock > NONE ) && ( FD_ISSET( My_Connections[i].sock, &My_Connects ))) FD_SET( My_Connections[i].sock, &write_sockets );
}
/* von welchen Sockets koennte gelesen werden? */
read_sockets = My_Sockets;
@@ -393,6 +439,11 @@ GLOBAL VOID Conn_Handler( INT Timeout )
/* Hier muss noch auf den Resolver Sub-Prozess gewartet werden */
FD_CLR( My_Connections[i].sock, &read_sockets );
}
if(( My_Connections[i].sock > NONE ) && ( FD_ISSET( My_Connections[i].sock, &My_Connects )))
{
/* Hier laeuft noch ein asyncrones connect() */
FD_CLR( My_Connections[i].sock, &read_sockets );
}
}
for( i = 0; i < My_Max_Fd + 1; i++ )
{
@@ -449,7 +500,7 @@ GLOBAL BOOLEAN Conn_WriteStr( CONN_ID Idx, CHAR *Format, ... )
}
#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" );
@@ -538,10 +589,13 @@ GLOBAL VOID Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformC
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 );
/* Bei Server-Verbindungen lasttry-Zeitpunkt so setzen, dass
* der naechste Verbindungsversuch in RECONNECT_DELAY Sekunden
* gestartet wird */
if( My_Connections[Idx].our_server >= 0 ) Conf_Server[My_Connections[Idx].our_server].lasttry = time( NULL ) - Conf_ConnectRetry + RECONNECT_DELAY;
FD_CLR( My_Connections[Idx].sock, &My_Sockets );
FD_CLR( My_Connections[Idx].sock, &My_Connects );
My_Connections[Idx].sock = NONE;
} /* Conn_Close */
@@ -555,7 +609,7 @@ GLOBAL VOID Conn_UpdateIdle( CONN_ID Idx )
}
GLOBAL INT32 Conn_GetIdle( CONN_ID Idx )
GLOBAL time_t Conn_GetIdle( CONN_ID Idx )
{
/* Idle-Time einer Verbindung liefern (in Sekunden) */
@@ -564,6 +618,15 @@ GLOBAL INT32 Conn_GetIdle( CONN_ID Idx )
} /* Conn_GetIdle */
GLOBAL time_t 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
@@ -629,12 +692,51 @@ LOCAL VOID Handle_Read( INT Sock )
LOCAL BOOLEAN Handle_Write( CONN_ID Idx )
{
/* Daten aus Schreibpuffer versenden */
/* Daten aus Schreibpuffer versenden bzw. Connection aufbauen */
INT len;
INT len, res, err;
assert( Idx >= 0 );
assert( My_Connections[Idx].sock > NONE );
if( FD_ISSET( My_Connections[Idx].sock, &My_Connects ))
{
/* es soll nichts geschrieben werden, sondern ein
* connect() hat ein Ergebnis geliefert */
FD_CLR( My_Connections[Idx].sock, &My_Connects );
/* Ergebnis des connect() ermitteln */
len = sizeof( err );
res = getsockopt( My_Connections[Idx].sock, SOL_SOCKET, SO_ERROR, &err, &len );
assert( len == sizeof( err ));
/* Fehler aufgetreten? */
if(( res != 0 ) || ( err != 0 ))
{
/* Fehler! */
if( res != 0 ) Log( LOG_CRIT, "getsockopt (connection %d): %s!", Idx, strerror( errno ));
else Log( LOG_CRIT, "Can't connect socket to \"%s:%d\" (connection %d): %s!", My_Connections[Idx].host, Conf_Server[My_Connections[Idx].our_server].port, Idx, strerror( err ));
/* Socket etc. pp. aufraeumen */
FD_CLR( My_Connections[Idx].sock, &My_Sockets );
close( My_Connections[Idx].sock );
Init_Conn_Struct( Idx );
/* Bei Server-Verbindungen lasttry-Zeitpunkt auf "jetzt" setzen */
Conf_Server[My_Connections[Idx].our_server].lasttry = time( NULL );
return FALSE;
}
Log( LOG_DEBUG, "Connection %d with \"%s:%d\" established, now sendig PASS and SERVER ...", Idx, My_Connections[Idx].host, Conf_Server[My_Connections[Idx].our_server].port );
/* PASS und SERVER verschicken */
Conn_WriteStr( Idx, "PASS %s "PASSSERVERADD, Conf_Server[My_Connections[Idx].our_server].pwd );
Conn_WriteStr( Idx, "SERVER %s :%s", Conf_ServerName, Conf_ServerInfo );
return TRUE;
}
assert( My_Connections[Idx].wdatalen > 0 );
/* Daten schreiben */
@@ -757,7 +859,7 @@ LOCAL VOID Read_Request( CONN_ID Idx )
{
/* 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, "Socket closed.", NULL, FALSE );
Conn_Close( Idx, NULL, "Client closed connection.", FALSE );
return;
}
@@ -765,7 +867,7 @@ LOCAL VOID Read_Request( CONN_ID Idx )
{
/* Fehler beim Lesen */
Log( LOG_ERR, "Read error on connection %d: %s!", Idx, strerror( errno ));
Conn_Close( Idx, "Read error!", NULL, FALSE );
Conn_Close( Idx, NULL, "Read error!", FALSE );
return;
}
@@ -876,8 +978,8 @@ LOCAL VOID Check_Connections( VOID )
if( My_Connections[i].lastdata < time( NULL ) - Conf_PingTimeout )
{
/* Timeout */
Log( LOG_INFO, "Connection %d: Timeout.", i );
Conn_Close( i, NULL, "Timeout", TRUE );
Log( LOG_DEBUG, "Connection %d timed out ...", i );
Conn_Close( i, NULL, "Timeout", FALSE );
}
}
}
@@ -891,6 +993,9 @@ LOCAL VOID Check_Servers( VOID )
INT idx, i, n;
RES_STAT *s;
/* Wenn "Passive-Mode" aktiv: nicht verbinden */
if( NGIRCd_Passive ) return;
for( i = 0; i < Conf_Server_Count; i++ )
{
@@ -968,7 +1073,7 @@ LOCAL VOID New_Server( INT Server, CONN_ID Idx )
return;
}
Log( LOG_INFO, "Establishing connection to \"%s\", %s (connection %d) ... ", Conf_Server[Server].host, Conf_Server[Server].ip, Idx );
Log( LOG_INFO, "Establishing connection to \"%s\", %s, port %d (connection %d) ... ", Conf_Server[Server].host, Conf_Server[Server].ip, Conf_Server[Server].port, Idx );
if( inet_aton( Conf_Server[Server].ip, &inaddr ) == 0 )
{
@@ -990,8 +1095,13 @@ LOCAL VOID New_Server( INT Server, CONN_ID Idx )
Log( LOG_CRIT, "Can't create socket: %s!", strerror( errno ));
return;
}
if( connect( new_sock, (struct sockaddr *)&new_addr, sizeof( new_addr )) < 0)
if( ! Init_Socket( new_sock )) return;
connect( new_sock, (struct sockaddr *)&new_addr, sizeof( new_addr ));
if( errno != EINPROGRESS )
{
close( new_sock );
Init_Conn_Struct( Idx );
Log( LOG_CRIT, "Can't connect socket: %s!", strerror( errno ));
@@ -1008,7 +1118,7 @@ LOCAL VOID New_Server( INT Server, CONN_ID Idx )
return;
}
Client_SetIntroducer( c, c );
/* Verbindung registrieren */
My_Connections[Idx].sock = new_sock;
My_Connections[Idx].addr = new_addr;
@@ -1016,11 +1126,8 @@ LOCAL VOID New_Server( INT Server, CONN_ID Idx )
/* Neuen Socket registrieren */
FD_SET( new_sock, &My_Sockets );
FD_SET( new_sock, &My_Connects );
if( new_sock > My_Max_Fd ) My_Max_Fd = new_sock;
/* PASS und SERVER verschicken */
Conn_WriteStr( Idx, "PASS %s "PROTOVER""PROTOSUFFIX" IRC|"PACKAGE"-"VERSION" P", Conf_Server[Server].pwd );
Conn_WriteStr( Idx, "SERVER %s :%s", Conf_ServerName, Conf_ServerInfo );
} /* New_Server */
@@ -1042,6 +1149,28 @@ LOCAL VOID Init_Conn_Struct( INT Idx )
} /* Init_Conn_Struct */
LOCAL BOOLEAN Init_Socket( INT Sock )
{
/* Socket-Optionen setzen */
INT on = 1;
if( fcntl( Sock, F_SETFL, O_NONBLOCK ) != 0 )
{
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_ERR, "Can't set socket options: %s!", strerror( errno ));
/* dieser Fehler kann ignoriert werden. */
}
return TRUE;
} /* Init_Socket */
LOCAL RES_STAT *ResolveAddr( struct sockaddr_in *Addr )
{
/* IP (asyncron!) aufloesen. Bei Fehler, z.B. wenn der

View File

@@ -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: conn.h,v 1.10 2002/01/06 15:18:15 alex Exp $
* $Id: conn.h,v 1.12 2002/02/23 00:03:54 alex Exp $
*
* conn.h: Verwaltung aller Netz-Verbindungen ("connections") (Header)
*
* $Log: conn.h,v $
* Revision 1.12 2002/02/23 00:03:54 alex
* - Ergebnistyp von Conn_GetIdle() und Conn_LastPing() auf "time_t" geaendert.
*
* 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.
*
@@ -52,6 +58,9 @@
#define __conn_h__
#include <time.h>
typedef INT CONN_ID;
typedef struct _Res_Stat
@@ -74,7 +83,8 @@ GLOBAL BOOLEAN Conn_WriteStr( CONN_ID Idx, CHAR *Format, ... );
GLOBAL VOID Conn_Close( CONN_ID Idx, CHAR *LogMsg, CHAR *FwdMsg, BOOLEAN InformClient );
GLOBAL VOID Conn_UpdateIdle( CONN_ID Idx );
GLOBAL INT32 Conn_GetIdle( CONN_ID Idx );
GLOBAL time_t Conn_GetIdle( CONN_ID Idx );
GLOBAL time_t Conn_LastPing( CONN_ID Idx );
#endif

View File

@@ -9,11 +9,43 @@
* 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.3 2002/01/03 02:24:00 alex Exp $
* $Id: defines.h,v 1.13 2002/03/02 00:43:31 alex Exp $
*
* defines.h: (globale) Konstanten
*
* $Log: defines.h,v $
* Revision 1.13 2002/03/02 00:43:31 alex
* - bei abgebrochene ausgehende Server-Verbindungen wird der naechste Ver-
* bindungsversuch in RECONNECT_DELAY Sekunden (3) unternommen und nicht
* mehr "ConnectRetry" Sekunden gewartet.
*
* Revision 1.12 2002/02/27 23:24:58 alex
* - CONNECTED und DISCONNECTED fuer die irc-xxx-Module wird nun hier definiert.
*
* Revision 1.11 2002/02/27 20:32:34 alex
* - neue Konstante: CHANNEL_TOPIC_LEN
*
* Revision 1.10 2002/02/27 18:22:45 alex
* - Mode "a" (away) in USERMODES aufgenommen.
*
* 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.
*
@@ -24,7 +56,6 @@
* - 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__
@@ -47,8 +78,6 @@
#define MAX_CONNECTIONS 100 /* max. Anzahl von Verbindungen an diesem Server */
#define MAX_CHANNELS 32 /* max. Anzahl Channels pro Nick */
#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 */
#define CLIENT_PASS_LEN 9 /* max. Laenge des Passwortes */
@@ -57,10 +86,13 @@
#define CLIENT_HOST_LEN 64 /* max. Laenge des Hostname */
#define CLIENT_MODE_LEN 8 /* max. Laenge der Client-Modes */
#define CLIENT_INFO_LEN 64 /* max. Infotext-Laenge (Server) */
#define COMMAND_LEN 513 /* max. Laenge eines Befehls, vgl. RFC 2812, 3.2 */
#define CLIENT_AWAY_LEN 128 /* max. Laenger der AWAY-Nachricht */
#define CHANNEL_NAME_LEN 51 /* max. Laenge eines Channel-Namens, vgl. RFC 2812, 1.3 */
#define CHANNEL_MODE_LEN 8 /* max. Laenge der Channel-Modes */
#define CHANNEL_TOPIC_LEN 128 /* max. Laenge eines Channel-Topics */
#define COMMAND_LEN 513 /* max. Laenge eines Befehls, vgl. RFC 2812, 3.2 */
#define READBUFFER_LEN 2 * COMMAND_LEN /* Laenge des Lesepuffers je Verbindung (Bytes) */
#define WRITEBUFFER_LEN 4096 /* Laenge des Schreibpuffers je Verbindung (Bytes) */
@@ -68,6 +100,17 @@
#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 RECONNECT_DELAY 3 /* Server-Links erst nach 3 Sekunden versuchen, wieder aufzubauen */
#define USERMODES "aio" /* unterstuetzte User-Modes */
#define CHANMODES "amnopqstv" /* unterstuetzte Channel-Modes */
#define CONNECTED TRUE /* fuer die irc-xxx-Module */
#define DISCONNECTED FALSE
#endif

View File

@@ -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: global.h,v 1.6 2002/01/05 15:55:11 alex Exp $
* $Id: global.h,v 1.7 2002/02/25 11:42:15 alex Exp $
*
* global.h: Globaler Header, wir in jedes(!) Modul eingebunden.
*
* $Log: global.h,v $
* Revision 1.7 2002/02/25 11:42:15 alex
* - unter A/UX wird _POSIX_SOURCE definiert: fuer Systemheader notwendig.
*
* Revision 1.6 2002/01/05 15:55:11 alex
* - Wrapper fuer inet_aton(): liefert immer Fehler.
*
@@ -43,12 +46,16 @@
#include "config.h"
#include "defines.h"
#if OS_UNIX_AUX
#define _POSIX_SOURCE /* muss unter A/UX definiert sein */
#endif
#ifndef HAVE_socklen_t
#define socklen_t int /* u.a. fuer Mac OS X */
#endif
#ifndef HAVE_INET_ATON
#define inet_aton( opt, bind ) 0
#define inet_aton( opt, bind ) 0 /* Dummy fuer inet_aton() */
#endif

726
src/ngircd/irc-login.c Normal file
View File

@@ -0,0 +1,726 @@
/*
* 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: irc-login.c,v 1.2 2002/03/02 00:49:11 alex Exp $
*
* irc-login.c: Anmeldung und Abmeldung im IRC
*
* $Log: irc-login.c,v $
* Revision 1.2 2002/03/02 00:49:11 alex
* - Bei der USER-Registrierung wird NICK nicht mehr sofort geforwarded,
* sondern erst dann, wenn auch ein gueltiges USER empfangen wurde.
*
* Revision 1.1 2002/02/27 23:26:21 alex
* - Modul aus irc.c bzw. irc.h ausgegliedert.
*
*/
#include <portab.h>
#include "global.h"
#include <imp.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ngircd.h"
#include "conf.h"
#include "irc.h"
#include "irc-write.h"
#include "log.h"
#include "messages.h"
#include <exp.h>
#include "irc-login.h"
LOCAL BOOLEAN Hello_User( CLIENT *Client );
LOCAL VOID Kill_Nick( CHAR *Nick, CHAR *Reason );
GLOBAL BOOLEAN IRC_PASS( CLIENT *Client, REQUEST *Req )
{
assert( Client != NULL );
assert( Req != NULL );
/* Fehler liefern, wenn kein lokaler Client */
if( Client_Conn( Client ) <= NONE ) return IRC_WriteStrClient( Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( Client ), Req->command );
if(( Client_Type( Client ) == CLIENT_UNKNOWN ) && ( Req->argc == 1))
{
/* noch nicht registrierte unbekannte Verbindung */
Log( LOG_DEBUG, "Connection %d: got PASS command ...", Client_Conn( Client ));
/* Passwort speichern */
Client_SetPassword( Client, Req->argv[0] );
Client_SetType( Client, CLIENT_GOTPASS );
return CONNECTED;
}
else if((( Client_Type( Client ) == CLIENT_UNKNOWN ) || ( Client_Type( Client ) == CLIENT_UNKNOWNSERVER )) && (( Req->argc == 3 ) || ( Req->argc == 4 )))
{
/* noch nicht registrierte Server-Verbindung */
Log( LOG_DEBUG, "Connection %d: got PASS command (new server link) ...", Client_Conn( Client ));
/* Passwort speichern */
Client_SetPassword( Client, Req->argv[0] );
Client_SetType( Client, CLIENT_GOTPASSSERVER );
return CONNECTED;
}
else if(( Client_Type( Client ) == CLIENT_UNKNOWN ) || ( Client_Type( Client ) == CLIENT_UNKNOWNSERVER ))
{
/* Falsche Anzahl Parameter? */
return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
}
else return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
} /* IRC_PASS */
GLOBAL BOOLEAN IRC_SERVER( CLIENT *Client, REQUEST *Req )
{
CHAR str[LINE_LEN], *ptr;
CLIENT *from, *c, *cl;
CL2CHAN *cl2chan;
INT max_hops, i;
CHANNEL *chan;
BOOLEAN ok;
assert( Client != NULL );
assert( Req != NULL );
/* Fehler liefern, wenn kein lokaler Client */
if( Client_Conn( Client ) <= NONE ) return IRC_WriteStrClient( Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( Client ), Req->command );
if( Client_Type( Client ) == CLIENT_GOTPASSSERVER )
{
/* Verbindung soll als Server-Server-Verbindung registriert werden */
Log( LOG_DEBUG, "Connection %d: got SERVER command (new server link) ...", Client_Conn( Client ));
/* Falsche Anzahl Parameter? */
if(( Req->argc != 2 ) && ( Req->argc != 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* Ist dieser Server bei uns konfiguriert? */
for( i = 0; i < Conf_Server_Count; i++ ) if( strcasecmp( Req->argv[0], Conf_Server[i].name ) == 0 ) break;
if( i >= Conf_Server_Count )
{
/* Server ist nicht konfiguriert! */
Log( LOG_ERR, "Connection %d: Server \"%s\" not configured here!", Client_Conn( Client ), Req->argv[0] );
Conn_Close( Client_Conn( Client ), NULL, "Server not configured here", TRUE );
return DISCONNECTED;
}
if( strcmp( Client_Password( Client ), Conf_Server[i].pwd ) != 0 )
{
/* Falsches Passwort */
Log( LOG_ERR, "Connection %d: Bad password for server \"%s\"!", Client_Conn( Client ), Req->argv[0] );
Conn_Close( Client_Conn( Client ), NULL, "Bad password", TRUE );
return DISCONNECTED;
}
/* Ist ein Server mit dieser ID bereits registriert? */
if( ! Client_CheckID( Client, Req->argv[0] )) return DISCONNECTED;
/* Server-Strukturen fuellen ;-) */
Client_SetID( Client, Req->argv[0] );
Client_SetHops( Client, 1 );
Client_SetInfo( Client, Req->argv[Req->argc - 1] );
/* Meldet sich der Server bei uns an? */
if( Req->argc == 2 )
{
/* Unseren SERVER- und PASS-Befehl senden */
ok = TRUE;
if( ! IRC_WriteStrClient( Client, "PASS %s "PASSSERVERADD, Conf_Server[i].pwd )) ok = FALSE;
else ok = IRC_WriteStrClient( Client, "SERVER %s 1 :%s", Conf_ServerName, Conf_ServerInfo );
if( ! ok )
{
Conn_Close( Client_Conn( Client ), "Unexpected server behavior!", NULL, FALSE );
return DISCONNECTED;
}
Client_SetIntroducer( Client, Client );
Client_SetToken( Client, 1 );
}
else Client_SetToken( Client, atoi( Req->argv[1] ));
Log( LOG_NOTICE, "Server \"%s\" registered (connection %d, 1 hop - direct link).", Client_ID( Client ), Client_Conn( Client ));
Client_SetType( Client, CLIENT_SERVER );
/* maximalen Hop Count ermitteln */
max_hops = 0;
c = Client_First( );
while( c )
{
if( Client_Hops( c ) > max_hops ) max_hops = Client_Hops( c );
c = Client_Next( c );
}
/* Alle bisherigen Server dem neuen Server bekannt machen,
* die bisherigen Server ueber den neuen informierenn */
for( i = 0; i < ( max_hops + 1 ); i++ )
{
c = Client_First( );
while( c )
{
if(( Client_Type( c ) == CLIENT_SERVER ) && ( c != Client ) && ( c != Client_ThisServer( )) && ( Client_Hops( c ) == i ))
{
if( Client_Conn( c ) > NONE )
{
/* Dem gefundenen Server gleich den neuen
* Server bekannt machen */
if( ! IRC_WriteStrClient( c, "SERVER %s %d %d :%s", Client_ID( Client ), Client_Hops( Client ) + 1, Client_MyToken( Client ), Client_Info( Client ))) return DISCONNECTED;
}
/* Den neuen Server ueber den alten informieren */
if( ! IRC_WriteStrClientPrefix( Client, Client_Hops( c ) == 1 ? Client_ThisServer( ) : Client_Introducer( c ), "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ))) return DISCONNECTED;
}
c = Client_Next( c );
}
}
/* alle User dem neuen Server bekannt machen */
c = Client_First( );
while( c )
{
if( Client_Type( c ) == CLIENT_USER )
{
/* User an neuen Server melden */
if( ! IRC_WriteStrClient( Client, "NICK %s %d %s %s %d +%s :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_User( c ), Client_Hostname( c ), Client_MyToken( Client_Introducer( c )), Client_Modes( c ), Client_Info( c ))) return DISCONNECTED;
}
c = Client_Next( c );
}
/* Channels dem neuen Server bekannt machen */
chan = Channel_First( );
while( chan )
{
sprintf( str, "NJOIN %s :", Channel_Name( chan ));
/* alle Member suchen */
cl2chan = Channel_FirstMember( chan );
while( cl2chan )
{
cl = Channel_GetClient( cl2chan );
assert( cl != NULL );
/* Nick, ggf. mit Modes, anhaengen */
if( str[strlen( str ) - 1] != ':' ) strcat( str, "," );
if( strchr( Channel_UserModes( chan, cl ), 'v' )) strcat( str, "+" );
if( strchr( Channel_UserModes( chan, cl ), 'o' )) strcat( str, "@" );
strcat( str, Client_ID( cl ));
if( strlen( str ) > ( LINE_LEN - CLIENT_NICK_LEN - 4 ))
{
/* Zeile senden */
if( ! IRC_WriteStrClient( Client, str )) return DISCONNECTED;
sprintf( str, "NJOIN %s :", Channel_Name( chan ));
}
cl2chan = Channel_NextMember( chan, cl2chan );
}
/* noch Daten da? */
if( str[strlen( str ) - 1] != ':')
{
/* Ja; Also senden ... */
if( ! IRC_WriteStrClient( Client, str )) return DISCONNECTED;
}
/* naechsten Channel suchen */
chan = Channel_Next( chan );
}
return CONNECTED;
}
else if( Client_Type( Client ) == CLIENT_SERVER )
{
/* Neuer Server wird im Netz angekuendigt */
/* Falsche Anzahl Parameter? */
if( Req->argc != 4 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* Ist ein Server mit dieser ID bereits registriert? */
if( ! Client_CheckID( Client, Req->argv[0] )) return DISCONNECTED;
/* Ueberfluessige Hostnamen aus Info-Text entfernen */
ptr = strchr( Req->argv[3] + 2, '[' );
if( ! ptr ) ptr = Req->argv[3];
from = Client_GetFromID( Req->prefix );
if( ! from )
{
/* Hm, Server, der diesen einfuehrt, ist nicht bekannt!? */
Log( LOG_ALERT, "Unknown ID in prefix of SERVER: \"%s\"! (on connection %d)", Req->prefix, Client_Conn( Client ));
Conn_Close( Client_Conn( Client ), NULL, "Unknown ID in prefix of SERVER", TRUE );
return DISCONNECTED;
}
/* Neue Client-Struktur anlegen */
c = Client_NewRemoteServer( Client, Req->argv[0], from, atoi( Req->argv[1] ), atoi( Req->argv[2] ), ptr, TRUE );
if( ! c )
{
/* Neue Client-Struktur konnte nicht angelegt werden */
Log( LOG_ALERT, "Can't create client structure for server! (on connection %d)", Client_Conn( Client ));
Conn_Close( Client_Conn( Client ), NULL, "Can't allocate client structure for remote server", TRUE );
return DISCONNECTED;
}
/* Log-Meldung zusammenbauen und ausgeben */
if(( Client_Hops( c ) > 1 ) && ( Req->prefix[0] )) sprintf( str, "connected to %s, ", Client_ID( from ));
else strcpy( str, "" );
Log( LOG_NOTICE, "Server \"%s\" registered (via %s, %s%d hop%s).", Client_ID( c ), Client_ID( Client ), str, Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
/* Andere Server informieren */
IRC_WriteStrServersPrefix( Client, from, "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ));
return CONNECTED;
}
else return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
} /* IRC_SERVER */
GLOBAL BOOLEAN IRC_NJOIN( CLIENT *Client, REQUEST *Req )
{
CHAR *channame, *ptr, modes[8];
BOOLEAN is_op, is_voiced;
CHANNEL *chan;
CLIENT *c;
assert( Client != NULL );
assert( Req != NULL );
if( Client_Type( Client ) != CLIENT_SERVER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTEREDSERVER_MSG, Client_ID( Client ));
/* Falsche Anzahl Parameter? */
if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
channame = Req->argv[0];
ptr = strtok( Req->argv[1], "," );
while( ptr )
{
is_op = is_voiced = FALSE;
/* Prefixe abschneiden */
while(( *ptr == '@' ) || ( *ptr == '+' ))
{
if( *ptr == '@' ) is_op = TRUE;
if( *ptr == '+' ) is_voiced = TRUE;
ptr++;
}
c = Client_GetFromID( ptr );
if( c )
{
Channel_Join( c, channame );
chan = Channel_Search( channame );
assert( chan != NULL );
if( is_op ) Channel_UserModeAdd( chan, c, 'o' );
if( is_voiced ) Channel_UserModeAdd( chan, c, 'v' );
/* im Channel bekannt machen */
IRC_WriteStrChannelPrefix( Client, chan, c, FALSE, "JOIN :%s", channame );
/* Channel-User-Modes setzen */
strcpy( modes, Channel_UserModes( chan, c ));
if( modes[0] )
{
/* Modes im Channel bekannt machen */
IRC_WriteStrChannelPrefix( Client, chan, Client, FALSE, "MODE %s +%s %s", channame, modes, Client_ID( c ));
}
}
else Log( LOG_ERR, "Got NJOIN for unknown nick \"%s\" for channel \"%s\"!", ptr, channame );
/* naechsten Nick suchen */
ptr = strtok( NULL, "," );
}
/* an andere Server weiterleiten */
IRC_WriteStrServersPrefix( Client, Client_ThisServer( ), "NJOIN %s :%s", Req->argv[0], Req->argv[1] );
return CONNECTED;
} /* IRC_NJOIN */
GLOBAL BOOLEAN IRC_NICK( CLIENT *Client, REQUEST *Req )
{
CLIENT *intr_c, *target, *c;
CHAR *modes;
assert( Client != NULL );
assert( Req != NULL );
/* Zumindest BitchX sendet NICK-USER in der falschen Reihenfolge. */
#ifndef STRICT_RFC
if( Client_Type( Client ) == CLIENT_UNKNOWN || Client_Type( Client ) == CLIENT_GOTPASS || Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTUSER || Client_Type( Client ) == CLIENT_USER || ( Client_Type( Client ) == CLIENT_SERVER && Req->argc == 1 ))
#else
if( Client_Type( Client ) == CLIENT_UNKNOWN || Client_Type( Client ) == CLIENT_GOTPASS || Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_USER || ( Client_Type( Client ) == CLIENT_SERVER && Req->argc == 1 ))
#endif
{
/* User-Registrierung bzw. Nick-Aenderung */
/* Falsche Anzahl Parameter? */
if( Req->argc != 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* "Ziel-Client" ermitteln */
if( Client_Type( Client ) == CLIENT_SERVER )
{
target = Client_GetFromID( Req->prefix );
if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] );
}
else
{
/* Ist der Client "restricted"? */
if( Client_HasMode( Client, 'r' )) return IRC_WriteStrClient( Client, ERR_RESTRICTED_MSG, Client_ID( Client ));
target = Client;
}
#ifndef STRICT_RFC
/* Wenn der Client zu seinem eigenen Nick wechseln will, so machen
* wir nichts. So macht es das Original und mind. Snak hat probleme,
* wenn wir es nicht so machen. Ob es so okay ist? Hm ... */
if( strcmp( Client_ID( target ), Req->argv[0] ) == 0 ) return CONNECTED;
#endif
/* pruefen, ob Nick bereits vergeben. Speziallfall: der Client
* will nur die Gross- und Kleinschreibung aendern. Das darf
* er natuerlich machen :-) */
if( strcasecmp( Client_ID( target ), Req->argv[0] ) != 0 )
{
if( ! Client_CheckNick( target, Req->argv[0] )) return CONNECTED;
}
if(( Client_Type( target ) != CLIENT_USER ) && ( Client_Type( target ) != CLIENT_SERVER ))
{
/* Neuer Client */
Log( LOG_DEBUG, "Connection %d: got valid NICK command ...", Client_Conn( Client ));
/* Client-Nick registrieren */
Client_SetID( target, Req->argv[0] );
/* schon ein USER da? Dann registrieren! */
if( Client_Type( Client ) == CLIENT_GOTUSER ) return Hello_User( Client );
else Client_SetType( Client, CLIENT_GOTNICK );
}
else
{
/* Nick-Aenderung */
Log( LOG_INFO, "User \"%s\" changed nick: \"%s\" -> \"%s\".", Client_Mask( target ), Client_ID( target ), Req->argv[0] );
/* alle betroffenen User und Server ueber Nick-Aenderung informieren */
if( Client_Type( Client ) == CLIENT_USER ) IRC_WriteStrClientPrefix( Client, Client, "NICK :%s", Req->argv[0] );
IRC_WriteStrServersPrefix( Client, target, "NICK :%s", Req->argv[0] );
IRC_WriteStrRelatedPrefix( target, target, FALSE, "NICK :%s", Req->argv[0] );
/* neuen Client-Nick speichern */
Client_SetID( target, Req->argv[0] );
}
return CONNECTED;
}
else if( Client_Type( Client ) == CLIENT_SERVER )
{
/* Server fuehrt neuen Client ein */
/* Falsche Anzahl Parameter? */
if( Req->argc != 7 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* Nick ueberpruefen */
c = Client_GetFromID( Req->argv[0] );
if( c )
{
/* Der neue Nick ist auf diesem Server bereits registriert:
* sowohl der neue, als auch der alte Client muessen nun
* disconnectiert werden. */
Log( LOG_ERR, "Server %s introduces already registered nick \"%s\"!", Client_ID( Client ), Req->argv[0] );
Kill_Nick( Req->argv[0], "Nick collision" );
return CONNECTED;
}
/* Server, zu dem der Client connectiert ist, suchen */
intr_c = Client_GetFromToken( Client, atoi( Req->argv[4] ));
if( ! intr_c )
{
Log( LOG_ERR, "Server %s introduces nick \"%s\" on unknown server!?", Client_ID( Client ), Req->argv[0] );
Kill_Nick( Req->argv[0], "Unknown server" );
return CONNECTED;
}
/* Neue Client-Struktur anlegen */
c = Client_NewRemoteUser( intr_c, Req->argv[0], atoi( Req->argv[1] ), Req->argv[2], Req->argv[3], atoi( Req->argv[4] ), Req->argv[5] + 1, Req->argv[6], TRUE );
if( ! c )
{
/* Eine neue Client-Struktur konnte nicht angelegt werden.
* Der Client muss disconnectiert werden, damit der Netz-
* status konsistent bleibt. */
Log( LOG_ALERT, "Can't create client structure! (on connection %d)", Client_Conn( Client ));
Kill_Nick( Req->argv[0], "Server error" );
return CONNECTED;
}
modes = Client_Modes( c );
if( *modes ) Log( LOG_DEBUG, "User \"%s\" (+%s) registered (via %s, on %s, %d hop%s).", Client_Mask( c ), modes, Client_ID( Client ), Client_ID( intr_c ), Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
else Log( LOG_DEBUG, "User \"%s\" registered (via %s, on %s, %d hop%s).", Client_Mask( c ), Client_ID( Client ), Client_ID( intr_c ), Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
/* Andere Server, ausser dem Introducer, informieren */
IRC_WriteStrServersPrefix( Client, Client, "NICK %s %d %s %s %d %s :%s", Req->argv[0], atoi( Req->argv[1] ) + 1, Req->argv[2], Req->argv[3], Client_MyToken( intr_c ), Req->argv[5], Req->argv[6] );
return CONNECTED;
}
else return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
} /* IRC_NICK */
GLOBAL BOOLEAN IRC_USER( CLIENT *Client, REQUEST *Req )
{
assert( Client != NULL );
assert( Req != NULL );
#ifndef STRICT_RFC
if( Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTPASS || Client_Type( Client ) == CLIENT_UNKNOWN )
#else
if( Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTPASS )
#endif
{
/* Falsche Anzahl Parameter? */
if( Req->argc != 4 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
Client_SetUser( Client, Req->argv[0], FALSE );
Client_SetInfo( Client, Req->argv[3] );
Log( LOG_DEBUG, "Connection %d: got valid USER command ...", Client_Conn( Client ));
if( Client_Type( Client ) == CLIENT_GOTNICK ) return Hello_User( Client );
else Client_SetType( Client, CLIENT_GOTUSER );
return CONNECTED;
}
else if( Client_Type( Client ) == CLIENT_USER || Client_Type( Client ) == CLIENT_SERVER || Client_Type( Client ) == CLIENT_SERVICE )
{
return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
}
else return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
} /* IRC_USER */
GLOBAL BOOLEAN IRC_QUIT( CLIENT *Client, REQUEST *Req )
{
CLIENT *target;
assert( Client != NULL );
assert( Req != NULL );
if(( Client_Type( Client ) == CLIENT_USER ) || ( Client_Type( Client ) == CLIENT_SERVICE ))
{
/* User / Service */
/* Falsche Anzahl Parameter? */
if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if( Req->argc == 0 ) Conn_Close( Client_Conn( Client ), "Got QUIT command.", NULL, TRUE );
else Conn_Close( Client_Conn( Client ), "Got QUIT command.", Req->argv[0], TRUE );
return DISCONNECTED;
}
else if ( Client_Type( Client ) == CLIENT_SERVER )
{
/* Server */
/* Falsche Anzahl Parameter? */
if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
target = Client_Search( Req->prefix );
if( ! target )
{
Log( LOG_ERR, "Got QUIT from %s for unknown client!?", Client_ID( Client ));
return CONNECTED;
}
if( Req->argc == 0 ) Client_Destroy( target, "Got QUIT command.", NULL );
else Client_Destroy( target, "Got QUIT command.", Req->argv[0] );
return CONNECTED;
}
else return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
} /* IRC_QUIT */
GLOBAL BOOLEAN IRC_SQUIT( CLIENT *Client, REQUEST *Req )
{
CLIENT *target;
CHAR msg[LINE_LEN + 64];
assert( Client != NULL );
assert( Req != NULL );
/* SQUIT ist nur fuer Server erlaubt */
if( Client_Type( Client ) != CLIENT_SERVER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
/* Falsche Anzahl Parameter? */
if( Req->argc != 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
Log( LOG_DEBUG, "Got SQUIT from %s for \"%s\": \"%s\" ...", Client_ID( Client ), Req->argv[0], Req->argv[1] );
/* SQUIT an alle Server weiterleiten */
IRC_WriteStrServers( Client, "SQUIT %s :%s", Req->argv[0], Req->argv[1] );
target = Client_GetFromID( Req->argv[0] );
if( ! target )
{
Log( LOG_ERR, "Got SQUIT from %s for unknown server \"%s\"!?", Client_ID( Client ), Req->argv[0] );
return CONNECTED;
}
if( Req->argv[1][0] )
{
if( strlen( Req->argv[1] ) > LINE_LEN ) Req->argv[1][LINE_LEN] = '\0';
sprintf( msg, "%s (SQUIT from %s).", Req->argv[1], Client_ID( Client ));
}
else sprintf( msg, "Got SQUIT from %s.", Client_ID( Client ));
if( Client_Conn( target ) > NONE )
{
/* dieser Server hat die Connection */
if( Req->argv[1][0] ) Conn_Close( Client_Conn( target ), msg, Req->argv[1], TRUE );
else Conn_Close( Client_Conn( target ), msg, NULL, TRUE );
return DISCONNECTED;
}
else
{
/* Verbindung hielt anderer Server */
Client_Destroy( target, msg, Req->argv[1] );
return CONNECTED;
}
} /* IRC_SQUIT */
GLOBAL BOOLEAN IRC_PING( CLIENT *Client, REQUEST *Req )
{
CLIENT *target, *from;
assert( Client != NULL );
assert( Req != NULL );
if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
/* Falsche Anzahl Parameter? */
if( Req->argc < 1 ) return IRC_WriteStrClient( Client, ERR_NOORIGIN_MSG, Client_ID( Client ));
if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if( Req->argc == 2 )
{
/* es wurde ein Ziel-Client angegeben */
target = Client_GetFromID( Req->argv[1] );
if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[1] );
if( target != Client_ThisServer( ))
{
/* ok, forwarden */
if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_GetFromID( Req->prefix );
else from = Client;
if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->prefix );
return IRC_WriteStrClientPrefix( target, from, "PING %s :%s", Client_ID( from ), Req->argv[1] );
}
}
Log( LOG_DEBUG, "Connection %d: got PING, sending PONG ...", Client_Conn( Client ));
return IRC_WriteStrClient( Client, "PONG %s :%s", Client_ID( Client_ThisServer( )), Client_ID( Client ));
} /* IRC_PING */
GLOBAL BOOLEAN IRC_PONG( CLIENT *Client, REQUEST *Req )
{
CLIENT *target, *from;
assert( Client != NULL );
assert( Req != NULL );
if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
/* Falsche Anzahl Parameter? */
if( Req->argc < 1 ) return IRC_WriteStrClient( Client, ERR_NOORIGIN_MSG, Client_ID( Client ));
if( Req->argc > 2 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* forwarden? */
if( Req->argc == 2 )
{
target = Client_GetFromID( Req->argv[1] );
if( ! target ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->argv[1] );
if( target != Client_ThisServer( ))
{
/* ok, forwarden */
if( Client_Type( Client ) == CLIENT_SERVER ) from = Client_GetFromID( Req->prefix );
else from = Client;
if( ! from ) return IRC_WriteStrClient( Client, ERR_NOSUCHSERVER_MSG, Client_ID( Client ), Req->prefix );
return IRC_WriteStrClientPrefix( target, from, "PONG %s :%s", Client_ID( from ), Req->argv[1] );
}
}
/* Der Connection-Timestamp wurde schon beim Lesen aus dem Socket
* aktualisiert, daher muss das hier nicht mehr gemacht werden. */
if( Client_Conn( Client ) > NONE ) Log( LOG_DEBUG, "Connection %d: received PONG. Lag: %ld seconds.", Client_Conn( Client ), time( NULL ) - Conn_LastPing( Client_Conn( Client )));
else Log( LOG_DEBUG, "Connection %d: received PONG.", Client_Conn( Client ));
return CONNECTED;
} /* IRC_PONG */
LOCAL BOOLEAN Hello_User( CLIENT *Client )
{
assert( Client != NULL );
/* Passwort ueberpruefen */
if( strcmp( Client_Password( Client ), Conf_ServerPwd ) != 0 )
{
/* Falsches Passwort */
Log( LOG_ERR, "User \"%s\" rejected (connection %d): Bad password!", Client_Mask( Client ), Client_Conn( Client ));
Conn_Close( Client_Conn( Client ), NULL, "Bad password", TRUE );
return DISCONNECTED;
}
Log( LOG_NOTICE, "User \"%s\" registered (connection %d).", Client_Mask( Client ), Client_Conn( Client ));
/* Andere Server informieren */
IRC_WriteStrServers( NULL, "NICK %s 1 %s %s 1 +%s :%s", Client_ID( Client ), Client_User( Client ), Client_Hostname( Client ), Client_Modes( Client ), Client_Info( Client ));
if( ! IRC_WriteStrClient( Client, RPL_WELCOME_MSG, Client_ID( Client ), Client_Mask( Client ))) return FALSE;
if( ! IRC_WriteStrClient( Client, RPL_YOURHOST_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )))) return FALSE;
if( ! IRC_WriteStrClient( Client, RPL_CREATED_MSG, Client_ID( Client ), NGIRCd_StartStr )) return FALSE;
if( ! IRC_WriteStrClient( Client, RPL_MYINFO_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )))) return FALSE;
Client_SetType( Client, CLIENT_USER );
if( ! IRC_Send_LUSERS( Client )) return DISCONNECTED;
if( ! IRC_Show_MOTD( Client )) return DISCONNECTED;
return CONNECTED;
} /* Hello_User */
LOCAL VOID Kill_Nick( CHAR *Nick, CHAR *Reason )
{
CLIENT *c;
assert( Nick != NULL );
assert( Reason != NULL );
Log( LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s", Nick, Reason );
/* andere Server benachrichtigen */
IRC_WriteStrServers( NULL, "KILL %s :%s", Nick, Reason );
/* Ggf. einen eigenen Client toeten */
c = Client_GetFromID( Nick );
if( c && ( Client_Conn( c ) != NONE )) Conn_Close( Client_Conn( c ), NULL, Reason, TRUE );
} /* Kill_Nick */
/* -eof- */

44
src/ngircd/irc-login.h Normal file
View File

@@ -0,0 +1,44 @@
/*
* 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: irc-login.h,v 1.1 2002/02/27 23:26:21 alex Exp $
*
* irc-login.h: Anmeldung und Abmeldung im IRC (Header)
*
* $Log: irc-login.h,v $
* Revision 1.1 2002/02/27 23:26:21 alex
* - Modul aus irc.c bzw. irc.h ausgegliedert.
*
*/
#ifndef __irc_login_h__
#define __irc_login_h__
#include "parse.h"
#include "client.h"
GLOBAL BOOLEAN IRC_PASS( CLIENT *Client, REQUEST *Req );
GLOBAL BOOLEAN IRC_NICK( CLIENT *Client, REQUEST *Req );
GLOBAL BOOLEAN IRC_USER( CLIENT *Client, REQUEST *Req );
GLOBAL BOOLEAN IRC_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 );
#endif
/* -eof- */

393
src/ngircd/irc-mode.c Normal file
View File

@@ -0,0 +1,393 @@
/*
* 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: irc-mode.c,v 1.1 2002/02/27 23:26:21 alex Exp $
*
* irc-mode.c: IRC-Befehle zur Mode-Aenderung (MODE, AWAY, ...)
*
* $Log: irc-mode.c,v $
* Revision 1.1 2002/02/27 23:26:21 alex
* - Modul aus irc.c bzw. irc.h ausgegliedert.
*
*/
#include <portab.h>
#include "global.h"
#include <imp.h>
#include <assert.h>
#include <string.h>
#include "channel.h"
#include "irc-write.h"
#include "log.h"
#include "messages.h"
#include <exp.h>
#include "irc-mode.h"
GLOBAL BOOLEAN IRC_MODE( CLIENT *Client, REQUEST *Req )
{
CHAR *mode_ptr, the_modes[CLIENT_MODE_LEN], x[2];
CLIENT *cl, *chan_cl, *prefix;
BOOLEAN set, ok;
CHANNEL *chan;
assert( Client != NULL );
assert( Req != NULL );
cl = chan_cl = prefix = NULL;
chan = NULL;
/* Valider Client? */
if(( Client_Type( Client ) != CLIENT_USER ) && ( Client_Type( Client ) != CLIENT_SERVER )) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
/* Keine Parameter? */
if( Req->argc < 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* Ziel suchen: Client bzw. Channel */
if( Client_IsValidNick( Req->argv[0] )) cl = Client_Search( Req->argv[0] );
if( Channel_IsValidName( Req->argv[0] )) chan = Channel_Search( Req->argv[0] );
/* Kein Ziel gefunden? */
if(( ! cl ) && ( ! chan )) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] );
assert(( cl && chan ) != TRUE );
/* Falsche Anzahl Parameter? */
if(( cl ) && ( Req->argc > 2 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if(( chan ) && ( Req->argc > 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
/* Client ermitteln, wenn bei Channel-Modes mit 3 Parametern */
if(( chan ) && (Req->argc == 3 ))
{
chan_cl = Client_Search( Req->argv[2] );
if( ! chan_cl ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->argv[0] );
}
/* Wenn Anfragender ein User ist: Zugriff erlaubt? */
if( Client_Type( Client ) == CLIENT_USER )
{
if( cl )
{
/* MODE ist nur fuer sich selber zulaessig! */
if( cl != Client ) return IRC_WriteStrClient( Client, ERR_USERSDONTMATCH_MSG, Client_ID( Client ));
}
if( chan )
{
/* Darf der User die Channel-Modes ermitteln? */
}
}
/* Werden die Modes "nur" erfragt? */
if(( cl ) && ( Req->argc == 1 )) return IRC_WriteStrClient( Client, RPL_UMODEIS_MSG, Client_ID( Client ), Client_Modes( cl ));
if(( chan ) && ( Req->argc == 1 )) return IRC_WriteStrClient( Client, RPL_CHANNELMODEIS_MSG, Client_ID( Client ), Channel_Name( chan ), Channel_Modes( chan ));
mode_ptr = Req->argv[1];
/* Sollen Modes gesetzt oder geloescht werden? */
if( cl )
{
if( *mode_ptr == '+' ) set = TRUE;
else if( *mode_ptr == '-' ) set = FALSE;
else return IRC_WriteStrClient( Client, ERR_UMODEUNKNOWNFLAG_MSG, Client_ID( Client ));
mode_ptr++;
}
else
{
if( *mode_ptr == '-' ) set = FALSE;
else set = TRUE;
if(( *mode_ptr == '-' ) || ( *mode_ptr == '+' )) mode_ptr++;
}
/* Prefix fuer Antworten etc. ermitteln */
if( Client_Type( Client ) == CLIENT_SERVER )
{
prefix = Client_GetFromID( Req->prefix );
if( ! prefix ) return IRC_WriteStrClient( Client, ERR_NOSUCHNICK_MSG, Client_ID( Client ), Req->prefix );
}
else prefix = Client;
/* Reply-String mit Aenderungen vorbereiten */
if( set ) strcpy( the_modes, "+" );
else strcpy( the_modes, "-" );
ok = TRUE;
x[1] = '\0';
while( *mode_ptr )
{
x[0] = '\0';
if( Client_Type( Client ) == CLIENT_SERVER )
{
/* Befehl kommt von einem Server, daher
* trauen wir ihm "unbesehen" ... */
x[0] = *mode_ptr;
if(( cl ) && ( x[0] == 'a' ))
{
/* away */
if( set ) Client_SetAway( cl, "Away" );
else Client_SetAway( cl, NULL );
}
}
else
{
/* Modes validieren */
if( cl )
{
/* User-Modes */
switch( *mode_ptr )
{
case 'i':
/* invisible */
x[0] = 'i';
break;
case 'r':
/* restricted (kann nur gesetzt werden) */
if( set ) x[0] = 'r';
else ok = IRC_WriteStrClient( Client, ERR_RESTRICTED_MSG, Client_ID( Client ));
break;
case 'o':
/* operator (kann nur geloescht werden) */
if( ! set )
{
Client_SetOperByMe( Client, FALSE );
x[0] = 'o';
}
else ok = IRC_WriteStrClient( Client, ERR_UMODEUNKNOWNFLAG_MSG, Client_ID( Client ));
break;
default:
Log( LOG_DEBUG, "Unknown mode \"%c%c\" from \"%s\"!?", set ? '+' : '-', *mode_ptr, Client_ID( Client ));
ok = IRC_WriteStrClient( Client, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Client ), set ? '+' : '-', *mode_ptr );
x[0] = '\0';
}
}
if( chan )
{
/* Ist der User ein Channel Operator? */
if( ! strchr( Channel_UserModes( chan, Client ), 'o' ))
{
Log( LOG_DEBUG, "Can't change modes: \"%s\" is not operator on %s!", Client_ID( Client ), Channel_Name( chan ));
ok = IRC_WriteStrClient( Client, ERR_CHANOPRIVSNEEDED_MSG, Client_ID( Client ), Channel_Name( chan ));
break;
}
/* Channel-Modes oder Channel-User-Modes */
if( chan_cl )
{
/* Channel-User-Modes */
switch( *mode_ptr )
{
case 'o':
/* Channel Operator */
x[0] = 'o';
break;
case 'v':
/* Voice */
x[0] = 'v';
break;
default:
Log( LOG_DEBUG, "Unknown channel-user-mode \"%c%c\" from \"%s\" on \"%s\" at %s!?", set ? '+' : '-', *mode_ptr, Client_ID( Client ), Client_ID( chan_cl ), Channel_Name( chan ));
ok = IRC_WriteStrClient( Client, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Client ), set ? '+' : '-', *mode_ptr );
x[0] = '\0';
}
}
else
{
/* Channel-Modes */
switch( *mode_ptr )
{
case 'a':
/* Anonymous */
x[0] = 'a';
break;
case 'm':
/* Moderated */
x[0] = 'm';
break;
case 'n':
/* kein Schreiben in den Channel von aussen */
x[0] = 'n';
break;
case 'p':
/* Private */
x[0] = 'p';
break;
case 'q':
/* Quiet */
x[0] = 'q';
break;
case 's':
/* Secret */
x[0] = 's';
break;
case 't':
/* Topic Lock */
x[0] = 't';
break;
default:
Log( LOG_DEBUG, "Unknown channel-mode \"%c%c\" from \"%s\" at %s!?", set ? '+' : '-', *mode_ptr, Client_ID( Client ), Channel_Name( chan ));
ok = IRC_WriteStrClient( Client, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Client ), set ? '+' : '-', *mode_ptr );
x[0] = '\0';
}
}
}
}
if( ! ok ) break;
mode_ptr++;
if( ! x[0] ) continue;
/* Okay, gueltigen Mode gefunden */
if( cl )
{
/* Es geht um User-Modes */
if( set )
{
/* Mode setzen. Wenn der Client ihn noch nicht hatte: merken */
if( Client_ModeAdd( cl, x[0] )) strcat( the_modes, x );
}
else
{
/* Modes geloescht. Wenn der Client ihn hatte: merken */
if( Client_ModeDel( cl, x[0] )) strcat( the_modes, x );
}
}
if( chan )
{
/* Es geht um Channel-Modes oder Channel-User-Modes */
if( chan_cl )
{
/* Channel-User-Modes */
if( set )
{
/* Mode setzen. Wenn der Channel ihn noch nicht hatte: merken */
if( Channel_UserModeAdd( chan, chan_cl, x[0] )) strcat( the_modes, x );
}
else
{
/* Mode setzen. Wenn der Channel ihn noch nicht hatte: merken */
if( Channel_UserModeDel( chan, chan_cl, x[0] )) strcat( the_modes, x );
}
}
else
{
/* Channel-Mode */
if( set )
{
/* Mode setzen. Wenn der Channel ihn noch nicht hatte: merken */
if( Channel_ModeAdd( chan, x[0] )) strcat( the_modes, x );
}
else
{
/* Mode setzen. Wenn der Channel ihn noch nicht hatte: merken */
if( Channel_ModeDel( chan, x[0] )) strcat( the_modes, x );
}
}
}
}
/* Wurden Modes geaendert? */
if( the_modes[1] )
{
if( cl )
{
/* Client-Mode */
if( Client_Type( Client ) == CLIENT_SERVER )
{
/* Modes an andere Server forwarden */
IRC_WriteStrServersPrefix( Client, prefix, "MODE %s :%s", Client_ID( cl ), the_modes );
}
else
{
/* Bestaetigung an Client schicken & andere Server informieren */
ok = IRC_WriteStrClientPrefix( Client, prefix, "MODE %s %s", Client_ID( cl ), the_modes );
IRC_WriteStrServersPrefix( Client, prefix, "MODE %s :%s", Client_ID( cl ), the_modes );
}
Log( LOG_DEBUG, "User \"%s\": Mode change, now \"%s\".", Client_Mask( cl ), Client_Modes( cl ));
}
if( chan )
{
/* Channel-Modes oder Channel-User-Mode */
if( chan_cl )
{
/* Channel-User-Mode */
if( Client_Type( Client ) == CLIENT_SERVER )
{
/* Modes an andere Server und Channel-User forwarden */
IRC_WriteStrServersPrefix( Client, prefix, "MODE %s %s :%s", Channel_Name( chan ), the_modes, Client_ID( chan_cl));
IRC_WriteStrChannelPrefix( Client, chan, prefix, FALSE, "MODE %s %s %s", Channel_Name( chan ), the_modes, Client_ID( chan_cl));
}
else
{
/* Bestaetigung an Client schicken & andere Server sowie Channel-User informieren */
ok = IRC_WriteStrClientPrefix( Client, prefix, "MODE %s %s %s", Channel_Name( chan ), the_modes, Client_ID( chan_cl));
IRC_WriteStrServersPrefix( Client, prefix, "MODE %s %s :%s", Channel_Name( chan ), the_modes, Client_ID( chan_cl));
IRC_WriteStrChannelPrefix( Client, chan, prefix, FALSE, "MODE %s %s %s", Channel_Name( chan ), the_modes, Client_ID( chan_cl));
}
Log( LOG_DEBUG, "User \"%s\" on %s: Mode change, now \"%s\".", Client_Mask( chan_cl), Channel_Name( chan ), Channel_UserModes( chan, chan_cl ));
}
else
{
/* Channel-Mode */
if( Client_Type( Client ) == CLIENT_SERVER )
{
/* Modes an andere Server und Channel-User forwarden */
IRC_WriteStrServersPrefix( Client, prefix, "MODE %s :%s", Channel_Name( chan ), the_modes );
IRC_WriteStrChannelPrefix( Client, chan, prefix, FALSE, "MODE %s %s", Channel_Name( chan ), the_modes );
}
else
{
/* Bestaetigung an Client schicken & andere Server sowie Channel-User informieren */
ok = IRC_WriteStrClientPrefix( Client, prefix, "MODE %s %s", Channel_Name( chan ), the_modes );
IRC_WriteStrServersPrefix( Client, prefix, "MODE %s :%s", Channel_Name( chan ), the_modes );
IRC_WriteStrChannelPrefix( Client, chan, prefix, FALSE, "MODE %s %s", Channel_Name( chan ), the_modes );
}
Log( LOG_DEBUG, "Channel \"%s\": Mode change, now \"%s\".", Channel_Name( chan ), Channel_Modes( chan ));
}
}
}
return ok;
} /* IRC_MODE */
GLOBAL BOOLEAN IRC_AWAY( CLIENT *Client, REQUEST *Req )
{
assert( Client != NULL );
assert( Req != NULL );
if( Client_Type( Client ) != CLIENT_USER ) return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
/* Falsche Anzahl Parameter? */
if( Req->argc > 1 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
if(( Req->argc == 1 ) && (Req->argv[0][0] ))
{
/* AWAY setzen */
Client_SetAway( Client, Req->argv[0] );
IRC_WriteStrServersPrefix( Client, Client, "MODE %s :+a", Client_ID( Client ));
return IRC_WriteStrClient( Client, RPL_NOWAWAY_MSG, Client_ID( Client ));
}
else
{
/* AWAY loeschen */
Client_SetAway( Client, NULL );
IRC_WriteStrServersPrefix( Client, Client, "MODE %s :-a", Client_ID( Client ));
return IRC_WriteStrClient( Client, RPL_UNAWAY_MSG, Client_ID( Client ));
}
} /* IRC_AWAY */
/* -eof- */

37
src/ngircd/irc-mode.h Normal file
View File

@@ -0,0 +1,37 @@
/*
* 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: irc-mode.h,v 1.1 2002/02/27 23:26:21 alex Exp $
*
* irc-mode.h: IRC-Befehle zur Mode-Aenderung (MODE, AWAY, ...) (Header)
*
* $Log: irc-mode.h,v $
* Revision 1.1 2002/02/27 23:26:21 alex
* - Modul aus irc.c bzw. irc.h ausgegliedert.
*
*/
#ifndef __irc_mode_h__
#define __irc_mode_h__
#include "parse.h"
#include "client.h"
GLOBAL BOOLEAN IRC_MODE( CLIENT *Client, REQUEST *Req );
GLOBAL BOOLEAN IRC_AWAY( CLIENT *Client, REQUEST *Req );
#endif
/* -eof- */

275
src/ngircd/irc-write.c Normal file
View File

@@ -0,0 +1,275 @@
/*
* 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: irc-write.c,v 1.1 2002/02/27 23:26:21 alex Exp $
*
* irc-write.c: IRC-Texte und Befehle ueber Netzwerk versenden
*
* $Log: irc-write.c,v $
* Revision 1.1 2002/02/27 23:26:21 alex
* - Modul aus irc.c bzw. irc.h ausgegliedert.
*
*/
#include <portab.h>
#include "global.h"
#include <imp.h>
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <exp.h>
#include "irc-write.h"
CHAR *Get_Prefix( CLIENT *Target, CLIENT *Client );
GLOBAL BOOLEAN IRC_WriteStrClient( CLIENT *Client, CHAR *Format, ... )
{
CHAR buffer[1000];
BOOLEAN ok = CONNECTED;
va_list ap;
assert( Client != NULL );
assert( Format != NULL );
va_start( ap, Format );
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
/* an den Client selber */
ok = IRC_WriteStrClientPrefix( Client, Client_ThisServer( ), buffer );
return ok;
} /* IRC_WriteStrClient */
GLOBAL BOOLEAN IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, CHAR *Format, ... )
{
/* Text an Clients, lokal bzw. remote, senden. */
CHAR buffer[1000];
va_list ap;
assert( Client != NULL );
assert( Format != NULL );
assert( Prefix != NULL );
va_start( ap, Format );
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
return Conn_WriteStr( Client_Conn( Client_NextHop( Client )), ":%s %s", Get_Prefix( Client_NextHop( Client ), Prefix ), buffer );
} /* IRC_WriteStrClientPrefix */
GLOBAL BOOLEAN IRC_WriteStrChannel( CLIENT *Client, CHANNEL *Chan, BOOLEAN Remote, CHAR *Format, ... )
{
CHAR buffer[1000];
va_list ap;
assert( Client != NULL );
assert( Format != NULL );
va_start( ap, Format );
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
return IRC_WriteStrChannelPrefix( Client, Chan, Client_ThisServer( ), Remote, buffer );
} /* IRC_WriteStrChannel */
GLOBAL BOOLEAN IRC_WriteStrChannelPrefix( CLIENT *Client, CHANNEL *Chan, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... )
{
BOOLEAN sock[MAX_CONNECTIONS], is_server[MAX_CONNECTIONS], ok = CONNECTED;
CHAR buffer[1000];
CL2CHAN *cl2chan;
CLIENT *c;
INT s, i;
va_list ap;
assert( Client != NULL );
assert( Chan != NULL );
assert( Prefix != NULL );
assert( Format != NULL );
va_start( ap, Format );
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
for( i = 0; i < MAX_CONNECTIONS; i++ ) sock[i] = FALSE;
/* An alle Clients, die in den selben Channels sind.
* Dabei aber nur einmal je Remote-Server */
cl2chan = Channel_FirstMember( Chan );
while( cl2chan )
{
c = Channel_GetClient( cl2chan );
if( ! Remote )
{
if( Client_Conn( c ) <= NONE ) c = NULL;
else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
}
if( c ) c = Client_NextHop( c );
if( c && ( c != Client ))
{
/* Ok, anderer Client */
s = Client_Conn( c );
assert( s >= 0 );
assert( s < MAX_CONNECTIONS );
sock[s] = TRUE;
if( Client_Type( c ) == CLIENT_SERVER ) is_server[s] = TRUE;
else is_server[s] = FALSE;
}
cl2chan = Channel_NextMember( Chan, cl2chan );
}
/* Senden ... */
for( i = 0; i < MAX_CONNECTIONS; i++ )
{
if( sock[i] )
{
if( is_server[i] ) ok = Conn_WriteStr( i, ":%s %s", Client_ID( Prefix ), buffer );
else ok = Conn_WriteStr( i, ":%s %s", Client_Mask( Prefix ), buffer );
if( ! ok ) break;
}
}
return ok;
} /* IRC_WriteStrChannelPrefix */
GLOBAL VOID IRC_WriteStrServers( CLIENT *ExceptOf, CHAR *Format, ... )
{
CHAR buffer[1000];
va_list ap;
assert( Format != NULL );
va_start( ap, Format );
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
/* an den Client selber */
return IRC_WriteStrServersPrefix( ExceptOf, Client_ThisServer( ), buffer );
} /* IRC_WriteStrServers */
GLOBAL VOID IRC_WriteStrServersPrefix( CLIENT *ExceptOf, CLIENT *Prefix, CHAR *Format, ... )
{
CHAR buffer[1000];
CLIENT *c;
va_list ap;
assert( Format != NULL );
assert( Prefix != NULL );
va_start( ap, Format );
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
c = Client_First( );
while( c )
{
if(( Client_Type( c ) == CLIENT_SERVER ) && ( Client_Conn( c ) > NONE ) && ( c != Client_ThisServer( )) && ( c != ExceptOf ))
{
/* Ziel-Server gefunden */
IRC_WriteStrClientPrefix( c, Prefix, buffer );
}
c = Client_Next( c );
}
} /* IRC_WriteStrServersPrefix */
GLOBAL BOOLEAN IRC_WriteStrRelatedPrefix( CLIENT *Client, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... )
{
BOOLEAN sock[MAX_CONNECTIONS], is_server[MAX_CONNECTIONS], ok = CONNECTED;
CL2CHAN *chan_cl2chan, *cl2chan;
CHAR buffer[1000];
CHANNEL *chan;
va_list ap;
CLIENT *c;
INT i, s;
assert( Client != NULL );
assert( Prefix != NULL );
assert( Format != NULL );
va_start( ap, Format );
vsnprintf( buffer, 1000, Format, ap );
va_end( ap );
/* initialisieren */
for( i = 0; i < MAX_CONNECTIONS; i++ ) sock[i] = FALSE;
/* An alle Clients, die in einem Channel mit dem "Ausloeser" sind,
* den Text schicken. An Remote-Server aber jeweils nur einmal. */
chan_cl2chan = Channel_FirstChannelOf( Client );
while( chan_cl2chan )
{
/* Channel des Users durchsuchen */
chan = Channel_GetChannel( chan_cl2chan );
cl2chan = Channel_FirstMember( chan );
while( cl2chan )
{
c = Channel_GetClient( cl2chan );
if( ! Remote )
{
if( Client_Conn( c ) <= NONE ) c = NULL;
else if( Client_Type( c ) == CLIENT_SERVER ) c = NULL;
}
if( c ) c = Client_NextHop( c );
if( c && ( c != Client ))
{
/* Ok, anderer Client */
s = Client_Conn( c );
assert( s >= 0 );
assert( s < MAX_CONNECTIONS );
sock[s] = TRUE;
if( Client_Type( c ) == CLIENT_SERVER ) is_server[s] = TRUE;
else is_server[s] = FALSE;
}
cl2chan = Channel_NextMember( chan, cl2chan );
}
/* naechsten Channel */
chan_cl2chan = Channel_NextChannelOf( Client, chan_cl2chan );
}
/* Senden ... */
for( i = 0; i < MAX_CONNECTIONS; i++ )
{
if( sock[i] )
{
if( is_server[i] ) ok = Conn_WriteStr( i, ":%s %s", Client_ID( Prefix ), buffer );
else ok = Conn_WriteStr( i, ":%s %s", Client_Mask( Prefix ), buffer );
if( ! ok ) break;
}
}
return ok;
} /* IRC_WriteStrRelatedPrefix */
CHAR *Get_Prefix( CLIENT *Target, CLIENT *Client )
{
assert( Target != NULL );
assert( Client != NULL );
if( Client_Type( Target ) == CLIENT_SERVER ) return Client_ID( Client );
else return Client_Mask( Client );
} /* Get_Prefix */
/* -eof- */

44
src/ngircd/irc-write.h Normal file
View File

@@ -0,0 +1,44 @@
/*
* 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: irc-write.h,v 1.1 2002/02/27 23:26:21 alex Exp $
*
* irc-write.h: IRC-Texte und Befehle ueber Netzwerk versenden (Header)
*
* $Log: irc-write.h,v $
* Revision 1.1 2002/02/27 23:26:21 alex
* - Modul aus irc.c bzw. irc.h ausgegliedert.
*
*/
#ifndef __irc_write_h__
#define __irc_write_h__
#include "channel.h"
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_WriteStrRelatedPrefix( CLIENT *Client, CLIENT *Prefix, BOOLEAN Remote, CHAR *Format, ... );
#endif
/* -eof- */

File diff suppressed because it is too large Load Diff

View File

@@ -9,62 +9,25 @@
* 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.16 2002/01/05 19:15:03 alex Exp $
* $Id: irc.h,v 1.27 2002/02/27 23:26:36 alex Exp $
*
* irc.h: IRC-Befehle (Header)
*
* $Log: irc.h,v $
* Revision 1.16 2002/01/05 19:15:03 alex
* - Fehlerpruefung bei select() in der "Hauptschleife" korrigiert.
* Revision 1.27 2002/02/27 23:26:36 alex
* - einige Funktionen in irc-xxx-Module ausgegliedert.
*
* Revision 1.15 2002/01/04 17:58:21 alex
* - IRC_WriteStrXXX()-Funktionen angepasst; neuer Befehl SQUIT.
* Revision 1.26 2002/02/27 20:33:13 alex
* - Channel-Topics implementiert.
*
* Revision 1.14 2002/01/03 02:26:07 alex
* - neue Befehle SERVER und NJOIN begonnen.
* Revision 1.25 2002/02/27 18:23:46 alex
* - IRC-Befehl "AWAY" implementert.
*
* Revision 1.13 2002/01/02 02:51:39 alex
* - Copyright-Texte angepasst.
* - neuer Befehl "ERROR".
* Revision 1.24 2002/02/23 21:39:48 alex
* - IRC-Befehl KILL sowie Kills bei Nick Collsisions implementiert.
*
* Revision 1.11 2001/12/31 15:33:13 alex
* - neuer Befehl NAMES, kleinere Bugfixes.
* - Bug bei PING behoben: war zu restriktiv implementiert :-)
*
* Revision 1.10 2001/12/31 02:18:51 alex
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
* - neuen Header "defines.h" mit (fast) allen Konstanten.
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
*
* Revision 1.9 2001/12/29 03:09:31 alex
* - Neue Funktion IRC_MODE() implementiert.
*
* Revision 1.8 2001/12/27 19:17:26 alex
* - neue Befehle PRIVMSG, NOTICE, PING.
*
* Revision 1.7 2001/12/27 16:55:41 alex
* - neu: IRC_WriteStrRelated(), Aenderungen auch in IRC_WriteStrClient().
*
* Revision 1.6 2001/12/26 14:45:37 alex
* - "Code Cleanups".
*
* Revision 1.5 2001/12/26 03:21:46 alex
* - PING/PONG-Befehle implementiert,
* - Meldungen ueberarbeitet: enthalten nun (fast) immer den Nick.
*
* Revision 1.4 2001/12/25 22:02:42 alex
* - neuer IRC-Befehl "/QUIT". Verbessertes Logging & Debug-Ausgaben.
*
* Revision 1.3 2001/12/25 19:19:30 alex
* - bessere Fehler-Abfragen, diverse Bugfixes.
* - Nicks werden nur einmal vergeben :-)
* - /MOTD wird unterstuetzt.
*
* Revision 1.2 2001/12/23 21:57:16 alex
* - erste IRC-Befehle zu implementieren begonnen.
*
* Revision 1.1 2001/12/14 08:13:43 alex
* - neues Modul begonnen :-)
* Revision 1.23 2002/02/17 23:38:58 alex
* - neuer IRC-Befehl VERSION implementiert: IRC_VERSION().
*/
@@ -72,34 +35,18 @@
#define __irc_h__
#include "parse.h"
#include "client.h"
#include "channel.h"
GLOBAL VOID IRC_Init( VOID );
GLOBAL VOID IRC_Exit( VOID );
GLOBAL BOOLEAN IRC_WriteStrClient( CLIENT *Client, CHAR *Format, ... );
GLOBAL BOOLEAN IRC_WriteStrClientPrefix( CLIENT *Client, CLIENT *Prefix, CHAR *Format, ... );
GLOBAL BOOLEAN IRC_WriteStrRelated( CLIENT *Client, 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_VERSION( CLIENT *Client, REQUEST *Req );
GLOBAL BOOLEAN IRC_PRIVMSG( CLIENT *Client, REQUEST *Req );
GLOBAL BOOLEAN IRC_NOTICE( CLIENT *Client, REQUEST *Req );
GLOBAL BOOLEAN IRC_MODE( CLIENT *Client, REQUEST *Req );
GLOBAL BOOLEAN IRC_NAMES( CLIENT *Client, REQUEST *Req );
GLOBAL BOOLEAN IRC_ISON( CLIENT *Client, REQUEST *Req );
GLOBAL BOOLEAN IRC_WHOIS( CLIENT *Client, REQUEST *Req );
@@ -110,6 +57,15 @@ 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_KILL( CLIENT *Client, REQUEST *Req );
GLOBAL BOOLEAN IRC_JOIN( CLIENT *Client, REQUEST *Req );
GLOBAL BOOLEAN IRC_PART( CLIENT *Client, REQUEST *Req );
GLOBAL BOOLEAN IRC_TOPIC( CLIENT *Client, REQUEST *Req );
GLOBAL BOOLEAN IRC_Send_NAMES( CLIENT *Client, CHANNEL *Chan );
GLOBAL BOOLEAN IRC_Send_LUSERS( CLIENT *Client );
GLOBAL BOOLEAN IRC_Show_MOTD( CLIENT *Client );
#endif

View File

@@ -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: log.c,v 1.16 2002/01/05 15:54:40 alex Exp $
* $Id: log.c,v 1.18 2002/02/19 20:07:13 alex Exp $
*
* log.c: Logging-Funktionen
*
* $Log: log.c,v $
* Revision 1.18 2002/02/19 20:07:13 alex
* - direkt nach dem Start werden die aktiven "Modes" ins Log geschrieben.
*
* 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.
*
@@ -82,48 +88,62 @@
#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
CHAR txt[127];
#ifdef USE_SYSLOG
/* Syslog initialisieren */
openlog( PACKAGE, LOG_CONS|LOG_PID, LOG_LOCAL5 );
#endif
Log( LOG_NOTICE, PACKAGE" version "VERSION"%s-"P_OSNAME"/"P_ARCHNAME" started.", txt );
/* Hello World! */
Log( LOG_NOTICE, "%s started.", NGIRCd_Version( ));
/* Informationen uebern den "Operation Mode" */
strcpy( txt, "" );
#ifdef DEBUG
if( NGIRCd_Debug )
{
if( txt[0] ) strcat( txt, ", " );
strcat( txt, "debug-mode" );
}
#endif
if( NGIRCd_NoDaemon )
{
if( txt[0] ) strcat( txt, ", " );
strcat( txt, "no-daemon-mode" );
}
if( NGIRCd_Passive )
{
if( txt[0] ) strcat( txt, ", " );
strcat( txt, "passive-mode" );
}
#ifdef SNIFFER
if( NGIRCd_Sniffer )
{
if( txt[0] ) strcat( txt, ", " );
strcat( txt, "network sniffer" );
}
#endif
if( txt[0] ) Log( LOG_INFO, "Activating: %s.", txt );
} /* Log_Init */
GLOBAL VOID Log_Exit( VOID )
{
/* Good Bye! */
Log( LOG_NOTICE, PACKAGE" done.");
#ifdef USE_SYSLOG
/* syslog abmelden */
closelog( );
#endif
} /* Log_Exit */
@@ -138,7 +158,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
@@ -148,7 +170,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
@@ -186,7 +208,9 @@ GLOBAL VOID Log_Resolver( 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

View File

@@ -9,11 +9,59 @@
* 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.17 2002/01/05 23:23:44 alex Exp $
* $Id: messages.h,v 1.33 2002/02/27 20:33:01 alex Exp $
*
* irc.h: IRC-Befehle (Header)
*
* $Log: messages.h,v $
* Revision 1.33 2002/02/27 20:33:01 alex
* - neue Text-Konstante: ERR_NOTONCHANNEL_MSG
*
* Revision 1.32 2002/02/27 18:23:24 alex
* - neue Text-Konstanten RPL_UNAWAY_MSG und RPL_NOWAWAY_MSG.
*
* Revision 1.31 2002/02/27 17:05:13 alex
* - neue Text-Konstante ERR_CANNOTSENDTOCHAN_MSG eingefuehrt.
*
* Revision 1.30 2002/02/17 23:39:24 alex
* - Konstanten sortiert, neue Konstante RPL_VERSION und RPL_VERSION_MSG.
*
* Revision 1.29 2002/02/17 17:42:53 alex
* - neue Text-Konstante ERR_UMODEUNKNOWNFLAG2_MSG.
*
* 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.
*
@@ -87,19 +135,44 @@
#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_MOTDSTART "375"
#define RPL_MOTDSTART_MSG RPL_MOTDSTART" %s :- %s message of the day"
#define RPL_UMODEIS "211"
#define RPL_UMODEIS_MSG RPL_UMODEIS" %s +%s"
#define RPL_LUSERCLIENT "251"
#define RPL_LUSERCLIENT_MSG RPL_LUSERCLIENT" %s :There are %d users and %d services on %d servers"
#define RPL_LUSEROP "252"
#define RPL_LUSEROP_MSG RPL_LUSEROP" %s %d :operator(s) online"
#define RPL_LUSERUNKNOWN "253"
#define RPL_LUSERUNKNOWN_MSG RPL_LUSERUNKNOWN" %s %d :unknown connection(s)"
#define RPL_LUSERCHANNELS "254"
#define RPL_LUSERCHANNELS_MSG RPL_LUSERCHANNELS" %s %d :channels formed"
#define RPL_LUSERME "255"
#define RPL_LUSERME_MSG RPL_LUSERME" %s :I have %d users, %d services and %d servers"
#define RPL_UNAWAY "305"
#define RPL_UNAWAY_MSG RPL_UNAWAY" %s :You are no longer marked as being away"
#define RPL_NOWAWAY "306"
#define RPL_NOWAWAY_MSG RPL_NOWAWAY" %s :You have been marked as being away"
#define RPL_MOTD "372"
#define RPL_MOTD_MSG RPL_MOTD" %s :- %s"
#define RPL_MOTDSTART "375"
#define RPL_MOTDSTART_MSG RPL_MOTDSTART" %s :- %s message of the day"
#define RPL_ENDOFMOTD "376"
#define RPL_ENDOFMOTD_MSG RPL_ENDOFMOTD" %s :End of MOTD command"
#define RPL_UMODEIS "211"
#define RPL_UMODEIS_MSG RPL_UMODEIS" %s +%s"
#define RPL_AWAY "301"
#define RPL_AWAY_MSG RPL_AWAY" %s %s :%s"
#define RPL_USERHOST "302"
#define RPL_USERHOST_MSG RPL_USERHOST" %s :"
@@ -123,10 +196,28 @@
#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_VERSION "351"
#define RPL_VERSION_MSG RPL_VERSION" %s "PACKAGE"-"VERSION".%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"
@@ -141,6 +232,12 @@
#define ERR_NOSUCHSERVER "402"
#define ERR_NOSUCHSERVER_MSG ERR_NOSUCHSERVER" %s %s :No such server"
#define ERR_NOSUCHCHANNEL "403"
#define ERR_NOSUCHCHANNEL_MSG ERR_NOSUCHCHANNEL" %s %s :No such channel"
#define ERR_CANNOTSENDTOCHAN "404"
#define ERR_CANNOTSENDTOCHAN_MSG ERR_CANNOTSENDTOCHAN" %s %s :Cannot send to channel"
#define ERR_NOORIGIN "409"
#define ERR_NOORIGIN_MSG ERR_NOORIGIN" %s :No origin specified"
@@ -162,6 +259,13 @@
#define ERR_NICKNAMEINUSE "433"
#define ERR_NICKNAMEINUSE_MSG ERR_NICKNAMEINUSE" %s %s :Nickname already in use"
#define ERR_NOTONCHANNEL "442"
#define ERR_NOTONCHANNEL_MSG ERR_NOTONCHANNEL" %s %s :You are not on that channel"
#define ERR_NOTREGISTERED "451"
#define ERR_NOTREGISTERED_MSG ERR_NOTREGISTERED" %s :Connection not registered"
#define ERR_NOTREGISTEREDSERVER_MSG ERR_NOTREGISTERED" %s :Connection not registered as server link"
#define ERR_NEEDMOREPARAMS "461"
#define ERR_NEEDMOREPARAMS_MSG ERR_NEEDMOREPARAMS" %s %s :Syntax error"
@@ -171,21 +275,22 @@
#define ERR_PASSWDMISMATCH "464"
#define ERR_PASSWDMISMATCH_MSG ERR_PASSWDMISMATCH" %s: Invalid password"
#define ERR_NOTREGISTERED "451"
#define ERR_NOTREGISTERED_MSG ERR_NOTREGISTERED" %s :Connection not registered"
#define ERR_NOTREGISTEREDSERVER_MSG ERR_NOTREGISTERED" %s :Connection not registered as server link"
#define ERR_NOPRIVILEGES "481"
#define ERR_NOPRIVILEGES_MSG ERR_NOPRIVILEGES" %s :Permission denied"
#define ERR_CHANOPRIVSNEEDED "482"
#define ERR_CHANOPRIVSNEEDED_MSG ERR_CHANOPRIVSNEEDED" %s %s :You are not channel operator"
#define ERR_RESTRICTED "484"
#define ERR_RESTRICTED_MSG ERR_RESTRICTED" %s :Your connection is restricted"
#define ERR_NOOPERHOST "491"
#define ERR_NOOPERHOST_MSG ERR_NOOPERHOST" %s :Not configured for your host"
#define ERR_UMODEUNKNOWNFLAG "501"
#define ERR_UMODEUNKNOWNFLAG_MSG ERR_UMODEUNKNOWNFLAG" %s :Unknown mode flag"
#define ERR_UMODEUNKNOWNFLAG_MSG ERR_UMODEUNKNOWNFLAG" %s :Unknown mode"
#define ERR_UMODEUNKNOWNFLAG2_MSG ERR_UMODEUNKNOWNFLAG" %s :Unknown mode \"%c%c\""
#define ERR_USERSDONTMATCH "502"
#define ERR_USERSDONTMATCH_MSG ERR_USERSDONTMATCH" %s :Can't set/get mode for other users"

View File

@@ -9,11 +9,45 @@
* 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.17 2002/01/02 02:51:16 alex Exp $
* $Id: ngircd.c,v 1.28 2002/02/27 23:24:29 alex Exp $
*
* ngircd.c: Hier beginnt alles ;-)
*
* $Log: ngircd.c,v $
* Revision 1.28 2002/02/27 23:24:29 alex
* - ueberfluessige Init- und Exit-Funktionen entfernt.
*
* Revision 1.27 2002/02/25 11:42:47 alex
* - wenn ein System sigaction() nicht kennt, so wird nun signal() verwendet.
*
* Revision 1.26 2002/02/23 19:06:47 alex
* - fuer SIGCHLD wird nun auch SA_NOCLDWAIT gesetzt, wenn vorhanden.
*
* Revision 1.25 2002/02/19 20:30:47 alex
* - SA_RESTART wird fuer Signale nur noch gesetzt, wenn es definiert ist.
*
* Revision 1.24 2002/02/19 20:08:24 alex
* - "Passive-Mode" implementiert: kein Auto-Conect zu anderen Servern.
* - NGIRCd_DebugLevel wird (fuer VERSION-Befehl) ermittelt.
*
* Revision 1.23 2002/02/17 23:40:21 alex
* - neue Funktion NGIRCd_VersionAddition(). NGIRCd_Version() aufgespaltet.
*
* 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.
*
@@ -80,8 +114,11 @@
#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>
@@ -103,14 +140,156 @@ 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;
NGIRCd_Passive = 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 */
#ifdef DEBUG
if( strcmp( argv[i], "--debug" ) == 0 )
{
NGIRCd_Debug = TRUE;
ok = TRUE;
}
#endif
if( strcmp( argv[i], "--help" ) == 0 )
{
Show_Version( ); puts( "" );
Show_Help( ); puts( "" );
exit( 1 );
}
if( strcmp( argv[i], "--nodaemon" ) == 0 )
{
NGIRCd_NoDaemon = TRUE;
ok = TRUE;
}
if( strcmp( argv[i], "--passive" ) == 0 )
{
NGIRCd_Passive = TRUE;
ok = TRUE;
}
#ifdef SNIFFER
if( strcmp( argv[i], "--sniffer" ) == 0 )
{
NGIRCd_Sniffer = TRUE;
ok = TRUE;
}
#endif
if( strcmp( argv[i], "--version" ) == 0 )
{
Show_Version( );
exit( 1 );
}
}
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
if( argv[i][n] == 'n' )
{
NGIRCd_NoDaemon = TRUE;
ok = TRUE;
}
if( argv[i][n] == 'p' )
{
NGIRCd_Passive = TRUE;
ok = TRUE;
}
#ifdef SNIFFER
if( argv[i][n] == 's' )
{
NGIRCd_Sniffer = TRUE;
ok = TRUE;
}
#endif
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 );
}
}
/* Debug-Level (fuer IRC-Befehl "VERSION") ermitteln */
strcpy( NGIRCd_DebugLevel, "" );
#ifdef DEBUG
if( NGIRCd_Debug ) strcpy( NGIRCd_DebugLevel, "1" );
#endif
#ifdef SNIFFER
if( NGIRCd_Sniffer ) strcpy( NGIRCd_DebugLevel, "2" );
#endif
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 ));
@@ -120,8 +299,6 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
/* Module initialisieren */
Log_Init( );
Conf_Init( );
Parse_Init( );
IRC_Init( );
Channel_Init( );
Client_Init( );
Conn_Init( );
@@ -143,8 +320,6 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
Conn_Exit( );
Client_Exit( );
Channel_Exit( );
IRC_Exit( );
Parse_Exit( );
Conf_Exit( );
Log_Exit( );
}
@@ -152,26 +327,88 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
} /* main */
GLOBAL CHAR *NGIRCd_Version( VOID )
{
STATIC CHAR version[126];
sprintf( version, PACKAGE" version "VERSION"-%s", NGIRCd_VersionAddition( ));
return version;
} /* NGIRCd_Version */
GLOBAL CHAR *NGIRCd_VersionAddition( VOID )
{
STATIC CHAR txt[64];
strcpy( txt, "" );
#ifdef USE_SYSLOG
if( txt[0] ) strcat( txt, "+" );
strcat( txt, "SYSLOG" );
#endif
#ifdef STRICT_RFC
if( txt[0] ) strcat( txt, "+" );
strcat( txt, "RFC" );
#endif
#ifdef DEBUG
if( txt[0] ) strcat( txt, "+" );
strcat( txt, "DEBUG" );
#endif
#ifdef SNIFFER
if( txt[0] ) strcat( txt, "+" );
strcat( txt, "SNIFFER" );
#endif
if( txt[0] ) strcat( txt, "-" );
strcat( txt, P_OSNAME"/"P_ARCHNAME );
return txt;
} /* NGIRCd_VersionAddition */
LOCAL VOID Initialize_Signal_Handler( VOID )
{
/* Signal-Handler initialisieren: einige Signale
* werden ignoriert, andere speziell behandelt. */
#ifdef HAVE_SIGACTION
/* sigaction() ist vorhanden */
struct sigaction saction;
/* Signal-Struktur initialisieren */
memset( &saction, 0, sizeof( saction ));
saction.sa_handler = Signal_Handler;
#ifdef SA_RESTART
saction.sa_flags |= SA_RESTART;
#endif
#ifdef SA_NOCLDWAIT
saction.sa_flags |= SA_NOCLDWAIT;
#endif
/* Signal-Handler einhaengen */
saction.sa_handler = Signal_Handler;
sigaction( SIGINT, &saction, NULL );
sigaction( SIGQUIT, &saction, NULL );
sigaction( SIGTERM, &saction, NULL);
sigaction( SIGHUP, &saction, NULL);
sigaction( SIGCHLD, &saction, NULL);
/* einige Signale ignorieren */
saction.sa_handler = SIG_IGN;
sigaction( SIGPIPE, &saction, NULL );
#else
/* kein sigaction() vorhanden */
/* Signal-Handler einhaengen */
signal( SIGINT, Signal_Handler );
signal( SIGQUIT, Signal_Handler );
signal( SIGTERM, Signal_Handler );
signal( SIGHUP, Signal_Handler );
signal( SIGCHLD, Signal_Handler );
/* einige Signale ignorieren */
signal( SIGPIPE, SIG_IGN );
#endif
} /* Initialize_Signal_Handler */
@@ -187,9 +424,16 @@ LOCAL VOID Signal_Handler( INT Signal )
case SIGINT:
case SIGQUIT:
/* wir soll(t)en uns wohl beenden ... */
Log( LOG_WARNING, "Got signal %d, terminating now ...", Signal );
if( Signal == SIGTERM ) Log( LOG_WARNING, "Got TERM signal, terminating now ..." );
else if( Signal == SIGINT ) Log( LOG_WARNING, "Got INT signal, terminating now ..." );
else if( Signal == SIGQUIT ) Log( LOG_WARNING, "Got QUIT signal, terminating now ..." );
NGIRCd_Quit = TRUE;
break;
case SIGHUP:
/* neu starten */
Log( LOG_WARNING, "Got HUP signal, restarting now ..." );
NGIRCd_Restart = TRUE;
break;
case SIGCHLD:
/* Child-Prozess wurde beendet. Zombies vermeiden: */
while( waitpid( -1, NULL, WNOHANG ) > 0);
@@ -223,4 +467,29 @@ 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" );
puts( " -p, --passive disable automatic connections to other servers" );
#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

@@ -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: ngircd.h,v 1.6 2002/01/02 02:44:37 alex Exp $
* $Id: ngircd.h,v 1.10 2002/02/19 20:07:48 alex Exp $
*
* ngircd.h: Prototypen aus dem "Haupt-Modul"
*
* $Log: ngircd.h,v $
* Revision 1.10 2002/02/19 20:07:48 alex
* - Neue Variablen NGIRCd_DebugVersion und NGIRCd_Passive.
*
* Revision 1.9 2002/02/17 23:40:32 alex
* - Neue Funktion NGIRCd_VersionAddition().
*
* 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.
*
@@ -45,9 +57,26 @@
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_Passive; /* nicht zu anderen Servern connecten */
GLOBAL BOOLEAN NGIRCd_Quit; /* TRUE: ngIRCd beenden */
GLOBAL BOOLEAN NGIRCd_Restart; /* TRUE: neu starten */
GLOBAL CHAR NGIRCd_DebugLevel[2]; /* Debug-Level fuer IRC_VERSION() */
GLOBAL CHAR *NGIRCd_Version( VOID );
GLOBAL CHAR *NGIRCd_VersionAddition( VOID );
#endif

View File

@@ -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: parse.c,v 1.16 2002/01/05 23:23:20 alex Exp $
* $Id: parse.c,v 1.28 2002/02/27 23:25:31 alex Exp $
*
* parse.c: Parsen der Client-Anfragen
*
* $Log: parse.c,v $
* Revision 1.28 2002/02/27 23:25:31 alex
* - Anpassungen an Aufteilung von irc.d, Init- und Exit-Funktionen entfernt.
*
* Revision 1.27 2002/02/27 20:33:13 alex
* - Channel-Topics implementiert.
*
* Revision 1.26 2002/02/27 18:23:46 alex
* - IRC-Befehl "AWAY" implementert.
*
* Revision 1.25 2002/02/26 20:52:15 alex
* - Fehler bei Fehlermeldung wg. unbekanntem Prefix behoben.
*
* Revision 1.24 2002/02/23 21:39:48 alex
* - IRC-Befehl KILL sowie Kills bei Nick Collsisions implementiert.
*
* Revision 1.23 2002/02/17 23:38:58 alex
* - neuer IRC-Befehl VERSION implementiert: IRC_VERSION().
*
* 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.
*
@@ -82,9 +118,13 @@
#include <stdio.h>
#include <string.h>
#include "ngircd.h"
#include "client.h"
#include "conn.h"
#include "irc.h"
#include "irc-login.h"
#include "irc-mode.h"
#include "irc-write.h"
#include "log.h"
#include "messages.h"
#include "tool.h"
@@ -104,16 +144,6 @@ LOCAL BOOLEAN Validate_Args( REQUEST *Req );
LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *Req );
GLOBAL VOID Parse_Init( VOID )
{
} /* Parse_Init */
GLOBAL VOID Parse_Exit( VOID )
{
} /* Parse_Exit */
GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
{
/* Client-Request parsen. Bei einem schwerwiegenden Fehler wird
@@ -127,7 +157,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 );
@@ -143,6 +173,11 @@ GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request )
ptr = strchr( Request, ' ' );
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;
@@ -151,7 +186,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" );
@@ -173,7 +216,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++;
@@ -266,12 +317,30 @@ LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *Req )
/* Zielserver ermitteln */
if(( Client_Type( client ) == CLIENT_SERVER ) && ( Req->argc > 0 )) target = Client_GetFromID( Req->argv[0] );
else target = NULL;
if( ! target ) return TRUE;
if( ! target )
{
if( Req->argc > 0 ) Log( LOG_WARNING, "Unknown target for status code: \"%s\"", Req->argv[0] );
else Log( LOG_WARNING, "Unknown target for status code!" );
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] ) return TRUE;
if( ! Req->prefix[0] )
{
Log( LOG_WARNING, "Got status code without prefix!?" );
return TRUE;
}
else prefix = Client_GetFromID( Req->prefix );
if( ! prefix ) return TRUE;
if( ! prefix )
{
Log( LOG_WARNING, "Got status code from unknown source: \"%s\"", Req->prefix );
return TRUE;
}
/* Statuscode weiterleiten */
strcpy( str, Req->command );
@@ -305,9 +374,17 @@ LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *Req )
else if( strcasecmp( Req->command, "DIE" ) == 0 ) return IRC_DIE( client, Req );
else if( strcasecmp( Req->command, "RESTART" ) == 0 ) return IRC_RESTART( client, Req );
else if( strcasecmp( Req->command, "ERROR" ) == 0 ) return IRC_ERROR( client, Req );
else if( strcasecmp( Req->command, "LUSERS" ) == 0 ) return IRC_LUSERS( client, Req );
else if( strcasecmp( Req->command, "LINKS" ) == 0 ) return IRC_LINKS( client, Req );
else if( strcasecmp( Req->command, "JOIN" ) == 0 ) return IRC_JOIN( client, Req );
else if( strcasecmp( Req->command, "PART" ) == 0 ) return IRC_PART( client, Req );
else if( strcasecmp( Req->command, "VERSION" ) == 0 ) return IRC_VERSION( client, Req );
else if( strcasecmp( Req->command, "KILL" ) == 0 ) return IRC_KILL( client, Req );
else if( strcasecmp( Req->command, "AWAY" ) == 0 ) return IRC_AWAY( client, Req );
else if( strcasecmp( Req->command, "TOPIC" ) == 0 ) return IRC_TOPIC( client, Req );
/* Unbekannter Befehl */
if( Client_Type( client ) != CLIENT_SERVER ) IRC_WriteStrClient( client, Client_ThisServer( ), ERR_UNKNOWNCOMMAND_MSG, Client_ID( client ), Req->command );
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;

View File

@@ -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.4 2002/01/02 02:43:50 alex Exp $
* $Id: parse.h,v 1.5 2002/02/27 23:24:29 alex Exp $
*
* parse.h: Parsen der Client-Anfragen (Header)
*
* $Log: parse.h,v $
* Revision 1.5 2002/02/27 23:24:29 alex
* - ueberfluessige Init- und Exit-Funktionen entfernt.
*
* Revision 1.4 2002/01/02 02:43:50 alex
* - Copyright-Text ergaenzt bzw. aktualisiert.
*
@@ -45,9 +48,6 @@ typedef struct _REQUEST /* vgl. RFC 2812, 2.3 */
} REQUEST;
GLOBAL VOID Parse_Init( VOID );
GLOBAL VOID Parse_Exit( VOID );
GLOBAL BOOLEAN Parse_Request( CONN_ID Idx, CHAR *Request );