#include "match.h"
#include "messages.h"
#include "parse.h"
+#include "tool.h"
#include "exp.h"
#include "irc.h"
static char *Option_String PARAMS((CONN_ID Idx));
-static bool Send_Message PARAMS((CLIENT *Client, REQUEST *Req, int ForceType, bool SendErrors));
-static bool Send_Message_Mask PARAMS((CLIENT *from, char *targetMask, char *message, bool SendErrors));
+static bool Send_Message PARAMS((CLIENT *Client, REQUEST *Req, int ForceType,
+ bool SendErrors));
+static bool Send_Message_Mask PARAMS((CLIENT *from, char *command,
+ char *targetMask, char *message,
+ bool SendErrors));
GLOBAL bool
} /* IRC_KILL */
+/**
+ * Handler for the IRC command NOTICE.
+ */
GLOBAL bool
-IRC_NOTICE( CLIENT *Client, REQUEST *Req )
+IRC_NOTICE(CLIENT *Client, REQUEST *Req)
{
return Send_Message(Client, Req, CLIENT_USER, false);
} /* IRC_NOTICE */
CLIENT *cl, *from;
CHANNEL *chan;
char *currentTarget = Req->argv[0];
- char *lastCurrentTarget;
+ char *lastCurrentTarget = NULL;
assert(Client != NULL);
assert(Req != NULL);
if (Req->argc == 0) {
if (!SendErrors)
- return true;
+ return CONNECTED;
return IRC_WriteStrClient(Client, ERR_NORECIPIENT_MSG,
Client_ID(Client), Req->command);
}
if (Req->argc == 1) {
if (!SendErrors)
- return true;
+ return CONNECTED;
return IRC_WriteStrClient(Client, ERR_NOTEXTTOSEND_MSG,
Client_ID(Client));
}
if (Req->argc > 2) {
if (!SendErrors)
- return true;
+ return CONNECTED;
return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
Client_ID(Client), Req->command);
}
from = Client_Search(Req->prefix);
else
from = Client;
- if (!from) {
+ if (!from)
return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
Client_ID(Client), Req->prefix);
- }
/* handle msgtarget = msgto *("," msgto) */
currentTarget = strtok_r(currentTarget, ",", &lastCurrentTarget);
+ ngt_UpperStr(Req->command);
while (currentTarget) {
/* Check for and handle valid <msgto> of form:
}
for (cl = Client_First(); cl != NULL; cl = Client_Next(cl)) {
- if (Client_Type(cl) != CLIENT_USER)
+ if (Client_Type(cl) != CLIENT_USER &&
+ Client_Type(cl) != CLIENT_SERVICE)
continue;
- if (nick != NULL) {
+ if (nick != NULL && host != NULL) {
if (strcmp(nick, Client_ID(cl)) == 0 &&
- strcmp(user, Client_User(cl)) == 0 &&
- strcasecmp(host, Client_Hostname(cl)) == 0)
+ strcmp(user, Client_User(cl)) == 0 &&
+ strcasecmp(host, Client_Hostname(cl)) == 0)
break;
else
continue;
}
if (strcasecmp(user, Client_User(cl)) != 0)
continue;
- if (host != NULL && strcasecmp(host, Client_Hostname(cl)) != 0)
+ if (host != NULL && strcasecmp(host,
+ Client_Hostname(cl)) != 0)
continue;
if (server != NULL && strcasecmp(server,
- Client_ID(Client_Introducer(cl))) != 0)
+ Client_ID(Client_Introducer(cl))) != 0)
continue;
break;
}
if (cl) {
/* Target is a user, enforce type */
+#ifndef STRICT_RFC
+ if (Client_Type(cl) != ForceType &&
+ !(ForceType == CLIENT_USER &&
+ (Client_Type(cl) == CLIENT_USER ||
+ Client_Type(cl) == CLIENT_SERVICE))) {
+#else
if (Client_Type(cl) != ForceType) {
+#endif
if (!SendErrors)
- return true;
- if (!IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
+ return CONNECTED;
+ return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
Client_ID(from),
- currentTarget))
- return false;
- } else if (SendErrors && (Client_Type(Client) != CLIENT_SERVER)
- && strchr(Client_Modes(cl), 'a')) {
+ currentTarget);
+ }
+
+#ifndef STRICT_RFC
+ if (ForceType == CLIENT_SERVICE &&
+ (Conn_Options(Client_Conn(Client_NextHop(cl)))
+ & CONN_RFC1459)) {
+ /* SQUERY command but RFC 1459 link: convert
+ * request to PRIVMSG command */
+ Req->command = "PRIVMSG";
+ }
+#endif
+
+ if (SendErrors && (Client_Type(Client) != CLIENT_SERVER)
+ && strchr(Client_Modes(cl), 'a')) {
/* Target is away */
- if (!SendErrors)
- return true;
- if (!IRC_WriteStrClient
- (from, RPL_AWAY_MSG, Client_ID(from), Client_ID(cl),
- Client_Away(cl)))
+ if (!IRC_WriteStrClient(from, RPL_AWAY_MSG,
+ Client_ID(from),
+ Client_ID(cl),
+ Client_Away(cl)))
return DISCONNECTED;
}
if (Client_Conn(from) > NONE) {
Conn_UpdateIdle(Client_Conn(from));
}
- if (!IRC_WriteStrClientPrefix(cl, from, "PRIVMSG %s :%s",
- Client_ID(cl), Req->argv[1]))
- return false;
- } else if (strchr("$#", currentTarget[0]) && strchr(currentTarget, '.')) {
- /* targetmask */
- if (!Send_Message_Mask(from, currentTarget, Req->argv[1],
- SendErrors))
- return false;
- } else if ((chan = Channel_Search(currentTarget))) {
+ if (!IRC_WriteStrClientPrefix(cl, from, "%s %s :%s",
+ Req->command, Client_ID(cl),
+ Req->argv[1]))
+ return DISCONNECTED;
+ } else if (ForceType != CLIENT_SERVICE
+ && (chan = Channel_Search(currentTarget))) {
/* channel */
- if (!Channel_Write(chan, from, Client, Req->argv[1]))
- return false;
+ if (!Channel_Write(chan, from, Client, Req->command,
+ SendErrors, Req->argv[1]))
+ return DISCONNECTED;
+ } else if (ForceType != CLIENT_SERVICE
+ && strchr("$#", currentTarget[0])
+ && strchr(currentTarget, '.')) {
+ /* targetmask */
+ if (!Send_Message_Mask(from, Req->command, currentTarget,
+ Req->argv[1], SendErrors))
+ return DISCONNECTED;
} else {
if (!SendErrors)
- return true;
+ return CONNECTED;
if (!IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
Client_ID(from), currentTarget))
- return false;
+ return DISCONNECTED;
}
currentTarget = strtok_r(NULL, ",", &lastCurrentTarget);
}
return CONNECTED;
-
} /* Send_Message */
static bool
-Send_Message_Mask(CLIENT * from, char * targetMask, char * message, bool SendErrors)
+Send_Message_Mask(CLIENT * from, char * command, char * targetMask,
+ char * message, bool SendErrors)
{
CLIENT *cl;
bool client_match;
if (strchr(Client_Modes(from), 'o') == NULL) {
if (!SendErrors)
return true;
- return IRC_WriteStrClient(from, ERR_NOPRIVILEGES_MSG, Client_ID(from));
+ return IRC_WriteStrClient(from, ERR_NOPRIVILEGES_MSG,
+ Client_ID(from));
}
if (targetMask[0] == '#') {
continue;
client_match = MatchCaseInsensitive(mask, Client_Hostname(cl));
if (client_match)
- if (!IRC_WriteStrClientPrefix(cl, from, "PRIVMSG %s :%s",
- Client_ID(cl), message))
+ if (!IRC_WriteStrClientPrefix(cl, from, "%s %s :%s",
+ command, Client_ID(cl), message))
return false;
}
} else {
if (Client_Type(cl) != CLIENT_USER)
continue;
client_match = MatchCaseInsensitive(mask,
- Client_ID(Client_Introducer(cl)));
+ Client_ID(Client_Introducer(cl)));
if (client_match)
- if (!IRC_WriteStrClientPrefix(cl, from, "PRIVMSG %s :%s",
- Client_ID(cl), message))
+ if (!IRC_WriteStrClientPrefix(cl, from, "%s %s :%s",
+ command, Client_ID(cl), message))
return false;
}
}