commit - 12db0bdc4fb2d4bf40d6961406400a248bac123c
commit + 47ca178a219d682c589b27e64ee1a4e936cc7bdc
blob - fbc51766fe7a1bf0fa3839aeb499f81a8f7af661
blob + d39fbd5177d5f57db24c45f21bea9648a634cf96
--- ChangeLog
+++ ChangeLog
ngIRCd HEAD
+ - 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.
- Re-added doc/SSL.txt to distribution -- got lost somewhere!?
- Fixes the wrong logging output when nested servers are introduced
to the network as well as the wrong output of the LINKS command.
--
-$Id: ChangeLog,v 1.328 2007/11/20 21:39:35 alex Exp $
+$Id: ChangeLog,v 1.329 2007/11/21 12:16:33 alex Exp $
blob - 2591b230dd7150d6b7f4ba11813b9db6bcbafda7
blob + a604926bd4e0e41ac28943b87727ee6f214d79a3
--- NEWS
+++ NEWS
ngIRCd HEAD
+ - New configuration option "MaxNickLength" to specify the allowed maximum
+ length of user nick names. Note: must be unique in an IRC network!
- Numeric 317: implemented "signon time" (displayed in WHOIS result).
- Added new server configuration option "Passive" for "Server" blocks to
disable automatic outgoing connections (similar to -p option to ngircd,
--
-$Id: NEWS,v 1.81 2007/10/14 14:17:32 alex Exp $
+$Id: NEWS,v 1.82 2007/11/21 12:16:33 alex Exp $
blob - 1ca7140d69505e665de32cd8dbc852fd2b81047f
blob + 1a032a79f5121ce9506b8f6a9d4227035cb8860f
--- contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj
+++ contrib/MacOSX/ngIRCd.xcodeproj/project.pbxproj
FA322D4D0CEF74B1001761B3 /* resolve.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D0C0CEF74B1001761B3 /* resolve.c */; };
FA322DBE0CEF7766001761B3 /* tool.c in Sources */ = {isa = PBXBuildFile; fileRef = FA322D330CEF74B1001761B3 /* tool.c */; };
FA322DC10CEF77CB001761B3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = FA322DC00CEF77CB001761B3 /* libz.dylib */; };
+ FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */ = {isa = PBXBuildFile; fileRef = FAE5CC2D0CF2308A007D69B6 /* numeric.c */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
FA322DB10CEF7565001761B3 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
FA322DBB0CEF773C001761B3 /* cvs-version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "cvs-version.h"; sourceTree = "<group>"; };
FA322DC00CEF77CB001761B3 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
+ FAE5CC2C0CF2308A007D69B6 /* numeric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = numeric.h; sourceTree = "<group>"; };
+ FAE5CC2D0CF2308A007D69B6 /* numeric.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = numeric.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
FA322D050CEF74B1001761B3 /* messages.h */,
FA322D060CEF74B1001761B3 /* ngircd.c */,
FA322D070CEF74B1001761B3 /* ngircd.h */,
+ FAE5CC2D0CF2308A007D69B6 /* numeric.c */,
+ FAE5CC2C0CF2308A007D69B6 /* numeric.h */,
FA322D080CEF74B1001761B3 /* parse.c */,
FA322D090CEF74B1001761B3 /* parse.h */,
FA322D0A0CEF74B1001761B3 /* rendezvous.c */,
FA322D4C0CEF74B1001761B3 /* rendezvous.c in Sources */,
FA322D4D0CEF74B1001761B3 /* resolve.c in Sources */,
FA322DBE0CEF7766001761B3 /* tool.c in Sources */,
+ FAE5CC2E0CF2308A007D69B6 /* numeric.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
blob - 14da84757493db2da0cad65be464120f2cf3ac23
blob + c81143e335928e9a7b7acc249117ebc227525cad
--- doc/Protocol.txt
+++ doc/Protocol.txt
ngIRCd - Next Generation IRC Server
- (c)2001-2003 by Alexander Barton,
+ (c)2001-2007 Alexander Barton,
alex@barton.de, http://www.barton.de/
ngIRCd is free software and published under the
peer understands this flag, it will send "MODE +I" and "MODE +b"
commands after the server link has been established.
+- H: The server supports the "enhanced server handshake", see section II.2
+ for a detailed description.
+
- o: IRC operators are allowed to change channel- and channel-user-modes
even if they aren't channel-operator of the affected channel.
defined in RFC 2813, section 4.1.1.
-II.2 Exchange channel-modes, topics, and persistent channels
+II.2 Enhanced Server Handshake
+The "enhanced server handshake" is used when both servers support this IRC+
+extension, which is indicated by the 'H' flag in the <serverflags> sent with
+the PASS command, see section II.1.
+
+It basically means, that after exchanging the PASS and SERVER commands the
+server is not registered in the network (as usual), but that IRC numerics
+are exchanged until the numeric 376 (ENDOFMOTD) is received. Afterwards the
+peer is registered in the network as with the regular IRC protocol.
+
+A server implementing the enhanced server handshake (and indicating this
+using 'H' in the <serverflags>) MUST ignore all unknown numerics to it
+silently.
+
+In addition, such a server should at least send the numeric 005 (ISUPPORT)
+to its peer, containing the following information. Syntax: <key>=<value>,
+one token per IRC parameter. If the server has to send more than 12 token
+it must send separate ISUPPORT numerics (this is a limitation of the IRC
+protocol which allows at max 15 arguments per command).
+
+ - NICKLEN: Maximum nickname length. Default: 9.
+ - CASEMAPPING: Case mapping used for nick- and channel name comparing.
+ Default: "ascii", the chars [a-z] are lowercase of [A-Z].
+ - PREFIX: List of channel modes a person can get and the respective prefix
+ a channel or nickname will get in case the person has it. The order of the
+ modes goes from most powerful to least powerful. Default: "(ov)@+"
+ - CHANTYPES: Supported channel prefixes. Default: "#".
+ - CHANMODES: List of channel modes for 4 types, separated by comma (","):
+ Mode that adds or removes a nick or address to a list, mode that changes
+ a setting (both have always has a parameter), mode that changes a setting
+ and only has a parameter when set, and mode that changes a setting and
+ never has a parameter. For example "bI,k,l,imnPst".
+ - CHANLIMIT: Maximum number of channels allowed to join by channel prefix,
+ for example "#:10".
+
+Please see <http://www.irc.org/tech_docs/005.html> for details.
+
+The information exchanged using ISUPPORT can be used to detect configuration
+incompatibilities (different maximum nick name length, for example) and
+therefore to disconnect the peer prior to registering it in the network.
+
+
+II.3 Exchange channel-modes, topics, and persistent channels
+
Command: CHANINFO
Parameters: <channel> +<modes> <key> <limit> [<topic>]
Used by: servers only
--
-$Id: Protocol.txt,v 1.13 2005/08/27 19:00:06 alex Exp $
+$Id: Protocol.txt,v 1.14 2007/11/21 12:16:35 alex Exp $
blob - e17b0e60690dd5b46a886985391acc7a083c3b9d
blob + 924f0595450939600f516516f97bf5b063bca401
--- doc/sample-ngircd.conf
+++ doc/sample-ngircd.conf
-# $Id: sample-ngircd.conf,v 1.41 2007/10/13 20:45:11 fw Exp $
+# $Id: sample-ngircd.conf,v 1.42 2007/11/21 12:16:35 alex Exp $
#
# This is a sample configuration file for the ngIRCd, which must be adepted
# Maximum number of channels a user can be member of (0: no limit):
;MaxJoins = 10
+ # Maximum length of an user nick name (Default: 9, as in RFC 2812).
+ # Please note that all servers in an IRC network MUST use the same
+ # maximum nick name length!
+ ;MaxNickLength = 9
+
[Operator]
# [Operator] sections are used to define IRC Operators. There may be
# more than one [Operator] block, one for each local operator.
blob - 8321900926d6218ec9ffb7ad34a3166a90f608dd
blob + 457a162caba1c71918304b67262f81ca0bfb8343
--- man/ngircd.conf.5.tmpl
+++ man/ngircd.conf.5.tmpl
.\"
-.\" $Id: ngircd.conf.5.tmpl,v 1.5 2007/10/25 11:01:19 fw Exp $
+.\" $Id: ngircd.conf.5.tmpl,v 1.6 2007/11/21 12:16:36 alex Exp $
.\"
.TH ngircd.conf 5 "August 2005" ngircd "ngIRCd Manual"
.SH NAME
\fBMaxJoins\fR
Maximum number of channels a user can be member of (0: no limit).
Default: 10.
+.TP
+\fBMaxNickLength\fR
+Maximum length of an user nick name (Default: 9, as in RFC 2812). Please
+note that all servers in an IRC network MUST use the same maximum nick name
+length!
.SH [OPERATOR]
.I [Operator]
sections are used to define IRC Operators. There may be more than one
blob - 52bd1615bd4fc5b9400e43ec5f96c8ac7e25829f
blob + 46513a8a54da042e4b74fbc21ef165ed23c20b4c
--- src/ngircd/Makefile.am
+++ src/ngircd/Makefile.am
# (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
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
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:
blob - 474ae4b6460c4be738b90e723065885ffa0a51ad
blob + c7d6427f939b72be30a05c2405ed20074cbbc3c7
--- src/ngircd/client.c
+++ src/ngircd/client.c
#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>
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;
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 )
blob - c9643dad491d75c5abefb7af49a7431ef31f1991
blob + c55aaf53a775f8945706a73305d3157ed277b623
--- src/ngircd/conf.c
+++ src/ngircd/conf.c
#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>
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;
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++] ));
return false;
} /* 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
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 ));
blob - ce09997c23ee8bffeb460c405a3791fa922b527c
blob + 371f94db64233155d2169f16093d93e5df470195
--- src/ngircd/conf.h
+++ src/ngircd/conf.h
* (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)
*/
/* 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));
blob - 251a6997dd3c1e084525cc29ede57c8219735cc2
blob + cccf48b43e5f719d3a19146f995956e36fd6803e
--- src/ngircd/defines.h
+++ src/ngircd/defines.h
* (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 $
*/
#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 */
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
blob - 4ed05b332b21f2506999886c564f02c70d00c2db
blob + 683f7d1b04b8a79f0f3ff04f2d94771c14270ee4
--- src/ngircd/irc-info.c
+++ src/ngircd/irc-info.c
#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>
}
return CONNECTED;
} /* 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- */
blob - 24181e375e7c0396860ff68ff3ef8bb4866deb3d
blob + 41e3953d1cd5ffab5988acbf099f70d748409154
--- src/ngircd/irc-info.h
+++ src/ngircd/irc-info.h
* (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)
*/
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
blob - caa78a1f3822993c3e9190d7a1c15d8e0e149e3b
blob + a095ddc00bbf45ca73b6ac553fbaff73e806756c
--- src/ngircd/irc-login.c
+++ src/ngircd/irc-login.c
#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>
/* 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 );
blob - 3fc0e2dc1e84f2032e1ad0aa4f1c70cc82b14e93
blob + d342ffab754f463ce423f842c41f56e9f37c192c
--- src/ngircd/irc-server.c
+++ src/ngircd/irc-server.c
#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>
#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.
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 );
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 );
+ /* Mark this connection as belonging to an configured server */
+ Conf_SetServer(i, con);
+
+ Client_SetType(Client, CLIENT_UNKNOWNSERVER);
- Client_SetType( Client, CLIENT_SERVER );
- Conf_SetServer( i, con );
-
#ifdef ZLIB
/* Kompression initialisieren, wenn erforderlich */
if( strchr( Client_Flags( Client ), 'Z' ))
}
#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 ..." );
+ 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
- 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);
- }
-
+ 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
- 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))
- return DISCONNECTED;
}
#endif
- return CONNECTED;
+ return IRC_Num_ENDOFMOTD(Client, Req);
}
else if( Client_Type( Client ) == CLIENT_SERVER )
{
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 */
blob - 6322b25368f74f1c849c3b44e1c128147ae128ef
blob + 9940d79117f98b5a9fc2ab2880f8aa7124678c0d
--- src/ngircd/irc-server.h
+++ src/ngircd/irc-server.h
* (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)
*/
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
blob - 1eb68b4c94f824950e6b239a5641bff22dbc8ae6
blob + d2a6d7ea8faae860f0df893edef82969acf80a3b
--- src/ngircd/ngircd.c
+++ src/ngircd/ngircd.c
#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
NGIRCd_Rehash( void )
{
char old_name[CLIENT_ID_LEN];
+ unsigned old_nicklen;
Log( LOG_NOTICE|LOG_snotice, "Re-reading configuration NOW!" );
NGIRCd_SignalRehash = false;
/* 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 */
Channel_InitPredefined( );
blob - b5e64a331ffd0a2c57b503e0d0ca2097d84747ec
blob + 5109169b72a068b8ff4655adda8bcb6637c093b1
--- src/ngircd/parse.c
+++ src/ngircd/parse.c
#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
#include "irc-oper.h"
#include "irc-server.h"
#include "irc-write.h"
+#include "numeric.h"
#include "exp.h"
{ "CHANINFO", IRC_CHANINFO, CLIENT_SERVER, 0, 0, 0 },
#endif
{ NULL, NULL, 0x0, 0, 0, 0 } /* Ende-Marke */
+};
+
+NUMERIC My_Numerics[] =
+{
+ { 005, IRC_Num_ISUPPORT },
+ { 376, IRC_Num_ENDOFMOTD },
+ { 0, NULL } /* end marker */
};
char str[LINE_LEN];
bool result;
COMMAND *cmd;
+ NUMERIC *num;
int i;
assert( Idx >= 0 );
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;
}
blob - b095666601ba7018284055dc8698232de88c9d4c
blob + e7a00879b5b826f7bef0dd4d604314fc0114ca09
--- src/ngircd/parse.h
+++ src/ngircd/parse.h
* (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)
*/
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 ));