From 040f5422f2c8262ab19832f1e9d0e269afad8ec1 Mon Sep 17 00:00:00 2001 From: Alexander Barton Date: Tue, 21 May 2002 00:10:16 +0000 Subject: [PATCH] - persistente und vordefinierte Channels implementiert. --- src/ngircd/channel.c | 43 ++++++++++++++++++++++++++-- src/ngircd/conf.c | 60 ++++++++++++++++++++++++++++++++++++++-- src/ngircd/conf.h | 13 ++++++++- src/ngircd/defines.h | 6 ++-- src/ngircd/irc-channel.c | 5 +++- src/ngircd/irc-mode.c | 6 +++- 6 files changed, 123 insertions(+), 10 deletions(-) diff --git a/src/ngircd/channel.c b/src/ngircd/channel.c index 31e568ca..c4231dc9 100644 --- a/src/ngircd/channel.c +++ b/src/ngircd/channel.c @@ -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: channel.c,v 1.21 2002/04/23 19:51:31 alex Exp $ + * $Id: channel.c,v 1.22 2002/05/21 00:10:16 alex Exp $ * * channel.c: Management der Channels */ @@ -26,6 +26,7 @@ #include #include "client.h" +#include "conf.h" #include "hash.h" #include "irc-write.h" #include "log.h" @@ -50,8 +51,41 @@ LOCAL BOOLEAN Delete_Channel( CHANNEL *Chan ); GLOBAL VOID Channel_Init( VOID ) { + CHANNEL *chan; + CHAR *c; + INT i; + My_Channels = NULL; My_Cl2Chan = NULL; + + /* Vordefinierte persistente Channels erzeugen */ + for( i = 0; i < Conf_Channel_Count; i++ ) + { + /* Ist ein Name konfiguriert? */ + if( ! Conf_Channel[i].name ) continue; + + /* Gueltiger Channel-Name? */ + if( ! Channel_IsValidName( Conf_Channel[i].name )) + { + Log( LOG_ERR, "Can't create pre-defined channel: invalid name: \"%s\"!", Conf_Channel[i].name ); + continue; + } + + /* Channel anlegen */ + chan = New_Chan( Conf_Channel[i].name ); + if( chan ) + { + /* Verketten */ + chan->next = My_Channels; + My_Channels = chan; + Channel_ModeAdd( chan, 'P' ); + Channel_SetTopic( chan, Conf_Channel[i].topic ); + c = Conf_Channel[i].modes; + while( *c ) Channel_ModeAdd( chan, *c++ ); + Log( LOG_INFO, "Created pre-defined channel \"%s\".", Conf_Channel[i].name ); + } + else Log( LOG_ERR, "Can't create pre-defined channel \"%s\"!", Conf_Channel[i].name ); + } } /* Channel_Init */ @@ -585,8 +619,11 @@ LOCAL BOOLEAN Remove_Client( CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, CHAR 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 ); + /* Wenn Channel nun leer und nicht pre-defined: loeschen */ + if( ! strchr( Channel_Modes( Chan ), 'P' )) + { + if( ! Get_First_Cl2Chan( NULL, Chan )) Delete_Channel( Chan ); + } return TRUE; } /* Remove_Client */ diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index f558d1a5..73d1cf49 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -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: conf.c,v 1.23 2002/03/30 13:08:10 alex Exp $ + * $Id: conf.c,v 1.24 2002/05/21 00:10:16 alex Exp $ * * conf.h: Konfiguration des ngircd */ @@ -46,6 +46,7 @@ LOCAL VOID Validate_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 ); +GLOBAL VOID Handle_CHANNEL( INT Line, CHAR *Var, CHAR *Arg ); LOCAL VOID Config_Error( CONST INT Level, CONST CHAR *Format, ... ); @@ -115,6 +116,15 @@ GLOBAL INT Conf_Test( VOID ) printf( " Group = %d\n", Conf_Server[i].group ); puts( "" ); } + + for( i = 0; i < Conf_Channel_Count; i++ ) + { + puts( "[CHANNEL]" ); + printf( " Name = %s\n", Conf_Channel[i].name ); + printf( " Modes = %s\n", Conf_Channel[i].modes ); + printf( " Topic = %s\n", Conf_Channel[i].topic ); + puts( "" ); + } return 0; } /* Conf_Test */ @@ -146,8 +156,8 @@ LOCAL VOID Set_Defaults( VOID ) Conf_ConnectRetry = 60; Conf_Oper_Count = 0; - Conf_Server_Count = 0; + Conf_Channel_Count = 0; } /* Set_Defaults */ @@ -214,6 +224,19 @@ LOCAL VOID Read_Config( VOID ) } continue; } + if( strcasecmp( section, "[CHANNEL]" ) == 0 ) + { + if( Conf_Channel_Count + 1 > MAX_DEFCHANNELS ) Config_Error( LOG_ERR, "Too many pre-defined channels configured." ); + else + { + /* neuen vordefinierten Channel initialisieren */ + strcpy( Conf_Channel[Conf_Channel_Count].name, "" ); + strcpy( Conf_Channel[Conf_Channel_Count].modes, "" ); + strcpy( Conf_Channel[Conf_Channel_Count].topic, "" ); + Conf_Channel_Count++; + } + continue; + } Config_Error( LOG_ERR, "%s, line %d: Unknown section \"%s\"!", NGIRCd_ConfFile, line, section ); section[0] = 0x1; } @@ -233,6 +256,7 @@ LOCAL VOID Read_Config( VOID ) 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 if( strcasecmp( section, "[CHANNEL]" ) == 0 ) Handle_CHANNEL( line, var, arg ); else Config_Error( LOG_ERR, "%s, line %d: Variable \"%s\" outside section!", NGIRCd_ConfFile, line, var ); } @@ -415,6 +439,38 @@ GLOBAL VOID Handle_SERVER( INT Line, CHAR *Var, CHAR *Arg ) } /* Handle_SERVER */ +GLOBAL VOID Handle_CHANNEL( INT Line, CHAR *Var, CHAR *Arg ) +{ + assert( Line > 0 ); + assert( Var != NULL ); + assert( Arg != NULL ); + + if( strcasecmp( Var, "Name" ) == 0 ) + { + /* Hostname des Servers */ + strncpy( Conf_Channel[Conf_Channel_Count - 1].name, Arg, CHANNEL_NAME_LEN - 1 ); + Conf_Channel[Conf_Channel_Count - 1].name[CHANNEL_NAME_LEN - 1] = '\0'; + return; + } + if( strcasecmp( Var, "Modes" ) == 0 ) + { + /* Name des Servers ("Nick") */ + strncpy( Conf_Channel[Conf_Channel_Count - 1].modes, Arg, CHANNEL_MODE_LEN - 1 ); + Conf_Channel[Conf_Channel_Count - 1].modes[CHANNEL_MODE_LEN - 1] = '\0'; + return; + } + if( strcasecmp( Var, "Topic" ) == 0 ) + { + /* Passwort des Servers */ + strncpy( Conf_Channel[Conf_Channel_Count - 1].topic, Arg, CHANNEL_TOPIC_LEN - 1 ); + Conf_Channel[Conf_Channel_Count - 1].topic[CHANNEL_TOPIC_LEN - 1] = '\0'; + return; + } + + Config_Error( LOG_ERR, "%s, line %d (section \"Channel\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var ); +} /* Handle_CHANNEL */ + + LOCAL VOID Validate_Config( VOID ) { /* Konfiguration ueberpruefen */ diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h index 2aefbcd4..74a24993 100644 --- a/src/ngircd/conf.h +++ b/src/ngircd/conf.h @@ -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: conf.h,v 1.15 2002/03/29 22:53:59 alex Exp $ + * $Id: conf.h,v 1.16 2002/05/21 00:10:16 alex Exp $ * * conf.h: Konfiguration des ngircd (Header) */ @@ -42,6 +42,13 @@ typedef struct _Conf_Server RES_STAT *res_stat; /* Status des Resolver */ } CONF_SERVER; +typedef struct _Conf_Channel +{ + CHAR name[CHANNEL_NAME_LEN]; /* Name des Channel */ + CHAR modes[CHANNEL_MODE_LEN]; /* Channel-Modes */ + CHAR topic[CHANNEL_TOPIC_LEN]; /* Topic des Channels */ +} CONF_CHANNEL; + /* Name ("Nick") des Servers */ GLOBAL CHAR Conf_ServerName[CLIENT_ID_LEN]; @@ -78,6 +85,10 @@ GLOBAL INT Conf_Oper_Count; GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS]; GLOBAL INT Conf_Server_Count; +/* Vorkonfigurierte Channels */ +GLOBAL CONF_CHANNEL Conf_Channel[MAX_DEFCHANNELS]; +GLOBAL INT Conf_Channel_Count; + GLOBAL VOID Conf_Init( VOID ); GLOBAL INT Conf_Test( VOID ); diff --git a/src/ngircd/defines.h b/src/ngircd/defines.h index a81a899d..aa7d1228 100644 --- a/src/ngircd/defines.h +++ b/src/ngircd/defines.h @@ -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: defines.h,v 1.23 2002/04/08 01:18:14 alex Exp $ + * $Id: defines.h,v 1.24 2002/05/21 00:10:16 alex Exp $ * * defines.h: (globale) Konstanten */ @@ -32,6 +32,8 @@ #define MAX_SERVERS 16 /* max. Anzahl konfigurierbarer Server ("Peers") */ +#define MAX_DEFCHANNELS 16 /* max. Anzahl vorkonfigurierbarerr Channels */ + #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 */ @@ -62,7 +64,7 @@ #define RECONNECT_DELAY 3 /* Server-Links erst nach 3 Sekunden versuchen, wieder aufzubauen */ #define USERMODES "aios" /* unterstuetzte User-Modes */ -#define CHANMODES "amnopqstv" /* unterstuetzte Channel-Modes */ +#define CHANMODES "amnopPqstv" /* unterstuetzte Channel-Modes */ #define CONNECTED TRUE /* fuer die irc-xxx-Module */ #define DISCONNECTED FALSE diff --git a/src/ngircd/irc-channel.c b/src/ngircd/irc-channel.c index 79ccdd9a..551c74bd 100644 --- a/src/ngircd/irc-channel.c +++ b/src/ngircd/irc-channel.c @@ -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: irc-channel.c,v 1.4 2002/04/23 19:51:14 alex Exp $ + * $Id: irc-channel.c,v 1.5 2002/05/21 00:10:16 alex Exp $ * * irc-channel.c: IRC-Channel-Befehle */ @@ -93,6 +93,9 @@ GLOBAL BOOLEAN IRC_JOIN( CLIENT *Client, REQUEST *Req ) flags++; } + /* Wenn persistenter Channel und IRC-Operator: zum Channel-OP machen */ + if(( strchr( Channel_Modes( chan ), 'P' )) && ( strchr( Client_Modes( target ), 'o' ))) Channel_UserModeAdd( chan, target, 'o' ); + /* Muessen Modes an andere Server gemeldet werden? */ strcpy( &modes[1], Channel_UserModes( chan, target )); if( modes[1] ) modes[0] = 0x7; diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c index 5b086c73..ca638fb4 100644 --- a/src/ngircd/irc-mode.c +++ b/src/ngircd/irc-mode.c @@ -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: irc-mode.c,v 1.4 2002/03/25 17:11:45 alex Exp $ + * $Id: irc-mode.c,v 1.5 2002/05/21 00:10:16 alex Exp $ * * irc-mode.c: IRC-Befehle zur Mode-Aenderung (MODE, AWAY, ...) */ @@ -227,6 +227,10 @@ GLOBAL BOOLEAN IRC_MODE( CLIENT *Client, REQUEST *Req ) /* Topic Lock */ x[0] = 't'; break; + case 'P': + /* Persistent */ + x[0] = 'P'; + break; default: Log( LOG_DEBUG, "Unknown channel-mode \"%c%c\" from \"%s\" at %s!?", set ? '+' : '-', *mode_ptr, Client_ID( Client ), Channel_Name( chan )); ok = IRC_WriteStrClient( Client, ERR_UMODEUNKNOWNFLAG2_MSG, Client_ID( Client ), set ? '+' : '-', *mode_ptr );