commit - 2546a13ad2949192eb70bf21e114ec60af287ee4
commit + d4eb55c79fb130844a08279cd574a19f188ffa99
blob - 43f2c1b6e4c1949724fa2e6281b70a11375a3ea3
blob + 000cb848f82f92df6f4760a32e20c7b4ccdcd165
--- src/ngircd/irc-info.c
+++ src/ngircd/irc-info.c
}
return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client), Channel_Name(Chan));
} /* IRC_Send_WHO */
-
-
-
-static bool
-MatchCaseInsensitive(const char *pattern, const char *searchme)
-{
- char haystack[COMMAND_LEN];
-
- strlcpy(haystack, searchme, sizeof(haystack));
-
- ngt_LowerStr(haystack);
-
- return Match(pattern, haystack);
-}
GLOBAL bool
blob - 2e3af757584b0d9630640da16029a6fe9e18b03f
blob + 9da8d38dc68c83630d4588046797e4dc91d3af87
--- src/ngircd/irc.c
+++ src/ngircd/irc.c
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 MatchCaseInsensitive PARAMS((const char *pattern, const char *searchme));
GLOBAL bool
{
CLIENT *cl, *from;
CHANNEL *chan;
- char *targetList = Req->argv[0];
char *currentTarget = Req->argv[0];
- unsigned int targetCount = 1;
+ char *lastCurrentTarget;
- assert( Client != NULL );
- assert( Req != NULL );
+ assert(Client != NULL);
+ assert(Req != NULL);
if (Req->argc == 0) {
if (!SendErrors)
Client_ID(Client), Req->prefix);
}
- while (*targetList) {
- if (*targetList == ',') {
- *targetList = '\0';
- targetCount++;
- }
- targetList++;
- }
+ /* handle msgtarget = msgto *("," msgto) */
+ currentTarget = strtok_r(currentTarget, ",", &lastCurrentTarget);
- while (targetCount > 0) {
+ while (currentTarget) {
+ /* Check for and handle valid <msgto> of form:
+ * RFC 2812 2.3.1:
+ * msgto = channel / ( user [ "%" host ] "@" servername )
+ * msgto =/ ( user "%" host ) / targetmask
+ * msgto =/ nickname / ( nickname "!" user "@" host )
+ */
if (strchr(currentTarget, '!') == NULL)
+ /* nickname */
cl = Client_Search(currentTarget);
else
cl = NULL;
+
if (cl == NULL) {
- char target[513]; // max mesage length plus null terminator
+ /* If currentTarget isn't a nickname check for:
+ * user ["%" host] "@" servername
+ * user "%" host
+ * nickname "!" user "@" host
+ */
+ char target[COMMAND_LEN];
char * nick = NULL;
char * user = NULL;
char * host = NULL;
char * server = NULL;
- strncpy(target, currentTarget, 512);
- target[512] = '\0';
+ strlcpy(target, currentTarget, COMMAND_LEN);
server = strchr(target, '@');
if (server) {
*server = '\0';
}
user = strchr(target, '!');
if (user) {
+ /* msgto form: nick!user@host */
*user = '\0';
user++;
nick = target;
- host = server; // <msgto> form: nick!user@host
+ host = server; /* not "@server" but "@host" */
} else {
user = target;
}
- if (user != NULL) {
- for (cl = Client_First(); cl != NULL; cl = Client_Next(cl)) {
- if (Client_Type(cl) != CLIENT_USER)
- continue;
- if (nick != NULL) {
- if (strcmp(nick, Client_ID(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)
- continue;
- if (server != NULL && strcasecmp(server, Client_ID(Client_Introducer(cl))) != 0)
- continue;
- break;
+ for (cl = Client_First(); cl != NULL; cl = Client_Next(cl)) {
+ if (Client_Type(cl) != CLIENT_USER)
+ continue;
+ if (nick != NULL) {
+ if (strcmp(nick, Client_ID(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)
+ continue;
+ if (server != NULL && strcasecmp(server,
+ Client_ID(Client_Introducer(cl))) != 0)
+ continue;
+ break;
}
}
Client_ID(from),
currentTarget))
return false;
- } else if ((Client_Type(Client) != CLIENT_SERVER
- && (strchr(Client_Modes(cl), 'a')))) {
+ } else if (SendErrors && (Client_Type(Client) != CLIENT_SERVER)
+ && strchr(Client_Modes(cl), 'a')) {
/* Target is away */
if (!SendErrors)
return true;
(from, RPL_AWAY_MSG, Client_ID(from), Client_ID(cl),
Client_Away(cl)))
return DISCONNECTED;
- } if (Client_Conn(from) > NONE) {
+ }
+ 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, '.')) {
- if (!Send_Message_Mask(from, currentTarget, Req->argv[1], SendErrors))
+ /* targetmask */
+ if (!Send_Message_Mask(from, currentTarget, Req->argv[1],
+ SendErrors))
return false;
} else if ((chan = Channel_Search(currentTarget))) {
- if (!Channel_Write(chan, from, Client, Req->argv[1]))
- return false;
+ /* channel */
+ if (!Channel_Write(chan, from, Client, Req->argv[1]))
+ return false;
} else {
if (!SendErrors)
return true;
return false;
}
- while (*currentTarget)
- currentTarget++;
-
- currentTarget++;
- targetCount--;
+ currentTarget = strtok_r(NULL, ",", &lastCurrentTarget);
}
return CONNECTED;
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, "PRIVMSG %s :%s",
+ Client_ID(cl), message))
return false;
}
} else {
for (cl = Client_First(); cl != NULL; cl = Client_Next(cl)) {
if (Client_Type(cl) != CLIENT_USER)
continue;
- client_match = MatchCaseInsensitive(mask, Client_ID(Client_Introducer(cl)));
+ client_match = MatchCaseInsensitive(mask,
+ 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, "PRIVMSG %s :%s",
+ Client_ID(cl), message))
return false;
}
}
} /* Send_Message_Mask */
-static bool
-MatchCaseInsensitive(const char *pattern, const char *searchme)
-{
- char haystack[COMMAND_LEN];
-
- strlcpy(haystack, searchme, sizeof(haystack));
-
- ngt_LowerStr(haystack);
-
- return Match(pattern, haystack);
-}
-
/* -eof- */
blob - 8f2fa2a60da60e2fb4a52b8a402e85c1aa7edd55
blob + 0f9009df815469ac9a97377127dc50cb72fe9bc3
--- src/ngircd/match.c
+++ src/ngircd/match.c
#include "exp.h"
#include "match.h"
+#include "defines.h"
+#include "tool.h"
/*
} /* Match */
+GLOBAL bool
+MatchCaseInsensitive(const char *pattern, const char *searchme)
+{
+ char haystack[COMMAND_LEN];
+
+ strlcpy(haystack, searchme, sizeof(haystack));
+
+ ngt_LowerStr(haystack);
+
+ return Match(pattern, haystack);
+} /* MatchCaseInsensitive */
+
+
static int
Matche( const char *p, const char *t )
{
blob - ac1aa962d9948b47067e7567d3b00f110349ca1a
blob + 0e8df74a25df204f50ce896247c12a9c81ea3134
--- src/ngircd/match.h
+++ src/ngircd/match.h
GLOBAL bool Match PARAMS(( const char *Pattern, const char *String ));
+GLOBAL bool MatchCaseInsensitive PARAMS(( const char *Pattern, const char *searchme ));
#endif
blob - 000334649d53e07230e36cff0c7be7c0a2abdb3c
blob + dd164822e418292bd46a412ffb76319e79257a39
--- src/testsuite/message-test.e
+++ src/testsuite/message-test.e
-# $Id: mode-test.e,v 1.7 2008/02/16 11:27:49 fw Exp $
-
spawn telnet localhost 6789
expect {
timeout { exit 1 }
"@* PRIVMSG nick :test\r*401*@* PRIVMSG nick :test"
}
-send "JOIN #testChannel\r"
-
send "privmsg doesnotexist :test\r"
expect {
timeout { exit 1 }
"401"
}
+send "privmsg ~user@ngircd.test.server :test\r"
+expect {
+ timeout { exit 1 }
+ "@* PRIVMSG nick :test"
+}
+
+
+send "privmsg ~user\%localhost :test\r"
+expect {
+ timeout { exit 1 }
+ "@* PRIVMSG nick :test"
+}
+
+send "privmsg nick!~user@localhost :test\r"
+expect {
+ timeout { exit 1 }
+ "@* PRIVMSG nick :test"
+}
+
send "away :away\r"
expect {
timeout { exit 1 }