add:  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; var add=true; var unknown_mode=false; var umode = new UMode(); for (modechar in modestr) { switch (modestr[modechar]) { case "+": if (!add) add=true; break; case "-": if (add) add=false; break; case "i": case "w": case "s": case "k": case "g": umode.tweak_mode(USERMODE_CHAR [modestr[modechar]],add); break; case "b": 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":  if (add && this.parent && Servers[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"); unknown_mode=true; } break; } } 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; 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) { 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; }  function IRCClient_check_timeout() { if (!this.pinged && ((time() - this.idletime) > YLines[this.ircclass].pingfreq)) { this.pinged = time(); this.rawout("PING :" + servername); } else if (this.pinged && ((time() - this.pinged) > YLines[this.ircclass].pingfreq)) { this.quit("Ping Timeout"); return 1; } return 0; }  function IRCClient_finalize_server_connect(states) { hcc_counter++; 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) { for (cl in CLines) { if(IRC_match(this.nick,CLines[cl].servername)) { this.rawout("PASS " + CLines[cl].password + " :" + states); break; } } this.rawout("CAPAB " + server_capab); this.rawout("SERVER " + servername + " 1 :" + serverdesc); } this.bcast_to_servers_raw(":" + servername + " SERVER " + this.nick + " 2 :" + this.info); this.synchronize(); }  function CLine(host,password,servername,port,ircclass) { this.host = host; this.password = password; this.servername = servername; this.port = port; this.ircclass = ircclass; this.lastconnect = 0; }  function HLine(allowedmask,servername) { this.allowedmask = allowedmask; this.servername = servername; }  function ILine(ipmask,password,hostmask,port,ircclass) { this.ipmask = ipmask; this.password = password; this.hostmask = hostmask; this.port = port; this.ircclass = ircclass; }  function KLine(hostmask,reason,type) { this.hostmask = hostmask; this.reason = reason; this.type = type; }  function NLine(host,password,servername,flags,ircclass) { this.host = host; this.password = password; this.servername = servername; this.flags = flags; this.ircclass = ircclass; }  function OLine(hostmask,password,nick,flags,ircclass) { this.hostmask = hostmask; this.password = password; this.nick = nick; this.flags = flags; this.ircclass = ircclass; }  function QLine(nick,reason) { this.nick = nick; this.reason = reason; }  function YLine(pingfreq,connfreq,maxlinks,sendq) { this.pingfreq = pingfreq; this.connfreq = connfreq; this.maxlinks = maxlinks; this.sendq = sendq; }  function ZLine(ipmask,reason) { this.ipmask = ipmask; this.reason = reason; }  function WhoWas(nick,uprefix,host,realname,server,serverdesc) { this.nick = nick; this.uprefix = uprefix; this.host = host; this.realname = realname; this.server = server; this.serverdesc = serverdesc; }  function NickBuf(oldnick,newnick) { this.oldnick = oldnick; this.newnick = newnick; }   function SJOIN_Nick(nick,isop,isvoice) { this.nick = nick; this.isop = isop; this.isvoice = isvoice; } 
context: function IRCClient_set_chanmode(chan,modeline,bounce_modes) {	if (!chan || !modeline)		return;	var cmode = new ChanMode(chan,this);	var cm_args = modeline.split(' ');	var add=true;	var mode_counter=0;	var mode_args_counter=1; // start counting at args, not the modestring	for (modechar in cm_args[0]) {		mode_counter++;		switch (cm_args[0][modechar]) {			case "+":				if (!add)					add=true;				mode_counter--;				break;			case "-":				if (add)					add=false;				mode_counter--;				break;			case "b":				if(add && (cm_args.length<=mode_args_counter)) {					cmode.addbits|=CHANMODE_BAN;//list bans					break;				}				cmode.tweaktmpmodelist(CHANMODE_BAN,add,					cm_args[mode_args_counter]);				mode_args_counter++;				break;			case "i":				cmode.tweaktmpmode(CHANMODE_INVITE,add);				break;			case "k":				if(cm_args.length > mode_args_counter) {					cmode.tweaktmpmode(CHANMODE_KEY,add);					cmode.state_arg[CHANMODE_KEY]=cm_args[mode_args_counter];					mode_args_counter++;				}				break;			case "l":				if (add && (cm_args.length > mode_args_counter)) {					cmode.tweaktmpmode(CHANMODE_LIMIT,true);					var regexp = "^[0-9]{1,5}$";					if(cm_args[mode_args_counter].match(regexp))						cmode.state_arg[CHANMODE_LIMIT]=cm_args[mode_args_counter];					mode_args_counter++;				} else if (!add) {					cmode.tweaktmpmode(CHANMODE_LIMIT,false);					if (cm_args.length > mode_args_counter)						mode_args_counter++;				}				break;			case "m":				cmode.tweaktmpmode(CHANMODE_MODERATED,add);				break;			case "n":				cmode.tweaktmpmode(CHANMODE_NOOUTSIDE,add);				break;			case "o":				if (cm_args.length <= mode_args_counter)					break;				cmode.tweaktmpmodelist(CHANMODE_OP,add,					cm_args[mode_args_counter]);				mode_args_counter++;				break;			case "p":				if( (add && !(chan.mode&CHANMODE_SECRET) ||				     (cmode.delbits&CHANMODE_SECRET) ) ||				    (!add) )					cmode.tweaktmpmode(CHANMODE_PRIVATE,add);				break;			case "s":				if( (add && !(chan.mode&CHANMODE_PRIVATE) ||				     (cmode.delbits&CHANMODE_PRIVATE) ) ||				    (!add) )					cmode.tweaktmpmode(CHANMODE_SECRET,add);				break;			case "t":				cmode.tweaktmpmode(CHANMODE_TOPIC,add);				break;			case "v":				if (cm_args.length <= mode_args_counter)					break;				cmode.tweaktmpmodelist(CHANMODE_VOICE,add,					cm_args[mode_args_counter]);				mode_args_counter++;				break;			default:				if ((!this.parent) && (!this.server))					this.numeric(472, cm_args[0][modechar] + " :is unknown mode char to me.");				mode_counter--;				break;		}		if (mode_counter == max_modes)			break;	}	// If we're bouncing modes, traverse our side of what the modes look	// like and remove any modes not mentioned by what was passed to the	// function.  Or, clear any ops, voiced members, or bans on the 'bad'	// side of the network sync.	if (bounce_modes) {		for (cm in MODE) {			if (MODE[cm].state && (chan.mode&cm) && 			    !(cmode.addbits&cm)) {				cmode.delbits |= cm;			} else if (MODE[cm].list) {				for (member in chan.modelist[cm]) {					cmode.delmodes += MODE[cm].modechar;					cmode.delmodeargs += " " +						chan.modelist[cm][member].nick;					delete chan.modelist[cm][member];				}			}		}	}	// Now we run through all the mode toggles and construct our lists for	// later display.  We also play with the channel bit switches here.	for (cm in MODE) {		if (MODE[cm].state) {			if ((cm&CHANMODE_KEY) && (cmode.addbits&CHANMODE_KEY)&& 			    cmode.state_arg[cm] && chan.arg[cm] &&			    !this.server && !this.parent && !bounce_modes) {				this.numeric(467, chan.nam +					" :Channel key already set.");			} else if ((cmode.addbits&cm) && (!(chan.mode&cm) ||			    ((cm==CHANMODE_LIMIT)&&(chan.arg[CHANMODE_LIMIT]!=			     cmode.state_arg[CHANMODE_LIMIT])) ) ) {				cmode.addmodes += MODE[cm].modechar;				chan.mode |= cm;				if (MODE[cm].args && MODE[cm].state) {					cmode.addmodeargs += " " +						cmode.state_arg[cm];					chan.arg[cm] = cmode.state_arg[cm];				}			} else if ((cmode.delbits&cm) && (chan.mode&cm)) {				cmode.delmodes += MODE[cm].modechar;				chan.mode &= ~cm;				if (MODE[cm].args && MODE[cm].state) {					cmode.delmodeargs += " " +						cmode.state_arg[cm];					chan.arg[cm] = "";				}			}		}	}	// This is a special case, if +b was passed to us without arguments,	// we simply display a list of bans on the channel.	if (cmode.addbits&CHANMODE_BAN) {		for (the_ban in chan.modelist[CHANMODE_BAN]) {			this.numeric(367, chan.nam + " " + chan.modelist[CHANMODE_BAN][the_ban] + " " + chan.bancreator[the_ban] + " " + chan.bantime[the_ban]);		}		this.numeric(368, chan.nam + " :End of Channel Ban List.");	}	// Bans are a specialized case, sigh.	for (z in cmode.tmplist[CHANMODE_BAN][true]) { // +b		var set_ban = create_ban_mask(			cmode.tmplist[CHANMODE_BAN][add][z]);		if ((chan.count_modelist(CHANMODE_BAN) >= max_bans) &&		     !this.server && !this.parent) {			this.numeric(478, chan.nam + " " + set_ban + " :" +				"Cannot add ban, channel's ban list is full.");		} else if (set_ban && !chan.isbanned(set_ban)) {			cmode.addmodes += "b";			cmode.addmodeargs += " " + set_ban;			var banid = chan.modelist[CHANMODE_BAN].push(set_ban);			chan.bantime[banid] = time();			chan.bancreator[banid] = this.nuh;		}	}	for (z in cmode.tmplist[CHANMODE_BAN][false]) { // -b		for (ban in chan.modelist[CHANMODE_BAN]) {			if (cmode.tmplist[CHANMODE_BAN][false][z].toUpperCase()			    == chan.modelist[CHANMODE_BAN][ban].toUpperCase()) {				cmode.delmodes += "b";				cmode.delmodeargs += " " +					cmode.tmplist[CHANMODE_BAN][false][z];				delete chan.modelist[CHANMODE_BAN][ban];				delete chan.bantime[ban];				delete chan.bancreator[ban];			}		}	}	// Modes where we just deal with lists of nicks.	cmode.affect_mode_list(CHANMODE_OP);	cmode.affect_mode_list(CHANMODE_VOICE);	if (!cmode.addmodes && !cmode.delmodes)		return 0;	var final_modestr = "";	if (cmode.addmodes)		final_modestr += "+" + cmode.addmodes;	if (cmode.delmodes)		final_modestr += "-" + cmode.delmodes;	if (cmode.addmodeargs)		final_modestr += cmode.addmodeargs;	if (cmode.delmodeargs)		final_modestr += cmode.delmodeargs;	var final_args = final_modestr.split(' ');	var arg_counter = 0;	var mode_counter = 0;	var mode_output = "";	var f_mode_args = "";	for (marg in final_args[0]) {		switch (final_args[0][marg]) {			case "+":				mode_output += "+";				add = true;				break;			case "-":				mode_output += "-";				add = false;				break;			case "l":				if (!add) {					mode_counter++;					mode_output += final_args[0][marg];					break;				}			case "b": // only modes with arguments			case "k":			case "l":			case "o":			case "v":				arg_counter++;				f_mode_args += " " + final_args[arg_counter];			default:				mode_counter++;				mode_output += final_args[0][marg];				break;		}		if (mode_counter >= max_modes) {			var str = "MODE " + chan.nam + " " + mode_output + f_mode_args;			if (!this.server)				this.bcast_to_channel(chan, str, true);			else				this.bcast_to_channel(chan, str, false);			if (chan.nam[0] != "&")				this.bcast_to_servers(str);			if (add)				mode_output = "+";			else				mode_output = "-";			f_mode_args = "";		}	}	if (mode_output.length > 1) {		str = "MODE " + chan.nam + " " + mode_output + f_mode_args;		if (!this.server)			this.bcast_to_channel(chan, str, true);		else			this.bcast_to_channel(chan, str, false);		if (chan.nam[0] != "&")			this.bcast_to_servers(str);	}	return 1;}
meta: 9592	/local1/tlutelli/issta_data/temp/all_js/javascript/2006_temp/2006/9592/6781c0e0b9e3a3ca5a5ff50ba3052f70eb666f04/ircd.js/buggy/ircd.js