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