diff --git a/exec/ircd.js b/exec/ircd.js index 2dfb36232614198699b9d25e373f5037f06206b7..85a6320e134d60ff5e4033338612b5a6f3472964 100644 --- a/exec/ircd.js +++ b/exec/ircd.js @@ -445,13 +445,14 @@ function oper_notice(ntype,nmessage) { } function create_ban_mask(str,kline) { - tmp_banstr = new Array; + var tmp_banstr = new Array; tmp_banstr[0] = ""; tmp_banstr[1] = ""; tmp_banstr[2] = ""; - bchar_counter = 0; - part_counter = 0; // BAN: 0!1@2 KLINE: 0@1 - regexp="[A-Za-z\{\}\`\^\_\|\\]\\[\\\\0-9\-.*?\~]"; + var bchar_counter = 0; + var part_counter = 0; // BAN: 0!1@2 KLINE: 0@1 + var regexp="[A-Za-z\{\}\`\^\_\|\\]\\[\\\\0-9\-.*?\~]"; + var finalstr; for (bchar in str) { if (str[bchar].match(regexp)) { tmp_banstr[part_counter] += str[bchar]; @@ -2333,12 +2334,12 @@ function IRCClient_do_complex_who(cmd) { var who = new Who(); var tmp; var eow = "*"; - var add; + var add = true; // assume the user is doing + by default var arg = 1; var whomask = ""; var chan; - if (cmd[2].toLowerCase() == "o") { // Compatibility with RFC1459. + if (cmd[2] && cmd[2].toLowerCase() == "o") { // RFC1459 Compatibility. tmp = cmd[1]; cmd[1] = cmd[2]; cmd[2] = tmp; @@ -2657,8 +2658,11 @@ function IRCClient_match_who_mask(mask) { } function IRCClient_do_who_usage() { - this.numeric(334,":/WHO [+|-][acghimnosuCM] <args>"); + this.numeric(334,":/WHO [+|-][acghimnosuCM] <args> <mask>"); this.numeric(334,":The modes as above work exactly like channel modes."); + this.numeric(334,":<mask> may be '*' or in nick!user@host notation."); + this.numeric(334,":i.e. '/WHO +a *.ca' would match all away users from *.ca"); + this.numeric(334,":No args/mask matches to everything by default."); this.numeric(334,":a : User is away."); this.numeric(334,":c <chan>: User is on <channel>, no wildcards."); this.numeric(334,":g <rnam>: Check against realname field, wildcards allowed."); @@ -4261,7 +4265,7 @@ function IRCClient_registered_commands(command, cmdline) { this.do_who_usage(); break; } - if (cmd[2]) { + if (cmd[2] || (cmd[1][0] == "-")||(cmd[1][0] == "+")) { this.do_complex_who(cmd); } else { this.do_basic_who(cmd[1]); @@ -4593,6 +4597,9 @@ function IRCClient_server_commands(origin, command, cmdline) { if (cmd[2][0] != "#") break; + var chan_members; + var cm_array; + if (cmd[3]) { var mode_args = ""; var tmp_modeargs = 0; @@ -4609,10 +4616,35 @@ function IRCClient_server_commands(origin, command, cmdline) { if ((cmd[4] == "") && cmd[5]) tmp_modeargs++; - var chan_members = ircstring(cmdline,4+tmp_modeargs).split(' '); + chan_members = ircstring(cmdline,4+tmp_modeargs).split(' '); if (chan_members == "") { - oper_notice("Notice","Server " + this.nick + " trying to SJOIN empty channel " + cmd[2]); + oper_notice("Notice","Server " + this.nick + " trying to SJOIN empty channel " + cmd[2] + " before processing."); + break; + } + + cm_array = new Array(); + + for (cm in chan_members) { + var isop = false; + var isvoice = false; + if (chan_members[cm][0] == "@") { + isop = true; + chan_members[cm] = chan_members[cm].slice(1); + } + if (chan_members[cm][0] == "+") { + isvoice = true; + chan_members[cm] = chan_members[cm].slice(1); + } + var tmp_nick = searchbynick(chan_members +[cm]); + if (!tmp_nick) + continue; + cm_array.push(new SJOIN_Nick(tmp_nick,isop,isvoice)); + } + + if (cm_array == "") { + oper_notice("Notice","Server " + this.nick + " trying to SJOIN empty channel " + cmd[2] + " post processing."); break; } } @@ -4648,22 +4680,13 @@ function IRCClient_server_commands(origin, command, cmdline) { var push_sync_modes = "+"; var push_sync_args = ""; var new_chan_members = ""; - for (member in chan_members) { + for (member in cm_array) { if (new_chan_members) new_chan_members += " "; - var is_op = false; - var is_voice = false; - if (chan_members[member][0] == "@") { - is_op = true; - chan_members[member] = chan_members[member].slice(1); - } - if (chan_members[member][0] == "+") { - is_voice = true; - chan_members[member] = chan_members[member].slice(1); - } - var member_obj = searchbynick(chan_members[member]); - if (!member_obj) - continue; + + var member_obj = cm_array[member].nick; + var is_voice = cm_array[member].isvoice; + var is_op = cm_array[member].isop; if (member_obj.onchannel(chan.nam.toUpperCase())) continue; @@ -4785,7 +4808,7 @@ function IRCClient_server_commands(origin, command, cmdline) { } break; case "MODE": - if (!cmd[1]) + if (!cmd[2]) break; // nasty kludge since we don't support per-mode TS yet. if (cmd[2].match(/^[0-9]+$/) && @@ -4805,6 +4828,7 @@ function IRCClient_server_commands(origin, command, cmdline) { ThisOrigin.set_chanmode(chan,modeline,false); } else { // assume it's for a user ThisOrigin.setusermode(cmd[2]); + this.bcast_to_servers_raw(":" + ThisOrigin.nick + " MODE " + ThisOrigin.nick + " " + cmd[2]); } break; case "MOTD": @@ -5482,3 +5506,11 @@ function NickBuf(oldnick,newnick) { this.oldnick = oldnick; this.newnick = newnick; } + +// used for tracking true SJOIN nicks. +function SJOIN_Nick(nick,isop,isvoice) { + this.nick = nick; + this.isop = isop; + this.isvoice = isvoice; +} +