1
0
mirror of https://github.com/osmarks/ngircd.git synced 2025-12-27 15:59:05 +00:00

Compare commits

..

89 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
34 changed files with 2734 additions and 1694 deletions

View File

@@ -10,7 +10,43 @@
-- ChangeLog / Aenderungen --
ngIRCd 0.2.x, xx.02.2002
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
@@ -103,4 +139,4 @@ ngIRCd 0.0.1, 31.12.2001
--
$Id: ChangeLog,v 1.20 2002/02/17 19:08:19 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,

15
NEWS
View File

@@ -10,6 +10,19 @@
-- 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
@@ -52,4 +65,4 @@ ngIRCd 0.0.1, 31.12.2001
--
$Id: NEWS,v 1.10 2002/02/15 14:35:55 alex Exp $
$Id: NEWS,v 1.16 2002/03/02 01:36:35 alex Exp $

View File

@@ -9,9 +9,25 @@
# 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.27 2002/02/17 21:50:38 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.
#
@@ -99,11 +115,9 @@
AC_INIT
AC_CONFIG_SRCDIR(src/ngircd/ngircd.c)
AM_INIT_AUTOMAKE(ngircd,0.2.1)
AM_INIT_AUTOMAKE(ngircd,0.3.0)
AM_CONFIG_HEADER(src/config.h)
# -- Variablen --
# -- C Compiler --
AC_PROG_CC
@@ -170,32 +184,44 @@ AC_TRY_COMPILE([
AC_MSG_RESULT(no)
])
# -- Libraries --
AC_CHECK_LIB(UTIL,memmove)
# -- Funktionen --
AC_FUNC_MALLOC
AC_CHECK_FUNCS([ \
gethostbyaddr gethostbyname gethostname inet_ntoa memmove memset \
select socket strcasecmp strchr strerror strftime 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_LIB(be,syslog)
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

@@ -42,5 +42,20 @@ A: Auf dem System ist eine zu alte Version von GNU autoconf installiert.
mit dem Befehl "rpm -e autoconf").
III. Bugs!?
~~~~~~~~~~~
Q: Gibt es eine Liste der bekannten Bugs bzw. Feature-Wuensche?
A: Ja. Es existiert ein Bug-Tracking-System fuer den ngIRCd (Bugzilla):
URL: <http://arthur.ath.cx/bugzilla/ngircd/>. Dort koennen Bugs ge-
meldet und Feature-Wunsche kundgetan werden. Bekannte Bugs koennen in
der Datenbank gesucht und aufgelistet werden.
Einen Account zum Suchen und Melden von Bugs bzw. Feature-Wuenschen
kannst du dir dort selber anlegen.
Q: Was mache ich, wenn ich einen Bug gefunden habe?
A: Am besten traegst du ihn in das Bug-Tracking-System des ngIRCd ein:
URL: <http://arthur.ath.cx/bugzilla/ngircd/>
--
$Id: FAQ.txt,v 1.1 2002/01/23 14:05:20 alex Exp $
$Id: FAQ.txt,v 1.2 2002/02/19 20:05:02 alex Exp $

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

@@ -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,23 @@
* 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.13 2002/02/11 01:00:12 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().
@@ -73,7 +85,7 @@
#include <string.h>
#include "client.h"
#include "irc.h"
#include "irc-write.h"
#include "log.h"
#include "messages.h"
@@ -308,10 +320,20 @@ GLOBAL CHANNEL *Channel_GetChannel( CL2CHAN *Cl2Chan )
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 */
@@ -434,6 +456,35 @@ GLOBAL CHAR *Channel_UserModes( CHANNEL *Chan, CLIENT *Client )
} /* 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 */
@@ -452,6 +503,7 @@ LOCAL CHANNEL *New_Chan( CHAR *Name )
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 );

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: channel.h,v 1.11 2002/02/11 01:00:22 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().
@@ -67,6 +73,7 @@ typedef struct _CHANNEL
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
@@ -97,6 +104,9 @@ 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 );
@@ -120,6 +130,8 @@ 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.37 2002/02/17 19:02:49 alex Exp $
* $Id: client.c,v 1.41 2002/03/02 01:35:50 alex Exp $
*
* client.c: Management aller Clients
*
@@ -21,6 +21,18 @@
* 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.
*
@@ -163,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"
@@ -345,7 +357,11 @@ GLOBAL VOID Client_Destroy( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg )
}
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 )
@@ -354,7 +370,19 @@ GLOBAL VOID Client_Destroy( CLIENT *Client, CHAR *LogMsg, CHAR *FwdMsg )
else IRC_WriteStrServersPrefix( Client_NextHop( c ), c, "SQUIT %s :", c->id );
}
}
else Log( LOG_NOTICE, "Unknown client \"%s\" unregistered: %s", c->id, txt );
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 );
}
}
free( c );
break;
@@ -430,6 +458,29 @@ 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 );
@@ -712,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 */
@@ -890,11 +950,23 @@ GLOBAL INT Client_UnknownCount( VOID )
GLOBAL BOOLEAN Client_IsValidNick( CHAR *Nick )
{
/* Ist der Nick gueltig? */
CHAR *ptr, goodchars[] = ";0123456789";
assert( Nick != NULL );
if( Nick[0] == '#' ) return FALSE;
if( strlen( Nick ) > CLIENT_NICK_LEN ) 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 */
@@ -959,6 +1031,7 @@ LOCAL CLIENT *New_Client_Struct( VOID )
c->hops = -1;
c->token = -1;
c->mytoken = -1;
strcpy( c->away, "" );
return c;
} /* New_Client */

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: client.h,v 1.22 2002/02/06 16:49:56 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().
*
@@ -125,6 +128,7 @@ typedef struct _CLIENT
CHAR modes[CLIENT_MODE_LEN]; /* Client Modes */
INT hops, token, mytoken; /* "Hops" und "Token" (-> SERVER-Befehl) */
BOOLEAN oper_by_me; /* IRC-Operator-Status durch diesen Server? */
CHAR away[CLIENT_AWAY_LEN]; /* AWAY-Text, wenn Mode 'a' gesetzt */
} CLIENT;
#else
typedef POINTER CLIENT;
@@ -167,6 +171,7 @@ 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 );
@@ -181,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 );

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,46 @@
* 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.36 2002/02/11 01:00:50 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().
*
@@ -208,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 );
@@ -221,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;
@@ -237,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;
@@ -263,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 );
}
}
}
@@ -286,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 ));
@@ -302,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 )
@@ -392,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;
@@ -402,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++ )
{
@@ -547,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 */
@@ -564,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) */
@@ -573,7 +618,7 @@ GLOBAL INT32 Conn_GetIdle( CONN_ID Idx )
} /* Conn_GetIdle */
GLOBAL INT32 Conn_LastPing( CONN_ID Idx )
GLOBAL time_t Conn_LastPing( CONN_ID Idx )
{
/* Zeitpunkt des letzten PING liefern */
@@ -647,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 */
@@ -775,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;
}
@@ -783,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;
}
@@ -894,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 );
}
}
}
@@ -909,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++ )
{
@@ -986,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 )
{
@@ -1008,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 ));
@@ -1026,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;
@@ -1034,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 "PASSSERVERADD, Conf_Server[Server].pwd );
Conn_WriteStr( Idx, "SERVER %s :%s", Conf_ServerName, Conf_ServerInfo );
} /* New_Server */
@@ -1060,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,14 @@
* 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.11 2002/02/11 01:00:50 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().
*
@@ -55,6 +58,9 @@
#define __conn_h__
#include <time.h>
typedef INT CONN_ID;
typedef struct _Res_Stat
@@ -77,8 +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 INT32 Conn_LastPing( 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,25 @@
* 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.9 2002/02/13 23:04:27 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.
*
@@ -72,9 +86,11 @@
#define CLIENT_HOST_LEN 64 /* max. Laenge des Hostname */
#define CLIENT_MODE_LEN 8 /* max. Laenge der Client-Modes */
#define CLIENT_INFO_LEN 64 /* max. Infotext-Laenge (Server) */
#define CLIENT_AWAY_LEN 128 /* max. Laenger der AWAY-Nachricht */
#define 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 */
@@ -87,10 +103,14 @@
#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 "io" /* unterstuetzte User-Modes */
#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,85 +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.22 2002/02/17 17:18:59 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.22 2002/02/17 17:18:59 alex
* - NICK korrigiert.
* Revision 1.27 2002/02/27 23:26:36 alex
* - einige Funktionen in irc-xxx-Module ausgegliedert.
*
* Revision 1.21 2002/01/27 21:53:57 alex
* - IRC_WriteStrServersPrefixID() und IRC_WriteStrClientPrefixID() wieder entfernt.
* Revision 1.26 2002/02/27 20:33:13 alex
* - Channel-Topics implementiert.
*
* Revision 1.20 2002/01/27 17:15:49 alex
* - anderungen an den Funktions-Prototypen von IRC_WriteStrChannel() und
* IRC_WriteStrChannelPrefix(),
* - neue: IRC_WriteStrClientPrefixID() und IRC_WriteStrServersPrefixID().
* Revision 1.25 2002/02/27 18:23:46 alex
* - IRC-Befehl "AWAY" implementert.
*
* Revision 1.19 2002/01/26 18:43:11 alex
* - neue Funktionen IRC_WriteStrChannelPrefix() und IRC_WriteStrChannel(),
* die IRC_Write_xxx_Related() sind dafuer entfallen.
* - IRC_PRIVMSG() kann nun auch mit Channels als Ziel umgehen.
* Revision 1.24 2002/02/23 21:39:48 alex
* - IRC-Befehl KILL sowie Kills bei Nick Collsisions implementiert.
*
* Revision 1.18 2002/01/21 00:04:13 alex
* - neue Funktionen IRC_JOIN, IRC_PART, IRC_WriteStrRelatedPrefix und
* IRC_WriteStrRelatedChannelPrefix().
*
* Revision 1.17 2002/01/11 23:50:55 alex
* - LINKS implementiert, LUSERS begonnen.
*
* Revision 1.16 2002/01/05 19:15:03 alex
* - Fehlerpruefung bei select() in der "Hauptschleife" korrigiert.
*
* Revision 1.15 2002/01/04 17:58:21 alex
* - IRC_WriteStrXXX()-Funktionen angepasst; neuer Befehl SQUIT.
*
* Revision 1.14 2002/01/03 02:26:07 alex
* - neue Befehle SERVER und NJOIN begonnen.
*
* Revision 1.13 2002/01/02 02:51:39 alex
* - Copyright-Texte angepasst.
* - neuer Befehl "ERROR".
*
* Revision 1.11 2001/12/31 15:33:13 alex
* - neuer Befehl NAMES, kleinere Bugfixes.
* - Bug bei PING behoben: war zu restriktiv implementiert :-)
*
* Revision 1.10 2001/12/31 02:18:51 alex
* - viele neue Befehle (WHOIS, ISON, OPER, DIE, RESTART),
* - neuen Header "defines.h" mit (fast) allen Konstanten.
* - Code Cleanups und viele "kleine" Aenderungen & Bugfixes.
*
* Revision 1.9 2001/12/29 03:09:31 alex
* - Neue Funktion IRC_MODE() implementiert.
*
* Revision 1.8 2001/12/27 19:17:26 alex
* - neue Befehle PRIVMSG, NOTICE, PING.
*
* Revision 1.7 2001/12/27 16:55:41 alex
* - neu: IRC_WriteStrRelated(), Aenderungen auch in IRC_WriteStrClient().
*
* Revision 1.6 2001/12/26 14:45:37 alex
* - "Code Cleanups".
*
* Revision 1.5 2001/12/26 03:21:46 alex
* - PING/PONG-Befehle implementiert,
* - Meldungen ueberarbeitet: enthalten nun (fast) immer den Nick.
*
* Revision 1.4 2001/12/25 22:02:42 alex
* - neuer IRC-Befehl "/QUIT". Verbessertes Logging & Debug-Ausgaben.
*
* Revision 1.3 2001/12/25 19:19:30 alex
* - bessere Fehler-Abfragen, diverse Bugfixes.
* - Nicks werden nur einmal vergeben :-)
* - /MOTD wird unterstuetzt.
*
* Revision 1.2 2001/12/23 21:57:16 alex
* - erste IRC-Befehle zu implementieren begonnen.
*
* Revision 1.1 2001/12/14 08:13:43 alex
* - neues Modul begonnen :-)
* Revision 1.23 2002/02/17 23:38:58 alex
* - neuer IRC-Befehl VERSION implementiert: IRC_VERSION().
*/
@@ -95,39 +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_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, ... );
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 );
@@ -138,9 +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,14 @@
* 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.17 2002/01/11 14:45:37 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".
*
@@ -94,17 +97,53 @@
GLOBAL VOID Log_Init( VOID )
{
CHAR txt[127];
#ifdef USE_SYSLOG
/* Syslog initialisieren */
openlog( PACKAGE, LOG_CONS|LOG_PID, LOG_LOCAL5 );
#endif
/* Hello World! */
Log( LOG_NOTICE, "%s started.", NGIRCd_Version( ));
/* Informationen uebern den "Operation Mode" */
strcpy( 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 */

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: messages.h,v 1.29 2002/02/17 17:42:53 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.
*
@@ -125,6 +137,9 @@
#define RPL_MYINFO "004"
#define RPL_MYINFO_MSG RPL_MYINFO" %s :%s ngircd-"VERSION" "USERMODES" "CHANMODES
#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"
@@ -140,17 +155,24 @@
#define RPL_LUSERME "255"
#define RPL_LUSERME_MSG RPL_LUSERME" %s :I have %d users, %d services and %d servers"
#define RPL_MOTDSTART "375"
#define RPL_MOTDSTART_MSG RPL_MOTDSTART" %s :- %s message of the day"
#define RPL_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 :"
@@ -185,6 +207,9 @@
#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 :"
@@ -197,7 +222,6 @@
#define RPL_ENDOFNAMES "366"
#define RPL_ENDOFNAMES_MSG RPL_ENDOFNAMES" %s %s :End of NAMES list"
#define RPL_YOUREOPER "381"
#define RPL_YOUREOPER_MSG RPL_YOUREOPER" %s :You are now an IRC Operator"
@@ -211,6 +235,9 @@
#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"
@@ -232,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"
@@ -241,10 +275,6 @@
#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"
@@ -257,6 +287,7 @@
#define ERR_NOOPERHOST "491"
#define ERR_NOOPERHOST_MSG ERR_NOOPERHOST" %s :Not configured for your host"
#define ERR_UMODEUNKNOWNFLAG "501"
#define ERR_UMODEUNKNOWNFLAG_MSG ERR_UMODEUNKNOWNFLAG" %s :Unknown mode"
#define ERR_UMODEUNKNOWNFLAG2_MSG ERR_UMODEUNKNOWNFLAG" %s :Unknown mode \"%c%c\""

View File

@@ -9,11 +9,30 @@
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
*
* $Id: ngircd.c,v 1.22 2002/01/22 17:15:39 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.
*
@@ -136,6 +155,7 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
NGIRCd_Restart = FALSE;
NGIRCd_Quit = FALSE;
NGIRCd_NoDaemon = FALSE;
NGIRCd_Passive = FALSE;
#ifdef DEBUG
NGIRCd_Debug = FALSE;
#endif
@@ -151,17 +171,6 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
{
/* Lange Option */
if( strcmp( argv[i], "--help" ) == 0 )
{
Show_Version( ); puts( "" );
Show_Help( ); puts( "" );
exit( 1 );
}
if( strcmp( argv[i], "--version" ) == 0 )
{
Show_Version( );
exit( 1 );
}
#ifdef DEBUG
if( strcmp( argv[i], "--debug" ) == 0 )
{
@@ -169,6 +178,22 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
ok = TRUE;
}
#endif
if( strcmp( argv[i], "--help" ) == 0 )
{
Show_Version( ); puts( "" );
Show_Help( ); puts( "" );
exit( 1 );
}
if( strcmp( argv[i], "--nodaemon" ) == 0 )
{
NGIRCd_NoDaemon = TRUE;
ok = TRUE;
}
if( strcmp( argv[i], "--passive" ) == 0 )
{
NGIRCd_Passive = TRUE;
ok = TRUE;
}
#ifdef SNIFFER
if( strcmp( argv[i], "--sniffer" ) == 0 )
{
@@ -176,10 +201,10 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
ok = TRUE;
}
#endif
if( strcmp( argv[i], "--nodaemon" ) == 0 )
if( strcmp( argv[i], "--version" ) == 0 )
{
NGIRCd_NoDaemon = TRUE;
ok = TRUE;
Show_Version( );
exit( 1 );
}
}
else if(( argv[i][0] == '-' ) && ( argv[i][1] != '-' ))
@@ -196,6 +221,16 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
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' )
{
@@ -203,11 +238,6 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
ok = TRUE;
}
#endif
if( argv[i][n] == 'n' )
{
NGIRCd_NoDaemon = TRUE;
ok = TRUE;
}
if( ! ok )
{
@@ -226,6 +256,15 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
}
}
/* 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
@@ -260,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( );
@@ -283,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( );
}
@@ -295,34 +330,40 @@ GLOBAL INT main( INT argc, CONST CHAR *argv[] )
GLOBAL CHAR *NGIRCd_Version( VOID )
{
STATIC CHAR version[126];
CHAR txt[64];
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, "+" );
else strcat( txt, "-" );
strcat( txt, "SYSLOG" );
#endif
#ifdef STRICT_RFC
if( txt[0] ) strcat( txt, "+" );
else strcat( txt, "-" );
strcat( txt, "RFC" );
#endif
#ifdef DEBUG
if( txt[0] ) strcat( txt, "+" );
else strcat( txt, "-" );
strcat( txt, "DEBUG" );
#endif
#ifdef SNIFFER
if( txt[0] ) strcat( txt, "+" );
else strcat( txt, "-" );
strcat( txt, "SNIFFER" );
#endif
sprintf( version, PACKAGE" version "VERSION"%s-"P_OSNAME"/"P_ARCHNAME, txt );
return version;
} /* NGIRCd_Version */
if( txt[0] ) strcat( txt, "-" );
strcat( txt, P_OSNAME"/"P_ARCHNAME );
return txt;
} /* NGIRCd_VersionAddition */
LOCAL VOID Initialize_Signal_Handler( VOID )
@@ -330,22 +371,44 @@ LOCAL VOID Initialize_Signal_Handler( VOID )
/* Signal-Handler initialisieren: einige Signale
* werden ignoriert, andere speziell behandelt. */
#ifdef HAVE_SIGACTION
/* sigaction() ist vorhanden */
struct sigaction saction;
/* Signal-Struktur initialisieren */
memset( &saction, 0, sizeof( saction ));
saction.sa_handler = Signal_Handler;
saction.sa_flags = SA_RESTART;
#ifdef SA_RESTART
saction.sa_flags |= SA_RESTART;
#endif
#ifdef SA_NOCLDWAIT
saction.sa_flags |= SA_NOCLDWAIT;
#endif
/* Signal-Handler einhaengen */
sigaction( SIGINT, &saction, NULL );
sigaction( SIGQUIT, &saction, NULL );
sigaction( SIGTERM, &saction, NULL);
sigaction( SIGHUP, &saction, NULL);
sigaction( SIGCHLD, &saction, NULL);
/* einige Signale ignorieren */
saction.sa_handler = SIG_IGN;
sigaction( SIGPIPE, &saction, NULL );
#else
/* kein sigaction() vorhanden */
/* Signal-Handler einhaengen */
signal( SIGINT, Signal_Handler );
signal( SIGQUIT, Signal_Handler );
signal( SIGTERM, Signal_Handler );
signal( SIGHUP, Signal_Handler );
signal( SIGCHLD, Signal_Handler );
/* einige Signale ignorieren */
signal( SIGPIPE, SIG_IGN );
#endif
} /* Initialize_Signal_Handler */
@@ -361,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);
@@ -413,6 +483,7 @@ LOCAL VOID Show_Help( VOID )
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

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: ngircd.h,v 1.8 2002/01/18 11:12:11 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.
*
@@ -61,11 +67,15 @@ GLOBAL BOOLEAN NGIRCd_Sniffer; /* Sniffer aktivieren */
GLOBAL BOOLEAN NGIRCd_NoDaemon; /* nicht im Hintergrund laufen */
GLOBAL BOOLEAN NGIRCd_Passive; /* nicht zu anderen Servern connecten */
GLOBAL BOOLEAN NGIRCd_Quit; /* TRUE: ngIRCd beenden */
GLOBAL BOOLEAN NGIRCd_Restart; /* TRUE: neu starten */
GLOBAL CHAR NGIRCd_DebugLevel[2]; /* Debug-Level fuer IRC_VERSION() */
GLOBAL CHAR *NGIRCd_Version( VOID );
GLOBAL CHAR *NGIRCd_VersionAddition( VOID );
#endif

View File

@@ -9,11 +9,29 @@
* Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste
* der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS.
*
* $Id: parse.c,v 1.22 2002/01/21 00:01:37 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.
*
@@ -104,6 +122,9 @@
#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"
@@ -123,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
@@ -308,7 +319,7 @@ LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *Req )
else target = NULL;
if( ! target )
{
if( target ) Log( LOG_WARNING, "Unknown target for status code: \"%s\"", Req->argv[0] );
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;
}
@@ -367,6 +378,10 @@ LOCAL BOOLEAN Handle_Request( CONN_ID Idx, REQUEST *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, ERR_UNKNOWNCOMMAND_MSG, Client_ID( client ), Req->command );

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