diff --git a/src/ngircd/channel.c b/src/ngircd/channel.c index 4f1aa760..29b8becd 100644 --- a/src/ngircd/channel.c +++ b/src/ngircd/channel.c @@ -97,55 +97,52 @@ Channel_InitPredefined( void ) { /* Generate predefined persistent channels */ - CHANNEL *chan; - char *c; - unsigned int i; + CHANNEL *new_chan; + const struct Conf_Channel *conf_chan; + const char *c; + size_t i, channel_count = array_length(&Conf_Channels, sizeof(*conf_chan)); - for( i = 0; i < Conf_Channel_Count; i++ ) - { - /* Check for Name configuration */ - if( ! Conf_Channel[i].name[0] ) continue; + conf_chan = array_start(&Conf_Channels); - /* Check for invalid 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 ); - array_free(&Conf_Channel[i].topic); + assert(channel_count == 0 || conf_chan != NULL); + + for (i = 0; i < channel_count; i++, conf_chan++) { + if (!conf_chan->name[0] || !Channel_IsValidName(conf_chan->name)) { + Log(LOG_ERR, "Can't create pre-defined channel: invalid name: \"%s\"", + conf_chan->name); continue; } - /* Check if the channel name is already in use */ - chan = Channel_Search( Conf_Channel[i].name ); - if( chan ) - { - Log( LOG_INFO, "Can't create pre-defined channel \"%s\": name already in use.", Conf_Channel[i].name ); - array_free(&Conf_Channel[i].topic); + new_chan = Channel_Search(conf_chan->name); + if (new_chan) { + Log(LOG_INFO, "Can't create pre-defined channel \"%s\": name already in use.", + conf_chan->name); continue; } - /* Create channel */ - chan = Channel_Create(Conf_Channel[i].name); - if (chan) { - Channel_ModeAdd(chan, 'P'); - - if (array_start(&Conf_Channel[i].topic) != NULL) - Channel_SetTopic(chan, NULL, - array_start(&Conf_Channel[i].topic)); - array_free(&Conf_Channel[i].topic); - - c = Conf_Channel[i].modes; - while (*c) - Channel_ModeAdd(chan, *c++); - - Channel_SetKey(chan, Conf_Channel[i].key); - Channel_SetMaxUsers(chan, Conf_Channel[i].maxusers); - - Log(LOG_INFO, "Created pre-defined channel \"%s\".", - Conf_Channel[i].name ); + new_chan = Channel_Create(conf_chan->name); + if (!new_chan) { + Log(LOG_ERR, "Can't create pre-defined channel \"%s\"", + conf_chan->name); + continue; } - else Log(LOG_ERR, "Can't create pre-defined channel \"%s\"!", - Conf_Channel[i].name ); + + Channel_ModeAdd(new_chan, 'P'); + + if (conf_chan->topic[0]) + Channel_SetTopic(new_chan, NULL, conf_chan->topic); + + c = conf_chan->modes; + while (*c) + Channel_ModeAdd(new_chan, *c++); + + Channel_SetKey(new_chan, conf_chan->key); + Channel_SetMaxUsers(new_chan, conf_chan->maxusers); + Log(LOG_INFO, "Created pre-defined channel \"%s\"", + conf_chan->name); } + if (channel_count) + array_free(&Conf_Channels); } /* Channel_InitPredefined */ diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index fe059380..c82ac2bf 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -54,7 +54,7 @@ static bool Use_Log = true; static CONF_SERVER New_Server; static int New_Server_Idx; - +static size_t Conf_Channel_Count; static void Set_Defaults PARAMS(( bool InitServers )); static bool Read_Config PARAMS(( bool ngircd_starting )); static bool Validate_Config PARAMS(( bool TestOnly, bool Rehash )); @@ -206,8 +206,9 @@ Conf_Test( void ) struct passwd *pwd; struct group *grp; unsigned int i; - char *topic; bool config_valid; + size_t predef_channel_count; + struct Conf_Channel *predef_chan; Use_Log = false; @@ -299,18 +300,20 @@ Conf_Test( void ) printf( " Passive = %s\n\n", Conf_Server[i].flags & CONF_SFLAG_DISABLED ? "yes" : "no"); } - for( i = 0; i < Conf_Channel_Count; i++ ) { - if( ! Conf_Channel[i].name[0] ) continue; + predef_channel_count = array_length(&Conf_Channels, sizeof(*predef_chan)); + predef_chan = array_start(&Conf_Channels); + + for (i = 0; i < predef_channel_count; i++, predef_chan++) { + if (!predef_chan->name[0]) + continue; /* Valid "Channel" section */ puts( "[CHANNEL]" ); - printf( " Name = %s\n", Conf_Channel[i].name ); - printf( " Modes = %s\n", Conf_Channel[i].modes ); - printf( " Key = %s\n", Conf_Channel[i].key ); - printf( " MaxUsers = %lu\n", Conf_Channel[i].maxusers ); - - topic = (char*)array_start(&Conf_Channel[i].topic); - printf( " Topic = %s\n\n", topic ? topic : ""); + printf(" Name = %s\n", predef_chan->name); + printf(" Modes = %s\n", predef_chan->modes); + printf(" Key = %s\n", predef_chan->key); + printf(" MaxUsers = %lu\n", predef_chan->maxusers); + printf(" Topic = %s\n\n", predef_chan->topic); } return (config_valid ? 0 : 1); @@ -656,20 +659,11 @@ Read_Config( bool ngircd_starting ) else New_Server_Idx = i; continue; } - if( strcasecmp( section, "[CHANNEL]" ) == 0 ) { - if( Conf_Channel_Count + 1 > MAX_DEFCHANNELS ) { - Config_Error( LOG_ERR, "Too many pre-defined channels configured." ); - } else { - /* Initialize new channel structure */ - strcpy( Conf_Channel[Conf_Channel_Count].name, "" ); - strcpy( Conf_Channel[Conf_Channel_Count].modes, "" ); - strcpy( Conf_Channel[Conf_Channel_Count].key, "" ); - Conf_Channel[Conf_Channel_Count].maxusers = 0; - array_free(&Conf_Channel[Conf_Channel_Count].topic); - Conf_Channel_Count++; - } + if (strcasecmp(section, "[CHANNEL]") == 0) { + Conf_Channel_Count++; continue; } + Config_Error( LOG_ERR, "%s, line %d: Unknown section \"%s\"!", NGIRCd_ConfFile, line, section ); section[0] = 0x1; } @@ -1162,18 +1156,22 @@ Handle_SERVER( int Line, char *Var, char *Arg ) Config_Error_TooLong(Line, Var); return; } - + Config_Error( LOG_ERR, "%s, line %d (section \"Server\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var ); } /* Handle_SERVER */ static bool -Handle_Channelname(size_t chancount, const char *name) +Handle_Channelname(struct Conf_Channel *new_chan, const char *name) { - size_t size = sizeof( Conf_Channel[chancount].name ); - char *dest = Conf_Channel[chancount].name; + size_t size = sizeof(new_chan->name); + char *dest = new_chan->name; + /* + * channels must begin with &, +, or '#', if it is + * missing, add a '#'. This is only here for user convenience. + */ if (*name && *name != '#') { *dest = '#'; --size; @@ -1184,48 +1182,54 @@ Handle_Channelname(size_t chancount, const char *name) static void -Handle_CHANNEL( int Line, char *Var, char *Arg ) +Handle_CHANNEL(int Line, char *Var, char *Arg) { size_t len; - size_t chancount = 0; + size_t chancount; + struct Conf_Channel *chan; assert( Line > 0 ); assert( Var != NULL ); assert( Arg != NULL ); - if (Conf_Channel_Count > 0) - chancount = Conf_Channel_Count - 1; + assert(Conf_Channel_Count > 0); - if( strcasecmp( Var, "Name" ) == 0 ) { - if (!Handle_Channelname(chancount, Arg)) - Config_Error_TooLong( Line, Var ); + chancount = Conf_Channel_Count - 1; + + chan = array_alloc(&Conf_Channels, sizeof(*chan), chancount); + if (!chan) { + Config_Error(LOG_ERR, "Could not allocate memory for predefined channel (%d:%s = %s)", Line, Var, Arg); return; } - if( strcasecmp( Var, "Modes" ) == 0 ) { + if (strcasecmp(Var, "Name") == 0) { + if (!Handle_Channelname(chan, Arg)) + Config_Error_TooLong(Line, Var); + return; + } + if (strcasecmp(Var, "Modes") == 0) { /* Initial modes */ - len = strlcpy( Conf_Channel[chancount].modes, Arg, sizeof( Conf_Channel[chancount].modes )); - if (len >= sizeof( Conf_Channel[chancount].modes )) + len = strlcpy(chan->modes, Arg, sizeof(chan->modes)); + if (len >= sizeof(chan->modes)) Config_Error_TooLong( Line, Var ); return; } if( strcasecmp( Var, "Topic" ) == 0 ) { /* Initial topic */ - if (!array_copys( &Conf_Channel[chancount].topic, Arg)) + len = strlcpy(chan->topic, Arg, sizeof(chan->topic)); + if (len >= sizeof(chan->topic)) Config_Error_TooLong( Line, Var ); return; } - if( strcasecmp( Var, "Key" ) == 0 ) { /* Initial Channel Key (mode k) */ - len = strlcpy(Conf_Channel[chancount].key, Arg, sizeof(Conf_Channel[chancount].key)); - if (len >= sizeof( Conf_Channel[chancount].key )) + len = strlcpy(chan->key, Arg, sizeof(chan->key)); + if (len >= sizeof(chan->key)) Config_Error_TooLong(Line, Var); return; } - if( strcasecmp( Var, "MaxUsers" ) == 0 ) { /* maximum user limit, mode l */ - Conf_Channel[chancount].maxusers = (unsigned long) atol(Arg); - if (Conf_Channel[chancount].maxusers == 0) + chan->maxusers = (unsigned long) atol(Arg); + if (chan->maxusers == 0) Config_Error_NaN(Line, Var); return; } diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h index 53284656..cd9cb958 100644 --- a/src/ngircd/conf.h +++ b/src/ngircd/conf.h @@ -67,14 +67,13 @@ struct SSLOptions { #endif -typedef struct _Conf_Channel -{ +struct Conf_Channel { char name[CHANNEL_NAME_LEN]; /* Name of the channel */ char modes[CHANNEL_MODE_LEN]; /* Initial channel modes */ char key[CLIENT_PASS_LEN]; /* Channel key ("password", mode "k" ) */ + char topic[COMMAND_LEN]; /* Initial topic */ unsigned long maxusers; /* maximum usercount for this channel, mode "l" */ - array topic; /* Initial topic */ -} CONF_CHANNEL; +}; #define CONF_SFLAG_ONCE 1 /* Delete this entry after next disconnect */ @@ -132,8 +131,8 @@ GLOBAL unsigned int Conf_Oper_Count; GLOBAL CONF_SERVER Conf_Server[MAX_SERVERS]; /* Pre-defined channels */ -GLOBAL CONF_CHANNEL Conf_Channel[MAX_DEFCHANNELS]; -GLOBAL unsigned int Conf_Channel_Count; +GLOBAL array Conf_Channels; + /* Pre-defined channels only */ GLOBAL bool Conf_PredefChannelsOnly; diff --git a/src/ngircd/defines.h b/src/ngircd/defines.h index 7abe6419..dccb15a8 100644 --- a/src/ngircd/defines.h +++ b/src/ngircd/defines.h @@ -36,8 +36,6 @@ #define MAX_SERVERS 16 /* Max. count of configurable servers */ -#define MAX_DEFCHANNELS 16 /* Max. count of predefined channels */ - #define MAX_SERVICES 8 /* Max. count of services */ #define MAX_WHOWAS 64 /* Max. number of WHOWAS items */