/*
* ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2018 Alexander Barton (alex@barton.de) and Contributors.
*
* 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
* Login and logout
*/
-#include "imp.h"
#include <assert.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
+#include <time.h>
#include "conn-func.h"
-#include "class.h"
#include "conf.h"
#include "channel.h"
#include "log.h"
#include "messages.h"
#include "parse.h"
#include "irc.h"
-#include "irc-info.h"
#include "irc-macros.h"
#include "irc-write.h"
-#include "exp.h"
#include "irc-login.h"
static void Change_Nick PARAMS((CLIENT * Origin, CLIENT * Target, char *NewNick,
} else if (Client_Type(Client) == CLIENT_UNKNOWN ||
Client_Type(Client) == CLIENT_UNKNOWNSERVER) {
/* Unregistered connection, but wrong number of arguments: */
- IRC_SetPenalty(Client, 2);
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
} else {
/* Protocol version */
if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) {
- int c2, c4;
+ char c2, c4;
c2 = Req->argv[1][2];
c4 = Req->argv[1][4];
IRC_NICK( CLIENT *Client, REQUEST *Req )
{
CLIENT *intr_c, *target, *c;
+ CHANNEL *chan;
char *nick, *user, *hostname, *modes, *info;
int token, hops;
/* Search "target" client */
if (Client_Type(Client) == CLIENT_SERVER) {
+ _IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
target = Client_Search(Req->prefix);
if (!target)
return IRC_WriteErrClient(Client,
#ifndef STRICT_RFC
if (Conf_AuthPing) {
+#ifdef HAVE_ARC4RANDOM
+ Conn_SetAuthPing(Client_Conn(Client), arc4random());
+#else
Conn_SetAuthPing(Client_Conn(Client), rand());
- IRC_WriteStrClient(Client, "PING :%ld",
+#endif
+ Conn_WriteStr(Client_Conn(Client), "PING :%ld",
Conn_GetAuthPing(Client_Conn(Client)));
LogDebug("Connection %d: sent AUTH PING %ld ...",
Client_Conn(Client),
Client_SetType( Client, CLIENT_GOTNICK );
} else {
/* Nickname change */
+
+ /* Check that the user isn't on any channels set +N */
+ if(Client_Type(Client) == CLIENT_USER &&
+ !Client_HasMode(Client, 'o')) {
+ chan = Channel_First();
+ while (chan) {
+ if(Channel_HasMode(chan, 'N') &&
+ Channel_IsMemberOf(chan, Client))
+ return IRC_WriteErrClient(Client,
+ ERR_NONICKCHANGE_MSG,
+ Client_ID(Client),
+ Channel_Name(chan));
+ chan = Channel_Next(chan);
+ }
+ }
+
Change_Nick(Client, target, Req->argv[0],
Client_Type(Client) == CLIENT_USER ? true : false);
IRC_SetPenalty(target, 2);
/* Server or service introduces new client */
/* Bad number of parameters? */
- if (Req->argc != 2 && Req->argc != 7) {
- IRC_SetPenalty(Client, 2);
+ if (Req->argc != 2 && Req->argc != 7)
return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
- }
if (Req->argc >= 7) {
/* RFC 2813 compatible syntax */
assert(Client != NULL);
assert(Req != NULL);
+ _IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
+
/* Search the originator */
from = Client_Search(Req->prefix);
if (!from)
/* Search the target */
target = Client_Search(Req->argv[0]);
- if (!target || Client_Type(target) != CLIENT_USER) {
+ if (!target || Client_Type(target) != CLIENT_USER)
return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->argv[0]);
- }
if (Client_Conn(target) <= NONE) {
/* We have to forward the message to the server handling
Client_Type(Client) == CLIENT_SERVICE) {
/* Server/service updating an user */
_IRC_ARGC_EQ_OR_RETURN_(Client, Req, 4)
+ _IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
c = Client_Search(Req->prefix);
if (!c)
Client_SetUser(Client, Req->argv[1], true);
Client_SetOrigUser(Client, Req->argv[1]);
- Client_SetHostname(Client, Req->argv[2]);
+ if (Conf_DNS)
+ Client_SetHostname(Client, Req->argv[2]);
+ else
+ Client_SetHostname(Client, Req->argv[3]);
Client_SetIPAText(Client, Req->argv[3]);
return CONNECTED;
IRC_QUIT( CLIENT *Client, REQUEST *Req )
{
CLIENT *target;
- char quitmsg[LINE_LEN];
+ char quitmsg[COMMAND_LEN];
assert(Client != NULL);
assert(Req != NULL);
if (Client_Type(Client) == CLIENT_SERVER) {
/* Server */
+ _IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
+
target = Client_Search(Req->prefix);
if (!target) {
Log(LOG_WARNING,
if (target != Client_ThisServer()) {
/* Ok, we have to forward the PING */
- if (Client_Type(Client) == CLIENT_SERVER)
+ if (Client_Type(Client) == CLIENT_SERVER) {
+ _IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
from = Client_Search(Req->prefix);
- else
+ } else
from = Client;
if (!from)
return IRC_WriteErrClient(Client,
/* Forward? */
if (Req->argc == 2 && Client_Type(Client) == CLIENT_SERVER) {
+ _IRC_REQUIRE_PREFIX_OR_RETURN_(Client, Req)
+
target = Client_Search(Req->argv[0]);
if (!target)
return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG,
if (auth_ping) {
LogDebug("AUTH PONG: waiting for token \"%ld\", got \"%s\" ...",
auth_ping, Req->argv[0]);
- if (auth_ping == atoi(Req->argv[0])) {
+ if (auth_ping == atol(Req->argv[0])) {
Conn_SetAuthPing(conn, 0);
if (Client_Type(Client) == CLIENT_WAITAUTHPING)
Login_User(Client);
} else
if (!IRC_WriteStrClient(Client,
- "To connect, type /QUOTE PONG %ld",
- auth_ping))
+ "NOTICE %s :To connect, type /QUOTE PONG %ld",
+ Client_ID(Client), auth_ping))
return DISCONNECTED;
}
#endif
if (Client_Type(Client) == CLIENT_SERVER && Conn_LastPing(conn) == 0) {
Log(LOG_INFO,
"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,
+ (long)(time(NULL) - Conn_GetSignon(conn)),
time(NULL) - Conn_GetSignon(conn) == 1 ? "" : "s",
Client_UserCount(), Channel_CountVisible(NULL));
Conn_UpdatePing(conn);
} else
LogDebug("Connection %d: received PONG. Lag: %ld seconds.",
- conn, time(NULL) - Conn_LastPing(conn));
+ conn, (long)(time(NULL) - Conn_LastPing(conn)));
return CONNECTED;
} /* IRC_PONG */