/*
* ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2006 Alexander Barton (alex@barton.de)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "portab.h"
-static char UNUSED id[] = "$Id: irc-server.c,v 1.37 2004/05/11 00:01:11 alex Exp $";
+static char UNUSED id[] = "$Id: irc-server.c,v 1.43 2006/12/07 17:57:20 fw Exp $";
#include "imp.h"
#include <assert.h>
#include "irc-server.h"
-GLOBAL BOOLEAN
+#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;
+ char str[LINE_LEN], *ptr, *modes, *topic;
CLIENT *from, *c, *cl;
CL2CHAN *cl2chan;
- INT max_hops, i;
+ int max_hops, i;
CHANNEL *chan;
- BOOLEAN ok;
+ bool ok;
CONN_ID con;
assert( Client != NULL );
assert( Req != NULL );
- /* Fehler liefern, wenn kein lokaler Client */
- if( Client_Conn( Client ) <= NONE ) return IRC_WriteStrClient( Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( Client ), Req->command );
+ /* Return an error if this is not a local client */
+ if (Client_Conn(Client) <= NONE)
+ return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG,
+ Client_ID(Client), Req->command);
- if( Client_Type( Client ) == CLIENT_GOTPASSSERVER )
- {
- /* Verbindung soll als Server-Server-Verbindung registriert werden */
- Log( LOG_DEBUG, "Connection %d: got SERVER command (new server link) ...", Client_Conn( Client ));
+ if (Client_Type(Client) == CLIENT_GOTPASS) {
+ /* We got a PASS command from the peer, and now a SERVER
+ * command: the peer tries to register itself as a server. */
+ LogDebug("Connection %d: got SERVER command (new server link) ...",
+ Client_Conn(Client));
/* Falsche Anzahl Parameter? */
if(( Req->argc != 2 ) && ( Req->argc != 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
{
/* Server ist nicht konfiguriert! */
Log( LOG_ERR, "Connection %d: Server \"%s\" not configured here!", Client_Conn( Client ), Req->argv[0] );
- Conn_Close( Client_Conn( Client ), NULL, "Server not configured here", TRUE );
+ Conn_Close( Client_Conn( Client ), NULL, "Server not configured here", true);
return DISCONNECTED;
}
if( strcmp( Client_Password( Client ), Conf_Server[i].pwd_in ) != 0 )
{
/* Falsches Passwort */
Log( LOG_ERR, "Connection %d: Got bad password from server \"%s\"!", Client_Conn( Client ), Req->argv[0] );
- Conn_Close( Client_Conn( Client ), NULL, "Bad password", TRUE );
+ Conn_Close( Client_Conn( Client ), NULL, "Bad password", true);
return DISCONNECTED;
}
if( Client_Token( Client ) != TOKEN_OUTBOUND )
{
/* Eingehende Verbindung: Unseren SERVER- und PASS-Befehl senden */
- ok = TRUE;
- if( ! IRC_WriteStrClient( Client, "PASS %s %s", Conf_Server[i].pwd_out, NGIRCd_ProtoID )) ok = FALSE;
+ ok = true;
+ if( ! IRC_WriteStrClient( Client, "PASS %s %s", Conf_Server[i].pwd_out, NGIRCd_ProtoID )) ok = false;
else ok = IRC_WriteStrClient( Client, "SERVER %s 1 :%s", Conf_ServerName, Conf_ServerInfo );
if( ! ok )
{
- Conn_Close( con, "Unexpected server behavior!", NULL, FALSE );
+ Conn_Close( con, "Unexpected server behavior!", NULL, false );
return DISCONNECTED;
}
Client_SetIntroducer( Client, Client );
if( ! Zip_InitConn( con ))
{
/* Fehler! */
- Conn_Close( con, "Can't inizialize compression (zlib)!", NULL, FALSE );
+ Conn_Close( con, "Can't inizialize compression (zlib)!", NULL, false );
return DISCONNECTED;
}
}
else
{
/* "CHANINFO <chan> +<modes> <key> <limit> :<topic>" */
- if( ! IRC_WriteStrClient( Client, "CHANINFO %s +%s %s %ld :%s", Channel_Name( chan ), modes, strchr( Channel_Modes( chan ), 'k' ) ? Channel_Key( chan ) : "*", strchr( Channel_Modes( chan ), 'l' ) ? Channel_MaxUsers( chan ) : 0L, topic )) return DISCONNECTED;
+ 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 ) : 0UL, topic ))
+ {
+ return DISCONNECTED;
+ }
}
}
}
if( ! IRC_WriteStrClient( Client, "%s", str )) return DISCONNECTED;
}
+ /* Get next channel ... */
+ chan = Channel_Next(chan);
+ }
+
#ifdef IRCPLUS
- if( strchr( Client_Flags( Client ), 'L' ))
- {
+ if (strchr(Client_Flags(Client), 'L')) {
#ifdef DEBUG
- Log( LOG_DEBUG, "Synchronizing INVITE- and BAN-lists ..." );
+ Log(LOG_DEBUG,
+ "Synchronizing INVITE- and BAN-lists ...");
#endif
- /* Synchronize INVITE- and BAN-lists */
- if( ! Lists_SendInvites( Client )) return DISCONNECTED;
- if( ! Lists_SendBans( Client )) return DISCONNECTED;
- }
+ /* Synchronize INVITE- and BAN-lists */
+ if (!Synchronize_Lists(Client))
+ return DISCONNECTED;
+ }
#endif
- /* naechsten Channel suchen */
- chan = Channel_Next( chan );
- }
-
return CONNECTED;
}
else if( Client_Type( Client ) == CLIENT_SERVER )
{
/* Hm, Server, der diesen einfuehrt, ist nicht bekannt!? */
Log( LOG_ALERT, "Unknown ID in prefix of SERVER: \"%s\"! (on connection %d)", Req->prefix, Client_Conn( Client ));
- Conn_Close( Client_Conn( Client ), NULL, "Unknown ID in prefix of SERVER", TRUE );
+ Conn_Close( Client_Conn( Client ), NULL, "Unknown ID in prefix of SERVER", true);
return DISCONNECTED;
}
/* Neue Client-Struktur anlegen */
- c = Client_NewRemoteServer( Client, Req->argv[0], from, atoi( Req->argv[1] ), atoi( Req->argv[2] ), ptr, TRUE );
+ c = Client_NewRemoteServer( Client, Req->argv[0], from, atoi( Req->argv[1] ), atoi( Req->argv[2] ), ptr, true);
if( ! c )
{
/* Neue Client-Struktur konnte nicht angelegt werden */
Log( LOG_ALERT, "Can't create client structure for server! (on connection %d)", Client_Conn( Client ));
- Conn_Close( Client_Conn( Client ), NULL, "Can't allocate client structure for remote server", TRUE );
+ Conn_Close( Client_Conn( Client ), NULL, "Can't allocate client structure for remote server", true);
return DISCONNECTED;
}
} /* IRC_SERVER */
-GLOBAL BOOLEAN
+GLOBAL bool
IRC_NJOIN( CLIENT *Client, REQUEST *Req )
{
- CHAR nick_in[COMMAND_LEN], nick_out[COMMAND_LEN], *channame, *ptr, modes[8];
- BOOLEAN is_op, is_voiced;
+ char nick_in[COMMAND_LEN], nick_out[COMMAND_LEN], *channame, *ptr, modes[8];
+ bool is_op, is_voiced;
CHANNEL *chan;
CLIENT *c;
ptr = strtok( nick_in, "," );
while( ptr )
{
- is_op = is_voiced = FALSE;
+ is_op = is_voiced = false;
/* Prefixe abschneiden */
while(( *ptr == '@' ) || ( *ptr == '+' ))
{
- if( *ptr == '@' ) is_op = TRUE;
- if( *ptr == '+' ) is_voiced = TRUE;
+ if( *ptr == '@' ) is_op = true;
+ if( *ptr == '+' ) is_voiced = true;
ptr++;
}
if( is_voiced ) Channel_UserModeAdd( chan, c, 'v' );
/* im Channel bekannt machen */
- IRC_WriteStrChannelPrefix( Client, chan, c, FALSE, "JOIN :%s", channame );
+ IRC_WriteStrChannelPrefix( Client, chan, c, false, "JOIN :%s", channame );
/* Channel-User-Modes setzen */
strlcpy( modes, Channel_UserModes( chan, c ), sizeof( modes ));
if( modes[0] )
{
/* Modes im Channel bekannt machen */
- IRC_WriteStrChannelPrefix( Client, chan, Client, FALSE, "MODE %s +%s %s", channame, modes, Client_ID( c ));
+ IRC_WriteStrChannelPrefix( Client, chan, Client, false, "MODE %s +%s %s", channame, modes, Client_ID( c ));
}
if( nick_out[0] != '\0' ) strlcat( nick_out, ",", sizeof( nick_out ));
} /* IRC_NJOIN */
-GLOBAL BOOLEAN
+GLOBAL bool
IRC_SQUIT( CLIENT *Client, REQUEST *Req )
{
CLIENT *target;
- CHAR msg[LINE_LEN + 64];
+ char msg[LINE_LEN + 64];
assert( Client != NULL );
assert( Req != NULL );
if( Client_Conn( target ) > NONE )
{
/* dieser Server hat die Connection */
- if( Req->argv[1][0] ) Conn_Close( Client_Conn( target ), msg, Req->argv[1], TRUE );
- else Conn_Close( Client_Conn( target ), msg, NULL, TRUE );
+ if( Req->argv[1][0] ) Conn_Close( Client_Conn( target ), msg, Req->argv[1], true);
+ else Conn_Close( Client_Conn( target ), msg, NULL, true);
return DISCONNECTED;
}
else
{
/* Verbindung hielt anderer Server */
- Client_Destroy( target, msg, Req->argv[1], FALSE );
+ Client_Destroy( target, msg, Req->argv[1], false );
return CONNECTED;
}
} /* IRC_SQUIT */