|
@@ -1,6 +1,6 @@
|
|
/*
|
|
/*
|
|
* ngIRCd -- The Next Generation IRC Daemon
|
|
* ngIRCd -- The Next Generation IRC Daemon
|
|
- * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
|
|
|
|
|
|
+ * Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
|
|
*
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* 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
|
|
* it under the terms of the GNU General Public License as published by
|
|
@@ -33,24 +33,21 @@
|
|
#include "parse.h"
|
|
#include "parse.h"
|
|
#include "irc.h"
|
|
#include "irc.h"
|
|
#include "irc-info.h"
|
|
#include "irc-info.h"
|
|
|
|
+#include "irc-macros.h"
|
|
#include "irc-write.h"
|
|
#include "irc-write.h"
|
|
|
|
|
|
#include "exp.h"
|
|
#include "exp.h"
|
|
#include "irc-login.h"
|
|
#include "irc-login.h"
|
|
|
|
|
|
-static void Kill_Nick PARAMS((char *Nick, char *Reason));
|
|
|
|
static void Change_Nick PARAMS((CLIENT * Origin, CLIENT * Target, char *NewNick,
|
|
static void Change_Nick PARAMS((CLIENT * Origin, CLIENT * Target, char *NewNick,
|
|
bool InformClient));
|
|
bool InformClient));
|
|
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Handler for the IRC "PASS" command.
|
|
* Handler for the IRC "PASS" command.
|
|
*
|
|
*
|
|
- * See RFC 2813 section 4.1.1, and RFC 2812 section 3.1.1.
|
|
|
|
- *
|
|
|
|
- * @param Client The client from which this command has been received.
|
|
|
|
- * @param Req Request structure with prefix and all parameters.
|
|
|
|
- * @returns CONNECTED or DISCONNECTED.
|
|
|
|
|
|
+ * @param Client The client from which this command has been received.
|
|
|
|
+ * @param Req Request structure with prefix and all parameters.
|
|
|
|
+ * @return CONNECTED or DISCONNECTED.
|
|
*/
|
|
*/
|
|
GLOBAL bool
|
|
GLOBAL bool
|
|
IRC_PASS( CLIENT *Client, REQUEST *Req )
|
|
IRC_PASS( CLIENT *Client, REQUEST *Req )
|
|
@@ -63,7 +60,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
|
|
|
|
|
|
/* Return an error if this is not a local client */
|
|
/* Return an error if this is not a local client */
|
|
if (Client_Conn(Client) <= NONE)
|
|
if (Client_Conn(Client) <= NONE)
|
|
- return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_UNKNOWNCOMMAND_MSG,
|
|
Client_ID(Client), Req->command);
|
|
Client_ID(Client), Req->command);
|
|
|
|
|
|
if (Client_Type(Client) == CLIENT_UNKNOWN && Req->argc == 1) {
|
|
if (Client_Type(Client) == CLIENT_UNKNOWN && Req->argc == 1) {
|
|
@@ -83,11 +80,12 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
|
|
} else if (Client_Type(Client) == CLIENT_UNKNOWN ||
|
|
} else if (Client_Type(Client) == CLIENT_UNKNOWN ||
|
|
Client_Type(Client) == CLIENT_UNKNOWNSERVER) {
|
|
Client_Type(Client) == CLIENT_UNKNOWNSERVER) {
|
|
/* Unregistered connection, but wrong number of arguments: */
|
|
/* Unregistered connection, but wrong number of arguments: */
|
|
- return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
|
|
|
|
|
+ IRC_SetPenalty(Client, 2);
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
|
Client_ID(Client), Req->command);
|
|
Client_ID(Client), Req->command);
|
|
} else {
|
|
} else {
|
|
/* Registered connection, PASS command is not allowed! */
|
|
/* Registered connection, PASS command is not allowed! */
|
|
- return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_ALREADYREGISTRED_MSG,
|
|
Client_ID(Client));
|
|
Client_ID(Client));
|
|
}
|
|
}
|
|
|
|
|
|
@@ -146,7 +144,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
|
|
} else
|
|
} else
|
|
flags = "";
|
|
flags = "";
|
|
Log(LOG_INFO,
|
|
Log(LOG_INFO,
|
|
- "Peer on conenction %d announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").",
|
|
|
|
|
|
+ "Peer on connection %d announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").",
|
|
Client_Conn(Client), impl, serverver,
|
|
Client_Conn(Client), impl, serverver,
|
|
protohigh, protolow, flags);
|
|
protohigh, protolow, flags);
|
|
} else {
|
|
} else {
|
|
@@ -167,19 +165,12 @@ IRC_PASS( CLIENT *Client, REQUEST *Req )
|
|
return CONNECTED;
|
|
return CONNECTED;
|
|
} /* IRC_PASS */
|
|
} /* IRC_PASS */
|
|
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Handler for the IRC "NICK" command.
|
|
* Handler for the IRC "NICK" command.
|
|
*
|
|
*
|
|
- * See RFC 2812, 3.1.2 "Nick message", and RFC 2813, 4.1.3 "Nick".
|
|
|
|
- *
|
|
|
|
- * This function implements the IRC command "NICK" which is used to register
|
|
|
|
- * with the server, to change already registered nicknames and to introduce
|
|
|
|
- * new users which are connected to other servers.
|
|
|
|
- *
|
|
|
|
- * @param Client The client from which this command has been received.
|
|
|
|
- * @param Req Request structure with prefix and all parameters.
|
|
|
|
- * @returns CONNECTED or DISCONNECTED.
|
|
|
|
|
|
+ * @param Client The client from which this command has been received.
|
|
|
|
+ * @param Req Request structure with prefix and all parameters.
|
|
|
|
+ * @return CONNECTED or DISCONNECTED.
|
|
*/
|
|
*/
|
|
GLOBAL bool
|
|
GLOBAL bool
|
|
IRC_NICK( CLIENT *Client, REQUEST *Req )
|
|
IRC_NICK( CLIENT *Client, REQUEST *Req )
|
|
@@ -204,31 +195,22 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
|
|
|| (Client_Type(Client) == CLIENT_SERVER && Req->argc == 1))
|
|
|| (Client_Type(Client) == CLIENT_SERVER && Req->argc == 1))
|
|
{
|
|
{
|
|
/* User registration or change of nickname */
|
|
/* User registration or change of nickname */
|
|
-
|
|
|
|
- /* Wrong number of arguments? */
|
|
|
|
- if( Req->argc != 1 )
|
|
|
|
- return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG,
|
|
|
|
- Client_ID( Client ),
|
|
|
|
- Req->command );
|
|
|
|
|
|
+ _IRC_ARGC_EQ_OR_RETURN_(Client, Req, 1)
|
|
|
|
|
|
/* Search "target" client */
|
|
/* Search "target" client */
|
|
- if( Client_Type( Client ) == CLIENT_SERVER )
|
|
|
|
- {
|
|
|
|
- target = Client_Search( Req->prefix );
|
|
|
|
- if( ! target )
|
|
|
|
- return IRC_WriteStrClient( Client,
|
|
|
|
- ERR_NOSUCHNICK_MSG,
|
|
|
|
- Client_ID( Client ),
|
|
|
|
- Req->argv[0] );
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
|
|
+ if (Client_Type(Client) == CLIENT_SERVER) {
|
|
|
|
+ target = Client_Search(Req->prefix);
|
|
|
|
+ if (!target)
|
|
|
|
+ return IRC_WriteErrClient(Client,
|
|
|
|
+ ERR_NOSUCHNICK_MSG,
|
|
|
|
+ Client_ID(Client),
|
|
|
|
+ Req->argv[0]);
|
|
|
|
+ } else {
|
|
/* Is this a restricted client? */
|
|
/* Is this a restricted client? */
|
|
- if( Client_HasMode( Client, 'r' ))
|
|
|
|
- return IRC_WriteStrClient( Client,
|
|
|
|
- ERR_RESTRICTED_MSG,
|
|
|
|
- Client_ID( Client ));
|
|
|
|
-
|
|
|
|
|
|
+ if (Client_HasMode(Client, 'r'))
|
|
|
|
+ return IRC_WriteErrClient(Client,
|
|
|
|
+ ERR_RESTRICTED_MSG,
|
|
|
|
+ Client_ID(Client));
|
|
target = Client;
|
|
target = Client;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -237,15 +219,14 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
|
|
* do anything. This is how the original ircd behaves and some
|
|
* do anything. This is how the original ircd behaves and some
|
|
* clients (for example Snak) expect it to be like this.
|
|
* clients (for example Snak) expect it to be like this.
|
|
* But I doubt that this is "really the right thing" ... */
|
|
* But I doubt that this is "really the right thing" ... */
|
|
- if( strcmp( Client_ID( target ), Req->argv[0] ) == 0 )
|
|
|
|
|
|
+ if (strcmp(Client_ID(target), Req->argv[0]) == 0)
|
|
return CONNECTED;
|
|
return CONNECTED;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/* Check that the new nickname is available. Special case:
|
|
/* Check that the new nickname is available. Special case:
|
|
* the client only changes from/to upper to lower case. */
|
|
* the client only changes from/to upper to lower case. */
|
|
- if( strcasecmp( Client_ID( target ), Req->argv[0] ) != 0 )
|
|
|
|
- {
|
|
|
|
- if( ! Client_CheckNick( target, Req->argv[0] ))
|
|
|
|
|
|
+ if (strcasecmp(Client_ID(target), Req->argv[0]) != 0) {
|
|
|
|
+ if (!Client_CheckNick(target, Req->argv[0]))
|
|
return CONNECTED;
|
|
return CONNECTED;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -261,7 +242,11 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
|
|
|
|
|
|
#ifndef STRICT_RFC
|
|
#ifndef STRICT_RFC
|
|
if (Conf_AuthPing) {
|
|
if (Conf_AuthPing) {
|
|
|
|
+#ifdef HAVE_ARC4RANDOM
|
|
|
|
+ Conn_SetAuthPing(Client_Conn(Client), arc4random());
|
|
|
|
+#else
|
|
Conn_SetAuthPing(Client_Conn(Client), rand());
|
|
Conn_SetAuthPing(Client_Conn(Client), rand());
|
|
|
|
+#endif
|
|
IRC_WriteStrClient(Client, "PING :%ld",
|
|
IRC_WriteStrClient(Client, "PING :%ld",
|
|
Conn_GetAuthPing(Client_Conn(Client)));
|
|
Conn_GetAuthPing(Client_Conn(Client)));
|
|
LogDebug("Connection %d: sent AUTH PING %ld ...",
|
|
LogDebug("Connection %d: sent AUTH PING %ld ...",
|
|
@@ -289,9 +274,11 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
|
|
/* Server or service introduces new client */
|
|
/* Server or service introduces new client */
|
|
|
|
|
|
/* Bad number of parameters? */
|
|
/* Bad number of parameters? */
|
|
- if (Req->argc != 2 && Req->argc != 7)
|
|
|
|
- return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
|
|
|
|
|
+ if (Req->argc != 2 && Req->argc != 7) {
|
|
|
|
+ IRC_SetPenalty(Client, 2);
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
|
Client_ID(Client), Req->command);
|
|
Client_ID(Client), Req->command);
|
|
|
|
+ }
|
|
|
|
|
|
if (Req->argc >= 7) {
|
|
if (Req->argc >= 7) {
|
|
/* RFC 2813 compatible syntax */
|
|
/* RFC 2813 compatible syntax */
|
|
@@ -319,28 +306,33 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
|
|
* the new nick is already present on this server:
|
|
* the new nick is already present on this server:
|
|
* the new and the old one have to be disconnected now.
|
|
* the new and the old one have to be disconnected now.
|
|
*/
|
|
*/
|
|
- Log( LOG_ERR, "Server %s introduces already registered nick \"%s\"!", Client_ID( Client ), Req->argv[0] );
|
|
|
|
- Kill_Nick( Req->argv[0], "Nick collision" );
|
|
|
|
- return CONNECTED;
|
|
|
|
|
|
+ Log(LOG_ERR,
|
|
|
|
+ "Server %s introduces already registered nick \"%s\"!",
|
|
|
|
+ Client_ID(Client), Req->argv[0]);
|
|
|
|
+ return IRC_KillClient(Client, NULL, Req->argv[0],
|
|
|
|
+ "Nick collision");
|
|
}
|
|
}
|
|
|
|
|
|
/* Find the Server this client is connected to */
|
|
/* Find the Server this client is connected to */
|
|
intr_c = Client_GetFromToken(Client, token);
|
|
intr_c = Client_GetFromToken(Client, token);
|
|
- if( ! intr_c )
|
|
|
|
- {
|
|
|
|
- Log( LOG_ERR, "Server %s introduces nick \"%s\" on unknown server!?", Client_ID( Client ), Req->argv[0] );
|
|
|
|
- Kill_Nick( Req->argv[0], "Unknown server" );
|
|
|
|
- return CONNECTED;
|
|
|
|
|
|
+ if (!intr_c) {
|
|
|
|
+ Log(LOG_ERR,
|
|
|
|
+ "Server %s introduces nick \"%s\" on unknown server!?",
|
|
|
|
+ Client_ID(Client), Req->argv[0]);
|
|
|
|
+ return IRC_KillClient(Client, NULL, Req->argv[0],
|
|
|
|
+ "Unknown server");
|
|
}
|
|
}
|
|
|
|
|
|
c = Client_NewRemoteUser(intr_c, nick, hops, user, hostname,
|
|
c = Client_NewRemoteUser(intr_c, nick, hops, user, hostname,
|
|
token, modes, info, true);
|
|
token, modes, info, true);
|
|
- if( ! c )
|
|
|
|
- {
|
|
|
|
- /* out of memory, need to disconnect client to keep network state consistent */
|
|
|
|
- Log( LOG_ALERT, "Can't create client structure! (on connection %d)", Client_Conn( Client ));
|
|
|
|
- Kill_Nick( Req->argv[0], "Server error" );
|
|
|
|
- return CONNECTED;
|
|
|
|
|
|
+ if (!c) {
|
|
|
|
+ /* Out of memory, we need to disconnect client to keep
|
|
|
|
+ * network state consistent! */
|
|
|
|
+ Log(LOG_ALERT,
|
|
|
|
+ "Can't create client structure! (on connection %d)",
|
|
|
|
+ Client_Conn(Client));
|
|
|
|
+ return IRC_KillClient(Client, NULL, Req->argv[0],
|
|
|
|
+ "Server error");
|
|
}
|
|
}
|
|
|
|
|
|
/* RFC 2813: client is now fully registered, inform all the
|
|
/* RFC 2813: client is now fully registered, inform all the
|
|
@@ -356,10 +348,11 @@ IRC_NICK( CLIENT *Client, REQUEST *Req )
|
|
|
|
|
|
return CONNECTED;
|
|
return CONNECTED;
|
|
}
|
|
}
|
|
- else return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
|
|
|
|
|
|
+ else
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_ALREADYREGISTRED_MSG,
|
|
|
|
+ Client_ID(Client));
|
|
} /* IRC_NICK */
|
|
} /* IRC_NICK */
|
|
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Handler for the IRC "SVSNICK" command.
|
|
* Handler for the IRC "SVSNICK" command.
|
|
*
|
|
*
|
|
@@ -375,10 +368,6 @@ IRC_SVSNICK(CLIENT *Client, REQUEST *Req)
|
|
assert(Client != NULL);
|
|
assert(Client != NULL);
|
|
assert(Req != NULL);
|
|
assert(Req != NULL);
|
|
|
|
|
|
- if (Req->argc != 2)
|
|
|
|
- return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
|
|
|
- Client_ID(Client), Req->command);
|
|
|
|
-
|
|
|
|
/* Search the originator */
|
|
/* Search the originator */
|
|
from = Client_Search(Req->prefix);
|
|
from = Client_Search(Req->prefix);
|
|
if (!from)
|
|
if (!from)
|
|
@@ -387,7 +376,7 @@ IRC_SVSNICK(CLIENT *Client, REQUEST *Req)
|
|
/* Search the target */
|
|
/* Search the target */
|
|
target = Client_Search(Req->argv[0]);
|
|
target = Client_Search(Req->argv[0]);
|
|
if (!target || Client_Type(target) != CLIENT_USER) {
|
|
if (!target || Client_Type(target) != CLIENT_USER) {
|
|
- return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,
|
|
Client_ID(Client), Req->argv[0]);
|
|
Client_ID(Client), Req->argv[0]);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -411,11 +400,9 @@ IRC_SVSNICK(CLIENT *Client, REQUEST *Req)
|
|
/**
|
|
/**
|
|
* Handler for the IRC "USER" command.
|
|
* Handler for the IRC "USER" command.
|
|
*
|
|
*
|
|
- * See RFC 2812, 3.1.3 "User message".
|
|
|
|
- *
|
|
|
|
- * @param Client The client from which this command has been received.
|
|
|
|
- * @param Req Request structure with prefix and all parameters.
|
|
|
|
- * @returns CONNECTED or DISCONNECTED.
|
|
|
|
|
|
+ * @param Client The client from which this command has been received.
|
|
|
|
+ * @param Req Request structure with prefix and all parameters.
|
|
|
|
+ * @return CONNECTED or DISCONNECTED.
|
|
*/
|
|
*/
|
|
GLOBAL bool
|
|
GLOBAL bool
|
|
IRC_USER(CLIENT * Client, REQUEST * Req)
|
|
IRC_USER(CLIENT * Client, REQUEST * Req)
|
|
@@ -433,18 +420,14 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
|
|
Client_Type(Client) == CLIENT_GOTPASS)
|
|
Client_Type(Client) == CLIENT_GOTPASS)
|
|
{
|
|
{
|
|
/* New connection */
|
|
/* New connection */
|
|
- if (Req->argc != 4)
|
|
|
|
- return IRC_WriteStrClient(Client,
|
|
|
|
- ERR_NEEDMOREPARAMS_MSG,
|
|
|
|
- Client_ID(Client),
|
|
|
|
- Req->command);
|
|
|
|
|
|
+ _IRC_ARGC_EQ_OR_RETURN_(Client, Req, 4)
|
|
|
|
|
|
/* User name: only alphanumeric characters and limited
|
|
/* User name: only alphanumeric characters and limited
|
|
punctuation is allowed.*/
|
|
punctuation is allowed.*/
|
|
ptr = Req->argv[0];
|
|
ptr = Req->argv[0];
|
|
while (*ptr) {
|
|
while (*ptr) {
|
|
if (!isalnum((int)*ptr) &&
|
|
if (!isalnum((int)*ptr) &&
|
|
- *ptr != '+' && *ptr != '-' &&
|
|
|
|
|
|
+ *ptr != '+' && *ptr != '-' && *ptr != '@' &&
|
|
*ptr != '.' && *ptr != '_') {
|
|
*ptr != '.' && *ptr != '_') {
|
|
Conn_Close(Client_Conn(Client), NULL,
|
|
Conn_Close(Client_Conn(Client), NULL,
|
|
"Invalid user name", true);
|
|
"Invalid user name", true);
|
|
@@ -453,6 +436,13 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
|
|
ptr++;
|
|
ptr++;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* Save the received username for authentication, and use
|
|
|
|
+ * it up to the first '@' as default user name (like ircd2.11,
|
|
|
|
+ * bahamut, ircd-seven, ...), prefixed with '~', if needed: */
|
|
|
|
+ Client_SetOrigUser(Client, Req->argv[0]);
|
|
|
|
+ ptr = strchr(Req->argv[0], '@');
|
|
|
|
+ if (ptr)
|
|
|
|
+ *ptr = '\0';
|
|
#ifdef IDENTAUTH
|
|
#ifdef IDENTAUTH
|
|
ptr = Client_User(Client);
|
|
ptr = Client_User(Client);
|
|
if (!ptr || !*ptr || *ptr == '~')
|
|
if (!ptr || !*ptr || *ptr == '~')
|
|
@@ -460,7 +450,6 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
|
|
#else
|
|
#else
|
|
Client_SetUser(Client, Req->argv[0], false);
|
|
Client_SetUser(Client, Req->argv[0], false);
|
|
#endif
|
|
#endif
|
|
- Client_SetOrigUser(Client, Req->argv[0]);
|
|
|
|
|
|
|
|
/* "Real name" or user info text: Don't set it to the empty
|
|
/* "Real name" or user info text: Don't set it to the empty
|
|
* string, the original ircd can't deal with such "real names"
|
|
* string, the original ircd can't deal with such "real names"
|
|
@@ -481,14 +470,11 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
|
|
} else if (Client_Type(Client) == CLIENT_SERVER ||
|
|
} else if (Client_Type(Client) == CLIENT_SERVER ||
|
|
Client_Type(Client) == CLIENT_SERVICE) {
|
|
Client_Type(Client) == CLIENT_SERVICE) {
|
|
/* Server/service updating an user */
|
|
/* Server/service updating an user */
|
|
- if (Req->argc != 4)
|
|
|
|
- return IRC_WriteStrClient(Client,
|
|
|
|
- ERR_NEEDMOREPARAMS_MSG,
|
|
|
|
- Client_ID(Client),
|
|
|
|
- Req->command);
|
|
|
|
|
|
+ _IRC_ARGC_EQ_OR_RETURN_(Client, Req, 4)
|
|
|
|
+
|
|
c = Client_Search(Req->prefix);
|
|
c = Client_Search(Req->prefix);
|
|
if (!c)
|
|
if (!c)
|
|
- return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,
|
|
Client_ID(Client),
|
|
Client_ID(Client),
|
|
Req->prefix);
|
|
Req->prefix);
|
|
|
|
|
|
@@ -508,29 +494,25 @@ IRC_USER(CLIENT * Client, REQUEST * Req)
|
|
return CONNECTED;
|
|
return CONNECTED;
|
|
} else if (Client_Type(Client) == CLIENT_USER) {
|
|
} else if (Client_Type(Client) == CLIENT_USER) {
|
|
/* Already registered connection */
|
|
/* Already registered connection */
|
|
- return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_ALREADYREGISTRED_MSG,
|
|
Client_ID(Client));
|
|
Client_ID(Client));
|
|
} else {
|
|
} else {
|
|
/* Unexpected/invalid connection state? */
|
|
/* Unexpected/invalid connection state? */
|
|
- return IRC_WriteStrClient(Client, ERR_NOTREGISTERED_MSG,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_NOTREGISTERED_MSG,
|
|
Client_ID(Client));
|
|
Client_ID(Client));
|
|
}
|
|
}
|
|
} /* IRC_USER */
|
|
} /* IRC_USER */
|
|
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Handler for the IRC "SERVICE" command.
|
|
* Handler for the IRC "SERVICE" command.
|
|
*
|
|
*
|
|
- * This function implements IRC Services registration using the SERVICE command
|
|
|
|
- * defined in RFC 2812 3.1.6 and RFC 2813 4.1.4.
|
|
|
|
- *
|
|
|
|
* At the moment ngIRCd doesn't support directly linked services, so this
|
|
* At the moment ngIRCd doesn't support directly linked services, so this
|
|
* function returns ERR_ERRONEUSNICKNAME when the SERVICE command has not been
|
|
* function returns ERR_ERRONEUSNICKNAME when the SERVICE command has not been
|
|
* received from a peer server.
|
|
* received from a peer server.
|
|
*
|
|
*
|
|
- * @param Client The client from which this command has been received.
|
|
|
|
- * @param Req Request structure with prefix and all parameters.
|
|
|
|
- * @returns CONNECTED or DISCONNECTED..
|
|
|
|
|
|
+ * @param Client The client from which this command has been received.
|
|
|
|
+ * @param Req Request structure with prefix and all parameters.
|
|
|
|
+ * @return CONNECTED or DISCONNECTED.
|
|
*/
|
|
*/
|
|
GLOBAL bool
|
|
GLOBAL bool
|
|
IRC_SERVICE(CLIENT *Client, REQUEST *Req)
|
|
IRC_SERVICE(CLIENT *Client, REQUEST *Req)
|
|
@@ -544,22 +526,13 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req)
|
|
|
|
|
|
if (Client_Type(Client) != CLIENT_GOTPASS &&
|
|
if (Client_Type(Client) != CLIENT_GOTPASS &&
|
|
Client_Type(Client) != CLIENT_SERVER)
|
|
Client_Type(Client) != CLIENT_SERVER)
|
|
- return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_ALREADYREGISTRED_MSG,
|
|
Client_ID(Client));
|
|
Client_ID(Client));
|
|
|
|
|
|
- if (Req->argc != 6)
|
|
|
|
- return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
|
|
|
- Client_ID(Client), Req->command);
|
|
|
|
-
|
|
|
|
if (Client_Type(Client) != CLIENT_SERVER)
|
|
if (Client_Type(Client) != CLIENT_SERVER)
|
|
- return IRC_WriteStrClient(Client, ERR_ERRONEUSNICKNAME_MSG,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_ERRONEUSNICKNAME_MSG,
|
|
Client_ID(Client), Req->argv[0]);
|
|
Client_ID(Client), Req->argv[0]);
|
|
|
|
|
|
- /* Bad number of parameters? */
|
|
|
|
- if (Req->argc != 6)
|
|
|
|
- return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
|
|
|
- Client_ID(Client), Req->command);
|
|
|
|
-
|
|
|
|
nick = Req->argv[0];
|
|
nick = Req->argv[0];
|
|
user = NULL; host = NULL;
|
|
user = NULL; host = NULL;
|
|
token = atoi(Req->argv[1]);
|
|
token = atoi(Req->argv[1]);
|
|
@@ -569,20 +542,20 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req)
|
|
/* Validate service name ("nickname") */
|
|
/* Validate service name ("nickname") */
|
|
c = Client_Search(nick);
|
|
c = Client_Search(nick);
|
|
if(c) {
|
|
if(c) {
|
|
- /* Nickname collission: disconnect (KILL) both clients! */
|
|
|
|
- Log(LOG_ERR, "Server %s introduces already registered service \"%s\"!",
|
|
|
|
|
|
+ /* Nickname collision: disconnect (KILL) both clients! */
|
|
|
|
+ Log(LOG_ERR,
|
|
|
|
+ "Server %s introduces already registered service \"%s\"!",
|
|
Client_ID(Client), nick);
|
|
Client_ID(Client), nick);
|
|
- Kill_Nick(nick, "Nick collision");
|
|
|
|
- return CONNECTED;
|
|
|
|
|
|
+ return IRC_KillClient(Client, NULL, nick, "Nick collision");
|
|
}
|
|
}
|
|
|
|
|
|
/* Get the server to which the service is connected */
|
|
/* Get the server to which the service is connected */
|
|
intr_c = Client_GetFromToken(Client, token);
|
|
intr_c = Client_GetFromToken(Client, token);
|
|
if (! intr_c) {
|
|
if (! intr_c) {
|
|
- Log(LOG_ERR, "Server %s introduces service \"%s\" on unknown server!?",
|
|
|
|
|
|
+ Log(LOG_ERR,
|
|
|
|
+ "Server %s introduces service \"%s\" on unknown server!?",
|
|
Client_ID(Client), nick);
|
|
Client_ID(Client), nick);
|
|
- Kill_Nick(nick, "Unknown server");
|
|
|
|
- return CONNECTED;
|
|
|
|
|
|
+ return IRC_KillClient(Client, NULL, nick, "Unknown server");
|
|
}
|
|
}
|
|
|
|
|
|
/* Get user and host name */
|
|
/* Get user and host name */
|
|
@@ -611,37 +584,28 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req)
|
|
if (! c) {
|
|
if (! c) {
|
|
/* Couldn't create client structure, so KILL the service to
|
|
/* Couldn't create client structure, so KILL the service to
|
|
* keep network status consistent ... */
|
|
* keep network status consistent ... */
|
|
- Log(LOG_ALERT, "Can't create client structure! (on connection %d)",
|
|
|
|
|
|
+ Log(LOG_ALERT,
|
|
|
|
+ "Can't create client structure! (on connection %d)",
|
|
Client_Conn(Client));
|
|
Client_Conn(Client));
|
|
- Kill_Nick(nick, "Server error");
|
|
|
|
- return CONNECTED;
|
|
|
|
|
|
+ return IRC_KillClient(Client, NULL, nick, "Server error");
|
|
}
|
|
}
|
|
|
|
|
|
Client_Introduce(Client, c, CLIENT_SERVICE);
|
|
Client_Introduce(Client, c, CLIENT_SERVICE);
|
|
return CONNECTED;
|
|
return CONNECTED;
|
|
} /* IRC_SERVICE */
|
|
} /* IRC_SERVICE */
|
|
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Handler for the IRC "WEBIRC" command.
|
|
* Handler for the IRC "WEBIRC" command.
|
|
*
|
|
*
|
|
- * See doc/Protocol.txt, section II.4:
|
|
|
|
- * "Update webchat/proxy client information".
|
|
|
|
- *
|
|
|
|
- * @param Client The client from which this command has been received.
|
|
|
|
- * @param Req Request structure with prefix and all parameters.
|
|
|
|
- * @returns CONNECTED or DISCONNECTED.
|
|
|
|
|
|
+ * @param Client The client from which this command has been received.
|
|
|
|
+ * @param Req Request structure with prefix and all parameters.
|
|
|
|
+ * @return CONNECTED or DISCONNECTED.
|
|
*/
|
|
*/
|
|
GLOBAL bool
|
|
GLOBAL bool
|
|
IRC_WEBIRC(CLIENT *Client, REQUEST *Req)
|
|
IRC_WEBIRC(CLIENT *Client, REQUEST *Req)
|
|
{
|
|
{
|
|
- /* Exactly 4 parameters are requited */
|
|
|
|
- if (Req->argc != 4)
|
|
|
|
- return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
|
|
|
- Client_ID(Client), Req->command);
|
|
|
|
-
|
|
|
|
if (!Conf_WebircPwd[0] || strcmp(Req->argv[0], Conf_WebircPwd) != 0)
|
|
if (!Conf_WebircPwd[0] || strcmp(Req->argv[0], Conf_WebircPwd) != 0)
|
|
- return IRC_WriteStrClient(Client, ERR_PASSWDMISMATCH_MSG,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_PASSWDMISMATCH_MSG,
|
|
Client_ID(Client));
|
|
Client_ID(Client));
|
|
|
|
|
|
LogDebug("Connection %d: got valid WEBIRC command: user=%s, host=%s, ip=%s",
|
|
LogDebug("Connection %d: got valid WEBIRC command: user=%s, host=%s, ip=%s",
|
|
@@ -650,33 +614,27 @@ IRC_WEBIRC(CLIENT *Client, REQUEST *Req)
|
|
Client_SetUser(Client, Req->argv[1], true);
|
|
Client_SetUser(Client, Req->argv[1], true);
|
|
Client_SetOrigUser(Client, Req->argv[1]);
|
|
Client_SetOrigUser(Client, Req->argv[1]);
|
|
Client_SetHostname(Client, Req->argv[2]);
|
|
Client_SetHostname(Client, Req->argv[2]);
|
|
|
|
+ Client_SetIPAText(Client, Req->argv[3]);
|
|
|
|
+
|
|
return CONNECTED;
|
|
return CONNECTED;
|
|
} /* IRC_WEBIRC */
|
|
} /* IRC_WEBIRC */
|
|
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Handler for the IRC "QUIT" command.
|
|
* Handler for the IRC "QUIT" command.
|
|
*
|
|
*
|
|
- * See RFC 2812, 3.1.7 "Quit", and RFC 2813, 4.1.5 "Quit".
|
|
|
|
- *
|
|
|
|
- * @param Client The client from which this command has been received.
|
|
|
|
- * @param Req Request structure with prefix and all parameters.
|
|
|
|
- * @returns CONNECTED or DISCONNECTED.
|
|
|
|
|
|
+ * @param Client The client from which this command has been received.
|
|
|
|
+ * @param Req Request structure with prefix and all parameters.
|
|
|
|
+ * @return CONNECTED or DISCONNECTED.
|
|
*/
|
|
*/
|
|
GLOBAL bool
|
|
GLOBAL bool
|
|
IRC_QUIT( CLIENT *Client, REQUEST *Req )
|
|
IRC_QUIT( CLIENT *Client, REQUEST *Req )
|
|
{
|
|
{
|
|
CLIENT *target;
|
|
CLIENT *target;
|
|
- char quitmsg[LINE_LEN];
|
|
|
|
|
|
+ char quitmsg[COMMAND_LEN];
|
|
|
|
|
|
assert(Client != NULL);
|
|
assert(Client != NULL);
|
|
assert(Req != NULL);
|
|
assert(Req != NULL);
|
|
|
|
|
|
- /* Wrong number of arguments? */
|
|
|
|
- if (Req->argc > 1)
|
|
|
|
- return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
|
|
|
- Client_ID(Client), Req->command);
|
|
|
|
-
|
|
|
|
if (Req->argc == 1)
|
|
if (Req->argc == 1)
|
|
strlcpy(quitmsg, Req->argv[0], sizeof quitmsg);
|
|
strlcpy(quitmsg, Req->argv[0], sizeof quitmsg);
|
|
|
|
|
|
@@ -691,11 +649,11 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
|
|
}
|
|
}
|
|
|
|
|
|
if (target != Client) {
|
|
if (target != Client) {
|
|
- Client_Destroy(target, "Got QUIT command.",
|
|
|
|
|
|
+ Client_Destroy(target, "Got QUIT command",
|
|
Req->argc == 1 ? quitmsg : NULL, true);
|
|
Req->argc == 1 ? quitmsg : NULL, true);
|
|
return CONNECTED;
|
|
return CONNECTED;
|
|
} else {
|
|
} else {
|
|
- Conn_Close(Client_Conn(Client), "Got QUIT command.",
|
|
|
|
|
|
+ Conn_Close(Client_Conn(Client), "Got QUIT command",
|
|
Req->argc == 1 ? quitmsg : NULL, true);
|
|
Req->argc == 1 ? quitmsg : NULL, true);
|
|
return DISCONNECTED;
|
|
return DISCONNECTED;
|
|
}
|
|
}
|
|
@@ -708,14 +666,13 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
|
|
}
|
|
}
|
|
|
|
|
|
/* User, Service, or not yet registered */
|
|
/* User, Service, or not yet registered */
|
|
- Conn_Close(Client_Conn(Client), "Got QUIT command.",
|
|
|
|
|
|
+ Conn_Close(Client_Conn(Client), "Got QUIT command",
|
|
Req->argc == 1 ? quitmsg : NULL, true);
|
|
Req->argc == 1 ? quitmsg : NULL, true);
|
|
|
|
|
|
return DISCONNECTED;
|
|
return DISCONNECTED;
|
|
}
|
|
}
|
|
} /* IRC_QUIT */
|
|
} /* IRC_QUIT */
|
|
|
|
|
|
-
|
|
|
|
#ifndef STRICT_RFC
|
|
#ifndef STRICT_RFC
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -724,9 +681,9 @@ IRC_QUIT( CLIENT *Client, REQUEST *Req )
|
|
* We handle these commands here to avoid the quite long timeout when
|
|
* We handle these commands here to avoid the quite long timeout when
|
|
* some user tries to access this IRC daemon using an web browser ...
|
|
* some user tries to access this IRC daemon using an web browser ...
|
|
*
|
|
*
|
|
- * @param Client The client from which this command has been received.
|
|
|
|
- * @param Req Request structure with prefix and all parameters.
|
|
|
|
- * @returns CONNECTED or DISCONNECTED.
|
|
|
|
|
|
+ * @param Client The client from which this command has been received.
|
|
|
|
+ * @param Req Request structure with prefix and all parameters.
|
|
|
|
+ * @return CONNECTED or DISCONNECTED.
|
|
*/
|
|
*/
|
|
GLOBAL bool
|
|
GLOBAL bool
|
|
IRC_QUIT_HTTP( CLIENT *Client, REQUEST *Req )
|
|
IRC_QUIT_HTTP( CLIENT *Client, REQUEST *Req )
|
|
@@ -738,15 +695,12 @@ IRC_QUIT_HTTP( CLIENT *Client, REQUEST *Req )
|
|
|
|
|
|
#endif
|
|
#endif
|
|
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Handler for the IRC "PING" command.
|
|
* Handler for the IRC "PING" command.
|
|
*
|
|
*
|
|
- * See RFC 2812, 3.7.2 "Ping message".
|
|
|
|
- *
|
|
|
|
- * @param Client The client from which this command has been received.
|
|
|
|
- * @param Req Request structure with prefix and all parameters.
|
|
|
|
- * @returns CONNECTED or DISCONNECTED.
|
|
|
|
|
|
+ * @param Client The client from which this command has been received.
|
|
|
|
+ * @param Req Request structure with prefix and all parameters.
|
|
|
|
+ * @return CONNECTED or DISCONNECTED.
|
|
*/
|
|
*/
|
|
GLOBAL bool
|
|
GLOBAL bool
|
|
IRC_PING(CLIENT *Client, REQUEST *Req)
|
|
IRC_PING(CLIENT *Client, REQUEST *Req)
|
|
@@ -757,13 +711,11 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
|
|
assert(Req != NULL);
|
|
assert(Req != NULL);
|
|
|
|
|
|
if (Req->argc < 1)
|
|
if (Req->argc < 1)
|
|
- return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_NOORIGIN_MSG,
|
|
Client_ID(Client));
|
|
Client_ID(Client));
|
|
#ifdef STRICT_RFC
|
|
#ifdef STRICT_RFC
|
|
/* Don't ignore additional arguments when in "strict" mode */
|
|
/* Don't ignore additional arguments when in "strict" mode */
|
|
- if (Req->argc > 2)
|
|
|
|
- return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
|
|
|
|
- Client_ID(Client), Req->command);
|
|
|
|
|
|
+ _IRC_ARGC_LE_OR_RETURN_(Client, Req, 2)
|
|
#endif
|
|
#endif
|
|
|
|
|
|
if (Req->argc > 1) {
|
|
if (Req->argc > 1) {
|
|
@@ -771,7 +723,7 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
|
|
target = Client_Search(Req->argv[1]);
|
|
target = Client_Search(Req->argv[1]);
|
|
|
|
|
|
if (!target || Client_Type(target) != CLIENT_SERVER)
|
|
if (!target || Client_Type(target) != CLIENT_SERVER)
|
|
- return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG,
|
|
Client_ID(Client), Req->argv[1]);
|
|
Client_ID(Client), Req->argv[1]);
|
|
|
|
|
|
if (target != Client_ThisServer()) {
|
|
if (target != Client_ThisServer()) {
|
|
@@ -781,7 +733,7 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
|
|
else
|
|
else
|
|
from = Client;
|
|
from = Client;
|
|
if (!from)
|
|
if (!from)
|
|
- return IRC_WriteStrClient(Client,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client,
|
|
ERR_NOSUCHSERVER_MSG,
|
|
ERR_NOSUCHSERVER_MSG,
|
|
Client_ID(Client), Req->prefix);
|
|
Client_ID(Client), Req->prefix);
|
|
|
|
|
|
@@ -799,7 +751,7 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
|
|
} else
|
|
} else
|
|
from = Client_ThisServer();
|
|
from = Client_ThisServer();
|
|
if (!from)
|
|
if (!from)
|
|
- return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG,
|
|
Client_ID(Client), Req->prefix);
|
|
Client_ID(Client), Req->prefix);
|
|
|
|
|
|
Log(LOG_DEBUG, "Connection %d: got PING, sending PONG ...",
|
|
Log(LOG_DEBUG, "Connection %d: got PING, sending PONG ...",
|
|
@@ -816,15 +768,12 @@ IRC_PING(CLIENT *Client, REQUEST *Req)
|
|
#endif
|
|
#endif
|
|
} /* IRC_PING */
|
|
} /* IRC_PING */
|
|
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Handler for the IRC "PONG" command.
|
|
* Handler for the IRC "PONG" command.
|
|
*
|
|
*
|
|
- * See RFC 2812, 3.7.3 "Pong message".
|
|
|
|
- *
|
|
|
|
- * @param Client The client from which this command has been received.
|
|
|
|
- * @param Req Request structure with prefix and all parameters.
|
|
|
|
- * @returns CONNECTED or DISCONNECTED.
|
|
|
|
|
|
+ * @param Client The client from which this command has been received.
|
|
|
|
+ * @param Req Request structure with prefix and all parameters.
|
|
|
|
+ * @return CONNECTED or DISCONNECTED.
|
|
*/
|
|
*/
|
|
GLOBAL bool
|
|
GLOBAL bool
|
|
IRC_PONG(CLIENT *Client, REQUEST *Req)
|
|
IRC_PONG(CLIENT *Client, REQUEST *Req)
|
|
@@ -842,26 +791,20 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
|
|
/* Wrong number of arguments? */
|
|
/* Wrong number of arguments? */
|
|
if (Req->argc < 1) {
|
|
if (Req->argc < 1) {
|
|
if (Client_Type(Client) == CLIENT_USER)
|
|
if (Client_Type(Client) == CLIENT_USER)
|
|
- return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_NOORIGIN_MSG,
|
|
Client_ID(Client));
|
|
Client_ID(Client));
|
|
else
|
|
else
|
|
return CONNECTED;
|
|
return CONNECTED;
|
|
}
|
|
}
|
|
- if (Req->argc > 2) {
|
|
|
|
- if (Client_Type(Client) == CLIENT_USER)
|
|
|
|
- return IRC_WriteStrClient(Client,
|
|
|
|
- ERR_NEEDMOREPARAMS_MSG,
|
|
|
|
- Client_ID(Client),
|
|
|
|
- Req->command);
|
|
|
|
- else
|
|
|
|
- return CONNECTED;
|
|
|
|
|
|
+ if (Client_Type(Client) == CLIENT_USER) {
|
|
|
|
+ _IRC_ARGC_LE_OR_RETURN_(Client, Req, 2)
|
|
}
|
|
}
|
|
|
|
|
|
/* Forward? */
|
|
/* Forward? */
|
|
if (Req->argc == 2 && Client_Type(Client) == CLIENT_SERVER) {
|
|
if (Req->argc == 2 && Client_Type(Client) == CLIENT_SERVER) {
|
|
target = Client_Search(Req->argv[0]);
|
|
target = Client_Search(Req->argv[0]);
|
|
if (!target)
|
|
if (!target)
|
|
- return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG,
|
|
Client_ID(Client), Req->argv[0]);
|
|
Client_ID(Client), Req->argv[0]);
|
|
|
|
|
|
from = Client_Search(Req->prefix);
|
|
from = Client_Search(Req->prefix);
|
|
@@ -869,7 +812,7 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
|
|
if (target != Client_ThisServer() && target != from) {
|
|
if (target != Client_ThisServer() && target != from) {
|
|
/* Ok, we have to forward the message. */
|
|
/* Ok, we have to forward the message. */
|
|
if (!from)
|
|
if (!from)
|
|
- return IRC_WriteStrClient(Client,
|
|
|
|
|
|
+ return IRC_WriteErrClient(Client,
|
|
ERR_NOSUCHSERVER_MSG,
|
|
ERR_NOSUCHSERVER_MSG,
|
|
Client_ID(Client), Req->prefix);
|
|
Client_ID(Client), Req->prefix);
|
|
|
|
|
|
@@ -907,8 +850,9 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
|
|
|
|
|
|
if (Client_Type(Client) == CLIENT_SERVER && Conn_LastPing(conn) == 0) {
|
|
if (Client_Type(Client) == CLIENT_SERVER && Conn_LastPing(conn) == 0) {
|
|
Log(LOG_INFO,
|
|
Log(LOG_INFO,
|
|
- "Synchronization with \"%s\" done (connection %d): %ld seconds [%ld users, %ld channels]",
|
|
|
|
|
|
+ "Synchronization with \"%s\" done (connection %d): %ld second%s [%ld users, %ld channels].",
|
|
Client_ID(Client), conn, time(NULL) - Conn_GetSignon(conn),
|
|
Client_ID(Client), conn, time(NULL) - Conn_GetSignon(conn),
|
|
|
|
+ time(NULL) - Conn_GetSignon(conn) == 1 ? "" : "s",
|
|
Client_UserCount(), Channel_CountVisible(NULL));
|
|
Client_UserCount(), Channel_CountVisible(NULL));
|
|
Conn_UpdatePing(conn);
|
|
Conn_UpdatePing(conn);
|
|
} else
|
|
} else
|
|
@@ -918,33 +862,6 @@ IRC_PONG(CLIENT *Client, REQUEST *Req)
|
|
return CONNECTED;
|
|
return CONNECTED;
|
|
} /* IRC_PONG */
|
|
} /* IRC_PONG */
|
|
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * Kill all users with a specific nickname in the network.
|
|
|
|
- *
|
|
|
|
- * @param Nick Nickname.
|
|
|
|
- * @param Reason Reason for the KILL.
|
|
|
|
- */
|
|
|
|
-static void
|
|
|
|
-Kill_Nick(char *Nick, char *Reason)
|
|
|
|
-{
|
|
|
|
- REQUEST r;
|
|
|
|
-
|
|
|
|
- assert (Nick != NULL);
|
|
|
|
- assert (Reason != NULL);
|
|
|
|
-
|
|
|
|
- r.prefix = NULL;
|
|
|
|
- r.argv[0] = Nick;
|
|
|
|
- r.argv[1] = Reason;
|
|
|
|
- r.argc = 2;
|
|
|
|
-
|
|
|
|
- Log(LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s",
|
|
|
|
- Nick, Reason);
|
|
|
|
-
|
|
|
|
- IRC_KILL(Client_ThisServer(), &r);
|
|
|
|
-} /* Kill_Nick */
|
|
|
|
-
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Change the nickname of a client.
|
|
* Change the nickname of a client.
|
|
*
|
|
*
|
|
@@ -984,5 +901,4 @@ Change_Nick(CLIENT *Origin, CLIENT *Target, char *NewNick, bool InformClient)
|
|
Client_SetID(Target, NewNick);
|
|
Client_SetID(Target, NewNick);
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
/* -eof- */
|
|
/* -eof- */
|