Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

Commits (2)
This diff is collapsed.
// $Id: ircd_channel.js,v 1.34 2019/08/06 20:44:39 deuce Exp $
//
// ircd_channel.js
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details:
// http://www.gnu.org/licenses/gpl.txt
//
// Synchronet IRC Daemon as per RFC 1459, link compatible with Bahamut 1.4
//
// Copyright 2003-2009 Randolph Erwin Sommerfeld <sysop@rrx.ca>
//
// ** Everything related to channels and their operation.
//
////////// Constants / Defines //////////
const CHANNEL_REVISION = "$Revision: 1.34 $".split(' ')[1];
/*
ircd/channel.js
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details:
https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
Everything related to channels in the IRCd and their operation.
Copyright 2003-2021 Randy Sommerfeld <cyan@synchro.net>
*/
const CHANMODE_NONE =(1<<0); // NONE
const CHANMODE_BAN =(1<<1); // b
......@@ -87,8 +83,11 @@ function Channel(nam) {
////////// Functions //////////
function ChanMode_tweaktmpmode(tmp_bit,add) {
if (!this.chan.modelist[CHANMODE_OP][this.user.id] &&
!this.user.server && !this.user.uline && !(this.mode&USERMODE_ADMIN)) {
if ( !this.chan.modelist[CHANMODE_OP][this.user.id]
&& !this.user.server
&& !this.user.uline
&& !(this.mode&USERMODE_ADMIN)
) {
this.user.numeric482(this.chan.nam);
return 0;
}
......@@ -102,15 +101,17 @@ function ChanMode_tweaktmpmode(tmp_bit,add) {
}
function ChanMode_tweaktmpmodelist(tmp_bit,add,arg) {
if (!this.chan.modelist[CHANMODE_OP][this.user.id] &&
!this.user.server && !this.user.uline && !(this.mode&USERMODE_ADMIN)) {
if ( !this.chan.modelist[CHANMODE_OP][this.user.id]
&& !this.user.server
&& !this.user.uline
&& !(this.mode&USERMODE_ADMIN)
) {
this.user.numeric482(this.chan.nam);
return 0;
}
for (lstitem in this.tmplist[tmp_bit][add]) {
// Is this argument in our list for this mode already?
if (this.tmplist[tmp_bit][add][lstitem].toUpperCase() ==
arg.toUpperCase())
if (this.tmplist[tmp_bit][add][lstitem].toUpperCase() == arg.toUpperCase())
return 0;
}
// It doesn't exist on our mode, push it in.
......@@ -122,8 +123,7 @@ function ChanMode_tweaktmpmodelist(tmp_bit,add,arg) {
else
oadd = true;
for (x in this.tmplist[tmp_bit][oadd]) {
if (this.tmplist[tmp_bit][oadd][x].toUpperCase() ==
arg.toUpperCase()) {
if (this.tmplist[tmp_bit][oadd][x].toUpperCase() == arg.toUpperCase()) {
delete this.tmplist[tmp_bit][oadd][x];
return 0;
}
......@@ -137,13 +137,14 @@ function ChanMode_affect_mode_list(list_bit) {
tmp_nick = Users[this.tmplist[list_bit][add][z].toUpperCase()];
if (!tmp_nick)
tmp_nick = search_nickbuf(this.tmplist[list_bit][add][z]);
if (tmp_nick && (add=="true") &&
!this.chan.modelist[list_bit][tmp_nick.id]) {
if (tmp_nick && (add=="true") && !this.chan.modelist[list_bit][tmp_nick.id]) {
this.addmodes += MODE[list_bit].modechar;
this.addmodeargs += " " + tmp_nick.nick;
this.chan.modelist[list_bit][tmp_nick.id] = tmp_nick;
} else if (tmp_nick && (add=="false") &&
this.chan.modelist[list_bit][tmp_nick.id]) {
} else if (tmp_nick
&& (add=="false")
&& this.chan.modelist[list_bit][tmp_nick.id]
) {
this.delmodes += MODE[list_bit].modechar;
this.delmodeargs += " " + tmp_nick.nick;
delete this.chan.modelist[list_bit][tmp_nick.id];
......@@ -382,14 +383,24 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) {
// 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])) ) ) {
if ( (cm&CHANMODE_KEY)
&& (cmode.addbits&CHANMODE_KEY)
&& cmode.state_arg[cm]
&& chan.arg[cm]
&& !this.server
&& !this.parent
&& !bounce_modes
) {
this.numeric(467, format("%s :Channel key already set.", chan.nam));
} 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) {
......@@ -413,7 +424,13 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) {
// 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(367, format(
"%s %s %s %s",
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.");
}
......@@ -422,8 +439,10 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) {
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) {
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)) {
......@@ -437,8 +456,9 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) {
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()) {
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];
......@@ -559,8 +579,9 @@ function IRCClient_do_join(chan_name,join_key) {
+ " :Cannot join channel (+i: invite only)");
return 0;
}
if ((chan.mode&CHANMODE_LIMIT) && (true_array_len(chan.users)
>= chan.arg[CHANMODE_LIMIT]) ) {
if ( (chan.mode&CHANMODE_LIMIT)
&& (true_array_len(chan.users) >= chan.arg[CHANMODE_LIMIT])
) {
this.numeric("471", chan.nam
+ " :Cannot join channel (+l: channel is full)");
return 0;
......@@ -592,10 +613,13 @@ function IRCClient_do_join(chan_name,join_key) {
}
}
if (chan_name[0] != "&") {
this.bcast_to_servers_raw(":" + this.nick + " SJOIN "
+ chan.created + " " + chan.nam,BAHAMUT);
this.bcast_to_servers_raw(":" + this.nick + " JOIN "
+ chan.nam + " " + chan.created,DREAMFORGE);
this.bcast_to_servers_raw(
format(":%s SJOIN %s %s",
this.nick,
chan.created,
chan.nam
)
);
}
} else {
// create a new channel
......@@ -610,16 +634,16 @@ function IRCClient_do_join(chan_name,join_key) {
chan.modelist[CHANMODE_OP][this.id] = this;
}
if (chan_name[0] != "&") {
this.bcast_to_servers_raw(":" + servername + " SJOIN "
+ chan.created + " " + chan.nam + " "
+ chan.chanmode() + " :" + create_op + this.nick,BAHAMUT);
this.bcast_to_servers_raw(":" + this.nick + " JOIN "
+ chan.nam,DREAMFORGE);
if (create_op) {
server_bcast_to_servers(":" + servername + " MODE "
+ chan.nam + " +o " + this.nick + " "
+ chan.created,DREAMFORGE);
}
this.bcast_to_servers_raw(
format(":%s SJOIN %s %s %s :%s%s",
servername,
chan.created,
chan.nam,
chan.chanmode(),
create_op,
this.nick
)
);
}
}
if (this.invited.toUpperCase() == chan.nam.toUpperCase())
......
/*
ircd/config.js
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details:
https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
Anything that handles manipulating the IRCd configuration.
Copyright 2003-2021 Randy Sommerfeld <cyan@synchro.net>
*/
function parse_nline_flags(flags) {
var nline_flags = 0;
for(thisflag in flags) {
switch(flags[thisflag]) {
case "q":
nline_flags |= NLINE_CHECK_QWKPASSWD;
break;
case "w":
nline_flags |= NLINE_IS_QWKMASTER;
break;
case "k":
nline_flags |= NLINE_CHECK_WITH_QWKMASTER;
break;
default:
log(LOG_WARNING,"!WARNING Unknown N:Line flag '"
+ flags[thisflag] + "' in config.");
break;
}
}
return nline_flags;
}
function parse_oline_flags(flags) {
var oline_flags = 0;
for(thisflag in flags) {
switch(flags[thisflag]) {
case "r":
oline_flags |= OLINE_CAN_REHASH;
break;
case "R":
oline_flags |= OLINE_CAN_RESTART;
break;
case "D":
oline_flags |= OLINE_CAN_DIE;
break;
case "g":
oline_flags |= OLINE_CAN_GLOBOPS;
break;
case "w":
oline_flags |= OLINE_CAN_WALLOPS;
break;
case "l":
oline_flags |= OLINE_CAN_LOCOPS;
break;
case "c":
oline_flags |= OLINE_CAN_LSQUITCON;
break;
case "C":
oline_flags |= OLINE_CAN_GSQUITCON;
break;
case "k":
oline_flags |= OLINE_CAN_LKILL;
break;
case "K":
oline_flags |= OLINE_CAN_GKILL;
break;
case "b":
oline_flags |= OLINE_CAN_KLINE;
break;
case "B":
oline_flags |= OLINE_CAN_UNKLINE;
break;
case "n":
oline_flags |= OLINE_CAN_LGNOTICE;
break;
case "N":
oline_flags |= OLINE_CAN_GGNOTICE;
break;
case "u":
oline_flags |= OLINE_CAN_UMODEC;
break;
case "A":
oline_flags |= OLINE_IS_ADMIN;
break;
case "a":
case "f":
case "F":
break; // All reserved for future use.
case "s":
oline_flags |= OLINE_CAN_CHATOPS;
break;
case "S":
oline_flags |= OLINE_CHECK_SYSPASSWD;
break;
case "x":
case "X":
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;
oline_flags |= OLINE_CAN_CHATOPS;
case "o":
oline_flags |= OLINE_CAN_REHASH;
oline_flags |= OLINE_CAN_GLOBOPS;
oline_flags |= OLINE_CAN_WALLOPS;
oline_flags |= OLINE_CAN_LOCOPS;
oline_flags |= OLINE_CAN_LSQUITCON;
oline_flags |= OLINE_CAN_LKILL;
oline_flags |= OLINE_CAN_KLINE;
oline_flags |= OLINE_CAN_UNKLINE;
oline_flags |= OLINE_CAN_LGNOTICE;
oline_flags |= OLINE_CAN_UMODEC;
break;
default:
log(LOG_WARNING,"!WARNING Unknown O:Line flag '"
+ flags[thisflag] + "' in config.");
break;
}
}
return oline_flags;
}
function read_config_file() {
/* All of these variables are global. */
Admin1 = "";
Admin2 = "";
Admin3 = "";
CLines = new Array;
HLines = new Array;
ILines = new Array;
KLines = new Array;
NLines = new Array;
OLines = new Array;
PLines = new Array;
QLines = new Array;
ULines = new Array;
diepass = "";
restartpass = "";
YLines = new Array;
ZLines = new Array;
/* End of global variables */
var fname="";
if (config_filename && config_filename.length) {
if(config_filename.indexOf('/')>=0 || config_filename.indexOf('\\')>=0)
fname=config_filename;
else
fname=system.ctrl_dir + config_filename;
} else {
fname=system.ctrl_dir + "ircd." + system.local_host_name + ".conf";
if(!file_exists(fname))
fname=system.ctrl_dir + "ircd." + system.host_name + ".conf";
if(!file_exists(fname))
fname=system.ctrl_dir + "ircd.conf";
}
log(LOG_INFO,"Trying to read configuration from: " + fname);
var file_handle = new File(fname);
if (file_handle.open("r")) {
if (fname.substr(fname.length-3,3) == "ini")
read_ini_config(file_handle);
else
read_conf_config(file_handle);
file_handle.close();
} else {
log("Couldn't open configuration file! Proceeding with defaults.");
}
time_config_read = time();
scan_for_klined_clients();
YLines[0] = new YLine(120,600,1,5050000); // default irc class
}
function ini_sections() {
this.IRCdInfo = ini_IRCdInfo;
this.Port = ini_Port;
this.ConnectClass = ini_ConnectClass;
this.Allow = ini_Allow;
this.Operator = ini_Operator;
this.Services = ini_Services;
this.Ban = ini_Ban;
this.Restrict = ini_Restrict;
this.Hub = ini_Hub;
}
function ini_IRCdInfo(arg, ini) {
log("ircdinfo " + ini.Hostname);
servername=ini.Hostname;
serverdesc=ini.Info;
Admin1=ini.Admin1;
Admin2=ini.Admin2;
Admin3=ini.Admin3;
}
/* Former M:Line */
function ini_Port(arg, ini) {
mline_port = arg;
}
/* Former Y:Line */
function ini_ConnectClass(arg, ini) {
YLines[arg] = new YLine(
parseInt(ini.PingFrequency),
parseInt(ini.ConnectFrequency),
parseInt(ini.Maximum),
parseInt(ini.SendQ)
);
}
/* Former I:Line */
function ini_Allow(arg, ini) {
ILines[arg] = new ILine(
ini.Mask,
null, /* password */
ini.Mask, /* hostmask */
null, /* port */
0 /* irc class */
);
}
/* Former O:Line */
function ini_Operator(arg, ini) {
}
/* Former U:Line */
function ini_Services(arg, ini) {
}
/* Former K:Line & Z:Line */
function ini_Ban(arg, ini) {
}
function ini_Restrict(arg, ini) {
}
/* Former H:Line */
function ini_Hub(arg, ini) {
HLines.push(new HLine(
"*", /* servermask permitted */
arg /* servername */
));
}
function read_ini_config(conf) {
var ini = conf.iniGetAllObjects();
var split;
var section_name;
var section_arg;
var Sections = new ini_sections();
for each(var i in ini) {
split = i.name.split(":");
section_name = split[0];
section_arg = split[1];
if (typeof Sections[section_name] === 'function')
Sections[section_name](section_arg, i);
}
}
function read_conf_config(conf) {
function fancy_split(line) {
var ret = [];
var i;
var s = 0;
var inb = false;
var str;
for (i = 0; i < line.length; i++) {
if (line[i] == ':') {
if (inb)
continue;
if (i > 0 && line[i-1] == ']')
str = line.slice(s, i-1);
else
str = line.slice(s, i);
ret.push(str);
s = i + 1;
}
else if (!inb && line[i] == '[' && s == i) {
inb = true;
s = i + 1;
}
else if (line[i] == ']' && (i+1 == line.length || line[i+1] == ':')) {
inb = false;
}
}
if (s < line.length) {
if (i > 0 && line[i-1] == ']')
str = line.slice(s, i-1);
else
str = line.slice(s, i);
ret.push(str);
}
return ret;
}
while (!conf.eof) {
var conf_line = conf.readln();
if ((conf_line != null) && conf_line.match("[:]")) {
var arg = fancy_split(conf_line);
for(argument in arg) {
arg[argument]=arg[argument].replace(
/SYSTEM_HOST_NAME/g,system.host_name);
arg[argument]=arg[argument].replace(
/SYSTEM_NAME/g,system.name);
if (typeof system.qwk_id !== "undefined") {
arg[argument]=arg[argument].replace(
/SYSTEM_QWKID/g,system.qwk_id.toLowerCase()
);
}
arg[argument]=arg[argument].replace(
/VERSION_NOTICE/g,system.version_notice);
}
switch (conf_line[0].toUpperCase()) {
case "A":
if (!arg[3])
break;
Admin1 = arg[1];
Admin2 = arg[2];
Admin3 = arg[3];
break;
case "C":
if (!arg[5])
break;
CLines.push(new CLine(arg[1],arg[2],arg[3],arg[4],
parseInt(arg[5]) ));
break;
case "H":
if (!arg[3])
break;
HLines.push(new HLine(arg[1],arg[3]));
break;
case "I":
if (!arg[5])
break;
ILines.push(new ILine(arg[1],arg[2],arg[3],arg[4],
arg[5]));
break;
case "K":
if (!arg[2])
break;
var kline_mask = create_ban_mask(arg[1],true);
if (!kline_mask) {
log(LOG_WARNING,"!WARNING Invalid K:Line ("
+ arg[1] + ")");
break;
}
KLines.push(new KLine(kline_mask,arg[2],"K"));
break;
case "M":
if (!arg[3])
break;
servername = arg[1];
serverdesc = arg[3];
mline_port = parseInt(arg[4]);
break;
case "N":
if (!arg[5])
break;
NLines.push(new NLine(arg[1],arg[2],arg[3],
parse_nline_flags(arg[4]),arg[5]) );
break;
case "O":
if (!arg[5])
break;
OLines.push(new OLine(arg[1],arg[2],arg[3],
parse_oline_flags(arg[4]),parseInt(arg[5]) ));
break;
case "P":
PLines.push(parseInt(arg[4]));
break;
case "Q":
if (!arg[3])
break;
QLines.push(new QLine(arg[3],arg[2]));
break;
case "U":
if (!arg[1])
break;
ULines.push(arg[1]);
break;
case "X":
diepass = arg[1];
restartpass = arg[2];
break;
case "Y":
if (!arg[5])
break;
YLines[parseInt(arg[1])] = new YLine(parseInt(arg[2]),
parseInt(arg[3]),parseInt(arg[4]),parseInt(arg[5]));
break;
case "Z":
if (!arg[2])
break;
ZLines.push(new ZLine(arg[1],arg[2]));
break;
case "#":
case ";":
default:
break;
}
}
}
}
This diff is collapsed.
// $Id: ircd_server.js,v 1.60 2020/04/03 22:21:51 deuce Exp $
//
// ircd_channel.js
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details:
// http://www.gnu.org/licenses/gpl.txt
//
// Synchronet IRC Daemon as per RFC 1459, link compatible with Bahamut 1.4
//
// Copyright 2003-2009 Randolph Erwin Sommerfeld <sysop@rrx.ca>
//
// ** Server to server operation is governed here.
//
////////// Constants / Defines //////////
const SERVER_REVISION = "$Revision: 1.60 $".split(' ')[1];
/*
ircd/server.js
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details:
https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
IRCd inter-server communication.
Copyright 2003-2021 Randy Sommerfeld <cyan@synchro.net>
*/
// Various N:Line permission bits
const NLINE_CHECK_QWKPASSWD =(1<<0); // q
const NLINE_IS_QWKMASTER =(1<<1); // w
const NLINE_CHECK_WITH_QWKMASTER =(1<<2); // k
const NLINE_IS_DREAMFORGE =(1<<3); // d
////////// Objects //////////
function IRC_Server() {
......@@ -53,7 +48,6 @@ function IRC_Server() {
this.outgoing = false;
// Variables (consts, really) that point to various state information
this.socket = "";
this.type = BAHAMUT; /* Assume bahamut by default */
////////// FUNCTIONS
// Functions we use to control clients (specific)
this.quit = Server_Quit;
......@@ -380,16 +374,6 @@ function Server_Work(cmdline) {
chan.created = cmd2_int;
}
cmd.shift();
} else if ( (cmdend_int == cmd[cmdend])
&& (this.type == DREAMFORGE) ) {
/* DreamForge style TS */
if (cmdend_int > chan.created) {
break;
} else if ((cmdend_int < chan.created) && ThisOrigin.server) {
bounce_modes = true;
chan.created = cmdend_int;
}
cmd.pop(); /* Strip the TS. */
}
cmd.shift();
cmd.shift();
......@@ -409,11 +393,13 @@ function Server_Work(cmdline) {
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 + "]");
umode_notice(USERMODE_STATS_LINKS,"StatsLinks",format(
"MOTD requested by %s (%s@%s) [%s]",
ThisOrigin.nick,
ThisOrigin.uprefix,
ThisOrigin.hostname,
ThisOrigin.servername
));
ThisOrigin.motd();
} else {
var dest_server = searchbyserver(cmd[1]);
......@@ -432,8 +418,9 @@ function Server_Work(cmdline) {
gnotice("Server " + this.nick + " trying to introduce nick " + collide.nick
+ " twice?! Ignoring.");
break;
} else if ((parseInt(collide.created) >
parseInt(cmd[3])) && this.hub) {
} 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.");
......@@ -454,8 +441,6 @@ function Server_Work(cmdline) {
}
}
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]
......@@ -479,36 +464,22 @@ function Server_Work(cmdline) {
break;
}
}
if (cmd[uprefixptr+1][0] == ".") /* CR "hidden mask" fix. */
cmd[uprefixptr+1] = cmd[uprefixptr+1].slice(1);
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];
/* What the hell. CR reverses these at random. */
if (parseInt(cmd[2]) > 100) {
NewNick.created = cmd[2];
NewNick.hops = cmd[3];
} else {
NewNick.hops = cmd[2];
NewNick.created = cmd[3];
}
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]);
NewNick.ip = int_to_ip(cmd[9]);
NewNick.setusermode(cmd[4]);
for (u in ULines) {
if (ULines[u] == cmd[uprefixptr+2]) {
NewNick.uline = true;
......@@ -516,26 +487,28 @@ function Server_Work(cmdline) {
}
}
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 "
+ ip_to_int(NewNick.ip)
+ " :" + 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);
this.bcast_to_servers_raw(
format("NICK %s %s %s %s %s %s %s 0 %s :%s",
NewNick.nick,
true_hops,
NewNick.created,
NewNick.get_usermode(true),
NewNick.uprefix,
NewNick.hostname,
NewNick.servername,
ip_to_int(NewNick.ip),
NewNick.realname
)
);
umode_notice(USERMODE_DEBUG,"RemoteClient",format(
"NICK %s %s@%s %s %s :%s",
NewNick.nick,
NewNick.uprefix,
NewNick.hostname,
NewNick.servername,
NewNick.ip,
NewNick.realname
));
} else { // we're a user changing our nick.
var ctuc = cmd[1].toUpperCase();
if ((Users[ctuc])&&Users[ctuc].nick.toUpperCase() !=
......@@ -606,14 +579,14 @@ function Server_Work(cmdline) {
var dest_server = searchbyserver(cmd[4]);
if (!dest_server) {
break;
} else if ((dest_server == -1) &&
(this.flags&NLINE_IS_QWKMASTER)) {
} 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) {
if (Unregistered[ur].nick == hunt) {
my_server = Unregistered[ur];
break;
}
......@@ -765,8 +738,9 @@ function Server_Work(cmdline) {
var my_modechar = cmd[3][tmpmc];
if (my_modechar == "+")
continue;
if ((my_modechar == "k") ||
(my_modechar == "l")) {
if ( (my_modechar == "k")
|| (my_modechar == "l")
) {
tmp_modeargs++;
incoming_modes[my_modechar] = cmd[tmp_modeargs];
} else {
......@@ -788,7 +762,7 @@ function Server_Work(cmdline) {
/* 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(' ');
......@@ -798,7 +772,7 @@ function Server_Work(cmdline) {
break;
}
cm_array = new Array; /* True array */
cm_array = [];
for (cm in chan_members) {
var isop = false;
......@@ -860,8 +834,6 @@ function Server_Work(cmdline) {
chan.users[member_obj.id] = member_obj;
var joinstr = "JOIN " + chan.nam;
member_obj.bcast_to_channel(chan, joinstr, false);
member_obj.bcast_to_servers_raw(":" + member_obj.nick
+ " " + joinstr, DREAMFORGE);
if (chan.created >= parseInt(cmd[1])) {
if (is_op) {
chan.modelist[CHANMODE_OP][member_obj.id]=member_obj.id;
......@@ -874,7 +846,6 @@ function Server_Work(cmdline) {
var mode1str = "MODE " + chan.nam + " "
+ push_sync_modes + push_sync_args;
this.bcast_to_channel(chan,mode1str);
this.bcast_to_servers(mode1str,DREAMFORGE);
push_sync_modes = "+";
push_sync_args = "";
num_sync_modes = 0;
......@@ -890,7 +861,6 @@ function Server_Work(cmdline) {
var mode2str = "MODE " + chan.nam + " "
+ push_sync_modes + push_sync_args;
this.bcast_to_channel(chan,mode2str);
this.bcast_to_servers(mode2str,DREAMFORGE);
push_sync_modes = "+";
push_sync_args = "";
num_sync_modes = 0;
......@@ -902,19 +872,21 @@ function Server_Work(cmdline) {
var mode3str = "MODE " + chan.nam + " "
+ push_sync_modes + push_sync_args;
this.bcast_to_channel(chan, mode3str);
this.bcast_to_servers(mode3str,DREAMFORGE);
}
// 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,BAHAMUT)
this.bcast_to_servers_raw(
format(":%s SJOIN %s %s %s :%s",
ThisOrigin.nick,
chan.created,
chan.nam,
chan.chanmode(true),
new_chan_members
)
);
} else {
if (ThisOrigin.server) {
umode_notice(USERMODE_OPER,"Notice", "Server " + ThisOrigin.nick
......@@ -926,8 +898,13 @@ function Server_Work(cmdline) {
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);
this.bcast_to_servers_raw(
format(":%s SJOIN %s %s",
ThisOrigin.nick,
chan.created,
chan.nam
)
);
}
break;
case "SQUIT":
......@@ -1111,17 +1088,17 @@ function Server_Work(cmdline) {
var akill_reason = IRC_string(cmdline,8);
var snd_prefix = ":" + ThisOrigin.nick + " ";
/* Propagate this to the network */
this.bcast_to_servers_raw(snd_prefix + cmdline,DREAMFORGE);
this.bcast_to_servers_raw(snd_prefix + "AKILL "
+ cmd[4] + " " /* host */
+ cmd[3] + " " /* user */
+ (cmd[7]-cmd[6]) + " " /* length */
+ cmd[5] + " " /* akiller */
+ ":" + akill_reason /* reason */
,BAHAMUT);
this.bcast_to_servers_raw(
format(":%s AKILL %s %s %s %s :%s",
ThisOrigin.nick,
cmd[4], /* host */
cmd[3], /* user */
(cmd[7]-cmd[6]), /* length */
cmd[5], /* akiller */
akill_reason /* reason */
)
);
var this_uh = cmd[3] + "@" + cmd[4];
if (isklined(this_uh))
......@@ -1134,10 +1111,6 @@ function Server_Work(cmdline) {
case "CAPAB":
case "BURST":
case "SVSMODE":
case "NETINFO": /* Dreamforge/Unreal/CR */
case "SMO": /* Dreamforge/Unreal/CR -- Send Usermode */
case "EOS": /* Dreamforge/Unreal/CR -- End Of Synch */
case "TUNL": /* Dreamforge/Unreal/CR */
case "SETHOST": /* We do not honour SETHOST. */
break; // Silently ignore for now.
default:
......@@ -1164,18 +1137,16 @@ function server_bcast_to_servers(str,type) {
}
}
function IRCClient_bcast_to_servers(str,type) {
function IRCClient_bcast_to_servers(str) {
for(thisClient in Local_Servers) {
var srv = Local_Servers[thisClient];
if ( (srv.nick != this.parent) && (!type || (srv.type == type)))
if (Local_Servers[thisClient].nick != this.parent)
Local_Servers[thisClient].originatorout(str,this);
}
}
function IRCClient_bcast_to_servers_raw(str,type) {
function IRCClient_bcast_to_servers_raw(str) {
for(thisClient in Local_Servers) {
var srv = Local_Servers[thisClient];
if ( (srv.nick != this.parent) && (!type || (srv.type == type)))
if (Local_Servers[thisClient].nick != this.parent)
Local_Servers[thisClient].rawout(str);
}
}
......@@ -1186,8 +1157,6 @@ function Server_Quit(str,suppress_bcast,is_netsplit,origin) {
if (is_netsplit) {
this.netsplit(str);
/* Fix for DreamForge's lack of NOQUIT */
this.bcast_to_servers_raw("SQUIT " + this.nick + " :" + str,DREAMFORGE);
} else if (this.local) {
this.netsplit(servername + " " + this.nick);
if (!suppress_bcast)
......@@ -1267,22 +1236,26 @@ function IRCClient_server_info(sni_server) {
}
function IRCClient_server_nick_info(sni_client) {
var actual_hops = parseInt(sni_client.hops) + 1;
var sendstr = "NICK " + sni_client.nick + " " + actual_hops + " " + sni_client.created + " ";
if (this.type == BAHAMUT)
sendstr += sni_client.get_usermode(true) + " ";
sendstr += sni_client.uprefix + " " + sni_client.hostname + " " + sni_client.servername + " 0 ";
if (this.type == BAHAMUT)
sendstr += ip_to_int(sni_client.ip) + " ";
sendstr += ":" + sni_client.realname;
this.rawout(sendstr);
if (this.type == DREAMFORGE)
this.rawout(":" + sni_client.nick + " MODE " + sni_client.nick + " :" + sni_client.get_usermode(true));
if (sni_client.away)
this.rawout(":" + sni_client.nick + " AWAY :" + sni_client.away);
this.rawout(
format("NICK %s %s %s %s %s %s %s 0 %s :%s",
sni_client.nick,
parseInt(sni_client.hops) + 1,
sni_client.created,
sni_client.get_usermode(true),
sni_client.uprefix,
sni_client.hostname,
sni_client.servername,
ip_to_int(sni_client.ip),
sni_client.realname
)
);
if (sni_client.away) {
this.rawout(format(":%s AWAY :%s",
sni_client.nick,
sni_client.away
));
}
}
function IRCClient_reintroduce_nick(nick) {
......@@ -1290,55 +1263,40 @@ function IRCClient_reintroduce_nick(nick) {
for (uchan in nick.channels) {
var chan = nick.channels[uchan];
if (this.type == DREAMFORGE) {
this.rawout(":" + nick.nick + " JOIN " + chan.nam);
if (chan.modelist[CHANMODE_OP][nick.id])
this.ircout("MODE " + chan.nam + " +o " + nick.nick + " " + chan.created);
if (chan.modelist[CHANMODE_VOICE][nick.id])
this.ircout("MODE " + chan.nam + " +v " + nick.nick + " " + chan.created);
} else { /* Bahamut */
var cmodes = "";
if (chan.modelist[CHANMODE_OP][nick.id])
cmodes += "@";
if (chan.modelist[CHANMODE_VOICE][nick.id])
cmodes += "+";
this.rawout("SJOIN " + chan.created + " " + chan.nam + " " + chan.chanmode(true)
+ " :" + cmodes + nick.nick);
var cmodes = "";
if (chan.modelist[CHANMODE_OP][nick.id])
cmodes += "@";
if (chan.modelist[CHANMODE_VOICE][nick.id])
cmodes += "+";
this.rawout(
format("SJOIN %s %s %s :%s%s",
chan.created,
chan.nam,
chan.chanmode(true),
cmodes,
nick.nick
)
);
if (chan.topic) {
this.rawout(
format("TOPIC %s %s %s :%s",
chan.nam,
chan.topicchangedby,
chan.topictime,
chan.topic
)
);
}
if (chan.topic)
this.rawout("TOPIC " + chan.nam + " " + chan.topicchangedby + " " + chan.topictime
+ " :" + chan.topic);
}
}
function IRCClient_server_chan_info(sni_chan) {
if (this.type == DREAMFORGE) {
var df_chan_occs = sni_chan.occupants().split(' ');
for (dfocc in df_chan_occs) {
var cmember = df_chan_occs[dfocc];
var mem_is_op = false;
var mem_is_voice = false;
if (cmember[0] == "@") {
cmember = cmember.slice(1);
mem_is_op = true;
}
if (cmember[0] == "+") {
cmember = cmember.slice(1);
mem_is_voice = true;
}
this.rawout(":" + cmember + " JOIN " + sni_chan.nam);
if (mem_is_op)
this.ircout("MODE " + sni_chan.nam + " +o " + cmember + " "
+ sni_chan.created);
if (mem_is_voice)
this.ircout("MODE " + sni_chan.nam + " +v " + cmember + " "
+ sni_chan.created);
}
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(format("SJOIN %s %s %s :%s",
sni_chan.created,
sni_chan.nam,
sni_chan.chanmode(true),
sni_chan.occupants()
));
var modecounter=0;
var modestr="+";
var modeargs="";
......@@ -1349,20 +1307,22 @@ function IRCClient_server_chan_info(sni_chan) {
modeargs += " ";
modeargs += sni_chan.modelist[CHANMODE_BAN][aBan];
if (modecounter >= max_modes) {
var outstr = "MODE " + sni_chan.nam + " " + modestr + " " + modeargs;
if (this.type == DREAMFORGE)
outstr += " " + sni_chan.created;
this.ircout(outstr);
this.ircout(format("MODE %s %s %s",
sni_chan.nam,
modestr,
modeargs
));
modecounter=0;
modestr="+";
modeargs="";
}
}
if (modeargs) {
var outstr = "MODE " + sni_chan.nam + " " + modestr + " " + modeargs;
if (this.type == DREAMFORGE)
outstr += " " + sni_chan.created;
this.ircout(outstr);
this.ircout(format("MODE %s %s %s",
sni_chan.nam,
modestr,
modeargs
));
}
}
......
// $Id: ircd_unreg.js,v 1.53 2020/04/04 03:34:03 deuce Exp $
//
// ircd_unreg.js
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details:
// http://www.gnu.org/licenses/gpl.txt
//
// Synchronet IRC Daemon as per RFC 1459, link compatible with Bahamut 1.4
//
// Copyright 2003-2010 Randolph Erwin Sommerfeld <sysop@rrx.ca>
//
// ** Handle unregistered clients.
//
/*
const UNREG_REVISION = "$Revision: 1.53 $".split(' ')[1];
ircd/unregistered.js
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details:
https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
How unregistered clients are handled in the IRCd.
Copyright 2003-2021 Randy Sommerfeld <cyan@synchro.net>
*/
////////// Objects //////////
function Unregistered_Client(id,socket) {
////////// VARIABLES
// Bools/Flags that change depending on connection state.
this.pinged = false; // Sent PING?
this.local = true; // FIXME: this is redundant.
this.criteria_met = false; // Have we met registration criteria?
this.pinged = false; // Sent PING?
this.local = true; // FIXME: this is redundant.
this.criteria_met = false; // Have we met registration criteria?
// Variables containing user/server information as we receive it.
this.id = id;
this.nick = "*";
......@@ -48,7 +45,6 @@ function Unregistered_Client(id,socket) {
////////// FUNCTIONS
// Functions we use to control clients (specific)
this.work = Unregistered_Commands;
// this.JSON_Unregistered_Commands = JSON_Unregistered_Commands;
this.IRC_Unregistered_Commands = IRC_Unregistered_Commands;
this.quit = Unregistered_Quit;
this.check_timeout = IRCClient_check_timeout;
......@@ -73,13 +69,17 @@ function Unregistered_Client(id,socket) {
Local_Sockets[id] = socket.descriptor;
Local_Sockets_Map[id] = this;
rebuild_socksel_array = true;
log(format("%04u",socket.descriptor)
+ " Accepted new connection: " + this.ip
+ " port " + socket.remote_port);
if ((this.ip.slice(0,4) == "127.") ||
(this.ip.slice(0,3) == "10.") ||
(this.ip.slice(0,8) == "192.168.") ||
(this.ip.slice(0,7) == "172.16." )) {
log(format("%04u Accepted new connection: %s port %s",
socket.descriptor,
this.ip,
socket.remote_port
));
if ( (this.ip.slice(0,4) == "127.")
|| (this.ip.slice(0,3) == "10.")
|| (this.ip.slice(0,8) == "192.168.")
|| (this.ip.slice(0,7) == "100.64.")
|| (this.ip.slice(0,7) == "172.16." )
) {
this.hostname = servername;
this.pending_resolve_time = false;
} else {
......@@ -99,7 +99,7 @@ function Unregistered_Commands(cmdline) {
cmdline = cmdline.slice(1);
if (debug)
log(LOG_DEBUG,"[UNREG]: " + cmdline);
log("[UNREG]: " + cmdline);
this.IRC_Unregistered_Commands(cmdline);
}
......@@ -128,7 +128,7 @@ function IRC_Unregistered_Commands(cmdline) {
return 0;
var legal_command = true; /* For tracking STATS M */
switch(command) {
case "PING":
if (!cmd[1]) {
......@@ -137,6 +137,7 @@ function IRC_Unregistered_Commands(cmdline) {
}
this.rawout("PONG " + servername + " :" + IRC_string(cmdline,1));
break;
case "CAP":
case "CAPAB":
break; // Silently ignore, for now.
case "NICK":
......@@ -166,23 +167,25 @@ function IRC_Unregistered_Commands(cmdline) {
break;
}
if (Servers[cmd[1].toLowerCase()]) {
if (parseInt(cmd[2]) < 2)
if (parseInt(cmd[2]) < 2)
this.quit("Server already exists.");
return 0;
}
var this_nline = 0;
var qwk_slave = false;
var qwkid = cmd[1].slice(0,cmd[1].indexOf(".")).toUpperCase();
if (parseInt(cmd[2]) < 2) {
if (parseInt(cmd[2]) < 2) {
for (nl in NLines) {
if ((NLines[nl].flags&NLINE_CHECK_QWKPASSWD) &&
wildmatch(cmd[1],NLines[nl].servername)) {
if ( (NLines[nl].flags&NLINE_CHECK_QWKPASSWD)
&& wildmatch(cmd[1],NLines[nl].servername)
) {
if (check_qwk_passwd(qwkid,this.password)) {
this_nline = NLines[nl];
break;
}
} else if ((NLines[nl].flags&NLINE_CHECK_WITH_QWKMASTER) &&
wildmatch(cmd[1],NLines[nl].servername)) {
} else if ( (NLines[nl].flags&NLINE_CHECK_WITH_QWKMASTER)
&& wildmatch(cmd[1],NLines[nl].servername)
) {
for (qwkm_nl in NLines) {
if (NLines[qwkm_nl].flags&NLINE_IS_QWKMASTER) {
var qwk_master = searchbyserver(NLines[qwkm_nl].servername);
......@@ -190,24 +193,33 @@ function IRC_Unregistered_Commands(cmdline) {
this.quit("No QWK master available for authorization.");
return 0;
} else {
qwk_master.rawout(":" + servername + " PASS " + this.password + " :" + qwkid + " QWK");
qwk_master.rawout(format(
":%s PASS %s :%s QWK",
servername,
this.password,
qwkid
));
qwk_slave = true;
}
}
}
} else if ((NLines[nl].password == this.password) &&
(wildmatch(cmd[1],NLines[nl].servername))
) {
this_nline = NLines[nl];
break;
} else if ( (NLines[nl].password == this.password)
&& (wildmatch(cmd[1],NLines[nl].servername))
) {
this_nline = NLines[nl];
break;
}
}
}
if ( (!this_nline ||
( (this_nline.password == "*") && !this.outgoing
&& !(this_nline.flags&NLINE_CHECK_QWKPASSWD) )
) && !qwk_slave) {
if (parseInt(cmd[2]) < 2)
if ( !qwk_slave
&& ( !this_nline
|| ( (this_nline.password == "*")
&& !this.outgoing
&& !(this_nline.flags&NLINE_CHECK_QWKPASSWD)
)
)
) {
if (parseInt(cmd[2]) < 2)
this.quit("UR Server not configured.");
return 0;
}
......@@ -247,8 +259,6 @@ function IRC_Unregistered_Commands(cmdline) {
}
}
}
if (this_nline.flags&NLINE_IS_DREAMFORGE)
new_server.type = DREAMFORGE;
new_server.finalize_server_connect("TS",this.sendps);
this.replaced_with = new_server;
break;
......@@ -357,13 +367,9 @@ function Unregistered_Welcome() {
var my_iline;
// FIXME: We don't compare connecting port.
for(thisILine in ILines) {
if ((wildmatch(this.uprefix + "@" +
this.ip,
ILines[thisILine].ipmask)) &&
(wildmatch(this.uprefix + "@" +
this.hostname,
ILines[thisILine].hostmask))
) {
if ( (wildmatch(this.uprefix + "@" + this.ip, ILines[thisILine].ipmask))
&& (wildmatch(this.uprefix + "@" + this.hostname, ILines[thisILine].hostmask))
) {
my_iline = ILines[thisILine];
break;
}
......@@ -425,9 +431,18 @@ function Unregistered_Welcome() {
if (server.client_update != undefined)
server.client_update(this.socket, this.nick, this.hostname);
var nickstr = "NICK " + this.nick + " 1 " + new_user.created + " ";
server_bcast_to_servers(nickstr + "+ " + this.uprefix + " " + this.hostname + " " + servername + " 0 " + ip_to_int(new_user.ip) + " :" + this.realname,BAHAMUT);