From ca0fd823551ac80b7c63c4b35414ce75af931e60 Mon Sep 17 00:00:00 2001 From: cyan <> Date: Sun, 5 Oct 2003 06:52:22 +0000 Subject: [PATCH] * 'Priv' would never have been shown as a channel name for +p channels. * Opers with a small o in their O:Line flags were being propagated as a big O * New command line option -x is for 'network debug' which will verbosely spit out synch info to the network via GLOBOPS. This will spam a network like crazy, so please don't use it unless you've been instructed to. This is to assist in debugging of misbehaving servers (read: software) over the network. * Rewrote this.setusermode(), because it was a mess. * Began work on breaking out usermodes into more discrete sections ala Bahamut, in particular: +w (Users) Allows the user to receive all WALLOPS messages. +b (Opers) User may receive CHATOPS messages. +g (Opers) User may receive GLOBOPS messages. +s (Users) Reception of variou server messages, including KILL. +c (Opers) Receive client connecting/disconnecting messages. +r (Opers) Receive 'rejected' client messages (i.e. unregd clients) +k (Opers) Receive server kill messages. +y (Opers) Observe STATS/INFO/LINKS/etc requests for possible abuse. +d (Opers) Can receive DEBUG notices. +n (Opers) For reception of 'routing' notices. * Because of this, WALLOPS is now an oper only command. * Replaced oper_notice() with umode_notice(), which writes out to all users of a particular user mode. * CHATOPS, GLOBOPS, and GNOTICE now all work properly. * Some appropriate messages are broadcast across the network, including more informative server messages (i.e. remote CONNECT, SQUIT, etc.) * Let other opers know that a user is doing /EVAL. * Add a kludge for 3.10 machines so that they'll mswait() longer, thus won't time out as quickly, hopefully giving them at least a few weeks worth of uptime. The downside to this is that they run slower, alas. (They probably should anyway, considering they don't have select() to throttle CPU usage.) --- exec/ircd.js | 420 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 324 insertions(+), 96 deletions(-) diff --git a/exec/ircd.js b/exec/ircd.js index 764a07419f..faa530de91 100644 --- a/exec/ircd.js +++ b/exec/ircd.js @@ -97,6 +97,42 @@ var default_port = 6667; var USERMODE_NONE =(1<<0); // NONE var USERMODE_OPER =(1<<1); // o var USERMODE_INVISIBLE =(1<<2); // i +var USERMODE_WALLOPS =(1<<3); // w +var USERMODE_CHATOPS =(1<<4); // b +var USERMODE_GLOBOPS =(1<<5); // g +var USERMODE_SERVER =(1<<6); // s +var USERMODE_CLIENT =(1<<7); // c +var USERMODE_REJECTED =(1<<8); // r +var USERMODE_KILL =(1<<9); // k +var USERMODE_FLOOD =(1<<10); // f +var USERMODE_SPY =(1<<11); // y +var USERMODE_DEBUG =(1<<12); // d +var USERMODE_ROUTING =(1<<13); // n +var USERMODE_HELP =(1<<14); // h +var USERMODE_NOTHROTTLE =(1<<15); // F + +USERMODE_CHAR = new Array(); +USERMODE_CHAR["o"] = USERMODE_OPER; +USERMODE_CHAR["i"] = USERMODE_INVISIBLE; +USERMODE_CHAR["w"] = USERMODE_WALLOPS; +USERMODE_CHAR["b"] = USERMODE_CHATOPS; +USERMODE_CHAR["g"] = USERMODE_GLOBOPS; +USERMODE_CHAR["s"] = USERMODE_SERVER; +USERMODE_CHAR["c"] = USERMODE_CLIENT; +USERMODE_CHAR["r"] = USERMODE_REJECTED; +USERMODE_CHAR["k"] = USERMODE_KILL; +USERMODE_CHAR["f"] = USERMODE_FLOOD; +USERMODE_CHAR["y"] = USERMODE_SPY; +USERMODE_CHAR["d"] = USERMODE_DEBUG; +USERMODE_CHAR["n"] = USERMODE_ROUTING; +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["o"] = true; +USERMODE_BCAST["i"] = true; +USERMODE_BCAST["h"] = true; // Channel modes var CHANMODE_NONE =(1<<0); // NONE @@ -177,12 +213,13 @@ var OLINE_CAN_LGNOTICE =(1<<12); // n var OLINE_CAN_GGNOTICE =(1<<13); // N // Synchronet IRCd doesn't have umode +Aa RESERVED // Synchronet IRCd doesn't have umode +a RESERVED -// Synchronet IRCd doesn't have umode +c RESERVED +var OLINE_CAN_UMODEC =(1<<16); // c // Synchronet IRCd doesn't have umode +f RESERVED // Synchronet IRCd doesn't have umode +F RESERVED var OLINE_CAN_CHATOPS =(1<<19); // s var OLINE_CHECK_SYSPASSWD =(1<<20); // S var OLINE_CAN_DEBUG =(1<<21); // x +var OLINE_IS_GOPER =(1<<22); // O "big O" // Various N:Line permission bits var NLINE_CHECK_QWKPASSWD =(1<<0); // q @@ -424,6 +461,7 @@ function parse_oline_flags(flags) { oline_flags |= OLINE_CAN_DEBUG; break; case "O": + oline_flags |= OLINE_IS_GOPER; oline_flags |= OLINE_CAN_GSQUITCON; oline_flags |= OLINE_CAN_GKILL; oline_flags |= OLINE_CAN_GGNOTICE; @@ -447,15 +485,16 @@ function parse_oline_flags(flags) { return oline_flags; } -function oper_notice(ntype,nmessage) { +function umode_notice(bit,ntype,nmessage) { log(ntype + ": " + nmessage); - for(thisoper in Clients) { - var oper=Clients[thisoper]; - if ((oper.mode&USERMODE_OPER) && !oper.parent) - oper.rawout(":" + servername + " NOTICE " + oper.nick + " :*** " + ntype + " -- " + nmessage); + for (thisuser in Clients) { + var user = Clients[thisuser]; + if ((user.mode&bit) && !user.parent && user.local) + user.rawout(":" + servername + " NOTICE " + user.nick + " :*** " + ntype + " -- " + nmessage); } + } - + function create_ban_mask(str,kline) { var tmp_banstr = new Array; tmp_banstr[0] = ""; @@ -579,7 +618,8 @@ function connect_to_server(this_cline,the_port) { connect_sock = new Socket(); connect_sock.connect(this_cline.host,the_port,ob_sock_timeout); if (connect_sock.is_connected) { - oper_notice("Routing","Connected! Sending info..."); + umode_notice(USERMODE_ROUTING,"Routing", + "Connected! Sending info..."); connect_sock.send("PASS " + this_cline.password + " :TS\r\n"); connect_sock.send("CAPAB " + server_capab + "\r\n"); connect_sock.send("SERVER " + servername + " 1 :" + serverdesc + "\r\n"); @@ -935,6 +975,9 @@ whowas_pointer = 0; nick_buffer = 1000; nick_pointer = 0; +sync_310 = false; +network_debug = false; + // Parse command-line arguments. config_filename=""; var cmdline_port; @@ -949,16 +992,23 @@ for (cmdarg=0;cmdarg<argc;cmdarg++) { case "-d": debug=true; break; + case "-x": + network_debug=true; + break; } } read_config_file(); -if(this.js==undefined) // v3.10? +if(this.js==undefined) { // v3.10? js = { terminated: false }; + sync_310 = true; +} -if(this.resolve_host==undefined) // v3.10? +if(this.resolve_host==undefined) { // v3.10? resolve_hostnames = false; + sync_310 = true; +} if(this.server==undefined) { // Running from JSexec? if (cmdline_port) @@ -1039,8 +1089,12 @@ while (!server.terminated) { for(thisPolled in readme) { Clients[poll_client_map[readme[thisPolled]]].work(); } - } else - mswait(1); // yield, don't peg the CPU + } else { + if (sync_310) + mswait(250); + else + mswait(1); + } // Scan C:Lines for servers to connect to automatically. var my_cline; @@ -1051,7 +1105,9 @@ while (!server.terminated) { ((time() - my_cline.lastconnect) > YLines[my_cline.ircclass].connfreq) ) { - oper_notice("Routing","Auto-connecting to " + CLines[thisCL].servername); + umode_notice(USERMODE_ROUTING,"Routing", + "Auto-connecting to " + + CLines[thisCL].servername); connect_to_server(CLines[thisCL]); } } @@ -1223,7 +1279,9 @@ function IRCClient(socket,new_id,local_client,do_newconn) { went_into_hostname = time() - went_into_hostname; if (went_into_hostname == "NaN") went_into_hostname=0; - oper_notice("DEBUG","resolve_host took " + went_into_hostname + " seconds."); + umode_notice(USERMODE_DEBUG,"Debug", + "resolve_host took " + + went_into_hostname + " seconds."); } } if (this.socket.remote_ip_address) @@ -1283,7 +1341,9 @@ function IRCClient_Quit(str,suppress_bcast,is_netsplit,origin) { this.bcast_to_servers_raw(":" + origin.nick + " SQUIT " + this.nick + " :" + str); this.netsplit(origin.nick + " " + this.nick); } else { // we should never land here - oper_notice("Notice","Netspliting a server which isn't local and doesn't have an origin."); + umode_notice(USERMODE_OPER,"Notice", + "Netspliting a server which isn't local and doesn't " + + "have an origin?!"); if (!suppress_bcast) this.bcast_to_servers_raw("SQUIT " + this.nick + " :" + str); this.netsplit(); @@ -1294,7 +1354,9 @@ function IRCClient_Quit(str,suppress_bcast,is_netsplit,origin) { if (this.local) { this.rawout("ERROR :Closing Link: [" + this.uprefix + "@" + this.hostname + "] (" + str + ")"); - oper_notice("Notice","Client exiting: " + this.nick + " (" + this.uprefix + "@" + this.hostname + ") [" + str + "] [" + this.ip + "]"); + umode_notice(USERMODE_CLIENT,"Client","Client exiting: " + + this.nick + " (" + this.uprefix + "@" + this.hostname + + ") [" + str + "] [" + this.ip + "]"); this.socket.close(); } @@ -1338,7 +1400,9 @@ function IRCClient_synchronize() { this.server_chan_info(Channels[my_channel]); } } - oper_notice("Routing","from " + servername + ": " + this.nick + " has processed user/channel burst, sending topic burst."); + umode_notice(USERMODE_ROUTING,"Routing","from " + servername + + ": " + this.nick + " has processed user/channel burst, " + + "sending topic burst."); for (my_channel in Channels) { if ((my_channel[0] == "#") && Channels[my_channel].topic) { var chan = Channels[my_channel]; @@ -1346,7 +1410,9 @@ function IRCClient_synchronize() { } } this.rawout("BURST 0"); // burst completed. - oper_notice("Routing","from " + servername + ": " + this.nick + " has processed topic burst (synched to network data)."); + umode_notice(USERMODE_ROUTING,"Routing","from " + servername + + ": " + this.nick + " has processed topic burst " + + "(synched to network data)."); } function IRCClient_server_info(sni_server) { @@ -1524,7 +1590,7 @@ function IRCClient_numeric322(chan,show_modes) { } if ((chan.mode&CHANMODE_PRIVATE) && !(this.mode&USERMODE_OPER) && - !this.onchannel(chan.nam.toUpperCase) ) { + !this.onchannel(chan.nam.toUpperCase()) ) { channel_name = "Priv"; } else { channel_name = chan.nam; @@ -1670,7 +1736,10 @@ function IRCClient_lusers() { } function IRCClient_motd() { - motd_file = new File(system.text_dir + "ircmotd.txt"); + umode_notice(USERMODE_SPY,"Spy","MOTD requested by " + this.nick + + " (" + this.uprefix + "@" + this.hostname + ") [" + + this.servername + "]"); + var motd_file = new File(system.text_dir + "ircmotd.txt"); if (motd_file.exists==false) this.numeric(422, ":MOTD file missing: " + motd_file.name); else if (motd_file.open("r")==false) @@ -2076,6 +2145,9 @@ function IRCClient_do_msg(target,type_str,send_str) { } function IRCClient_do_admin() { + umode_notice(USERMODE_SPY,"ADMIN requested by " + this.nick + " (" + + this.uprefix + "@" + this.hostname + ") [" + this.servername + + "]"); if (Admin1 && Admin2 && Admin3) { this.numeric(256, ":Administrative info about " + servername); this.numeric(257, ":" + Admin1); @@ -2087,6 +2159,9 @@ function IRCClient_do_admin() { } function IRCClient_do_info() { + umode_notice(USERMODE_SPY,"Spy","INFO requested by " + this.nick + + " (" + this.uprefix + "@" + this.hostname + ") [" + + this.servername + "]"); this.numeric(371, ":" + VERSION + " Copyright 2003 Randy Sommerfeld."); this.numeric(371, ":" + system.version_notice + " " + system.copyright + "."); this.numeric(371, ": "); @@ -2253,6 +2328,9 @@ function IRCClient_do_summon(summon_user) { function IRCClient_do_links(mask) { if (!mask) mask = "*"; + umode_notice(USERMODE_SPY,"Spy","LINKS " + mask + " requested from " + + this.nick + " (" + this.uprefix + "@" + this.hostname + ") [" + + this.servername + "]"); for(thisServer in Clients) { var Server=Clients[thisServer]; if (Server && (Server.conntype == TYPE_SERVER) && @@ -2331,10 +2409,16 @@ function IRCClient_do_connect(con_server,con_port) { this.server_notice("Invalid port: " + con_port); return 0; } + var msg = " CONNECT " + con_cline.servername + " " + con_port + + " from " + this.nick + "[" + this.uprefix + "@" + + this.hostname + "]"; var con_type = "Local"; - if (this.parent) + if (this.parent) { con_type = "Remote"; - oper_notice("Routing","from " + servername + ": " + con_type + " CONNECT " + con_cline.servername + " " + con_port + " from " + this.nick + "[" + this.uprefix + "@" + this.hostname + "]"); + server_bcast_to_servers("GNOTICE :Remote" + msg); + } + umode_notice(USERMODE_ROUTING,"Routing","from "+servername+": " + + con_type + msg); connect_to_server(con_cline,con_port); return 1; } @@ -3515,77 +3599,112 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) { return 1; } +function UMode_tweak_mode(bit,add) { + if (add) { + this.add_flags |= bit; + this.del_flags &= ~bit; + } else { + this.add_flags &= ~bit; + this.del_flags |= bit; + } +} + +function UMode() { + this.add_flags = 0; + this.del_flags = 0; + this.tweak_mode = UMode_tweak_mode; +} + function IRCClient_setusermode(modestr) { if (!modestr) return 0; - add=true; - unknown_mode=false; - addbits=USERMODE_NONE; - delbits=USERMODE_NONE; + var add=true; + var unknown_mode=false; + var umode = new UMode(); for (modechar in modestr) { switch (modestr[modechar]) { case "+": - add=true; + if (!add) + add=true; break; case "-": - add=false; + if (add) + add=false; break; case "i": - if(add) { - addbits|=USERMODE_INVISIBLE; - delbits&=~USERMODE_INVISIBLE; - } else { - addbits&=~USERMODE_INVISIBLE; - delbits|=USERMODE_INVISIBLE; - } + case "w": + case "s": + case "k": + umode.tweak_mode(USERMODE_CHAR + [modestr[modechar]],add); + break; + case "b": + case "g": + case "r": + case "f": + case "y": + case "d": + case "n": + if (this.mode&USERMODE_OPER) + umode.tweak_mode(USERMODE_CHAR + [modestr[modechar]],add); break; case "o": // Allow +o only by servers or non-local users. - if (add && (this.parent) && - Clients[this.parent].hub) { - addbits|=USERMODE_OPER; - delbits&=~USERMODE_OPER; - } - if(!add) { - addbits&=~USERMODE_OPER; - delbits|=USERMODE_OPER; - } + if (add && this.parent && + Clients[this.parent].hub) + umode.tweak_mode(USERMODE_OPER,true); + else if (!add) + umode.tweak_mode(USERMODE_OPER,false); + break; + case "c": + if ((this.mode&USERMODE_OPER) && + (this.flags&OLINE_CAN_UMODEC)) + umode.tweak_mode(USERMODE_CLIENT,add); break; default: if (!unknown_mode && !this.parent) { - this.numeric("501", ":Unknown MODE flag"); + this.numeric(501, ":Unknown MODE flag"); unknown_mode=true; } break; } } - addmodes = ""; - delmodes = ""; - if ((addbits&USERMODE_INVISIBLE) && !(this.mode&USERMODE_INVISIBLE)) { - addmodes += "i"; - this.mode |= USERMODE_INVISIBLE; - } else if ((delbits&USERMODE_INVISIBLE) && (this.mode&USERMODE_INVISIBLE)) { - delmodes += "i"; - this.mode &= ~USERMODE_INVISIBLE; - } - if ((addbits&USERMODE_OPER) && !(this.mode&USERMODE_OPER)) { - addmodes += "o"; - this.mode |= USERMODE_OPER; - } else if ((delbits&USERMODE_OPER) && (this.mode&USERMODE_OPER)) { - delmodes += "o"; - this.mode &= ~USERMODE_OPER; + var addmodes = ""; + var delmodes = ""; + var bcast_addmodes = ""; + var bcast_delmodes = ""; + for (mym in USERMODE_CHAR) { + if ((umode.add_flags&USERMODE_CHAR[mym]) && + !(this.mode&USERMODE_CHAR[mym])) { + addmodes += mym; + if (USERMODE_BCAST[mym]) + bcast_addmodes += mym; + this.mode |= USERMODE_CHAR[mym]; + } else if ((umode.del_flags&USERMODE_CHAR[mym]) && + (this.mode&USERMODE_CHAR[mym])) { + delmodes += mym; + if (USERMODE_BCAST[mym]) + bcast_delmodes += mym; + this.mode &= ~USERMODE_CHAR[mym]; + } } if (!addmodes && !delmodes) return 0; - final_modestr = ""; + var final_modestr = ""; + var bcast_modestr = ""; if (addmodes) final_modestr += "+" + addmodes; if (delmodes) final_modestr += "-" + delmodes; + if (bcast_addmodes) + bcast_modestr += "+" + bcast_addmodes; + if (bcast_delmodes) + bcast_modestr += "-" + bcast_delmodes; if (!this.parent) { - str = "MODE " + this.nick + " " + final_modestr; - this.originatorout(str,this); - this.bcast_to_servers(str); + this.originatorout("MODE "+this.nick+" "+final_modestr,this); + if (bcast_addmodes || bcast_delmodes) + this.bcast_to_servers("MODE "+this.nick+" "+bcast_modestr,this); } return 1; } @@ -3809,7 +3928,9 @@ function IRCClient_unregistered_commands(command, cmdline) { this.numeric("005", "MODES=" + max_modes + " MAXCHANNELS=" + max_user_chans + " CHANNELLEN=" + max_chanlen + " MAXBANS=" + max_bans + " NICKLEN=" + max_nicklen + " TOPICLEN=" + max_topiclen + " KICKLEN=" + max_kicklen + " CHANTYPES=#& PREFIX=(ov)@+ NETWORK=Synchronet CASEMAPPING=ascii CHANMODES=b,k,l,imnpst STATUSMSG=@+ :are available on this server."); this.lusers(); this.motd(); - oper_notice("Notice","Client connecting: " + this.nick + " (" + this.uprefix + "@" + this.hostname + ") [" + this.socket.remote_ip_address + "] {1}"); + umode_notice(USERMODE_CLIENT,"Client","Client connecting: " + + this.nick + " (" + this.uprefix + "@" + this.hostname + + ") [" + this.socket.remote_ip_address + "] {1}"); if (server.client_update != undefined) server.client_update(this.socket, this.nick, this.hostname); server_bcast_to_servers("NICK " + this.nick + " 1 " + this.created + " " + this.get_usermode() + " " + this.uprefix + " " + this.hostname + " " + servername + " 0 " + ip_to_int(this.ip) + " :" + this.realname); @@ -3897,15 +4018,15 @@ function IRCClient_registered_commands(command, cmdline) { case "D": if (debug) { debug=false; - oper_notice("Notice","Debug mode disabled by " + this.ircnuh); + umode_notice(USERMODE_OPER,"Notice","Debug mode disabled by " + this.ircnuh); } else { debug=true; - oper_notice("Notice","Debug mode enabled by " + this.ircnuh); + umode_notice(USERMODE_OPER,"Notice","Debug mode enabled by " + this.ircnuh); } break; case "Y": if (cmd[2]) { - oper_notice("Notice","branch.yield_freq set to " + cmd[2] + " by " + this.ircnuh); + umode_notice(USERMODE_DEBUG,"Debug","branch.yield_freq set to " + cmd[2] + " by " + this.ircnuh); branch.yield_freq = parseInt(cmd[2]); } break; @@ -3934,7 +4055,8 @@ function IRCClient_registered_commands(command, cmdline) { } cmd.shift(); var exp = cmd.join(' '); /* expression */ - this.server_notice("Evaluating: " + exp); + umode_notice(USERMODE_DEBUG,"Debug","Oper " + + this.nick + " is using EVAL: " + exp); try { this.server_notice("Result: " + eval(exp)); } catch(e) { @@ -4116,7 +4238,9 @@ function IRCClient_registered_commands(command, cmdline) { break; } KLines.push(new KLine(kline_mask,ircstring(cmdline),"k")); - oper_notice("Notice", this.nick + " added temporary 99 min. k-line for [" + kline_mask + "] [0]"); + umode_notice(USERMODE_OPER,"Notice", this.nick + + " added temporary 99 min. k-line for [" + + kline_mask + "] [0]"); scan_for_klined_clients(); break; case "UNKLINE": @@ -4139,7 +4263,9 @@ function IRCClient_registered_commands(command, cmdline) { break; } remove_kline(kline_mask); - oper_notice("Notice", this.nick + " has removed the K-Line for: [" + kline_mask + "] (1 matches)"); + umode_notice(USERMODE_OPER,"Notice", this.nick + + " has removed the K-Line for: [" + + kline_mask + "] (1 matches)"); break; case "LINKS": if (!cmd[1]) { // * @@ -4358,11 +4484,15 @@ function IRCClient_registered_commands(command, cmdline) { this.numeric("381", ":You are now an IRC operator."); this.mode|=USERMODE_OPER; this.rawout(":" + this.nick + " MODE " + this.nick + " +o"); - oper_notice("Notice", this.nick + " (" + this.uprefix + "@" + this.hostname + ") is now operator (O)"); - this.bcast_to_servers("MODE "+ this.nick +" +o"); + umode_notice(USERMODE_SERVER,"Notice", + this.nick + " (" + this.uprefix + + "@" + this.hostname + ") " + + "is now operator (O)"); + if (OLines[ol].flags&OLINE_IS_GOPER) + this.bcast_to_servers("MODE "+ this.nick +" +o"); } else { this.numeric("491", ":No O:Lines for your host. Attempt logged."); - oper_notice("Notice","Failed OPER attempt by " + this.nick + " (" + this.uprefix + "@" + this.hostname + ")"); + umode_notice(USERMODE_OPER,"Notice","Failed OPER attempt by " + this.nick + " (" + this.uprefix + "@" + this.hostname + ")"); } break; case "PART": @@ -4459,7 +4589,9 @@ function IRCClient_registered_commands(command, cmdline) { break; } this.numeric(382, this.nick + " ircd.conf :Rehashing."); - oper_notice("Notice",this.nick + " is rehashing Server config file while whistling innocently"); + umode_notice(USERMODE_SERVER,"Notice",this.nick + + " is rehashing Server config file while " + + "whistling innocently"); read_config_file(); break; case "RESTART": @@ -4476,7 +4608,7 @@ function IRCClient_registered_commands(command, cmdline) { break; } var rs_str = "Aieeeee!!! Restarting server..."; - oper_notice("Notice",rs_str); + umode_notice(USERMODE_SERVER,"Notice",rs_str); terminate_everything(rs_str); break; case "SQUIT": @@ -4507,7 +4639,10 @@ function IRCClient_registered_commands(command, cmdline) { sq_server.rawout(":" + this.nick + " SQUIT " + sq_server.nick + " :" + reason); break; } - oper_notice("Routing","from " + servername + ": Received SQUIT " + cmd[1] + " from " + this.nick + "[" + this.uprefix + "@" + this.hostname + "] (" + reason + ")"); + umode_notice(USERMODE_ROUTING,"Routing","from " + + servername + ": Received SQUIT " + cmd[1] + + " from " + this.nick + "[" + this.uprefix + + "@" + this.hostname + "] (" + reason + ")"); sq_server.quit(reason); break; case "STATS": @@ -4694,11 +4829,41 @@ function IRCClient_registered_commands(command, cmdline) { this.numeric481(); break; } - oper_notice("LocOps","from " + this.nick + ": " + ircstring(cmdline)); + umode_notice(USERMODE_OPER,"LocOps","from " + + this.nick + ": " + ircstring(cmdline)); + break; + case "CHATOPS": + if (!((this.mode&USERMODE_OPER) && + (this.flags&OLINE_CAN_CHATOPS))) { + this.numeric481(); + break; + } + umode_notice(USERMODE_CHATOPS,"ChatOps","from " + + this.nick + ": " + ircstring(cmdline)); + server_bcast_to_servers(":" + this.nick + " CHATOPS :"+ + ircstring(cmdline)); break; case "GLOBOPS": + if (!((this.mode&USERMODE_OPER) && + (this.flags&OLINE_CAN_GLOBOPS))) { + this.numeric481(); + break; + } + if (!cmd[1]) { + this.numeric461("GLOBOPS"); + break; + } + umode_notice(USERMODE_GLOBOPS,"Global","from " + + this.nick + ": " + ircstring(cmdline)); + server_bcast_to_servers(":" + this.nick + " GLOBOPS :"+ + ircstring(cmdline)); + break; case "WALLOPS": - // allow non-opers to wallop for assistance, perhaps. + if (!((this.mode&USERMODE_OPER) && + (this.flags&OLINE_CAN_WALLOPS))) { + this.numeric481(); + break; + } if (!cmd[1]) { this.numeric461("WALLOPS"); break; @@ -4855,7 +5020,9 @@ function IRCClient_server_commands(origin, command, cmdline) { var killtype = "KILL"; } if (!ThisOrigin) { - oper_notice("Notice","Server " + this.nick + " trying to pass message for non-existent origin: " + origin); + umode_notice(USERMODE_OPER,"Notice","Server " + this.nick + + " trying to pass message for non-existent origin: " + + origin); this.rawout(killtype + " " + origin + " :" + servername + " (" + origin + "(?) <- " + this.nick + ")"); return 0; } @@ -4874,11 +5041,34 @@ function IRCClient_server_commands(origin, command, cmdline) { switch(command) { case "GNOTICE": + if (!cmd[1]) + break; + umode_notice(USERMODE_ROUTING,"Routing","from " + + this.nick + ": " + ircstring(cmdline)); + this.bcast_to_servers_raw(":" + this.nick + " " + + "GNOTICE :" + ircstring(cmdline)); + break; case "GLOBOPS": + if (!cmd[1]) + break; + umode_notice(USERMODE_GLOBOPS,"Global","from " + + ThisOrigin.nick + ": " + ircstring(cmdline)); + this.bcast_to_servers_raw(":" + ThisOrigin.nick + " " + + "GLOBOPS :" + ircstring(cmdline)); + break; + case "CHATOPS": + if (!cmd[1]) + break; + umode_notice(USERMODE_CHATOPS,"ChatOps","from " + + ThisOrigin.nick + ": " + ircstring(cmdline)); + this.bcast_to_servers_raw(":" + ThisOrigin.nick + " " + + "CHATOPS :" + ircstring(cmdline)); + break; case "WALLOPS": if (!cmd[1]) break; - str = ":" + origin + " WALLOPS :" + ircstring(cmdline); + var str = ":" + ThisOrigin.nick + " WALLOPS :" + + ircstring(cmdline); wallopers(str); this.bcast_to_servers_raw(str); break; @@ -4897,6 +5087,8 @@ function IRCClient_server_commands(origin, command, cmdline) { } break; case "AWAY": + if (network_debug) + server_bcast_to_servers("GLOBOPS :" + ThisOrigin.nick + " " + cmdline); if (!cmd[1]) ThisOrigin.away = ""; else @@ -4915,7 +5107,9 @@ function IRCClient_server_commands(origin, command, cmdline) { } break; case "ERROR": - oper_notice("Notice", "ERROR from " + this.nick + "[(+)0@" + this.hostname + "] -- " + ircstring(cmdline)); + umode_notice(USERMODE_ROUTING,"Notice", "ERROR from " + + this.nick + "[(+)0@" + this.hostname + "] -- "+ + ircstring(cmdline)); ThisOrigin.quit(ircstring(cmdline)); break; case "INFO": @@ -4935,12 +5129,12 @@ function IRCClient_server_commands(origin, command, cmdline) { case "INVITE": if (!cmd[2]) break; - chanid = searchbychannel(cmd[2]); + var chanid = searchbychannel(cmd[2]); if (!chanid) break; if (!chanid.ismode(this.id,CHANLIST_OP)) break; - nickid = searchbynick(cmd[1]); + var nickid = searchbynick(cmd[1]); if (!nickid) break; if (nickid.onchannel(chanid.nam.toUpperCase())) @@ -4954,6 +5148,9 @@ function IRCClient_server_commands(origin, command, cmdline) { var str; var kick_reason; + if (network_debug) + server_bcast_to_servers("GLOBOPS :" + ThisOrigin.nick + " " + cmdline); + if (!cmd[2]) break; chanid = searchbychannel(cmd[1]); @@ -4976,6 +5173,8 @@ function IRCClient_server_commands(origin, command, cmdline) { nickid.rmchan(Channels[chanid.nam.toUpperCase()]); break; case "JOIN": + if (network_debug) + server_bcast_to_servers("GLOBOPS :" + ThisOrigin.nick + " " + cmdline); if (!cmd[1]) break; if (cmd[1][0] == ":") @@ -5042,6 +5241,9 @@ function IRCClient_server_commands(origin, command, cmdline) { this.rawout(":" + servername + " PASS " + result + " :" + cmd[2] + " QWK " + ThisOrigin.nick); break; case "SJOIN": + if (network_debug) + server_bcast_to_servers("GLOBOPS :" + ThisOrigin.nick + " " + cmdline); + if (!cmd[2]) break; if (cmd[2][0] != "#") @@ -5069,7 +5271,7 @@ function IRCClient_server_commands(origin, command, cmdline) { chan_members = ircstring(cmdline,4+tmp_modeargs).split(' '); if (chan_members == "") { - oper_notice("Notice","Server " + this.nick + " trying to SJOIN empty channel " + cmd[2] + " before processing."); + umode_notice(USERMODE_OPER,"Notice","Server " + this.nick + " trying to SJOIN empty channel " + cmd[2] + " before processing."); break; } @@ -5094,7 +5296,7 @@ function IRCClient_server_commands(origin, command, cmdline) { } if (cm_array == "") { - oper_notice("Notice","Server " + this.nick + " trying to SJOIN empty channel " + cmd[2] + " post processing."); + umode_notice(USERMODE_OPER,"Notice","Server " + this.nick + " trying to SJOIN empty channel " + cmd[2] + " post processing."); break; } } @@ -5196,6 +5398,9 @@ function IRCClient_server_commands(origin, command, cmdline) { var sq_server; var reason; + if (network_debug) + server_bcast_to_servers("GLOBOPS :" + ThisOrigin.nick + " " + cmdline); + if (!cmd[1] || !this.hub) sq_server = this; else @@ -5220,9 +5425,16 @@ function IRCClient_server_commands(origin, command, cmdline) { sq_server.rawout(":" + ThisOrigin.nick + " SQUIT " + sq_server.nick + " :" + reason); 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); break; case "KILL": + if (network_debug) + server_bcast_to_servers("GLOBOPS :" + ThisOrigin.nick + " " + cmdline); if (!cmd[2]) break; if (cmd[1].match(/[.]/)) @@ -5237,10 +5449,11 @@ function IRCClient_server_commands(origin, command, cmdline) { target = searchbynick(search_nickbuf(kills[kill])); if (target && (this.hub || (target.parent == this.id)) ) { + umode_notice(USERMODE_KILL,"Notice","Received KILL message for " + target.ircnuh + ". From " + ThisOrigin.nick + " Path: target!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) { - oper_notice("Notice","Non-Hub server " + this.nick + " trying to KILL " + target.nick); + umode_notice(USERMODE_OPER,"Notice","Non-Hub server " + this.nick + " trying to KILL " + target.nick); this.reintroduce_nick(target); } } @@ -5258,6 +5471,8 @@ function IRCClient_server_commands(origin, command, cmdline) { } break; case "MODE": + if (network_debug) + server_bcast_to_servers("GLOBOPS :" + ThisOrigin.nick + " " + cmdline); if (!cmd[2]) break; // nasty kludge since we don't support per-mode TS yet. @@ -5296,6 +5511,8 @@ function IRCClient_server_commands(origin, command, cmdline) { } break; case "NICK": + if (network_debug) + server_bcast_to_servers("GLOBOPS :" + ThisOrigin.nick + " " + cmdline); if (!cmd[2] || (!cmd[8] && (cmd[2][0] != ":")) ) break; var collide = searchbynick(cmd[1]); @@ -5307,7 +5524,7 @@ function IRCClient_server_commands(origin, command, cmdline) { this.bcast_to_servers("KILL " + collide.nick + " :Nickname Collision."); collide.quit("Nickname Collision",true); } else if (collide && !this.hub) { - oper_notice("Notice","Server " + this.nick + " trying to collide nick " + collide.nick + " forwards, reversing."); + umode_notice(USERMODE_OPER,"Notice","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 @@ -5327,7 +5544,7 @@ function IRCClient_server_commands(origin, command, cmdline) { } else if (cmd[10]) { if (!this.hub) { if(!this.check_nickname(cmd[1])) { - oper_notice("Notice","Server " + this.nick + " trying to introduce invalid nickname: " + cmd[1] + ", killed."); + umode_notice(USERMODE_OPER,"Notice","Server " + this.nick + " trying to introduce invalid nickname: " + cmd[1] + ", killed."); this.ircout("KILL " + cmd[1] + " :Bogus Nickname."); break; } @@ -5338,7 +5555,7 @@ function IRCClient_server_commands(origin, command, cmdline) { var test_server = searchbyserver(cmd[7]); if (!test_server || (this.id != test_server.parent)) { - oper_notice("Notice","Server " + this.nick + " trying to introduce nick from server not behind it: " + cmd[1] + "@" + cmd[7]); + umode_notice(USERMODE_OPER,"Notice","Server " + this.nick + " trying to introduce nick from server not behind it: " + cmd[1] + "@" + cmd[7]); this.ircout("KILL " + cmd[1] + " :Invalid Origin."); break; } @@ -5380,6 +5597,8 @@ function IRCClient_server_commands(origin, command, cmdline) { } break; case "PART": + if (network_debug) + server_bcast_to_servers("GLOBOPS :" + ThisOrigin.nick + " " + cmdline); if (!cmd[1]) break; the_channels = cmd[1].split(","); @@ -5442,9 +5661,13 @@ function IRCClient_server_commands(origin, command, cmdline) { this.pinged = false; break; case "QUIT": + if (network_debug) + server_bcast_to_servers("GLOBOPS :" + ThisOrigin.nick + " " + cmdline); ThisOrigin.quit(ircstring(cmdline)); break; case "SERVER": + if (network_debug) + server_bcast_to_servers("GLOBOPS :" + ThisOrigin.nick + " " + cmdline); if (!cmd[3]) break; if ((cmd[2] == 1) && !this.realname) { @@ -5467,7 +5690,7 @@ function IRCClient_server_commands(origin, command, cmdline) { newsrv.conntype = TYPE_SERVER; newsrv.linkparent = ThisOrigin.nick; } else { - oper_notice("Routing","from " + servername + ": Non-Hub link " + this.nick + " introduced " + cmd[1] + "(*)."); + 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; } @@ -5529,6 +5752,8 @@ function IRCClient_server_commands(origin, command, cmdline) { } break; case "TOPIC": + if (network_debug) + server_bcast_to_servers("GLOBOPS :" + ThisOrigin.nick + " " + cmdline); if (!cmd[4]) break; var chan = searchbychannel(cmd[1]); @@ -5610,7 +5835,7 @@ function IRCClient_server_commands(origin, command, cmdline) { if (!cmd[6]) break; if (!ThisOrigin.isulined) { - oper_notice("Notice","Non-U:Lined server " + ThisOrigin.nick + " trying to utilize AKILL."); + umode_notice(USERMODE_OPER,"Notice","Non-U:Lined server " + ThisOrigin.nick + " trying to utilize AKILL."); break; } @@ -5696,15 +5921,18 @@ function IRCClient_work() { this.registered_commands(command,cmdline); } else if (this.conntype == TYPE_SERVER) { this.server_commands(origin,command,cmdline); - } else { - oper_notice("Notice","Client has bogus conntype!"); + } else { // Uh, someone messed up :( + umode_notice(UMODE_OPER,"Notice", + "Client has bogus conntype!"); } } } function IRCClient_finalize_server_connect(states) { hcc_counter++; - oper_notice("Routing","Link with " + this.nick + "[unknown@" + this.hostname + "] established, states: " + states); + umode_notice(USERMODE_ROUTING,"Routing","Link with " + this.nick + + "[unknown@" + this.hostname + "] established, states: " + + states); if (server.client_update != undefined) server.client_update(this.socket, this.nick, this.hostname); if (!this.sentps) { @@ -5870,7 +6098,7 @@ function Channel_isbanned(banned_nuh) { function Channel_occupants() { var chan_occupants=""; for(thisChannel_user in this.users) { - Channel_user=Clients[this.users[thisChannel_user]]; + var Channel_user=Clients[this.users[thisChannel_user]]; if (Channel_user.nick && (Channel_user.conntype != TYPE_SERVER)) { if (chan_occupants) -- GitLab