diff --git a/exec/ircd.js b/exec/ircd.js index 358e78f20f1a4f1c6017f7870f129cd1cd91f892..cc167dc71238d47223624fe19d0227f72f868d69 100644 --- a/exec/ircd.js +++ b/exec/ircd.js @@ -94,16 +94,16 @@ var default_port = 6667; log(VERSION + " started."); // Our primary arrays. -Unregistered = new Array; -Users = new Array; -Servers = new Array; -Channels = new Array; +Unregistered = new Object; +Users = new Object; +Servers = new Object; +Channels = new Object; -Local_Sockets = new Array; -Local_Sockets_Map = new Array; +Local_Sockets = new Object; +Local_Sockets_Map = new Object; -Selectable_Sockets = new Array; -Selectable_Sockets_Map = new Array; +Selectable_Sockets = new Object; +Selectable_Sockets_Map = new Object; Global_CommandLine = ""; // We use this to track if a cmdline causes a crash. @@ -112,23 +112,23 @@ hcc_users = 0; hcc_counter = 0; server_uptime = time(); -WhoWasHistory = new Array; -NickHistory = new Array; +WhoWasHistory = new Object; +NickHistory = new Array; /* A true array using push and pop */ whowas_buffer = 1000; whowas_pointer = 0; nick_buffer = 1000; nick_pointer = 0; /* Keep track of commands and how long they take to execute. */ -Profile = new Array; +Profile = new Object; // This is where our unique ID for each client comes from for unreg'd clients. next_client_id = 0; // An array containing all the objects containing local sockets that we need // to poll. -Local_Users = new Array; -Local_Servers = new Array; +Local_Users = new Object; +Local_Servers = new Object; rebuild_socksel_array = false; @@ -172,7 +172,7 @@ server.socket.nonblocking = true; // REQUIRED! server.socket.debug = false; // Will spam your log if true :) // Now open additional listening sockets as defined on the P:Line in ircd.conf -open_plines = new Array(); +open_plines = new Array(); /* True Array */ // Make our 'server' object the first open P:Line open_plines[0] = server.socket; for (pl in PLines) { @@ -1284,7 +1284,7 @@ function IRCClient_onchanwith(target) { //////////////////// Auxillary Functions //////////////////// function IRCClient_bcast_to_uchans_unique(str) { - var already_bcast = new Array(); + var already_bcast = new Object; for(thisChannel in this.channels) { var userchannel=this.channels[thisChannel]; for (j in userchannel.users) { @@ -1316,7 +1316,7 @@ function IRCClient_bcast_to_channel(chan, str, bounce) { } function IRCClient_bcast_to_channel_servers(chan, str) { - var sent_to_servers = new Array; + var sent_to_servers = new Object; for(thisUser in chan.users) { var aUser=chan.users[thisUser]; if (!aUser.local && (this.parent != aUser.parent) && @@ -2945,7 +2945,7 @@ function SJOIN_Nick(nick,isop,isvoice) { // Track IRC socket queues function IRC_Queue() { - this.queue = new Array(); + this.queue = new Array; this.bytes = 0; this.add = Queue_Add; } diff --git a/exec/load/ircd_channel.js b/exec/load/ircd_channel.js index d0ae89f742159c49993c81f0b6955898963a7316..f9c9e13e6d5a95c7a97ea716de5f820851a02e18 100644 --- a/exec/load/ircd_channel.js +++ b/exec/load/ircd_channel.js @@ -25,44 +25,39 @@ const CHANNEL_REVISION = "$Revision$".split(' ')[1]; const CHANMODE_NONE =(1<<0); // NONE const CHANMODE_BAN =(1<<1); // b -const CHANMODE_INVITE =(1<<2); // i +const CHANMODE_INVITE =(1<<2); // i const CHANMODE_KEY =(1<<3); // k -const CHANMODE_LIMIT =(1<<4); // l -const CHANMODE_MODERATED =(1<<5); // m -const CHANMODE_NOOUTSIDE =(1<<6); // n +const CHANMODE_LIMIT =(1<<4); // l +const CHANMODE_MODERATED=(1<<5); // m +const CHANMODE_NOOUTSIDE=(1<<6); // n const CHANMODE_OP =(1<<7); // o -const CHANMODE_PRIVATE =(1<<8); // p -const CHANMODE_SECRET =(1<<9); // s -const CHANMODE_TOPIC =(1<<10); // t -const CHANMODE_VOICE =(1<<11); // v +const CHANMODE_PRIVATE =(1<<8); // p +const CHANMODE_SECRET =(1<<9); // s +const CHANMODE_TOPIC =(1<<10); // t +const CHANMODE_VOICE =(1<<11); // v -// These are used in the mode crunching section to figure out what character -// to display in the crunched MODE line. +/* These are used in the mode crunching section to figure out what character + to display in the crunched MODE line. */ function Mode(modechar,args,state,list,isnick) { - // The mode's character - this.modechar = modechar; - // Does this mode take a single argument only? - this.args = args; - // Is this mode a stateful mode? (i.e. changes channel behaviour) - this.state = state; - // Can this mode accept a list? - this.list = list; - // Is the list a nick (true), or a n!u@h IRC mask (false)? - this.isnick = isnick; + this.modechar = modechar; /* The mode's character */ + this.args = args; /* Does this mode take only a single arg? */ + this.state = state; /* Stateful? (changes channel behaviour) */ + this.list = list; /* Does this mode accept a list? */ + this.isnick = isnick; /* Is nick (true) or a n!u@h mask (false) */ } -MODE = new Array(); +MODE = new Object; MODE[CHANMODE_BAN] = new Mode("b",true,false,true,false); -MODE[CHANMODE_INVITE] = new Mode("i",false,true,false,false); +MODE[CHANMODE_INVITE] = new Mode("i",false,true,false,false); MODE[CHANMODE_KEY] = new Mode("k",true,true,false,false); -MODE[CHANMODE_LIMIT] = new Mode("l",true,true,false,false); -MODE[CHANMODE_MODERATED] = new Mode("m",false,true,false,false); -MODE[CHANMODE_NOOUTSIDE] = new Mode("n",false,true,false,false); +MODE[CHANMODE_LIMIT] = new Mode("l",true,true,false,false); +MODE[CHANMODE_MODERATED]= new Mode("m",false,true,false,false); +MODE[CHANMODE_NOOUTSIDE]= new Mode("n",false,true,false,false); MODE[CHANMODE_OP] = new Mode("o",true,false,true,true); -MODE[CHANMODE_PRIVATE] = new Mode("p",false,true,false,false); -MODE[CHANMODE_SECRET] = new Mode("s",false,true,false,false); -MODE[CHANMODE_TOPIC] = new Mode("t",false,true,false,false); -MODE[CHANMODE_VOICE] = new Mode("v",true,false,true,true); +MODE[CHANMODE_PRIVATE] = new Mode("p",false,true,false,false); +MODE[CHANMODE_SECRET] = new Mode("s",false,true,false,false); +MODE[CHANMODE_TOPIC] = new Mode("t",false,true,false,false); +MODE[CHANMODE_VOICE] = new Mode("v",true,false,true,true); ////////// Objects ////////// function Channel(nam) { @@ -71,16 +66,16 @@ function Channel(nam) { this.topic=""; this.topictime=0; this.topicchangedby=""; - this.arg = new Array; + this.arg = new Object; this.arg[CHANMODE_LIMIT] = 0; this.arg[CHANMODE_KEY] = ""; - this.users=new Array; - this.modelist=new Array; - this.modelist[CHANMODE_OP]=new Array; - this.modelist[CHANMODE_VOICE]=new Array; - this.modelist[CHANMODE_BAN]=new Array; - this.bantime=new Array; - this.bancreator=new Array; + this.users=new Object; + this.modelist=new Object; + this.modelist[CHANMODE_OP]=new Object; + this.modelist[CHANMODE_VOICE]=new Object; + this.modelist[CHANMODE_BAN]=new Array; /* True Array */ + this.bantime=new Object; + this.bancreator=new Object; this.created=time(); this.chanmode=Channel_chanmode; this.isbanned=Channel_isbanned; @@ -225,17 +220,17 @@ function Channel_occupants() { // Yay, version 3.0 of this.set_chanmode(), eradicates any global variables. function ChanMode(chan,user) { - this.tmplist = new Array(); - this.tmplist[CHANMODE_OP] = new Array(); - this.tmplist[CHANMODE_OP][false] = new Array(); //deop - this.tmplist[CHANMODE_OP][true] = new Array(); //op - this.tmplist[CHANMODE_VOICE] = new Array(); - this.tmplist[CHANMODE_VOICE][false] = new Array(); //devoice - this.tmplist[CHANMODE_VOICE][true] = new Array(); //voice - this.tmplist[CHANMODE_BAN] = new Array(); - this.tmplist[CHANMODE_BAN][false] = new Array(); //unban - this.tmplist[CHANMODE_BAN][true] = new Array(); //ban - this.state_arg = new Array(); + this.tmplist = new Object; + this.tmplist[CHANMODE_OP] = new Object; + this.tmplist[CHANMODE_OP][false] = new Object; //deop + this.tmplist[CHANMODE_OP][true] = new Object; //op + this.tmplist[CHANMODE_VOICE] = new Object; + this.tmplist[CHANMODE_VOICE][false] = new Object; //devoice + this.tmplist[CHANMODE_VOICE][true] = new Object; //voice + this.tmplist[CHANMODE_BAN] = new Object; + this.tmplist[CHANMODE_BAN][false] = new Object; //unban + this.tmplist[CHANMODE_BAN][true] = new Object; //ban + this.state_arg = new Object; this.state_arg[CHANMODE_KEY] = ""; this.state_arg[CHANMODE_LIMIT] = ""; this.addbits = 0; @@ -545,12 +540,15 @@ function IRCClient_do_join(chan_name,join_key) { this.numeric403(chan_name); return 0; } - if(chan_name.search(/[\x00-\x20\x2c\xa0]/)!=-1) { - if (this.local) { - this.numeric(479, chan_name - + " :Channel name contains illegal characters."); + for (theChar in chan_name) { + var theChar_code = chan_name[theChar].charCodeAt(0); + if ((theChar_code <= 32) || (theChar_code == 44) || + (chan_name[theChar].charCodeAt(0) == 160)) { + if (this.local) + this.numeric(479, chan_name + + " :Channel name contains illegal characters."); + return 0; } - return 0; } if (this.channels[uc_chan_name]) return 0; diff --git a/exec/load/ircd_server.js b/exec/load/ircd_server.js index b79534b4cacc0e112b773cd8280af79d22522398..5becbb00ea2a3fb806ef539f1afcce3ca5dc9a66 100644 --- a/exec/load/ircd_server.js +++ b/exec/load/ircd_server.js @@ -89,9 +89,9 @@ function IRC_Server() { function Server_Work() { var clockticks = system.timer; - var command; var cmdline; - var origin; + var cmd; + var command; if (!this.socket.is_connected) { this.quit("Connection reset by peer"); @@ -156,906 +156,939 @@ function Server_Work() { var legal_command = true; /* For tracking STATS M */ switch(command) { - // PING at the top thanks to RFC1459 - case "PING": - if (!cmd[1]) - break; - if (cmd[2] && (cmd[2][0] == ":")) - cmd[2] = cmd[2].slice(1); - var tmp_server; - if (cmd[2]) - tmp_server = searchbyserver(cmd[2]); - if (tmp_server && (tmp_server != -1) && - (tmp_server.id != ThisOrigin.id)) { - tmp_server.rawout(":" + ThisOrigin.nick + " PING " + ThisOrigin.nick + " :" + tmp_server.nick); - break; - } - if (cmd[1][0] == ":") - cmd[1] = cmd[1].slice(1); - if (!cmd[2]) - this.ircout("PONG " + servername + " :" + cmd[1]); - else - this.ircout("PONG " + cmd[2] + " :" + cmd[1]); + // PING at the top thanks to RFC1459 + case "PING": + if (!cmd[1]) break; - case "ADMIN": - if (!cmd[1] || ThisOrigin.server) - break; - if (cmd[1][0] == ":") - cmd[1] = cmd[1].slice(1); - if (wildmatch(servername,cmd[1])) { - ThisOrigin.do_admin(); - } else { - var dest_server = searchbyserver(cmd[1]); - if (!dest_server) - break; - dest_server.rawout(":" + ThisOrigin.nick + " ADMIN :" + dest_server.nick); - } + if (cmd[2] && (cmd[2][0] == ":")) + cmd[2] = cmd[2].slice(1); + var tmp_server; + if (cmd[2]) + tmp_server = searchbyserver(cmd[2]); + if (tmp_server && (tmp_server != -1) && (tmp_server.id != ThisOrigin.id)) { + tmp_server.rawout(":" + ThisOrigin.nick + " PING " + ThisOrigin.nick + " :" + tmp_server.nick); break; - case "AKILL": - var this_uh; - - if (!cmd[6]) - break; - if (!ThisOrigin.uline) { - umode_notice(USERMODE_OPER,"Notice","Non-U:Lined server " + ThisOrigin.nick + " trying to utilize AKILL."); + } + if (cmd[1][0] == ":") + cmd[1] = cmd[1].slice(1); + if (!cmd[2]) + this.ircout("PONG " + servername + " :" + cmd[1]); + else + this.ircout("PONG " + cmd[2] + " :" + cmd[1]); + break; + case "ADMIN": + if (!cmd[1] || ThisOrigin.server) + break; + if (cmd[1][0] == ":") + cmd[1] = cmd[1].slice(1); + if (wildmatch(servername,cmd[1])) { + ThisOrigin.do_admin(); + } else { + var dest_server = searchbyserver(cmd[1]); + if (!dest_server) break; - } + dest_server.rawout(":" + ThisOrigin.nick + " ADMIN :" + dest_server.nick); + } + break; + case "AKILL": + var this_uh; - this_uh = cmd[2] + "@" + cmd[1]; - if (isklined(this_uh)) - break; - KLines.push(new KLine(this_uh,IRC_string(cmdline,6),"A")); - this.bcast_to_servers_raw(":" + ThisOrigin.nick + " " + cmdline); - scan_for_klined_clients(); + if (!cmd[6]) break; - case "AWAY": - if (ThisOrigin.server) - break; - var send_away = "AWAY"; - var my_ircstr = IRC_string(cmdline,1); - if (!my_ircstr) { - ThisOrigin.away = ""; - } else { - ThisOrigin.away = my_ircstr; - send_away += " :" + my_ircstr; - } - this.bcast_to_servers_raw(":" + ThisOrigin.nick + " " + send_away); + if (!ThisOrigin.uline) { + umode_notice(USERMODE_OPER,"Notice","Non-U:Lined server " + ThisOrigin.nick + + " trying to utilize AKILL."); break; - case "CHATOPS": - if (!cmd[1]) - break; - var my_ircstr = IRC_string(cmdline,1); - umode_notice(USERMODE_CHATOPS,"ChatOps","from " + - ThisOrigin.nick + ": " + my_ircstr); - this.bcast_to_servers_raw(":" + ThisOrigin.nick + " " + - "CHATOPS :" + my_ircstr); + } + + this_uh = cmd[2] + "@" + cmd[1]; + if (isklined(this_uh)) break; - case "CONNECT": - if (!cmd[3] || !this.hub || ThisOrigin.server) - break; - if (wildmatch(servername, cmd[3])) { - ThisOrigin.do_connect(cmd[1],cmd[2]); - } else { - var dest_server = searchbyserver(cmd[3]); - if (!dest_server) - break; - dest_server.rawout(":" + ThisOrigin.nick + " CONNECT " + cmd[1] + " " + cmd[2] + " " + dest_server.nick); - } + KLines.push(new KLine(this_uh,IRC_string(cmdline,6),"A")); + this.bcast_to_servers_raw(":" + ThisOrigin.nick + " " + cmdline); + scan_for_klined_clients(); + break; + case "AWAY": + if (ThisOrigin.server) break; - case "GLOBOPS": - if (!cmd[1]) - break; - var my_ircstr = IRC_string(cmdline,1); - ThisOrigin.globops(my_ircstr); + var send_away = "AWAY"; + var my_ircstr = IRC_string(cmdline,1); + if (!my_ircstr) { + ThisOrigin.away = ""; + } else { + ThisOrigin.away = my_ircstr; + send_away += " :" + my_ircstr; + } + this.bcast_to_servers_raw(":" + ThisOrigin.nick + " " + send_away); + break; + case "CHATOPS": + if (!cmd[1]) break; - case "GNOTICE": - if (!cmd[1]) + var my_ircstr = IRC_string(cmdline,1); + umode_notice(USERMODE_CHATOPS,"ChatOps","from " + + ThisOrigin.nick + ": " + my_ircstr); + this.bcast_to_servers_raw(":" + ThisOrigin.nick + " " + + "CHATOPS :" + my_ircstr); + break; + case "CONNECT": + if (!cmd[3] || !this.hub || ThisOrigin.server) + break; + if (wildmatch(servername, cmd[3])) { + ThisOrigin.do_connect(cmd[1],cmd[2]); + } else { + var dest_server = searchbyserver(cmd[3]); + if (!dest_server) break; - var my_ircstr = IRC_string(cmdline,1); - umode_notice(USERMODE_ROUTING,"Routing","from " + - ThisOrigin.nick + ": " + my_ircstr); - this.bcast_to_servers_raw(":" + ThisOrigin.nick + " " + - "GNOTICE :" + my_ircstr); + dest_server.rawout(":" + ThisOrigin.nick + " CONNECT " + cmd[1] + " " + cmd[2] + " " + + dest_server.nick); + } + break; + case "GLOBOPS": + if (!cmd[1]) break; - case "ERROR": - var my_ircstr = IRC_string(cmdline,1); - gnotice("ERROR from " + this.nick + " [(+)0@" + - this.hostname + "] -- " + my_ircstr); - ThisOrigin.quit(my_ircstr); + var my_ircstr = IRC_string(cmdline,1); + ThisOrigin.globops(my_ircstr); + break; + case "GNOTICE": + if (!cmd[1]) break; - case "INFO": - if (!cmd[1] || ThisOrigin.server) - break; - if (cmd[1][0] == ":") - cmd[1] = cmd[1].slice(1); - if (wildmatch(servername, cmd[1])) { - ThisOrigin.do_info(); - } else { - var dest_server = searchbyserver(cmd[1]); - if (!dest_server) - break; - dest_server.rawout(":" + ThisOrigin.nick + " INFO :" + dest_server.nick); - } + var my_ircstr = IRC_string(cmdline,1); + umode_notice(USERMODE_ROUTING,"Routing","from " + ThisOrigin.nick + ": " + my_ircstr); + this.bcast_to_servers_raw(":" + ThisOrigin.nick + " " + "GNOTICE :" + my_ircstr); + break; + case "ERROR": + var my_ircstr = IRC_string(cmdline,1); + gnotice("ERROR from " + this.nick + " [(+)0@" + this.hostname + "] -- " + my_ircstr); + ThisOrigin.quit(my_ircstr); + break; + case "INFO": + if (!cmd[1] || ThisOrigin.server) break; - case "INVITE": - if (!cmd[2] || ThisOrigin.server) + if (cmd[1][0] == ":") + cmd[1] = cmd[1].slice(1); + if (wildmatch(servername, cmd[1])) { + ThisOrigin.do_info(); + } else { + var dest_server = searchbyserver(cmd[1]); + if (!dest_server) break; - if (cmd[2][0] == ":") - cmd[2] = cmd[2].slice(1); - var chan = Channels[cmd[2].toUpperCase()]; - if (!chan) - break; - if (!chan.modelist[CHANMODE_OP][ThisOrigin.id]) - break; - var nick = Users[cmd[1].toUpperCase()]; - if (!nick) - break; - if (!nick.channels[chan.nam.toUpperCase()]) - break; - nick.originatorout("INVITE " + nick.nick + " :" + - chan.nam,ThisOrigin); - nick.invited = chan.nam.toUpperCase(); + dest_server.rawout(":" + ThisOrigin.nick + " INFO :" + dest_server.nick); + } + break; + case "INVITE": + if (!cmd[2] || ThisOrigin.server) break; - case "JOIN": - if (!cmd[1] || ThisOrigin.server) - break; - if (cmd[1][0] == ":") - cmd[1]=cmd[1].slice(1); - var the_channels = cmd[1].split(","); - for (jchan in the_channels) { - if (the_channels[jchan][0] != "#") - continue; - ThisOrigin.do_join(the_channels[jchan].slice(0,max_chanlen),""); - } + if (cmd[2][0] == ":") + cmd[2] = cmd[2].slice(1); + var chan = Channels[cmd[2].toUpperCase()]; + if (!chan) break; - case "KICK": - var chanid; - var nickid; - var str; - var kick_reason; + if (!chan.modelist[CHANMODE_OP][ThisOrigin.id]) + break; + var nick = Users[cmd[1].toUpperCase()]; + if (!nick) + break; + if (!nick.channels[chan.nam.toUpperCase()]) + break; + nick.originatorout("INVITE " + nick.nick + " :" + chan.nam,ThisOrigin); + nick.invited = chan.nam.toUpperCase(); + break; + case "JOIN": + if (!cmd[1] || ThisOrigin.server) + break; + if (cmd[1][0] == ":") + cmd[1]=cmd[1].slice(1); + var the_channels = cmd[1].split(","); + for (jchan in the_channels) { + if (the_channels[jchan][0] != "#") + continue; + ThisOrigin.do_join(the_channels[jchan].slice(0,max_chanlen),""); + } + break; + case "KICK": + var chanid; + var nickid; + var str; + var kick_reason; - if (!cmd[2]) - break; - chanid = Channels[cmd[1].toUpperCase()]; - if (!chanid) - break; - nickid = Users[cmd[2].toUpperCase()]; - if (!nickid) - nickid = search_nickbuf(cmd[2]); - if (!nickid) - break; - if (!nickid.channels[chanid.nam.toUpperCase()]) - break; - if (cmd[3]) - kick_reason = IRC_string(cmdline,3).slice(0,max_kicklen); - else - kick_reason = ThisOrigin.nick; - str = "KICK " + chanid.nam + " " + nickid.nick + " :" + kick_reason; - ThisOrigin.bcast_to_channel(chanid, str, false); - this.bcast_to_servers_raw(":" + ThisOrigin.nick + " " + str); - nickid.rmchan(chanid); + if (!cmd[2]) break; - case "KILL": - if (!cmd[1] || !cmd[2]) - break; - if (cmd[1].match(/[.]/)) - break; - if (cmd[2] == ":") - break; - var reason = IRC_string(cmdline,2); - var kills = cmd[1].split(","); - for(kill in kills) { - var target = Users[kills[kill].toUpperCase()]; - if (!target) - target = search_nickbuf(kills[kill]); - if (target && (this.hub || - (target.parent == this.nick)) ) { - umode_notice(USERMODE_KILL,"Notice","Received KILL message for " + target.nuh + ". From " + ThisOrigin.nick + " Path: " + target.nick + "!Synchronet!" + ThisOrigin.nick + " (" + reason + ")"); - this.bcast_to_servers_raw(":" + ThisOrigin.nick + " KILL " + target.nick + " :" + reason); - target.quit("KILLED by " + ThisOrigin.nick + " (" + reason + ")",true); - } else if (target && !this.hub) { - umode_notice(USERMODE_OPER,"Notice","Non-Hub server " + this.nick + " trying to KILL " + target.nick); - this.reintroduce_nick(target); - } + chanid = Channels[cmd[1].toUpperCase()]; + if (!chanid) + break; + nickid = Users[cmd[2].toUpperCase()]; + if (!nickid) + nickid = search_nickbuf(cmd[2]); + if (!nickid) + break; + if (!nickid.channels[chanid.nam.toUpperCase()]) + break; + if (cmd[3]) + kick_reason = IRC_string(cmdline,3).slice(0,max_kicklen); + else + kick_reason = ThisOrigin.nick; + str = "KICK " + chanid.nam + " " + nickid.nick + " :" + kick_reason; + ThisOrigin.bcast_to_channel(chanid, str, false); + this.bcast_to_servers_raw(":" + ThisOrigin.nick + " " + str); + nickid.rmchan(chanid); + break; + case "KILL": + if (!cmd[1] || !cmd[2]) + break; + if (cmd[1].match(/[.]/)) + break; + if (cmd[2] == ":") + break; + var reason = IRC_string(cmdline,2); + var kills = cmd[1].split(","); + for(kill in kills) { + var target = Users[kills[kill].toUpperCase()]; + if (!target) + target = search_nickbuf(kills[kill]); + if (target && (this.hub || (target.parent == this.nick)) ) { + umode_notice(USERMODE_KILL,"Notice","Received KILL message for " + target.nuh + + ". From " + ThisOrigin.nick + " Path: " + target.nick + "!Synchronet!" + + ThisOrigin.nick + " (" + reason + ")"); + this.bcast_to_servers_raw(":" + ThisOrigin.nick + " KILL " + target.nick + " :" + reason); + target.quit("KILLED by " + ThisOrigin.nick + " (" + reason + ")",true); + } else if (target && !this.hub) { + umode_notice(USERMODE_OPER,"Notice","Non-Hub server " + this.nick + " trying to KILL " + + target.nick); + this.reintroduce_nick(target); } + } + break; + case "LINKS": + if (!cmd[1] || !cmd[2] || ThisOrigin.server) break; - case "LINKS": - if (!cmd[1] || !cmd[2] || ThisOrigin.server) + if (match_irc_mask(servername, cmd[1])) { + ThisOrigin.do_links(cmd[2]); + } else { + var dest_server = searchbyserver(cmd[1]); + if (!dest_server) break; - if (match_irc_mask(servername, cmd[1])) { - ThisOrigin.do_links(cmd[2]); - } else { - var dest_server = searchbyserver(cmd[1]); - if (!dest_server) - break; - dest_server.rawout(":" + ThisOrigin.nick + " LINKS " + dest_server.nick + " " + cmd[2]); - } + dest_server.rawout(":" + ThisOrigin.nick + " LINKS " + dest_server.nick + " " + cmd[2]); + } + break; + case "MODE": + if (!cmd[1] || !cmd[2]) break; - case "MODE": - if (!cmd[1] || !cmd[2]) + if (cmd[1][0] == "#") { + var chan = Channels[cmd[1].toUpperCase()]; + if (!chan) break; - if (cmd[1][0] == "#") { - var chan = Channels[cmd[1].toUpperCase()]; - if (!chan) + var modeline; + var cmdend = cmd.length - 1; + var cmd2_int = parseInt(cmd[2]); + var cmdend_int = parseInt(cmd[cmdend]); + // Detect if this is a TSMODE. If so, handle. + /* TODO: Sync IRCd should support TSMODE! */ + if (cmd2_int == cmd[2]) { + if (cmd2_int > chan.created) break; - var modeline; - var cmdend = cmd.length - 1; - var cmd2_int = parseInt(cmd[2]); - var cmdend_int = parseInt(cmd[cmdend]); - // Detect if this is a TSMODE. If so, handle. - /* TODO: Sync IRCd should support TSMODE! */ - if (cmd2_int == cmd[2]) { - if (cmd2_int > chan.created) - break; - cmd.shift(); - } else if (cmdend_int == cmd[cmdend]) { - /* DreamForge style TS */ - if (cmdend_int > chan.created) - break; - cmd.pop(); /* Strip the TS. */ - } - cmd.shift(); cmd.shift(); - var modeline = cmd.join(" "); - ThisOrigin.set_chanmode(chan,modeline,false); - } else { // assume it's for a user - var my_modes = ThisOrigin.setusermode(IRC_string(cmd[2],0)); - if (my_modes) { - this.bcast_to_servers_raw(":" + ThisOrigin.nick - + " MODE " + ThisOrigin.nick + " " + my_modes); - } - } - break; - case "MOTD": - if (!cmd[1] || ThisOrigin.server) - break; - if (cmd[1][0] == ":") - cmd[1] = cmd[1].slice(1); - if (wildmatch(servername, cmd[1])) { - umode_notice(USERMODE_SPY,"Spy", - "MOTD requested by " + ThisOrigin.nick+ - " (" + ThisOrigin.uprefix + "@" + - ThisOrigin.hostname + ") [" + - ThisOrigin.servername + "]"); - ThisOrigin.motd(); - } else { - var dest_server = searchbyserver(cmd[1]); - if (!dest_server) + } else if (cmdend_int == cmd[cmdend]) { + /* DreamForge style TS */ + if (cmdend_int > chan.created) break; - dest_server.rawout(":" + ThisOrigin.nick + " MOTD :" + dest_server.nick); + cmd.pop(); /* Strip the TS. */ + } + cmd.shift(); + cmd.shift(); + var modeline = cmd.join(" "); + ThisOrigin.set_chanmode(chan,modeline,false); + } else { // assume it's for a user + var my_modes = ThisOrigin.setusermode(IRC_string(cmd[2],0)); + if (my_modes) { + this.bcast_to_servers_raw(":" + ThisOrigin.nick + + " MODE " + ThisOrigin.nick + " " + my_modes); } + } + break; + case "MOTD": + if (!cmd[1] || ThisOrigin.server) break; - case "NICK": - if (!cmd[2]) + if (cmd[1][0] == ":") + cmd[1] = cmd[1].slice(1); + if (wildmatch(servername, cmd[1])) { + umode_notice(USERMODE_SPY,"Spy", + "MOTD requested by " + ThisOrigin.nick+ + " (" + ThisOrigin.uprefix + "@" + + ThisOrigin.hostname + ") [" + + ThisOrigin.servername + "]"); + ThisOrigin.motd(); + } else { + var dest_server = searchbyserver(cmd[1]); + if (!dest_server) break; - if (ThisOrigin.server && cmd[8]) { - var collide = Users[cmd[1].toUpperCase()]; - if (collide) { - if (collide.parent == this.nick) { - gnotice("Server " + this.nick + " trying to introduce nick " + collide.nick + " twice?! Ignoring."); - break; - } else if ((parseInt(collide.created) > - parseInt(cmd[3])) && this.hub) { - // Nuke our side of things, allow this newly - // introduced nick to overrule. - collide.numeric(436, collide.nick + " :Nickname Collision KILL."); - this.bcast_to_servers("KILL " + collide.nick + " :Nickname Collision."); - collide.quit("Nickname Collision",true); - } else if (!this.hub) { - gnotice("Server " + this.nick + " trying to collide nick " + collide.nick + " forwards, reversing."); - // Don't collide our side of things from a leaf - this.ircout("KILL " + cmd[1] + " :Inverse Nickname Collision."); - // Reintroduce our nick, because the remote end - // probably killed it already on our behalf. - this.reintroduce_nick(collide); - break; - } else if (this.hub) { - // Other side should nuke on our behalf. - break; - } - } - var uprefixptr = 5; /* Bahamut */ - if (this.type == DREAMFORGE) - uprefixptr = 4; - if (!this.hub) { - if(!this.check_nickname(cmd[1],true)) { - gnotice("Server " + this.nick + " trying to introduce invalid nickname: " + cmd[1] + ", killed."); - this.ircout("KILL " + cmd[1] + " :Bogus Nickname."); - break; - } - cmd[2] = 1; // Force hops to 1. - cmd[3] = time(); // Force TS on nick. - cmd[7] = this.nick // Force server name - } else { // if we're a hub - var test_server = searchbyserver(cmd[uprefixptr+2]); - if (!test_server || (this.nick != - test_server.parent)) { - if (debug && test_server) - log(LOG_DEBUG,"this.nick: " + this.nick + " test_server.parent: " + test_server.parent); - umode_notice(USERMODE_OPER,"Notice","Server " + this.nick + " trying to introduce nick from server not behind it: " + cmd[1] + "@" + cmd[uprefixptr+2]); - this.ircout("KILL " + cmd[1] + " :Invalid Origin."); - break; - } - } - var new_id = "id" + next_client_id; - next_client_id++; - Users[cmd[1].toUpperCase()] = new IRC_User(new_id); - var NewNick = Users[cmd[1].toUpperCase()]; - NewNick.local = false; // not local. duh. - NewNick.nick = cmd[1]; - NewNick.hops = cmd[2]; - NewNick.created = cmd[3]; - NewNick.uprefix = cmd[uprefixptr]; - NewNick.hostname = cmd[uprefixptr+1]; - NewNick.servername = cmd[uprefixptr+2]; - var rnptr = 10; /* Bahamut */ - if (this.type == DREAMFORGE) - rnptr = 8; - NewNick.realname = IRC_string(cmdline,rnptr); - NewNick.parent = this.nick; - if (this.type == DREAMFORGE) - NewNick.ip = 0; - else /* Bahamut */ - NewNick.ip = int_to_ip(cmd[9]); - if (this.type == BAHAMUT) - NewNick.setusermode(cmd[4]); - for (u in ULines) { - if (ULines[u] == cmd[uprefixptr+2]) { - NewNick.uline = true; - break; - } + dest_server.rawout(":" + ThisOrigin.nick + " MOTD :" + dest_server.nick); + } + break; + case "NICK": + if (!cmd[2]) + break; + if (ThisOrigin.server && cmd[8]) { + var collide = Users[cmd[1].toUpperCase()]; + if (collide) { + if (collide.parent == this.nick) { + gnotice("Server " + this.nick + " trying to introduce nick " + collide.nick + + " twice?! Ignoring."); + break; + } else if ((parseInt(collide.created) > + parseInt(cmd[3])) && this.hub) { + // Nuke our side of things, allow this newly + // introduced nick to overrule. + collide.numeric(436, collide.nick + " :Nickname Collision KILL."); + this.bcast_to_servers("KILL " + collide.nick + " :Nickname Collision."); + collide.quit("Nickname Collision",true); + } else if (!this.hub) { + gnotice("Server " + this.nick + " trying to collide nick " + collide.nick + + " forwards, reversing."); + // Don't collide our side of things from a leaf + this.ircout("KILL " + cmd[1] + " :Inverse Nickname Collision."); + // Reintroduce our nick, because the remote end + // probably killed it already on our behalf. + this.reintroduce_nick(collide); + break; + } else if (this.hub) { + // Other side should nuke on our behalf. + break; } - var true_hops = parseInt(NewNick.hops)+1; - this.bcast_to_servers_raw("NICK " + NewNick.nick + " " + true_hops + " " + NewNick.created + " " + NewNick.get_usermode(true) + " " + NewNick.uprefix + " " + NewNick.hostname + " " + NewNick.servername + " 0 " + cmd[9] + " :" + NewNick.realname,BAHAMUT); - this.bcast_to_servers_raw("NICK " + NewNick.nick + " " + true_hops + " " + NewNick.created + " " + NewNick.uprefix + " " + NewNick.hostname + " " + NewNick.servername + " 0 :" + NewNick.realname,DREAMFORGE); - } else { // we're a user changing our nick. - var ctuc = cmd[1].toUpperCase(); - if ((Users[ctuc])&&Users[ctuc].nick.toUpperCase() != - ThisOrigin.nick.toUpperCase()) { - gnotice("Server " + this.nick + " trying to collide nick via NICK changeover: " + ThisOrigin.nick + " -> " + cmd[1]); - server_bcast_to_servers("KILL " + ThisOrigin.nick + " :Bogus nickname changeover."); - ThisOrigin.quit("Bogus nickname changeover."); - this.ircout("KILL " + cmd[1] + " :Bogus nickname changeover."); - this.reintroduce_nick(Users[ctuc]); + } + var uprefixptr = 5; /* Bahamut */ + if (this.type == DREAMFORGE) + uprefixptr = 4; + if (!this.hub) { + if(!this.check_nickname(cmd[1],true)) { + gnotice("Server " + this.nick + " trying to introduce invalid nickname: " + cmd[1] + + ", killed."); + this.ircout("KILL " + cmd[1] + " :Bogus Nickname."); break; } - if (ThisOrigin.check_nickname(cmd[1]) < 1) { - gnotice("Server " + this.nick + " trying to change to bogus nick: " + ThisOrigin.nick + " -> " + cmd[1]); - this.bcast_to_servers_raw("KILL " + ThisOrigin.nick + " :Bogus nickname switch detected."); - this.ircout("KILL " + cmd[1] + " :Bogus nickname switch detected."); - ThisOrigin.quit("Bogus nickname switch detected.",true); + cmd[2] = 1; // Force hops to 1. + cmd[3] = time(); // Force TS on nick. + cmd[7] = this.nick // Force server name + } else { // if we're a hub + var test_server = searchbyserver(cmd[uprefixptr+2]); + if (!test_server || (this.nick != + test_server.parent)) { + if (debug && test_server) + log(LOG_DEBUG,"this.nick: " + this.nick + " test_server.parent: " + test_server.parent); + umode_notice(USERMODE_OPER,"Notice","Server " + this.nick + + " trying to introduce nick from server not behind it: " + + cmd[1] + "@" + cmd[uprefixptr+2]); + this.ircout("KILL " + cmd[1] + " :Invalid Origin."); break; } - if (this.hub) - ThisOrigin.created = parseInt(IRC_string(cmd[2],0)); - else - ThisOrigin.created = time(); - ThisOrigin.bcast_to_uchans_unique("NICK " + cmd[1]); - this.bcast_to_servers_raw(":" + ThisOrigin.nick + " NICK " + cmd[1] + " :" + ThisOrigin.created); - if (ctuc != ThisOrigin.nick.toUpperCase()) { - push_nickbuf(ThisOrigin.nick,cmd[1]); - Users[cmd[1].toUpperCase()] = ThisOrigin; - delete Users[ThisOrigin.nick.toUpperCase()]; + } + var new_id = "id" + next_client_id; + next_client_id++; + Users[cmd[1].toUpperCase()] = new IRC_User(new_id); + var NewNick = Users[cmd[1].toUpperCase()]; + NewNick.local = false; // not local. duh. + NewNick.nick = cmd[1]; + NewNick.hops = cmd[2]; + NewNick.created = cmd[3]; + NewNick.uprefix = cmd[uprefixptr]; + NewNick.hostname = cmd[uprefixptr+1]; + NewNick.servername = cmd[uprefixptr+2]; + var rnptr = 10; /* Bahamut */ + if (this.type == DREAMFORGE) + rnptr = 8; + NewNick.realname = IRC_string(cmdline,rnptr); + NewNick.parent = this.nick; + if (this.type == DREAMFORGE) + NewNick.ip = 0; + else /* Bahamut */ + NewNick.ip = int_to_ip(cmd[9]); + if (this.type == BAHAMUT) + NewNick.setusermode(cmd[4]); + for (u in ULines) { + if (ULines[u] == cmd[uprefixptr+2]) { + NewNick.uline = true; + break; } - ThisOrigin.nick = cmd[1]; } - break; - case "NOTICE": - // FIXME: servers should be able to send notices. - if (!cmd[1] || ThisOrigin.server) + var true_hops = parseInt(NewNick.hops)+1; + this.bcast_to_servers_raw("NICK " + + NewNick.nick + " " + + true_hops + " " + + NewNick.created + " " + + NewNick.get_usermode(true) + " " + + NewNick.uprefix + " " + + NewNick.hostname + " " + + NewNick.servername + " " + + "0 " + + cmd[9] + + " :" + NewNick.realname,BAHAMUT); + this.bcast_to_servers_raw("NICK " + + NewNick.nick + " " + + true_hops + " " + + NewNick.created + " " + + NewNick.uprefix + " " + + NewNick.hostname + " " + + NewNick.servername + " " + + "0 " + + ":" + NewNick.realname,DREAMFORGE); + } else { // we're a user changing our nick. + var ctuc = cmd[1].toUpperCase(); + if ((Users[ctuc])&&Users[ctuc].nick.toUpperCase() != + ThisOrigin.nick.toUpperCase()) { + gnotice("Server " + this.nick + " trying to collide nick via NICK changeover: " + + ThisOrigin.nick + " -> " + cmd[1]); + server_bcast_to_servers("KILL " + ThisOrigin.nick + " :Bogus nickname changeover."); + ThisOrigin.quit("Bogus nickname changeover."); + this.ircout("KILL " + cmd[1] + " :Bogus nickname changeover."); + this.reintroduce_nick(Users[ctuc]); break; - var my_ircstr = IRC_string(cmdline,2); - if (!cmd[2] || !my_ircstr) - break; - var targets = cmd[1].split(","); - for (nt in targets) { - if (targets[nt][0] != "&") - ThisOrigin.do_msg(targets[nt],"NOTICE",my_ircstr); } - break; - case "PART": - if (!cmd[1] || ThisOrigin.server) + if (ThisOrigin.check_nickname(cmd[1]) < 1) { + gnotice("Server " + this.nick + " trying to change to bogus nick: " + + ThisOrigin.nick + " -> " + cmd[1]); + this.bcast_to_servers_raw("KILL " + ThisOrigin.nick + " :Bogus nickname switch detected."); + this.ircout("KILL " + cmd[1] + " :Bogus nickname switch detected."); + ThisOrigin.quit("Bogus nickname switch detected.",true); break; - var the_channels = cmd[1].split(","); - for(pchan in the_channels) { - ThisOrigin.do_part(the_channels[pchan]); } + if (this.hub) + ThisOrigin.created = parseInt(IRC_string(cmd[2],0)); + else + ThisOrigin.created = time(); + ThisOrigin.bcast_to_uchans_unique("NICK " + cmd[1]); + this.bcast_to_servers_raw(":" + ThisOrigin.nick + " NICK " + cmd[1] + " :" + ThisOrigin.created); + if (ctuc != ThisOrigin.nick.toUpperCase()) { + push_nickbuf(ThisOrigin.nick,cmd[1]); + Users[cmd[1].toUpperCase()] = ThisOrigin; + delete Users[ThisOrigin.nick.toUpperCase()]; + } + ThisOrigin.nick = cmd[1]; + } + break; + case "NOTICE": + // FIXME: servers should be able to send notices. + if (!cmd[1] || ThisOrigin.server) + break; + var my_ircstr = IRC_string(cmdline,2); + if (!cmd[2] || !my_ircstr) + break; + var targets = cmd[1].split(","); + for (nt in targets) { + if (targets[nt][0] != "&") + ThisOrigin.do_msg(targets[nt],"NOTICE",my_ircstr); + } + break; + case "PART": + if (!cmd[1] || ThisOrigin.server) break; - case "PASS": - var result; + var the_channels = cmd[1].split(","); + for(pchan in the_channels) { + ThisOrigin.do_part(the_channels[pchan]); + } + break; + case "PASS": + var result; - if (!this.hub || !cmd[3]) - break; - if (cmd[3] != "QWK") + if (!this.hub || !cmd[3]) + break; + if (cmd[3] != "QWK") + break; + if (cmd[2][0] == ":") + cmd[2] = cmd[2].slice(1); + if (cmd[4]) { // pass the message on to target. + var dest_server = searchbyserver(cmd[4]); + if (!dest_server) { break; - if (cmd[2][0] == ":") - cmd[2] = cmd[2].slice(1); - if (cmd[4]) { // pass the message on to target. - var dest_server = searchbyserver(cmd[4]); - if (!dest_server) { - break; - } else if ((dest_server == -1) && - (this.flags&NLINE_IS_QWKMASTER)) { - var qwkid = cmd[2].toLowerCase(); - var hunt = qwkid + ".synchro.net"; - var my_server = 0; - for (ur in Unregistered) { - if (Unregistered[ur].nick == - hunt) { - my_server = Unregistered[ur]; - break; - } - } - if (!my_server) - break; - if (cmd[1] != "OK") { - my_server.quit("Server not configured."); + } else if ((dest_server == -1) && + (this.flags&NLINE_IS_QWKMASTER)) { + var qwkid = cmd[2].toLowerCase(); + var hunt = qwkid + ".synchro.net"; + var my_server = 0; + for (ur in Unregistered) { + if (Unregistered[ur].nick == + hunt) { + my_server = Unregistered[ur]; break; } - Servers[my_server.nick.toLowerCase()] = new IRC_Server(); - var ns = Servers[my_server.id]; - ns.id = my_server.id; - ns.nick = my_server.nick; - ns.info = my_server.realname; - ns.socket = my_server.socket; - delete Unregistered[my_server.id]; - ns.finalize_server_connect("QWK",true); + } + if (!my_server) + break; + if (cmd[1] != "OK") { + my_server.quit("Server not configured."); break; - } else if (dest_server) { - if (dest_server == -1) - break; // security trap - dest_server.rawout(":" + ThisOrigin.nick + " PASS " + cmd[1] + " :" + cmd[2] + " QWK " + dest_server.nick); } + Servers[my_server.nick.toLowerCase()] = new IRC_Server(); + var ns = Servers[my_server.id]; + ns.id = my_server.id; + ns.nick = my_server.nick; + ns.info = my_server.realname; + ns.socket = my_server.socket; + delete Unregistered[my_server.id]; + ns.finalize_server_connect("QWK",true); break; + } else if (dest_server) { + if (dest_server == -1) + break; // security trap + dest_server.rawout(":" + ThisOrigin.nick + " PASS " + cmd[1] + " :" + cmd[2] + + " QWK " + dest_server.nick); } - // Are we passing this on to our qwk-master? - for (nl in NLines) { - if (NLines[nl].flags&NLINE_IS_QWKMASTER) { - var qwk_master = searchbyserver(NLines[nl].servername); - if (qwk_master) { - qwk_master.rawout(":" + ThisOrigin.nick + " PASS " + cmd[1] + " :" + cmd[2] + " QWK"); - return 0; - } - } - } - // If we got here, we must be the qwk master. Process. - if (check_qwk_passwd(cmd[2],cmd[1])) - result = "OK"; - else - result = "VOID"; - this.rawout(":" + servername + " PASS " + result + " :" + cmd[2] + " QWK " + ThisOrigin.nick); break; - case "PONG": - if (cmd[2]) { - if (cmd[2][0] == ":") - cmd[2] = cmd[2].slice(1); - var my_server = searchbyserver(cmd[2]); - if (!my_server) { - break; - } else if (my_server == -1) { - var my_nick = Users[cmd[2].toUpperCase()]; - if (my_nick) - my_nick.rawout(":" + ThisOrigin.nick + " PONG " + cmd[1] + " :" + my_nick.nick); - else - this.pinged = false; - break; - } else if (my_server) { - my_server.rawout(":" + ThisOrigin.nick + " PONG " + cmd[1] + " :" + cmd[2]); - break; + } + // Are we passing this on to our qwk-master? + for (nl in NLines) { + if (NLines[nl].flags&NLINE_IS_QWKMASTER) { + var qwk_master = searchbyserver(NLines[nl].servername); + if (qwk_master) { + qwk_master.rawout(":" + ThisOrigin.nick + " PASS " + cmd[1] + " :" + cmd[2] + " QWK"); + return 0; } } - this.pinged = false; - break; - case "PRIVMSG": - if (!cmd[1] || ThisOrigin.server) + } + // If we got here, we must be the qwk master. Process. + if (check_qwk_passwd(cmd[2],cmd[1])) + result = "OK"; + else + result = "VOID"; + this.rawout(":" + servername + " PASS " + result + " :" + cmd[2] + " QWK " + ThisOrigin.nick); + break; + case "PONG": + if (cmd[2]) { + if (cmd[2][0] == ":") + cmd[2] = cmd[2].slice(1); + var my_server = searchbyserver(cmd[2]); + if (!my_server) { break; - var my_ircstr = IRC_string(cmdline,2); - if (!cmd[2] || !my_ircstr) + } else if (my_server == -1) { + var my_nick = Users[cmd[2].toUpperCase()]; + if (my_nick) + my_nick.rawout(":" + ThisOrigin.nick + " PONG " + cmd[1] + " :" + my_nick.nick); + else + this.pinged = false; + break; + } else if (my_server) { + my_server.rawout(":" + ThisOrigin.nick + " PONG " + cmd[1] + " :" + cmd[2]); break; - var targets = cmd[1].split(","); - for (pm in targets) { - if (targets[pm][0] != "&") - ThisOrigin.do_msg(targets[pm],"PRIVMSG",my_ircstr); } + } + this.pinged = false; + break; + case "PRIVMSG": + if (!cmd[1] || ThisOrigin.server) break; - case "QUIT": - ThisOrigin.quit(IRC_string(cmdline,2)); + var my_ircstr = IRC_string(cmdline,2); + if (!cmd[2] || !my_ircstr) break; - case "SERVER": - if (!cmd[3]) - break; - // FIXME: when on Earth does this happen? :P? - var hops = parseInt(cmd[2]); - if ((hops == 1) && !this.info) { - umode_notice(USERMODE_OPER,"Notice", "Server " - + cmd[1] + " updating info after handshake???"); - this.nick = cmd[1]; - this.hops = 1; - this.info = IRC_string(cmdline,3); - this.linkparent = servername; - this.parent = this.nick; - var newsrv = this; - } else if (hops > 1) { - if (this.hub) { - if (searchbyserver(cmd[1])) { - this.quit("Server " + cmd[1] + " already exists."); - return 0; - } - var lcserver = cmd[1].toLowerCase(); - var new_id = "id" + next_client_id; - next_client_id++; - Servers[lcserver] = new IRC_Server; - var newsrv = Servers[lcserver]; - newsrv.hops = cmd[2]; - newsrv.nick = cmd[1]; - newsrv.info = IRC_string(cmdline,3); - newsrv.parent = this.nick; - newsrv.linkparent = ThisOrigin.nick; - newsrv.local = false; - for (u in ULines) { - if (ULines[u] == cmd[1]) { - newsrv.uline = true; - break; - } - } - } else { - umode_notice(USERMODE_ROUTING,"Routing","from " + servername + ": Non-Hub link " + this.nick + " introduced " + cmd[1] + "(*)."); - this.quit("Too many servers. You have no H:Line to introduce " + cmd[1] + ".",true); + var targets = cmd[1].split(","); + for (pm in targets) { + if (targets[pm][0] != "&") + ThisOrigin.do_msg(targets[pm],"PRIVMSG",my_ircstr); + } + break; + case "QUIT": + ThisOrigin.quit(IRC_string(cmdline,2)); + break; + case "SERVER": + if (!cmd[3]) + break; + // FIXME: when on Earth does this happen? :P? + var hops = parseInt(cmd[2]); + if ((hops == 1) && !this.info) { + umode_notice(USERMODE_OPER,"Notice", "Server " + cmd[1] + " updating info after handshake???"); + this.nick = cmd[1]; + this.hops = 1; + this.info = IRC_string(cmdline,3); + this.linkparent = servername; + this.parent = this.nick; + var newsrv = this; + } else if (hops > 1) { + if (this.hub) { + if (searchbyserver(cmd[1])) { + this.quit("Server " + cmd[1] + " already exists."); return 0; } + var lcserver = cmd[1].toLowerCase(); + var new_id = "id" + next_client_id; + next_client_id++; + Servers[lcserver] = new IRC_Server; + var newsrv = Servers[lcserver]; + newsrv.hops = cmd[2]; + newsrv.nick = cmd[1]; + newsrv.info = IRC_string(cmdline,3); + newsrv.parent = this.nick; + newsrv.linkparent = ThisOrigin.nick; + newsrv.local = false; + for (u in ULines) { + if (ULines[u] == cmd[1]) { + newsrv.uline = true; + break; + } + } } else { - umode_notice(USERMODE_OPER,"Notice","Refusing to comply with supposedly bogus SERVER command from " + this.nick + ": " + cmdline); - break; + umode_notice(USERMODE_ROUTING,"Routing","from " + servername + + ": Non-Hub link " + this.nick + " introduced " + cmd[1] + "(*)."); + this.quit("Too many servers. You have no H:Line to introduce " + cmd[1] + ".",true); + return 0; } - this.bcast_to_servers_raw(":" + newsrv.linkparent + " SERVER " + newsrv.nick + " " + (parseInt(newsrv.hops)+1) + " :" + newsrv.info); + } else { + umode_notice(USERMODE_OPER,"Notice","Refusing to comply with supposedly bogus SERVER command from " + + this.nick + ": " + cmdline); + break; + } + this.bcast_to_servers_raw(":" + newsrv.linkparent + " SERVER " + newsrv.nick + " " + + (parseInt(newsrv.hops)+1) + " :" + newsrv.info); + break; + case "SJOIN": + if (!cmd[2]) + break; + if (cmd[2][0] != "#") break; - case "SJOIN": - if (!cmd[2]) - break; - if (cmd[2][0] != "#") - break; - var chan_members; - var cm_array; - var mode_args; + var chan_members; + var cm_array; + var mode_args; - if (cmd[3]) { - var incoming_modes = new Array; - var tmp_modeargs = 3; + if (cmd[3]) { + var incoming_modes = new Object; + var tmp_modeargs = 3; - /* Parse the modes and break them down */ - for (tmpmc in cmd[3]) { - var my_modechar = cmd[3][tmpmc]; - if (my_modechar == "+") - continue; - if ((my_modechar == "k") || - (my_modechar == "l")) { - tmp_modeargs++; - incoming_modes[my_modechar] = cmd[tmp_modeargs]; - } else { - incoming_modes[my_modechar] = true; - } + /* Parse the modes and break them down */ + for (tmpmc in cmd[3]) { + var my_modechar = cmd[3][tmpmc]; + if (my_modechar == "+") + continue; + if ((my_modechar == "k") || + (my_modechar == "l")) { + tmp_modeargs++; + incoming_modes[my_modechar] = cmd[tmp_modeargs]; + } else { + incoming_modes[my_modechar] = true; } + } - /* Reconstruct our modes into a string now */ - var mode_args_chars = "+"; - var mode_args_args = ""; - for (my_mc in incoming_modes) { - mode_args_chars += my_mc; - if ((my_mc == "k") || (my_mc == "l")) { - mode_args_args += " " + incoming_modes[my_mc]; - } + /* Reconstruct our modes into a string now */ + var mode_args_chars = "+"; + var mode_args_args = ""; + for (my_mc in incoming_modes) { + mode_args_chars += my_mc; + if ((my_mc == "k") || (my_mc == "l")) { + mode_args_args += " " + incoming_modes[my_mc]; } - mode_args = mode_args_chars + mode_args_args; + } + mode_args = mode_args_chars + mode_args_args; - /* The following corrects a bug in Bahamut.. */ - if ((cmd[4] == "") && cmd[5]) - tmp_modeargs++; - - tmp_modeargs++; /* Jump to start of string */ - chan_members = IRC_string(cmdline,tmp_modeargs).split(' '); + /* The following corrects a bug in Bahamut.. */ + if ((cmd[4] == "") && cmd[5]) + tmp_modeargs++; + + tmp_modeargs++; /* Jump to start of string */ + chan_members = IRC_string(cmdline,tmp_modeargs).split(' '); - if (chan_members == "") { - umode_notice(USERMODE_OPER,"Notice","Server " + this.nick + " trying to SJOIN empty channel " + cmd[2] + " before processing."); - break; - } + if (chan_members == "") { + umode_notice(USERMODE_OPER,"Notice","Server " + this.nick + " trying to SJOIN empty channel " + + cmd[2] + " before processing."); + break; + } - cm_array = new Array; + cm_array = new Array; /* True 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 = Users[chan_members[cm].toUpperCase()]; - if (!tmp_nick) - continue; - cm_array.push(new SJOIN_Nick(tmp_nick,isop,isvoice)); + 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 (cm_array.length < 1) { - umode_notice(USERMODE_OPER,"Notice","Server " + this.nick + " trying to SJOIN empty channel " + cmd[2] + " post processing."); - break; + if (chan_members[cm][0] == "+") { + isvoice = true; + chan_members[cm] = chan_members[cm].slice(1); } - + var tmp_nick = Users[chan_members[cm].toUpperCase()]; + if (!tmp_nick) + continue; + cm_array.push(new SJOIN_Nick(tmp_nick,isop,isvoice)); } - var cn_tuc = cmd[2].toUpperCase(); - var chan = Channels[cmd[2].toUpperCase()]; - if (!chan) { - Channels[cn_tuc]=new Channel(cn_tuc); - chan = Channels[cn_tuc]; - chan.nam = cmd[2]; - chan.created = parseInt(cmd[1]); - chan.topic = ""; - chan.users = new Array; - chan.modelist[CHANMODE_BAN] = new Array; - chan.modelist[CHANMODE_VOICE] = new Array; - chan.modelist[CHANMODE_OP] = new Array; - chan.mode = CHANMODE_NONE; + if (cm_array.length < 1) { + umode_notice(USERMODE_OPER,"Notice","Server " + this.nick + " trying to SJOIN empty channel " + + cmd[2] + " post processing."); + break; } - if (cmd[3]) { - var bounce_modes = true; - if (!ThisOrigin.local || - (chan.created == parseInt(cmd[1]))) - bounce_modes = false; - if (chan.created >= parseInt(cmd[1])) - this.set_chanmode(chan, mode_args, bounce_modes); + } - var num_sync_modes = 0; - var push_sync_modes = "+"; - var push_sync_args = ""; - var new_chan_members = ""; - for (member in cm_array) { - if (new_chan_members) - new_chan_members += " "; + var cn_tuc = cmd[2].toUpperCase(); + var chan = Channels[cmd[2].toUpperCase()]; + if (!chan) { + Channels[cn_tuc]=new Channel(cn_tuc); + chan = Channels[cn_tuc]; + chan.nam = cmd[2]; + chan.created = parseInt(cmd[1]); + chan.topic = ""; + chan.users = new Object; + chan.modelist[CHANMODE_BAN] = new Object; + chan.modelist[CHANMODE_VOICE] = new Object; + chan.modelist[CHANMODE_OP] = new Object; + chan.mode = CHANMODE_NONE; + } - var member_obj = cm_array[member].nick; - var is_voice = cm_array[member].isvoice; - var is_op = cm_array[member].isop; + if (cmd[3]) { + var bounce_modes = true; + if (!ThisOrigin.local || + (chan.created == parseInt(cmd[1]))) + bounce_modes = false; + if (chan.created >= parseInt(cmd[1])) + this.set_chanmode(chan, mode_args, bounce_modes); - if (member_obj.channels[chan.nam.toUpperCase()]) - continue; - member_obj.channels[chan.nam.toUpperCase()] = chan; - chan.users[member_obj.id] = member_obj; - member_obj.bcast_to_channel(chan, "JOIN " + chan.nam, false); - if (chan.created >= parseInt(cmd[1])) { - if (is_op) { - chan.modelist[CHANMODE_OP][member_obj.id] = member_obj.id; - push_sync_modes += "o"; - push_sync_args += " " + member_obj.nick; - num_sync_modes++; - new_chan_members += "@"; - } - if (num_sync_modes >= max_modes) { - this.bcast_to_channel(chan, "MODE " + chan.nam + " " + push_sync_modes + push_sync_args); - push_sync_modes = "+"; - push_sync_args = ""; - num_sync_modes = 0; - } - if (is_voice) { - chan.modelist[CHANMODE_VOICE][member_obj.id] = member_obj; - push_sync_modes += "v"; - push_sync_args += " " + member_obj.nick; - num_sync_modes++; - new_chan_members += "+"; - } - if (num_sync_modes >= max_modes) { - this.bcast_to_channel(chan, "MODE " + chan.nam + " " + push_sync_modes + push_sync_args); - push_sync_modes = "+"; - push_sync_args = ""; - num_sync_modes = 0; - } - } - new_chan_members += member_obj.nick; - } - if (num_sync_modes) - this.bcast_to_channel(chan, "MODE " + chan.nam + " " + push_sync_modes + push_sync_args); + var num_sync_modes = 0; + var push_sync_modes = "+"; + var push_sync_args = ""; + var new_chan_members = ""; + for (member in cm_array) { + if (new_chan_members) + new_chan_members += " "; - // Synchronize the TS to what we received. - if (chan.created > parseInt(cmd[1])) - chan.created = parseInt(cmd[1]); + var member_obj = cm_array[member].nick; + var is_voice = cm_array[member].isvoice; + var is_op = cm_array[member].isop; - this.bcast_to_servers_raw(":" + ThisOrigin.nick + " SJOIN " + chan.created + " " + chan.nam + " " + chan.chanmode(true) + " :" + new_chan_members) - } else { - if (ThisOrigin.server) { - umode_notice(USERMODE_OPER,"Notice", "Server " + ThisOrigin.nick + " trying to SJOIN itself to a channel?!"); - break; + if (member_obj.channels[chan.nam.toUpperCase()]) + continue; + member_obj.channels[chan.nam.toUpperCase()] = chan; + chan.users[member_obj.id] = member_obj; + member_obj.bcast_to_channel(chan, "JOIN " + chan.nam, false); + if (chan.created >= parseInt(cmd[1])) { + if (is_op) { + chan.modelist[CHANMODE_OP][member_obj.id] = member_obj.id; + push_sync_modes += "o"; + push_sync_args += " " + member_obj.nick; + num_sync_modes++; + new_chan_members += "@"; + } + if (num_sync_modes >= max_modes) { + this.bcast_to_channel(chan,"MODE " + chan.nam + " " + push_sync_modes + push_sync_args); + push_sync_modes = "+"; + push_sync_args = ""; + num_sync_modes = 0; + } + if (is_voice) { + chan.modelist[CHANMODE_VOICE][member_obj.id] = member_obj; + push_sync_modes += "v"; + push_sync_args += " " + member_obj.nick; + num_sync_modes++; + new_chan_members += "+"; + } + if (num_sync_modes >= max_modes) { + this.bcast_to_channel(chan,"MODE " + chan.nam + " " + push_sync_modes + push_sync_args); + push_sync_modes = "+"; + push_sync_args = ""; + num_sync_modes = 0; + } } - if (ThisOrigin.channels[chan.nam.toUpperCase()]) - break; - ThisOrigin.channels[chan.nam.toUpperCase()] = chan; - chan.users[ThisOrigin.id] = ThisOrigin; - ThisOrigin.bcast_to_channel(chan, "JOIN " + chan.nam, false); - this.bcast_to_servers_raw(":" + ThisOrigin.nick + " SJOIN " + chan.created + " " + chan.nam,BAHAMUT); - this.bcast_to_servers_raw(":" + ThisOrigin.nick + " JOIN " + chan.nam,DREAMFORGE); + new_chan_members += member_obj.nick; } - break; - case "SQUIT": - var sq_server; - var reason; + if (num_sync_modes) + this.bcast_to_channel(chan, "MODE " + chan.nam + " " + push_sync_modes + push_sync_args); - if (!cmd[1] || !this.hub) - sq_server = this; - else - sq_server = searchbyserver(cmd[1]); - if (!sq_server) - break; - reason = IRC_string(cmdline,2); - if (!reason || !cmd[2]) - reason = ThisOrigin.nick; - if (sq_server == -1) { - this.bcast_to_servers_raw("SQUIT " + this.nick + " :Forwards SQUIT."); - this.quit("Forwards SQUIT.",true); - break; - } - // message from our uplink telling us a server is gone - if (this.nick == sq_server.parent) { - sq_server.quit(reason,false,false,ThisOrigin); + // Synchronize the TS to what we received. + if (chan.created > parseInt(cmd[1])) + chan.created = parseInt(cmd[1]); + + this.bcast_to_servers_raw(":" + ThisOrigin.nick + " SJOIN " + chan.created + " " + chan.nam + " " + + chan.chanmode(true) + " :" + new_chan_members) + } else { + if (ThisOrigin.server) { + umode_notice(USERMODE_OPER,"Notice", "Server " + ThisOrigin.nick + + " trying to SJOIN itself to a channel?!"); break; } - // oper or server going for squit of a server - if (!sq_server.local) { - sq_server.rawout(":" + ThisOrigin.nick + " SQUIT " + sq_server.nick + " :" + reason); + if (ThisOrigin.channels[chan.nam.toUpperCase()]) break; - } - var msg = "Received SQUIT " + cmd[1] + " from " + - ThisOrigin.nick + "(" + reason + ")"; - server_bcast_to_servers("GNOTICE :" + msg); - umode_notice(USERMODE_ROUTING,"Routing","from " + - servername + ": " + msg); - sq_server.quit(reason); + ThisOrigin.channels[chan.nam.toUpperCase()] = chan; + chan.users[ThisOrigin.id] = ThisOrigin; + ThisOrigin.bcast_to_channel(chan, "JOIN " + chan.nam, false); + this.bcast_to_servers_raw(":" + ThisOrigin.nick + " SJOIN " + chan.created +" "+ chan.nam,BAHAMUT); + this.bcast_to_servers_raw(":" + ThisOrigin.nick + " JOIN " + chan.nam,DREAMFORGE); + } + break; + case "SQUIT": + var sq_server; + var reason; + + if (!cmd[1] || !this.hub) + sq_server = this; + else + sq_server = searchbyserver(cmd[1]); + if (!sq_server) break; - case "STATS": - if (!cmd[2] || ThisOrigin.server) - break; - if (cmd[2][0] == ":") - cmd[2] = cmd[2].slice(1); - if (wildmatch(servername, cmd[2])) { - ThisOrigin.do_stats(cmd[1][0]); - } else { - var dest_server = searchbyserver(cmd[2]); - if (!dest_server) - break; - dest_server.rawout(":" + ThisOrigin.nick + " STATS " + cmd[1][0] + " :" + dest_server.nick); - } + reason = IRC_string(cmdline,2); + if (!reason || !cmd[2]) + reason = ThisOrigin.nick; + if (sq_server == -1) { + this.bcast_to_servers_raw("SQUIT " + this.nick + " :Forwards SQUIT."); + this.quit("Forwards SQUIT.",true); break; - case "SUMMON": - if (!cmd[2] || ThisOrigin.server) - break; - if (cmd[2][0] == ":") - cmd[2] = cmd[2].slice(1); - if (wildmatch(servername, cmd[2])) { - if (enable_users_summon) { - ThisOrigin.do_summon(cmd[1]); - } else { - ThisOrigin.numeric445(); - break; - } - } else { - var dest_server = searchbyserver(cmd[1]); - if (!dest_server) - break; - dest_server.rawout(":" + ThisOrigin.nick + " SUMMON " + cmd[1] + " :" + dest_server.nick); - } + } + // message from our uplink telling us a server is gone + if (this.nick == sq_server.parent) { + sq_server.quit(reason,false,false,ThisOrigin); break; - case "TIME": - if (!cmd[1] || ThisOrigin.server) - break; - if (cmd[1][0] == ":") - cmd[1] = cmd[1].slice(1); - if (wildmatch(servername, cmd[1])) { - ThisOrigin.numeric391(); - } else { - var dest_server = searchbyserver(cmd[1]); - if (!dest_server) - break; - dest_server.rawout(":" + ThisOrigin.nick + " TIME :" + dest_server.nick); - } + } + // oper or server going for squit of a server + if (!sq_server.local) { + sq_server.rawout(":" + ThisOrigin.nick + " SQUIT " + sq_server.nick + " :" + reason); break; - case "TOPIC": - if (!cmd[4]) - break; - var chan = Channels[cmd[1].toUpperCase()]; - if (!chan) - break; - var the_topic = IRC_string(cmdline,4); - if (the_topic == chan.topic) - break; - chan.topic = the_topic; - if (this.hub) - chan.topictime = cmd[3]; - else - chan.topictime = time(); - chan.topicchangedby = cmd[2]; - var str = "TOPIC " + chan.nam + " :" + chan.topic; - ThisOrigin.bcast_to_channel(chan,str,false); - this.bcast_to_servers_raw(":" + ThisOrigin.nick + " TOPIC " + chan.nam + " " + cmd[2] + " " + chan.topictime + " :" + chan.topic); + } + var msg = "Received SQUIT " + cmd[1] + " from " + + ThisOrigin.nick + "(" + reason + ")"; + server_bcast_to_servers("GNOTICE :" + msg); + umode_notice(USERMODE_ROUTING,"Routing","from " + + servername + ": " + msg); + sq_server.quit(reason); + break; + case "STATS": + if (!cmd[2] || ThisOrigin.server) break; - case "TRACE": - if (!cmd[1] || ThisOrigin.server) + if (cmd[2][0] == ":") + cmd[2] = cmd[2].slice(1); + if (wildmatch(servername, cmd[2])) { + ThisOrigin.do_stats(cmd[1][0]); + } else { + var dest_server = searchbyserver(cmd[2]); + if (!dest_server) break; - ThisOrigin.do_trace(cmd[1]); + dest_server.rawout(":" + ThisOrigin.nick + " STATS " + cmd[1][0] + " :" + dest_server.nick); + } + break; + case "SUMMON": + if (!cmd[2] || ThisOrigin.server) break; - case "USERS": - if (!cmd[1] || ThisOrigin.server) - break; - if (cmd[1][0] == ":") - cmd[1] = cmd[1].slice(1); - if (searchbyserver(cmd[1]) == -1) { - ThisOrigin.numeric351(); + if (cmd[2][0] == ":") + cmd[2] = cmd[2].slice(1); + if (wildmatch(servername, cmd[2])) { + if (enable_users_summon) { + ThisOrigin.do_summon(cmd[1]); } else { - // psst, pass it on - var dest_server = searchbyserver(cmd[1]); - if (!dest_server) - break; - dest_server.rawout(":" + ThisOrigin.nick + " USERS :" + dest_server.nick); - } - break; - case "VERSION": - if (!cmd[1] || ThisOrigin.server) + ThisOrigin.numeric445(); break; - if (cmd[1][0] == ":") - cmd[1] = cmd[1].slice(1); - if (searchbyserver(cmd[1]) == -1) { - // it's for us, return the message - ThisOrigin.numeric351(); - } else { - // psst, pass it on - var dest_server = searchbyserver(cmd[1]); - if (!dest_server) - break; // someone messed up. - dest_server.rawout(":" + ThisOrigin.nick + " VERSION :" + dest_server.nick); } + } else { + var dest_server = searchbyserver(cmd[1]); + if (!dest_server) + break; + dest_server.rawout(":" + ThisOrigin.nick + " SUMMON " + cmd[1] + " :" + dest_server.nick); + } + break; + case "TIME": + if (!cmd[1] || ThisOrigin.server) break; - case "WALLOPS": - if (!cmd[1]) + if (cmd[1][0] == ":") + cmd[1] = cmd[1].slice(1); + if (wildmatch(servername, cmd[1])) { + ThisOrigin.numeric391(); + } else { + var dest_server = searchbyserver(cmd[1]); + if (!dest_server) break; - var str = ":" + ThisOrigin.nick + " WALLOPS :" + - IRC_string(cmdline,1); - wallopers(str); - this.bcast_to_servers_raw(str); + dest_server.rawout(":" + ThisOrigin.nick + " TIME :" + dest_server.nick); + } + break; + case "TOPIC": + if (!cmd[4]) + break; + var chan = Channels[cmd[1].toUpperCase()]; + if (!chan) + break; + var the_topic = IRC_string(cmdline,4); + if (the_topic == chan.topic) break; - case "WHOIS": - if (!cmd[2] || ThisOrigin.server) + chan.topic = the_topic; + if (this.hub) + chan.topictime = cmd[3]; + else + chan.topictime = time(); + chan.topicchangedby = cmd[2]; + var str = "TOPIC " + chan.nam + " :" + chan.topic; + ThisOrigin.bcast_to_channel(chan,str,false); + this.bcast_to_servers_raw(":" + ThisOrigin.nick + " TOPIC " + chan.nam + " " + cmd[2] + " " + + chan.topictime + " :" + chan.topic); + break; + case "TRACE": + if (!cmd[1] || ThisOrigin.server) + break; + ThisOrigin.do_trace(cmd[1]); + break; + case "USERS": + if (!cmd[1] || ThisOrigin.server) + break; + if (cmd[1][0] == ":") + cmd[1] = cmd[1].slice(1); + if (searchbyserver(cmd[1]) == -1) { + ThisOrigin.numeric351(); + } else { + // psst, pass it on + var dest_server = searchbyserver(cmd[1]); + if (!dest_server) break; - if (searchbyserver(cmd[1]) == -1) { - var wi_nicks = IRC_string(cmd[2],0).split(","); - for (wi_nick in wi_nicks) { - var wi = Users[wi_nicks[wi_nick].toUpperCase()]; - if (wi) - ThisOrigin.do_whois(wi); - else - ThisOrigin.numeric401(wi_nicks[wi_nick]); - } - ThisOrigin.numeric(318, wi_nicks[0]+" :End of /WHOIS list."); - } else { - var dest_server = searchbyserver(cmd[1]); - if (!dest_server) - break; - dest_server.rawout(":" + ThisOrigin.nick + " WHOIS " - + dest_server.nick + " :" + IRC_string(cmd[2],0)); - } + dest_server.rawout(":" + ThisOrigin.nick + " USERS :" + dest_server.nick); + } + break; + case "VERSION": + if (!cmd[1] || ThisOrigin.server) + break; + if (cmd[1][0] == ":") + cmd[1] = cmd[1].slice(1); + if (searchbyserver(cmd[1]) == -1) { + // it's for us, return the message + ThisOrigin.numeric351(); + } else { + // psst, pass it on + var dest_server = searchbyserver(cmd[1]); + if (!dest_server) + break; // someone messed up. + dest_server.rawout(":" + ThisOrigin.nick + " VERSION :" + dest_server.nick); + } + break; + case "WALLOPS": + if (!cmd[1]) break; - case "CAPAB": - case "BURST": - case "SVSMODE": - case "NETINFO": /* Dreamforge/Unreal/CR */ - case "SMO": /* Dreamforge/Unreal/CR */ - case "EOS": /* Dreamforge/Unreal/CR */ - case "SETHOST": /* We do not honour SETHOST. */ - break; // Silently ignore for now. - default: - umode_notice(USERMODE_OPER,"Notice","Server " + ThisOrigin.nick + " sent unrecognized command: " + cmdline); - legal_command = false; + var str = ":" + ThisOrigin.nick + " WALLOPS :" + + IRC_string(cmdline,1); + wallopers(str); + this.bcast_to_servers_raw(str); + break; + case "WHOIS": + if (!cmd[2] || ThisOrigin.server) break; + if (searchbyserver(cmd[1]) == -1) { + var wi_nicks = IRC_string(cmd[2],0).split(","); + for (wi_nick in wi_nicks) { + var wi = Users[wi_nicks[wi_nick].toUpperCase()]; + if (wi) + ThisOrigin.do_whois(wi); + else + ThisOrigin.numeric401(wi_nicks[wi_nick]); + } + ThisOrigin.numeric(318, wi_nicks[0]+" :End of /WHOIS list."); + } else { + var dest_server = searchbyserver(cmd[1]); + if (!dest_server) + break; + dest_server.rawout(":" + ThisOrigin.nick + " WHOIS " + + dest_server.nick + " :" + IRC_string(cmd[2],0)); + } + break; + case "CAPAB": + case "BURST": + case "SVSMODE": + case "NETINFO": /* Dreamforge/Unreal/CR */ + case "SMO": /* Dreamforge/Unreal/CR */ + case "EOS": /* Dreamforge/Unreal/CR */ + case "SETHOST": /* We do not honour SETHOST. */ + break; // Silently ignore for now. + default: + umode_notice(USERMODE_OPER,"Notice","Server " + ThisOrigin.nick + " sent unrecognized command: " + + cmdline); + legal_command = false; + break; } if (legal_command) { @@ -1155,7 +1188,8 @@ function IRCClient_synchronize() { for (my_channel in Channels) { if ((my_channel[0] == "#") && Channels[my_channel].topic) { var chan = Channels[my_channel]; - this.rawout("TOPIC " + chan.nam + " " + chan.topicchangedby + " " + chan.topictime + " :" + chan.topic); + this.rawout("TOPIC " + chan.nam + " " + chan.topicchangedby + " " + chan.topictime + + " :" + chan.topic); } } this.rawout("BURST 0"); // burst completed. @@ -1165,7 +1199,8 @@ function IRCClient_synchronize() { function IRCClient_server_info(sni_server) { var realhops = parseInt(sni_server.hops)+1; - this.rawout(":" + sni_server.linkparent + " SERVER " + sni_server.nick + " " + realhops + " :" + sni_server.info); + this.rawout(":" + sni_server.linkparent + " SERVER " + sni_server.nick + " " + realhops + + " :" + sni_server.info); } function IRCClient_server_nick_info(sni_client) { @@ -1204,10 +1239,12 @@ function IRCClient_reintroduce_nick(nick) { cmodes += "@"; if (chan.modelist[CHANMODE_VOICE][nick.id]) cmodes += "+"; - this.rawout("SJOIN " + chan.created + " " + chan.nam + " " + chan.chanmode(true) + " :" + cmodes + nick.nick); + this.rawout("SJOIN " + chan.created + " " + chan.nam + " " + chan.chanmode(true) + + " :" + cmodes + nick.nick); } if (chan.topic) - this.rawout("TOPIC " + chan.nam + " " + chan.topicchangedby + " " + chan.topictime + " :" + chan.topic); + this.rawout("TOPIC " + chan.nam + " " + chan.topicchangedby + " " + chan.topictime + + " :" + chan.topic); } } @@ -1224,7 +1261,8 @@ function IRCClient_server_chan_info(sni_chan) { } this.ircout("MODE " + sni_chan.nam + " " + sni_chan.chanmode(true) + " " + sni_chan.created); } else { /* Bahamut */ - this.rawout("SJOIN " + sni_chan.created + " " + sni_chan.nam + " " + sni_chan.chanmode(true) + " :" + sni_chan.occupants()) + this.rawout("SJOIN " + sni_chan.created + " " + sni_chan.nam + " " + sni_chan.chanmode(true) + + " :" + sni_chan.occupants()) } var modecounter=0; var modestr="+"; diff --git a/exec/load/ircd_user.js b/exec/load/ircd_user.js index a870834be216a377824e32ef29ccaf87eb60f348..312bcca358b6a458e62d34c816926fccfab158b8 100644 --- a/exec/load/ircd_user.js +++ b/exec/load/ircd_user.js @@ -40,7 +40,7 @@ const USERMODE_ROUTING =(1<<13); // n const USERMODE_HELP =(1<<14); // h const USERMODE_NOTHROTTLE =(1<<15); // F -USERMODE_CHAR = new Array(); +USERMODE_CHAR = new Object; USERMODE_CHAR["o"] = USERMODE_OPER; USERMODE_CHAR["i"] = USERMODE_INVISIBLE; USERMODE_CHAR["w"] = USERMODE_WALLOPS; @@ -58,13 +58,13 @@ USERMODE_CHAR["h"] = USERMODE_HELP; USERMODE_CHAR["F"] = USERMODE_NOTHROTTLE; // Most umodes aren't propagated across the network. Define the ones that are. -USERMODE_BCAST = new Array; +USERMODE_BCAST = new Object; USERMODE_BCAST["o"] = true; USERMODE_BCAST["i"] = true; USERMODE_BCAST["h"] = true; // FIXME: Services modes are broadcast but not displayed to the user. -USERMODE_SERVICES = new Array; +USERMODE_SERVICES = new Object; // Various permissions that can be set on an O:Line const OLINE_CAN_REHASH =(1<<0); // r @@ -126,7 +126,7 @@ function IRC_User(id) { this.uline = false; // Are we services? // Variables containing user/server information as we receive it. this.away = ""; - this.channels = new Array; + this.channels = new Object; this.connecttime = time(); this.created = 0; this.flags = 0; @@ -949,7 +949,7 @@ function User_Work() { this.numeric(353,"* * :"+tmp); this.numeric(366, "* :End of /NAMES list."); } else { - var chans = cmd[1].split(','); + chans = cmd[1].split(','); for (nc in chans) { if ((chans[nc][0] == "#") || (chans[nc][0] == "&")) { @@ -1348,10 +1348,10 @@ function User_Work() { } var firstnick=""; var aWhoWas; - var ww_nick_uc = cmd[1].toUpperCase(); for (aWhoWas=whowas_pointer;aWhoWas>=0;aWhoWas--) { var wwh = WhoWasHistory[aWhoWas]; - if (wwh && (wwh.nick.toUpperCase() == ww_nick_uc)) { + if (wwh && (wwh.nick.toUpperCase() == + cmd[1].toUpperCase())) { this.numeric(314,wwh.nick + " " + wwh.uprefix + " " + wwh.host + " * :" + wwh.realname); this.numeric(312,wwh.nick + " " + wwh.server + " :" @@ -1362,7 +1362,8 @@ function User_Work() { } for (aWhoWas=whowas_buffer;aWhoWas>=whowas_pointer;aWhoWas--) { var wwh = WhoWasHistory[aWhoWas]; - if (wwh && (wwh.nick.toUpperCase() == ww_nick_uc)) { + if (wwh && (wwh.nick.toUpperCase() == + cmd[1].toUpperCase())) { this.numeric(314,wwh.nick + " " + wwh.uprefix + " " + wwh.host + " * :" + wwh.realname); this.numeric(312,wwh.nick + " " + wwh.server + " :"