X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Firc.c;h=2466b6bf9e47ef9ed7c084fe0a2af93a6570cf0f;hb=3a2ac66f7ff5985cae4de390a8e510ae7ff2a5a6;hp=3a2a9affbe97d1dd80cea10c5abe4e784f117a86;hpb=71e9ac486f1bdbe7e14adc20969c065f6bbeafe4;p=ngircd-alex.git diff --git a/src/ngircd/irc.c b/src/ngircd/irc.c index 3a2a9aff..2466b6bf 100644 --- a/src/ngircd/irc.c +++ b/src/ngircd/irc.c @@ -33,6 +33,7 @@ static char UNUSED id[] = "$Id: irc.c,v 1.132 2008/01/15 22:28:14 fw Exp $"; #include "match.h" #include "messages.h" #include "parse.h" +#include "tool.h" #include "exp.h" #include "irc.h" @@ -349,6 +350,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) /* handle msgtarget = msgto *("," msgto) */ currentTarget = strtok_r(currentTarget, ",", &lastCurrentTarget); + ngt_UpperStr(Req->command); while (currentTarget) { /* Check for and handle valid of form: @@ -398,7 +400,8 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) } 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 && host != NULL) { if (strcmp(nick, Client_ID(cl)) == 0 && @@ -436,6 +439,17 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) Client_ID(from), 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 */ @@ -452,16 +466,19 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors) Req->command, Client_ID(cl), Req->argv[1])) return DISCONNECTED; - } else if (strchr("$#", currentTarget[0]) + } else if (ForceType != CLIENT_SERVICE + && (chan = Channel_Search(currentTarget))) { + if (!Channel_Write(chan, from, Client, Req->command, + SendErrors, Req->argv[1])) + return DISCONNECTED; + } else if (ForceType != CLIENT_SERVICE + /* $#: server/target mask, RFC 2812, sec. 3.3.1 */ + && strchr("$#", currentTarget[0]) && strchr(currentTarget, '.')) { /* targetmask */ if (!Send_Message_Mask(from, Req->command, currentTarget, Req->argv[1], SendErrors)) return DISCONNECTED; - } else if ((chan = Channel_Search(currentTarget))) { - /* channel */ - if (!Channel_Write(chan, from, Client, Req->argv[1])) - return DISCONNECTED; } else { if (!SendErrors) return CONNECTED; @@ -484,6 +501,7 @@ Send_Message_Mask(CLIENT * from, char * command, char * targetMask, CLIENT *cl; bool client_match; char *mask = targetMask + 1; + const char *check_wildcards; cl = NULL; @@ -494,6 +512,21 @@ Send_Message_Mask(CLIENT * from, char * command, char * targetMask, Client_ID(from)); } + /* + * RFC 2812, sec. 3.3.1 requires that targetMask have at least one + * dot (".") and no wildcards ("*", "?") following the last one. + */ + check_wildcards = strrchr(targetMask, '.'); + assert(check_wildcards != NULL); + if (check_wildcards && + check_wildcards[strcspn(check_wildcards, "*?")]) + { + if (!SendErrors) + return true; + return IRC_WriteStrClient(from, ERR_WILDTOPLEVEL, targetMask); + } + + /* #: hostmask, see RFC 2812, sec. 3.3.1 */ if (targetMask[0] == '#') { for (cl = Client_First(); cl != NULL; cl = Client_Next(cl)) { if (Client_Type(cl) != CLIENT_USER) @@ -505,6 +538,7 @@ Send_Message_Mask(CLIENT * from, char * command, char * targetMask, return false; } } else { + assert(targetMask[0] == '$'); /* $: server mask, see RFC 2812, sec. 3.3.1 */ for (cl = Client_First(); cl != NULL; cl = Client_Next(cl)) { if (Client_Type(cl) != CLIENT_USER) continue;