1
0
mirror of https://github.com/osmarks/ngircd.git synced 2025-10-29 21:13:01 +00:00

Introduce option to configure the maximum nick name lenth in ngircd.conf

- New configuration option "MaxNickLength" to specify the allowed maximum
  length of user nick names. Note: must be unique in an IRC network!
- Enhanced the IRC+ protocol to support an enhanced "server handshake" and
  enable server to recognice numeric 005 (ISUPPORT) and 376 (ENDOFMOTD).
  See doc/Protocol.txt for details.
This commit is contained in:
Alexander Barton
2007-11-21 12:16:33 +00:00
parent 12db0bdc4f
commit 47ca178a21
19 changed files with 241 additions and 243 deletions

View File

@@ -8,7 +8,7 @@
# (at your option) any later version.
# Please read the file COPYING, README and AUTHORS for more information.
#
# $Id: Makefile.am,v 1.49 2006/03/11 01:48:50 alex Exp $
# $Id: Makefile.am,v 1.50 2007/11/21 12:16:36 alex Exp $
#
AUTOMAKE_OPTIONS = ../portab/ansi2knr
@@ -23,7 +23,7 @@ sbin_PROGRAMS = ngircd
ngircd_SOURCES = ngircd.c array.c channel.c client.c conf.c conn.c conn-func.c \
conn-zip.c hash.c io.c irc.c irc-channel.c irc-info.c irc-login.c \
irc-mode.c irc-op.c irc-oper.c irc-server.c irc-write.c lists.c log.c \
match.c parse.c rendezvous.c resolve.c
match.c numeric.c parse.c rendezvous.c resolve.c
ngircd_LDFLAGS = -L../portab -L../tool
@@ -32,7 +32,7 @@ ngircd_LDADD = -lngportab -lngtool
noinst_HEADERS = ngircd.h array.h channel.h client.h conf.h conn.h conn-func.h \
conn-zip.h hash.h io.h irc.h irc-channel.h irc-info.h irc-login.h \
irc-mode.h irc-op.h irc-oper.h irc-server.h irc-write.h lists.h log.h \
match.h parse.h rendezvous.h resolve.h \
match.h numeric.h parse.h rendezvous.h resolve.h \
defines.h messages.h
clean-local:

View File

@@ -17,7 +17,7 @@
#include "portab.h"
static char UNUSED id[] = "$Id: client.c,v 1.96 2007/10/25 11:01:19 fw Exp $";
static char UNUSED id[] = "$Id: client.c,v 1.97 2007/11/21 12:16:36 alex Exp $";
#include "imp.h"
#include <assert.h>
@@ -609,7 +609,8 @@ Client_ID( CLIENT *Client )
assert( Client != NULL );
#ifdef DEBUG
if( Client->type == CLIENT_USER ) assert( strlen( Client->id ) < CLIENT_NICK_LEN );
if(Client->type == CLIENT_USER)
assert(strlen(Client->id) < Conf_MaxNickLength);
#endif
if( Client->id[0] ) return Client->id;
@@ -952,7 +953,7 @@ Client_IsValidNick( const char *Nick )
if( Nick[0] == '#' ) return false;
if( strchr( goodchars, Nick[0] )) return false;
if( strlen( Nick ) >= CLIENT_NICK_LEN ) return false;
if( strlen( Nick ) >= Conf_MaxNickLength) return false;
ptr = Nick;
while( *ptr )

View File

@@ -14,7 +14,7 @@
#include "portab.h"
static char UNUSED id[] = "$Id: conf.c,v 1.101 2007/10/25 11:01:19 fw Exp $";
static char UNUSED id[] = "$Id: conf.c,v 1.102 2007/11/21 12:16:36 alex Exp $";
#include "imp.h"
#include <assert.h>
@@ -208,7 +208,8 @@ Conf_Test( void )
printf( " NoDNS = %s\n", Conf_NoDNS ? "yes" : "no");
printf( " MaxConnections = %ld\n", Conf_MaxConnections);
printf( " MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP);
printf( " MaxJoins = %d\n\n", Conf_MaxJoins);
printf( " MaxJoins = %d\n", Conf_MaxJoins>0 ? Conf_MaxJoins : -1);
printf( " MaxNickLength = %u\n\n", Conf_MaxNickLength - 1);
for( i = 0; i < Conf_Oper_Count; i++ ) {
if( ! Conf_Oper[i].name[0] ) continue;
@@ -452,6 +453,7 @@ Set_Defaults( bool InitServers )
Conf_MaxConnections = 0;
Conf_MaxConnectionsIP = 5;
Conf_MaxJoins = 10;
Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
/* Initialize server configuration structures */
if( InitServers ) for( i = 0; i < MAX_SERVERS; Init_Server_Struct( &Conf_Server[i++] ));
@@ -638,6 +640,27 @@ Check_ArgIsTrue( const char *Arg )
} /* Check_ArgIsTrue */
static unsigned int Handle_MaxNickLength(int Line, const char *Arg)
{
unsigned new;
new = (unsigned) atoi(Arg) + 1;
if (new > CLIENT_NICK_LEN) {
Config_Error(LOG_WARNING,
"%s, line %d: Value of \"MaxNickLength\" exceeds %u!",
NGIRCd_ConfFile, Line, CLIENT_NICK_LEN - 1);
return CLIENT_NICK_LEN;
}
if (new < 2) {
Config_Error(LOG_WARNING,
"%s, line %d: Value of \"MaxNickLength\" must be at least 1!",
NGIRCd_ConfFile, Line);
return 2;
}
return new;
} /* Handle_MaxNickLength */
static void
Handle_GLOBAL( int Line, char *Var, char *Arg )
{
@@ -827,6 +850,13 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
Conf_MaxJoins = atoi( Arg );
return;
}
if( strcasecmp( Var, "MaxNickLength" ) == 0 ) {
/* Maximum length of a nick name; must be same on all servers
* within the IRC network! */
Conf_MaxNickLength = Handle_MaxNickLength(Line, Arg);
return;
}
if( strcasecmp( Var, "Listen" ) == 0 ) {
/* IP-Address to bind sockets */
len = strlcpy( Conf_ListenAddress, Arg, sizeof( Conf_ListenAddress ));

View File

@@ -8,7 +8,7 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: conf.h,v 1.44 2007/10/25 11:01:19 fw Exp $
* $Id: conf.h,v 1.45 2007/11/21 12:16:36 alex Exp $
*
* Configuration management (header)
*/
@@ -135,6 +135,8 @@ GLOBAL int Conf_MaxJoins;
/* Maximum number of connections per IP address */
GLOBAL int Conf_MaxConnectionsIP;
/* Maximum length of a nick name */
GLOBAL unsigned int Conf_MaxNickLength;
GLOBAL void Conf_Init PARAMS((void));
GLOBAL void Conf_Rehash PARAMS((void));

View File

@@ -8,7 +8,7 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: defines.h,v 1.61 2007/08/02 10:14:26 fw Exp $
* $Id: defines.h,v 1.62 2007/11/21 12:16:36 alex Exp $
*/
@@ -47,8 +47,9 @@
#define CLIENT_ID_LEN 64 /* Max. length of an IRC ID; see RFC
RFC 2812 section 1.1 and 1.2.1 */
#define CLIENT_NICK_LEN 10 /* Max. nick length, see. RFC 2812
section 1.2.1 */
#define CLIENT_NICK_LEN_DEFAULT 10 /* Default nick length, see. RFC 2812
* section 1.2.1 */
#define CLIENT_NICK_LEN 32 /* Maximum nick name length */
#define CLIENT_PASS_LEN 21 /* Max. password length */
#define CLIENT_USER_LEN 10 /* Max. length of user name ("login")
see RFC 2812, section 1.2.1 */
@@ -81,7 +82,7 @@
protocol, see doc/Protocol.txt */
#ifdef IRCPLUS
# define IRCPLUSFLAGS "CL" /* Standard IRC+ flags */
# define IRCPLUSFLAGS "CHL" /* Standard IRC+ flags */
#endif
#define STARTUP_DELAY 1 /* Delay outgoing connections n seconds

View File

@@ -14,7 +14,7 @@
#include "portab.h"
static char UNUSED id[] = "$Id: irc-info.c,v 1.39 2007/11/18 15:05:35 alex Exp $";
static char UNUSED id[] = "$Id: irc-info.c,v 1.40 2007/11/21 12:16:36 alex Exp $";
#include "imp.h"
#include <assert.h>
@@ -1050,4 +1050,22 @@ IRC_Send_WHO( CLIENT *Client, CHANNEL *Chan, bool OnlyOps )
} /* IRC_Send_WHO */
/**
* Send the ISUPPORT numeric (005).
* This numeric indicates the features that are supported by this server.
* See <http://www.irc.org/tech_docs/005.html> for details.
*/
GLOBAL bool
IRC_Send_ISUPPORT PARAMS((CLIENT * Client))
{
if (!IRC_WriteStrClient(Client, RPL_ISUPPORT1_MSG, Client_ID(Client),
Conf_MaxJoins))
return DISCONNECTED;
return IRC_WriteStrClient(Client, RPL_ISUPPORT2_MSG, Client_ID(Client),
CHANNEL_NAME_LEN - 1, Conf_MaxNickLength - 1,
COMMAND_LEN - 23, CLIENT_AWAY_LEN - 1,
COMMAND_LEN - 113);
} /* IRC_Send_ISUPPORT */
/* -eof- */

View File

@@ -8,7 +8,7 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: irc-info.h,v 1.3 2005/03/19 18:43:48 fw Exp $
* $Id: irc-info.h,v 1.4 2007/11/21 12:16:36 alex Exp $
*
* IRC info commands (header)
*/
@@ -36,6 +36,7 @@ GLOBAL bool IRC_Send_LUSERS PARAMS(( CLIENT *Client ));
GLOBAL bool IRC_Send_NAMES PARAMS(( CLIENT *Client, CHANNEL *Chan ));
GLOBAL bool IRC_Show_MOTD PARAMS(( CLIENT *Client ));
GLOBAL bool IRC_Send_WHO PARAMS(( CLIENT *Client, CHANNEL *Chan, bool OnlyOps ));
GLOBAL bool IRC_Send_ISUPPORT PARAMS(( CLIENT *Client ));
#endif

View File

@@ -14,7 +14,7 @@
#include "portab.h"
static char UNUSED id[] = "$Id: irc-login.c,v 1.53 2006/10/03 10:28:38 alex Exp $";
static char UNUSED id[] = "$Id: irc-login.c,v 1.54 2007/11/21 12:16:36 alex Exp $";
#include "imp.h"
#include <assert.h>
@@ -618,12 +618,7 @@ Hello_User( CLIENT *Client )
/* Features supported by this server (005 numeric, ISUPPORT),
* see <http://www.irc.org/tech_docs/005.html> for details. */
if (! IRC_WriteStrClient(Client, RPL_ISUPPORT1_MSG, Client_ID(Client),
Conf_MaxJoins))
return DISCONNECTED;
if (! IRC_WriteStrClient(Client, RPL_ISUPPORT2_MSG, Client_ID(Client),
CHANNEL_NAME_LEN-1, CLIENT_NICK_LEN-1, COMMAND_LEN-23,
CLIENT_AWAY_LEN-1, COMMAND_LEN-113))
if (! IRC_Send_ISUPPORT(Client))
return DISCONNECTED;
Client_SetType( Client, CLIENT_USER );

View File

@@ -14,7 +14,7 @@
#include "portab.h"
static char UNUSED id[] = "$Id: irc-server.c,v 1.45 2007/11/20 20:02:41 alex Exp $";
static char UNUSED id[] = "$Id: irc-server.c,v 1.46 2007/11/21 12:16:36 alex Exp $";
#include "imp.h"
#include <assert.h>
@@ -35,54 +35,14 @@ static char UNUSED id[] = "$Id: irc-server.c,v 1.45 2007/11/20 20:02:41 alex Exp
#include "log.h"
#include "messages.h"
#include "parse.h"
#include "numeric.h"
#include "ngircd.h"
#include "irc-info.h"
#include "exp.h"
#include "irc-server.h"
#ifdef IRCPLUS
static bool
Synchronize_Lists( CLIENT *Client )
{
CHANNEL *c;
struct list_head *head;
struct list_elem *elem;
assert( Client != NULL );
c = Channel_First();
while (c) {
head = Channel_GetListBans(c);
elem = Lists_GetFirst(head);
while (elem) {
if( ! IRC_WriteStrClient( Client, "MODE %s +b %s",
Channel_Name(c), Lists_GetMask(elem)))
{
return false;
}
elem = Lists_GetNext(elem);
}
head = Channel_GetListInvites(c);
elem = Lists_GetFirst(head);
while (elem) {
if( ! IRC_WriteStrClient( Client, "MODE %s +I %s",
Channel_Name( c ), Lists_GetMask(elem)))
{
return false;
}
elem = Lists_GetNext(elem);
}
c = Channel_Next(c);
}
return true;
}
#endif
/**
* Handler for the IRC command "SERVER".
* See RFC 2813 section 4.1.2.
@@ -90,12 +50,10 @@ Synchronize_Lists( CLIENT *Client )
GLOBAL bool
IRC_SERVER( CLIENT *Client, REQUEST *Req )
{
char str[LINE_LEN], *ptr, *modes, *topic;
CLIENT *from, *c, *cl;
CL2CHAN *cl2chan;
int max_hops, i;
CHANNEL *chan;
char str[LINE_LEN], *ptr;
CLIENT *from, *c;
bool ok;
int i;
CONN_ID con;
assert( Client != NULL );
@@ -164,10 +122,10 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
Client_SetToken( Client, atoi( Req->argv[1] ));
}
Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" registered (connection %d, 1 hop - direct link).", Client_ID( Client ), con );
Client_SetType( Client, CLIENT_SERVER );
Conf_SetServer( i, con );
/* Mark this connection as belonging to an configured server */
Conf_SetServer(i, con);
Client_SetType(Client, CLIENT_UNKNOWNSERVER);
#ifdef ZLIB
/* Kompression initialisieren, wenn erforderlich */
@@ -182,145 +140,23 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
}
#endif
/* maximalen Hop Count ermitteln */
max_hops = 0;
c = Client_First( );
while( c )
{
if( Client_Hops( c ) > max_hops ) max_hops = Client_Hops( c );
c = Client_Next( c );
}
/* Alle bisherigen Server dem neuen Server bekannt machen,
* die bisherigen Server ueber den neuen informierenn */
for( i = 0; i < ( max_hops + 1 ); i++ )
{
c = Client_First( );
while( c )
{
if(( Client_Type( c ) == CLIENT_SERVER ) && ( c != Client ) && ( c != Client_ThisServer( )) && ( Client_Hops( c ) == i ))
{
if( Client_Conn( c ) > NONE )
{
/* Dem gefundenen Server gleich den neuen
* Server bekannt machen */
if( ! IRC_WriteStrClient( c, "SERVER %s %d %d :%s", Client_ID( Client ), Client_Hops( Client ) + 1, Client_MyToken( Client ), Client_Info( Client ))) return DISCONNECTED;
}
/* Inform the new server about this one */
if (! IRC_WriteStrClientPrefix(Client,
Client_Hops(c) == 1 ? Client_ThisServer() : Client_TopServer(c),
"SERVER %s %d %d :%s",
Client_ID(c), Client_Hops(c) + 1,
Client_MyToken(c), Client_Info(c)))
return DISCONNECTED;
}
c = Client_Next( c );
}
}
/* alle User dem neuen Server bekannt machen */
c = Client_First( );
while( c )
{
if( Client_Type( c ) == CLIENT_USER )
{
/* User an neuen Server melden */
if( ! IRC_WriteStrClient( Client, "NICK %s %d %s %s %d +%s :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_User( c ), Client_Hostname( c ), Client_MyToken( Client_Introducer( c )), Client_Modes( c ), Client_Info( c ))) return DISCONNECTED;
}
c = Client_Next( c );
}
/* Channels dem neuen Server bekannt machen */
chan = Channel_First( );
while( chan )
{
#ifdef IRCPLUS
/* Send CHANINFO if the peer supports it */
if( strchr( Client_Flags( Client ), 'C' ))
{
#ifdef DEBUG
Log( LOG_DEBUG, "Sending CHANINFO commands ..." );
#endif
modes = Channel_Modes( chan );
topic = Channel_Topic( chan );
if( *modes || *topic )
{
/* send CHANINFO */
if(( ! strchr( Channel_Modes( chan ), 'k' )) && ( ! strchr( Channel_Modes( chan ), 'l' )) && ( ! *topic ))
{
/* "CHANINFO <chan> +<modes>" */
if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s", Channel_Name( chan ), modes )) return DISCONNECTED;
}
else if(( ! strchr( Channel_Modes( chan ), 'k' )) && ( ! strchr( Channel_Modes( chan ), 'l' )))
{
/* "CHANINFO <chan> +<modes> :<topic>" */
if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s :%s", Channel_Name( chan ), modes, topic )) return DISCONNECTED;
}
else
{
/* "CHANINFO <chan> +<modes> <key> <limit> :<topic>" */
if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s %s %lu :%s",
Channel_Name( chan ), modes,
strchr( Channel_Modes( chan ), 'k' ) ? Channel_Key( chan ) : "*",
strchr( Channel_Modes( chan ), 'l' ) ? Channel_MaxUsers( chan ) : 0, topic ))
{
return DISCONNECTED;
}
}
}
}
#endif
/* alle Member suchen */
cl2chan = Channel_FirstMember( chan );
snprintf( str, sizeof( str ), "NJOIN %s :", Channel_Name( chan ));
while( cl2chan )
{
cl = Channel_GetClient( cl2chan );
assert( cl != NULL );
/* Nick, ggf. mit Modes, anhaengen */
if( str[strlen( str ) - 1] != ':' ) strlcat( str, ",", sizeof( str ));
if( strchr( Channel_UserModes( chan, cl ), 'v' )) strlcat( str, "+", sizeof( str ));
if( strchr( Channel_UserModes( chan, cl ), 'o' )) strlcat( str, "@", sizeof( str ));
strlcat( str, Client_ID( cl ), sizeof( str ));
if( strlen( str ) > ( LINE_LEN - CLIENT_NICK_LEN - 8 ))
{
/* Zeile senden */
if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
snprintf( str, sizeof( str ), "NJOIN %s :", Channel_Name( chan ));
}
cl2chan = Channel_NextMember( chan, cl2chan );
}
/* noch Daten da? */
if( str[strlen( str ) - 1] != ':')
{
/* Ja; Also senden ... */
if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
}
/* Get next channel ... */
chan = Channel_Next(chan);
}
#ifdef IRCPLUS
if (strchr(Client_Flags(Client), 'L')) {
#ifdef DEBUG
Log(LOG_DEBUG,
"Synchronizing INVITE- and BAN-lists ...");
#endif
/* Synchronize INVITE- and BAN-lists */
if (!Synchronize_Lists(Client))
if (strchr(Client_Flags(Client), 'H')) {
LogDebug("Peer supports IRC+ extended server handshake ...");
if (!IRC_Send_ISUPPORT(Client))
return DISCONNECTED;
return IRC_WriteStrClient(Client, RPL_ENDOFMOTD_MSG,
Client_ID(Client));
} else {
#endif
if (Conf_MaxNickLength != CLIENT_NICK_LEN_DEFAULT)
Log(LOG_CRIT,
"Attention: this server uses a non-standard nick length, but the peer doesn't support the IRC+ extended server handshake!");
#ifdef IRCPLUS
}
#endif
return CONNECTED;
return IRC_Num_ENDOFMOTD(Client, Req);
}
else if( Client_Type( Client ) == CLIENT_SERVER )
{
@@ -364,8 +200,9 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req )
IRC_WriteStrServersPrefix( Client, from, "SERVER %s %d %d :%s", Client_ID( c ), Client_Hops( c ) + 1, Client_MyToken( c ), Client_Info( c ));
return CONNECTED;
}
else return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
} else
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
} /* IRC_SERVER */

View File

@@ -8,7 +8,7 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: irc-server.h,v 1.5 2005/03/19 18:43:49 fw Exp $
* $Id: irc-server.h,v 1.6 2007/11/21 12:16:36 alex Exp $
*
* IRC commands for server links (header)
*/
@@ -22,6 +22,8 @@ GLOBAL bool IRC_SERVER PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_NJOIN PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_SQUIT PARAMS((CLIENT *Client, REQUEST *Req ));
GLOBAL bool IRC_ENDOFMOTD_Server PARAMS((CLIENT *Client));
#endif

View File

@@ -12,7 +12,7 @@
#include "portab.h"
static char UNUSED id[] = "$Id: ngircd.c,v 1.116 2007/11/15 01:03:01 fw Exp $";
static char UNUSED id[] = "$Id: ngircd.c,v 1.117 2007/11/21 12:16:36 alex Exp $";
/**
* @file
@@ -422,6 +422,7 @@ GLOBAL void
NGIRCd_Rehash( void )
{
char old_name[CLIENT_ID_LEN];
unsigned old_nicklen;
Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" );
NGIRCd_SignalRehash = false;
@@ -429,17 +430,22 @@ NGIRCd_Rehash( void )
/* Close down all listening sockets */
Conn_ExitListeners( );
/* Remember old server name */
/* Remember old server name and nick name length */
strlcpy( old_name, Conf_ServerName, sizeof old_name );
old_nicklen = Conf_MaxNickLength;
/* Re-read configuration ... */
Conf_Rehash( );
/* Recover old server name: it can't be changed during run-time */
if( strcmp( old_name, Conf_ServerName ) != 0 )
{
strlcpy( Conf_ServerName, old_name, sizeof Conf_ServerName );
Log( LOG_ERR, "Can't change \"ServerName\" on runtime! Ignored new name." );
/* Recover old server name and nick name length: these values can't
* be changed during run-time */
if (strcmp(old_name, Conf_ServerName) != 0 ) {
strlcpy(Conf_ServerName, old_name, sizeof Conf_ServerName);
Log(LOG_ERR, "Can't change \"ServerName\" on runtime! Ignored new name.");
}
if (old_nicklen != Conf_MaxNickLength) {
Conf_MaxNickLength = old_nicklen;
Log(LOG_ERR, "Can't change \"MaxNickLength\" on runtime! Ignored new value.");
}
/* Create new pre-defined channels */

View File

@@ -12,7 +12,7 @@
#include "portab.h"
static char UNUSED id[] = "$Id: parse.c,v 1.68 2007/08/02 10:14:26 fw Exp $";
static char UNUSED id[] = "$Id: parse.c,v 1.69 2007/11/21 12:16:36 alex Exp $";
/**
* @file
@@ -48,6 +48,7 @@ static char UNUSED id[] = "$Id: parse.c,v 1.68 2007/08/02 10:14:26 fw Exp $";
#include "irc-oper.h"
#include "irc-server.h"
#include "irc-write.h"
#include "numeric.h"
#include "exp.h"
@@ -103,6 +104,13 @@ COMMAND My_Commands[] =
{ NULL, NULL, 0x0, 0, 0, 0 } /* Ende-Marke */
};
NUMERIC My_Numerics[] =
{
{ 005, IRC_Num_ISUPPORT },
{ 376, IRC_Num_ENDOFMOTD },
{ 0, NULL } /* end marker */
};
static void Init_Request PARAMS(( REQUEST *Req ));
@@ -349,6 +357,7 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
char str[LINE_LEN];
bool result;
COMMAND *cmd;
NUMERIC *num;
int i;
assert( Idx >= 0 );
@@ -358,25 +367,45 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
client = Conn_GetClient( Idx );
assert( client != NULL );
/* Statuscode? */
if(( Client_Type( client ) == CLIENT_SERVER ) && ( strlen( Req->command ) == 3 ) && ( atoi( Req->command ) > 100 ))
{
/* Command is a status code from an other server */
/* Numeric? */
if ((Client_Type(client) == CLIENT_SERVER ||
Client_Type(client) == CLIENT_UNKNOWNSERVER)
&& strlen(Req->command) == 3 && atoi(Req->command) > 1) {
/* Command is a status code ("numeric") from an other server */
/* Determine target */
if( Req->argc > 0 ) target = Client_Search( Req->argv[0] );
else target = NULL;
if( ! target )
{
if (Req->argc > 0)
target = Client_Search( Req->argv[0] );
else
target = NULL;
if (!target) {
/* Status code without target!? */
if( Req->argc > 0 ) Log( LOG_WARNING, "Unknown target for status code %s: \"%s\"", Req->command, Req->argv[0] );
else Log( LOG_WARNING, "Unknown target for status code %s!", Req->command );
if (Req->argc > 0)
Log(LOG_WARNING,
"Unknown target for status code %s: \"%s\"",
Req->command, Req->argv[0]);
else
Log(LOG_WARNING,
"Unknown target for status code %s!",
Req->command);
return true;
}
if( target == Client_ThisServer( ))
{
/* This server is the target, ignore it */
Log( LOG_DEBUG, "Ignored status code %s from \"%s\".", Req->command, Client_ID( client ));
if (target == Client_ThisServer()) {
/* This server is the target of the numeric */
i = atoi(Req->command);
num = My_Numerics;
while (num->numeric > 0) {
if (i != num->numeric) {
num++;
continue;
}
result = (num->function)(client, Req);
return result;
}
LogDebug("Ignored status code %s from \"%s\".",
Req->command, Client_ID(client));
return true;
}

View File

@@ -8,7 +8,7 @@
* (at your option) any later version.
* Please read the file COPYING, README and AUTHORS for more information.
*
* $Id: parse.h,v 1.11 2005/03/19 18:43:49 fw Exp $
* $Id: parse.h,v 1.12 2007/11/21 12:16:36 alex Exp $
*
* IRC command parser and validator (header)
*/
@@ -33,11 +33,18 @@ typedef struct _COMMAND
char *name; /* command name */
bool (*function) PARAMS(( CLIENT *Client, REQUEST *Request ));
CLIENT_TYPE type; /* valid client types (bit mask) */
long lcount, rcount; /* number of local and remote calls */
long bytes; /* number of bytes created */
long lcount, rcount; /* number of local and remote calls */
long bytes; /* number of bytes created */
} COMMAND;
typedef struct _NUMERIC
{
int numeric; /* numeric */
bool (*function) PARAMS(( CLIENT *Client, REQUEST *Request ));
} NUMERIC;
GLOBAL bool Parse_Request PARAMS((CONN_ID Idx, char *Request ));
GLOBAL COMMAND *Parse_GetCommandStruct PARAMS(( void ));