Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Main
Synchronet
Compare Revisions
b6fe381f0ee21b9eac16cb872878d5d534b9e82e...2c5aa02fff48137df1de117ea23f0ba6fbde4aaa
Commits (2)
IRCd 1.9b
· c04a8dcd
Randy Sommerfeld
authored
May 22, 2021
c04a8dcd
Merge branch 'master' into 'master'
· 2c5aa02f
Rob Swindell
authored
May 22, 2021
IRCd 1.9b See merge request
main/sbbs!126
2c5aa02f
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
3514 additions
and
2917 deletions
+3514
-2917
exec/ircd.js
exec/ircd.js
+96
-266
exec/load/ircd/channel.js
exec/load/ircd/channel.js
+151
-152
exec/load/ircd/config.js
exec/load/ircd/config.js
+73
-67
exec/load/ircd/core.js
exec/load/ircd/core.js
+966
-520
exec/load/ircd/server.js
exec/load/ircd/server.js
+949
-811
exec/load/ircd/unregistered.js
exec/load/ircd/unregistered.js
+287
-246
exec/load/ircd/user.js
exec/load/ircd/user.js
+826
-817
exec/load/irclib.js
exec/load/irclib.js
+158
-32
text/ircmotd.txt
text/ircmotd.txt
+8
-6
No files found.
exec/ircd.js
View file @
2c5aa02f
...
...
@@ -26,6 +26,7 @@ load("sbbsdefs.js");
load
(
"
sockdefs.js
"
);
load
(
"
nodedefs.js
"
);
load
(
"
irclib.js
"
);
load
(
"
dns.js
"
);
/* Libraries specific to the IRCd */
load
(
"
ircd/core.js
"
);
...
...
@@ -35,293 +36,122 @@ load("ircd/channel.js");
load
(
"
ircd/server.js
"
);
load
(
"
ircd/config.js
"
);
/* Global Constants */
const
VERSION
=
"
SynchronetIRCd-1.9a
"
;
/*** Global Constants - Always in ALL_UPPERCASE ***/
const
VERSION
=
"
SynchronetIRCd-1.9b
"
;
const
VERSION_STR
=
format
(
"
Synchronet %s%s-%s%s (IRCd by Randy Sommerfeld)
"
,
system
.
version
,
system
.
revision
,
system
.
platform
,
system
.
beta_version
);
/* This will be replaced with a dynamic CAPAB system later. */
const
Server_CAPAB
=
"
TS3 NOQUIT SSJOIN BURST UNCONNECT NICKIP TSMODE
"
;
// The number of seconds to block before giving up on outbound CONNECT
// attempts (when connecting to another IRC server -- i.e. a hub) This value
// is important because connecing is a BLOCKING operation, so your IRC *will*
// freeze for the amount of time it takes to connect.
const
ob_sock_timeout
=
3
;
// Should we enable the USERS and SUMMON commands? These allow IRC users to
// view users on the local BBS and summon them to IRC via a Synchronet telegram
// message respectively. Some people might be running the ircd standalone, or
// otherwise don't want anonymous IRC users to have access to these commands.
// We enable this by default because there's typically nothing wrong with
// seeing who's on an arbitrary BBS or summoning them to IRC.
const
enable_users_summon
=
true
;
// EVERY server on the network MUST have the same values in ALL of these
// categories. If you change these, you WILL NOT be able to link to the
// Synchronet IRC network. Linking servers with different values here WILL
// cause your network to desynchronize (and possibly crash the IRCD)
// Remember, this is Synchronet, not Desynchronet ;)
const
max_chanlen
=
100
;
// Maximum channel name length.
const
max_nicklen
=
30
;
// Maximum nickname length.
const
max_modes
=
6
;
// Maximum modes on single MODE command
const
max_user_chans
=
100
;
// Maximum channels users can join
const
max_bans
=
25
;
// Maximum bans (+b) per channel
const
max_topiclen
=
307
;
// Maximum length of topic per channel
const
max_kicklen
=
307
;
// Maximum length of kick reasons
const
max_who
=
100
;
// Maximum replies to WHO for non-oper users
const
max_silence
=
10
;
// Maximum entries on a user's SILENCE list
const
server_uptime
=
time
();
/* This will be replaced with a dynamic CAPAB system */
const
SERVER_CAPAB
=
"
TS3 NOQUIT SSJOIN BURST UNCONNECT NICKIP TSMODE
"
;
/* This will be in the configuration for 2.0 */
const
SUMMON
=
true
;
/* Need to detect when a server doesn't line up with these on the network. */
const
MAX_CHANLEN
=
100
;
/* Maximum channel name length. */
const
MAX_NICKLEN
=
30
;
/* Maximum nickname length. */
const
MAX_MODES
=
6
;
/* Maximum modes on single MODE command */
const
MAX_USER_CHANS
=
100
;
/* Maximum channels users can join */
const
MAX_BANS
=
25
;
/* Maximum bans (+b) per channel */
const
MAX_TOPICLEN
=
307
;
/* Maximum length of topic per channel */
const
MAX_KICKLEN
=
307
;
/* Maximum length of kick reasons */
const
MAX_WHO
=
100
;
/* Maximum replies to WHO for non-oper users */
const
MAX_SILENCE
=
10
;
/* Maximum entries on a user's SILENCE list */
const
MAX_WHOWAS
=
1000
;
/* Size of the WHOWAS buffer */
const
MAX_NICKHISTORY
=
1000
;
/* Size of the nick change history buffer */
const
MAX_CLIENT_RECVQ
=
2560
;
/* Maximum size of unregistered & user recvq */
const
MAX_AWAYLEN
=
80
;
/* Maximum away message length */
const
MAX_USERHOST
=
6
;
/* Maximum arguments to USERHOST command */
const
MAX_REALNAME
=
50
;
/* Maximum length of users real name field */
const
SERVER_UPTIME
=
system
.
timer
;
const
SERVER_UPTIME_STRF
=
strftime
(
"
%a %b %d %Y at %H:%M:%S %Z
"
,
time
());
/*** Global Objects, Arrays and Variables - Always in Mixed_Case ***/
/* Global Objects */
var
DNS_Resolver
=
new
DNS
();
/* Every object (unregistered, server, user) is tagged with a unique ID */
var
Assigned_IDs
=
{};
/* Key: Numeric ID */
var
Unregistered
=
{};
/* Key: Numeric ID */
var
Users
=
{};
/* Key: .toUpperCase() nick */
var
Servers
=
{};
/* Key: .toLowerCase() nick */
var
Channels
=
{};
/* Key: .toUpperCase() channel name, including prefix */
var
Local_Users
=
{};
var
Local_Servers
=
{};
var
WhoWas
=
{};
/* Stores uppercase nicks */
var
WhoWasMap
=
[];
/* An array pointing to WhoWas object entries */
var
NickHistory
=
[];
/* Nick change tracking */
var
Profile
=
{};
/* CPU profiling */
/* Global Variables */
var
Default_Port
=
6667
;
// This will dump all I/O to and from the server to your Synchronet console.
// It also enables some more verbose WALLOPS, especially as they pertain to
// blocking functions.
// The special "DEBUG" oper command also switches this value.
var
debug
=
false
;
var
default_port
=
6667
;
/* This was previously on its own in the functions
Maybe there was a reason why? */
var
time_config_read
;
/* Primary arrays */
var
Unregistered
=
new
Object
;
var
Users
=
new
Object
;
var
Servers
=
new
Object
;
var
Channels
=
new
Object
;
var
Local_Sockets
=
new
Object
;
var
Local_Sockets_Map
=
new
Object
;
var
Selectable_Sockets
=
new
Object
;
var
Selectable_Sockets_Map
=
new
Object
;
/* Highest Connection Count tracking */
var
hcc_total
=
0
;
var
hcc_users
=
0
;
var
hcc_counter
=
0
;
var
WhoWas
=
new
Object
;
/* Stores uppercase nicks */
var
WhoWasMap
=
new
Array
;
/* A true push/pop array pointing to WhoWas entries */
var
WhoWas_Buffer
=
1000
;
/* Maximum number of WhoWas entries to keep track of */
var
NickHistory
=
new
Array
;
/* A true array using push and pop */
var
NickHistorySize
=
1000
;
/* Keep track of commands and how long they take to execute. */
var
Profile
=
new
Object
;
/* This is where our unique ID for each client comes from for unreg'd clients. */
var
next_client_id
=
0
;
// An array containing all the objects containing local sockets that we need
// to poll.
var
Local_Users
=
new
Object
;
var
Local_Servers
=
new
Object
;
var
rebuild_socksel_array
=
true
;
var
network_debug
=
false
;
var
last_recvq_check
=
0
;
var
servername
=
"
server.invalid
"
;
var
serverdesc
=
"
No description provided.
"
;
log
(
VERSION
+
"
started.
"
);
// Parse command-line arguments.
var
config_filename
=
""
;
var
cmdline_port
;
var
cmdarg
;
for
(
cmdarg
=
0
;
cmdarg
<
argc
;
cmdarg
++
)
{
switch
(
argv
[
cmdarg
].
toLowerCase
())
{
case
"
-f
"
:
config_filename
=
argv
[
++
cmdarg
];
break
;
case
"
-p
"
:
cmdline_port
=
parseInt
(
argv
[
++
cmdarg
]);
break
;
case
"
-d
"
:
debug
=
true
;
break
;
case
"
-a
"
:
cmdline_addr
=
argv
[
++
cmdarg
].
split
(
'
,
'
);
break
;
}
}
var
Time_Config_Read
;
/* Stores time() of when the config was last read */
/* Temporary hack to make JSexec testing code not complain */
var
mline_port
;
/* Will this server try to enforce good network behaviour? */
/* Setting to "true" results in bouncing bad modes, KILLing bogus NICKs, etc. */
var
Enforcement
=
true
;
read_config_file
();
/* Highest Connection Count ("HCC") tracking */
var
HCC_Total
=
0
;
var
HCC_Users
=
0
;
var
HCC_Counter
=
0
;
/* This tests if we're running from JSexec or not */
if
(
this
.
server
==
undefined
)
{
if
(
!
jsexec_revision_detail
)
var
jsexec_revision_detail
=
"
JSexec
"
;
var
ServerName
;
var
ServerDesc
=
""
;
if
(
cmdline_port
)
default_port
=
cmdline_port
;
else
if
(
typeof
mline_port
!==
undefined
)
default_port
=
mline_port
;
/* Runtime configuration */
var
Config_Filename
=
""
;
var
server
=
{
socket
:
false
,
terminated
:
false
,
version_detail
:
jsexec_revision_detail
,
interface_ip_addr_list
:
[
"
0.0.0.0
"
,
"
::
"
]
};
var
Restart_Password
;
var
Die_Password
;
server
.
socket
=
create_new_socket
(
default_port
)
var
Admin1
;
var
Admin2
;
var
Admin3
;
if
(
!
server
.
socket
)
exit
();
}
var
CLines
=
[];
/* Server [C]onnect lines */
var
NLines
=
[];
/* Server inbound connect lines */
var
HLines
=
[];
/* Hubs */
var
ILines
=
[];
/* IRC Classes */
var
KLines
=
[];
/* user@hostname based bans */
var
OLines
=
[];
/* IRC Operators */
var
PLines
=
[];
/* Ports for the IRCd to listen to */
var
QLines
=
[];
/* [Q]uarantined (reserved) nicknames */
var
ULines
=
[];
/* Servers allowed to send unchecked MODE amongst other things */
var
YLines
=
[];
/* Defines what user & server objects get what settings */
var
ZLines
=
[];
/* IP based bans */
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
var
open_plines
=
new
Array
();
/* True Array */
// Make our 'server' object the first open P:Line
open_plines
[
0
]
=
server
.
socket
;
for
(
pl
in
PLines
)
{
var
new_pl_sock
=
create_new_socket
(
PLines
[
pl
]);
if
(
new_pl_sock
)
{
new_pl_sock
.
nonblocking
=
true
;
new_pl_sock
.
debug
=
false
;
open_plines
.
push
(
new_pl_sock
);
}
}
/** Begin executing code **/
js
.
branch_limit
=
0
;
// we're not an infinite loop.
js
.
auto_terminate
=
false
;
// we handle our own termination requests
/*** Main Loop ***/
while
(
!
js
.
terminated
)
{
if
(
file_date
(
system
.
ctrl_dir
+
"
ircd.rehash
"
)
>
time_config_read
)
read_config_file
();
/* Setup a new socket if a connection is accepted. */
for
(
pl
in
open_plines
)
{
if
(
open_plines
[
pl
].
poll
())
{
var
client_sock
=
open_plines
[
pl
].
accept
();
log
(
LOG_DEBUG
,
"
Accepting new connection on port
"
+
client_sock
.
local_port
);
if
(
client_sock
)
{
client_sock
.
nonblocking
=
true
;
switch
(
client_sock
.
local_port
)
{
case
994
:
case
6697
:
client_sock
.
ssl_server
=
1
;
}
if
(
!
client_sock
.
remote_ip_address
)
{
log
(
LOG_DEBUG
,
"
Socket has no IP address. Closing.
"
);
client_sock
.
close
();
}
else
if
(
iszlined
(
client_sock
.
remote_ip_address
))
{
client_sock
.
send
(
format
(
"
:%s 465 * :You've been Z:Lined from this server.
\r\n
"
,
servername
));
client_sock
.
close
();
}
else
{
var
new_id
=
"
id
"
+
next_client_id
;
next_client_id
++
;
if
(
server
.
client_add
!=
undefined
)
server
.
client_add
(
client_sock
);
if
(
server
.
clients
!=
undefined
)
log
(
LOG_DEBUG
,
format
(
"
%d clients
"
,
server
.
clients
));
Unregistered
[
new_id
]
=
new
Unregistered_Client
(
new_id
,
client_sock
);
}
}
else
log
(
LOG_DEBUG
,
"
!ERROR
"
+
open_plines
[
pl
].
error
+
"
accepting connection
"
);
}
}
log
(
LOG_NOTICE
,
VERSION
+
"
started.
"
);
// Check for pending DNS hostname resolutions.
for
(
this_unreg
in
Unregistered
)
{
if
(
Unregistered
[
this_unreg
]
&&
Unregistered
[
this_unreg
].
pending_resolve_time
)
Unregistered
[
this_unreg
].
resolve_check
();
}
/* If we're running from JSexec we don't have a global server object, so fake one. */
if
(
server
===
undefined
)
{
/* Define the global here so Startup() can manipulate it. */
var
server
=
"
JSexec
"
;
}
// Only rebuild our selectable sockets if required.
if
(
rebuild_socksel_array
)
{
Selectable_Sockets
=
new
Array
;
Selectable_Sockets_Map
=
new
Array
;
for
(
i
in
Local_Sockets
)
{
Selectable_Sockets
.
push
(
Local_Sockets
[
i
]);
Selectable_Sockets_Map
.
push
(
Local_Sockets_Map
[
i
]);
}
rebuild_socksel_array
=
false
;
}
Startup
();
/* Check for ping timeouts and process queues. */
/* FIXME/TODO: These need to be changed to a mapping system ASAP. */
for
(
this_sock
in
Selectable_Sockets
)
{
if
(
Selectable_Sockets_Map
[
this_sock
])
{
Selectable_Sockets_Map
[
this_sock
].
check_timeout
();
Selectable_Sockets_Map
[
this_sock
].
check_queues
();
}
}
js
.
do_callbacks
=
true
;
// do some work.
if
(
Selectable_Sockets
.
length
)
{
var
readme
=
socket_select
(
Selectable_Sockets
,
1
/*secs*/
);
try
{
for
(
thisPolled
in
readme
)
{
if
(
Selectable_Sockets_Map
[
readme
[
thisPolled
]])
{
var
conn
=
Selectable_Sockets_Map
[
readme
[
thisPolled
]];
if
(
!
conn
.
socket
.
is_connected
)
{
conn
.
quit
(
"
Connection reset by peer.
"
);
continue
;
}
conn
.
recvq
.
recv
(
conn
.
socket
);
}
}
}
catch
(
e
)
{
gnotice
(
"
FATAL ERROR:
"
+
e
);
log
(
LOG_ERR
,
"
JavaScript exception:
"
+
e
);
terminate_everything
(
"
A fatal error occured!
"
,
/* ERROR? */
true
);
}
}
else
{
/* Nothing's connected to us, so hang out for a bit */
mswait
(
100
);
}
// Scan C:Lines for servers to connect to automatically.
var
my_cline
;
for
(
thisCL
in
CLines
)
{
my_cline
=
CLines
[
thisCL
];
if
(
my_cline
.
port
&&
YLines
[
my_cline
.
ircclass
].
connfreq
&&
(
YLines
[
my_cline
.
ircclass
].
maxlinks
>
YLines
[
my_cline
.
ircclass
].
active
)
&&
(
search_server_only
(
my_cline
.
servername
)
<
1
)
&&
((
time
()
-
my_cline
.
lastconnect
)
>
YLines
[
my_cline
.
ircclass
].
connfreq
)
)
{
umode_notice
(
USERMODE_ROUTING
,
"
Routing
"
,
format
(
"
Auto-connecting to %s (%s)
"
,
CLines
[
thisCL
].
servername
,
CLines
[
thisCL
].
host
)
);
connect_to_server
(
CLines
[
thisCL
]);
}
function
config_rehash_semaphore_check
()
{
if
(
file_date
(
system
.
ctrl_dir
+
"
ircd.rehash
"
)
>
Time_Config_Read
)
{
Read_Config_File
();
}
}
js
.
setInterval
(
config_rehash_semaphore_check
,
1000
/* milliseconds */
);
Open_PLines
();
/* We
've
exit
ed the main loop, so terminate everything
. */
terminate_everything
(
"
Term
in
a
ted.
"
);
/* We exit
here and pass everything to the callback engine
. */
/* Deuce says I can't use exit(). So just pretend it's here
in
s
te
a
d.
*/
exec/load/ircd/channel.js
View file @
2c5aa02f
...
...
@@ -19,69 +19,60 @@
*/
const
CHANMODE_NONE
=
(
1
<<
0
);
// NONE
const
CHANMODE_BAN
=
(
1
<<
1
);
// b
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_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
/* 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
)
{
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) */
}
/* Channel Modes */
const
CHANMODE_NONE
=
(
1
<<
0
);
const
CHANMODE_BAN
=
(
1
<<
1
);
/* +b */
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_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
MODE
=
{};
MODE
[
CHANMODE_BAN
]
=
new
IRC_Channel_Mode
(
"
b
"
,
true
,
false
,
true
,
false
);
MODE
[
CHANMODE_INVITE
]
=
new
IRC_Channel_Mode
(
"
i
"
,
false
,
true
,
false
,
false
);
MODE
[
CHANMODE_KEY
]
=
new
IRC_Channel_Mode
(
"
k
"
,
true
,
true
,
false
,
false
);
MODE
[
CHANMODE_LIMIT
]
=
new
IRC_Channel_Mode
(
"
l
"
,
true
,
true
,
false
,
false
);
MODE
[
CHANMODE_MODERATED
]
=
new
IRC_Channel_Mode
(
"
m
"
,
false
,
true
,
false
,
false
);
MODE
[
CHANMODE_NOOUTSIDE
]
=
new
IRC_Channel_Mode
(
"
n
"
,
false
,
true
,
false
,
false
);
MODE
[
CHANMODE_OP
]
=
new
IRC_Channel_Mode
(
"
o
"
,
true
,
false
,
true
,
true
);
MODE
[
CHANMODE_PRIVATE
]
=
new
IRC_Channel_Mode
(
"
p
"
,
false
,
true
,
false
,
false
);
MODE
[
CHANMODE_SECRET
]
=
new
IRC_Channel_Mode
(
"
s
"
,
false
,
true
,
false
,
false
);
MODE
[
CHANMODE_TOPIC
]
=
new
IRC_Channel_Mode
(
"
t
"
,
false
,
true
,
false
,
false
);
MODE
[
CHANMODE_VOICE
]
=
new
IRC_Channel_Mode
(
"
v
"
,
true
,
false
,
true
,
true
);
/* Object Prototypes */
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_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_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
);
////////// Objects //////////
function
Channel
(
nam
)
{
this
.
nam
=
nam
;
this
.
mode
=
CHANMODE_NONE
;
this
.
topic
=
""
;
this
.
topictime
=
0
;
this
.
topicchangedby
=
""
;
this
.
arg
=
new
Object
;
this
.
nam
=
nam
;
this
.
mode
=
CHANMODE_NONE
;
this
.
topic
=
""
;
this
.
topictime
=
0
;
this
.
topicchangedby
=
""
;
this
.
arg
=
{}
;
this
.
arg
[
CHANMODE_LIMIT
]
=
0
;
this
.
arg
[
CHANMODE_KEY
]
=
""
;
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
;
this
.
count_modelist
=
Channel_count_modelist
;
this
.
occupants
=
Channel_occupants
;
this
.
match_list_mask
=
Channel_match_list_mask
;
this
.
users
=
{};
this
.
modelist
=
{};
this
.
modelist
[
CHANMODE_OP
]
=
{};
this
.
modelist
[
CHANMODE_VOICE
]
=
{};
this
.
modelist
[
CHANMODE_BAN
]
=
[];
this
.
bantime
=
{};
this
.
bancreator
=
{};
this
.
created
=
time
();
/* Functions */
this
.
chanmode
=
Channel_chanmode
;
this
.
isbanned
=
Channel_isbanned
;
this
.
count_modelist
=
Channel_count_modelist
;
this
.
occupants
=
Channel_Occupants
;
this
.
match_list_mask
=
Channel_match_list_mask
;
}
////////// Functions //////////
function
ChanMode_tweaktmpmode
(
tmp_bit
,
add
)
{
if
(
!
this
.
chan
.
modelist
[
CHANMODE_OP
][
this
.
user
.
id
]
&&
!
this
.
user
.
server
...
...
@@ -100,7 +91,9 @@ function ChanMode_tweaktmpmode(tmp_bit,add) {
}
}
function
ChanMode_tweaktmpmodelist
(
tmp_bit
,
add
,
arg
)
{
function
ChanMode_tweaktmpmodelist
(
bit
,
add
,
arg
)
{
var
i
;
if
(
!
this
.
chan
.
modelist
[
CHANMODE_OP
][
this
.
user
.
id
]
&&
!
this
.
user
.
server
&&
!
this
.
user
.
uline
...
...
@@ -109,29 +102,24 @@ function ChanMode_tweaktmpmodelist(tmp_bit,add,arg) {
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
())
for
(
i
in
this
.
tmplist
[
bit
][
add
])
{
/
*
Is this argument in our list for this mode already?
*/
if
(
this
.
tmplist
[
bit
][
add
][
i
].
toUpperCase
()
==
arg
.
toUpperCase
())
return
0
;
}
// It doesn't exist on our mode, push it in.
this
.
tmplist
[
tmp_bit
][
add
].
push
(
arg
);
// Check for it against the other mode, and maybe nuke it.
var
oadd
;
if
(
add
)
oadd
=
false
;
else
oadd
=
true
;
for
(
x
in
this
.
tmplist
[
tmp_bit
][
oadd
])
{
if
(
this
.
tmplist
[
tmp_bit
][
oadd
][
x
].
toUpperCase
()
==
arg
.
toUpperCase
())
{
delete
this
.
tmplist
[
tmp_bit
][
oadd
][
x
];
/* It doesn't exist on our mode, push it in. */
this
.
tmplist
[
bit
][
add
].
push
(
arg
);
/* Check for it against the other mode, and maybe nuke it. */
for
(
i
in
this
.
tmplist
[
bit
][
add
?
false
:
true
])
{
if
(
this
.
tmplist
[
bit
][
add
?
false
:
true
][
i
].
toUpperCase
()
==
arg
.
toUpperCase
())
{
delete
this
.
tmplist
[
bit
][
add
?
false
:
true
][
i
];
return
0
;
}
}
}
function
ChanMode_affect_mode_list
(
list_bit
)
{
var
tmp_nick
;
var
tmp_nick
,
add
,
z
;
for
(
add
in
this
.
tmplist
[
list_bit
])
{
for
(
z
in
this
.
tmplist
[
list_bit
][
add
])
{
tmp_nick
=
Users
[
this
.
tmplist
[
list_bit
][
add
][
z
].
toUpperCase
()];
...
...
@@ -156,12 +144,15 @@ function ChanMode_affect_mode_list(list_bit) {
}
function
Channel_count_modelist
(
list_bit
)
{
var
tmp_counter
=
0
;
for
(
tmp_count
in
this
.
modelist
[
list_bit
])
{
if
(
this
.
modelist
[
list_bit
][
tmp_count
])
tmp_counter
++
;
var
i
;
var
ret
=
0
;
for
(
i
in
this
.
modelist
[
list_bit
])
{
if
(
this
.
modelist
[
list_bit
][
i
])
ret
++
;
}
return
tmp_counter
;
return
ret
;
}
function
Channel_chanmode
(
show_args
)
{
...
...
@@ -194,32 +185,37 @@ function Channel_chanmode(show_args) {
return
tmp_mode
+
tmp_extras
;
}
function
Channel_isbanned
(
banned_nuh
)
{
for
(
this_ban
in
this
.
modelist
[
CHANMODE_BAN
])
{
if
(
wildmatch
(
banned_nuh
,
this
.
modelist
[
CHANMODE_BAN
][
this_ban
]))
function
Channel_isbanned
(
nuh
)
{
var
i
;
for
(
i
in
this
.
modelist
[
CHANMODE_BAN
])
{
if
(
wildmatch
(
nuh
,
this
.
modelist
[
CHANMODE_BAN
][
i
]))
return
1
;
}
return
0
;
}
function
Channel_occupants
()
{
var
chan_occupants
=
""
;
for
(
thisChannel_user
in
this
.
users
)
{
var
Channel_user
=
this
.
users
[
thisChannel_user
];
if
(
Channel_user
.
nick
)
{
if
(
chan_occupants
)
chan_occupants
+=
"
"
;
if
(
this
.
modelist
[
CHANMODE_OP
][
Channel_user
.
id
])
chan_occupants
+=
"
@
"
;
if
(
this
.
modelist
[
CHANMODE_VOICE
][
Channel_user
.
id
])
chan_occupants
+=
"
+
"
;
chan_occupants
+=
Channel_user
.
nick
;
function
Channel_Occupants
()
{
var
i
;
var
user
;
var
ret
=
""
;
for
(
i
in
this
.
users
)
{
user
=
this
.
users
[
i
];
if
(
user
.
nick
)
{
if
(
ret
)
ret
+=
"
"
;
if
(
this
.
modelist
[
CHANMODE_OP
][
user
.
id
])
ret
+=
"
@
"
;
if
(
this
.
modelist
[
CHANMODE_VOICE
][
user
.
id
])
ret
+=
"
+
"
;
ret
+=
user
.
nick
;
}
}
return
chan_occupants
;
return
ret
;
}
// Yay, version 3.0 of this.set_chanmode(), eradicates any global variables.
function
ChanMode
(
chan
,
user
)
{
this
.
tmplist
=
new
Object
;
this
.
tmplist
[
CHANMODE_OP
]
=
new
Object
;
...
...
@@ -249,6 +245,8 @@ function ChanMode(chan,user) {
}
function
IRCClient_set_chanmode
(
chan
,
modeline
,
bounce_modes
)
{
var
i
,
j
;
if
(
!
chan
||
!
modeline
)
return
;
...
...
@@ -261,9 +259,9 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) {
var
mode_counter
=
0
;
var
mode_args_counter
=
1
;
// start counting at args, not the modestring
for
(
modechar
in
cm_args
[
0
])
{
for
(
i
in
cm_args
[
0
])
{
mode_counter
++
;
switch
(
cm_args
[
0
][
modechar
])
{
switch
(
cm_args
[
0
][
i
])
{
case
"
+
"
:
if
(
!
add
)
add
=
true
;
...
...
@@ -345,11 +343,11 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) {
break
;
default
:
if
((
!
this
.
parent
)
&&
(
!
this
.
server
))
this
.
numeric
(
472
,
cm_args
[
0
][
modechar
]
+
"
:is unknown mode char to me.
"
);
this
.
numeric
(
472
,
cm_args
[
0
][
i
]
+
"
:is unknown mode char to me.
"
);
mode_counter
--
;
break
;
}
if
(
mode_counter
==
max_modes
)
if
(
mode_counter
==
MAX_MODES
)
break
;
}
...
...
@@ -358,22 +356,22 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) {
// 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
&&
MODE
[
cm
].
isnick
)
{
for
(
member
in
chan
.
modelist
[
cm
])
{
cmode
.
delmodes
+=
MODE
[
cm
].
modechar
;
cmode
.
delmodeargs
+=
"
"
+
chan
.
modelist
[
cm
][
member
].
nick
;
delete
chan
.
modelist
[
cm
][
member
];
for
(
i
in
MODE
)
{
if
(
MODE
[
i
].
state
&&
(
chan
.
mode
&
i
)
&&
!
(
cmode
.
addbits
&
i
))
{
cmode
.
delbits
|=
i
;
}
else
if
(
MODE
[
i
].
list
&&
MODE
[
i
].
isnick
)
{
for
(
j
in
chan
.
modelist
[
i
])
{
cmode
.
delmodes
+=
MODE
[
i
].
modechar
;
cmode
.
delmodeargs
+=
"
"
+
chan
.
modelist
[
i
][
j
].
nick
;
delete
chan
.
modelist
[
i
][
j
];
}
}
else
if
(
MODE
[
cm
].
list
&&
!
MODE
[
cm
].
isnick
)
{
for
(
ban
in
chan
.
modelist
[
cm
])
{
cmode
.
delmodes
+=
MODE
[
cm
].
modechar
;
cmode
.
delmodeargs
+=
"
"
+
chan
.
modelist
[
cm
][
ban
];
delete
chan
.
modelist
[
cm
][
ban
];
delete
chan
.
bantime
[
ban
];
delete
chan
.
bancreator
[
ban
];
}
else
if
(
MODE
[
i
].
list
&&
!
MODE
[
i
].
isnick
)
{
for
(
j
in
chan
.
modelist
[
i
])
{
cmode
.
delmodes
+=
MODE
[
i
].
modechar
;
cmode
.
delmodeargs
+=
"
"
+
chan
.
modelist
[
i
][
j
];
delete
chan
.
modelist
[
i
][
j
];
delete
chan
.
bantime
[
j
];
delete
chan
.
bancreator
[
j
];
}
}
}
...
...
@@ -381,40 +379,40 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) {
// 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
)
for
(
i
in
MODE
)
{
if
(
MODE
[
i
].
state
)
{
if
(
(
i
&
CHANMODE_KEY
)
&&
(
cmode
.
addbits
&
CHANMODE_KEY
)
&&
cmode
.
state_arg
[
cm
]
&&
chan
.
arg
[
cm
]
&&
cmode
.
state_arg
[
i
]
&&
chan
.
arg
[
i
]
&&
!
this
.
server
&&
!
this
.
parent
&&
!
bounce_modes
)
{
this
.
numeric
(
467
,
format
(
"
%s :Channel key already set.
"
,
chan
.
nam
));
}
else
if
(
(
cmode
.
addbits
&
cm
)
}
else
if
(
(
cmode
.
addbits
&
i
)
&&
(
!
(
chan
.
mode
&
cm
)
!
(
chan
.
mode
&
i
)
||
(
(
cm
==
CHANMODE_LIMIT
)
(
i
==
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
.
addmodes
+=
MODE
[
i
].
modechar
;
chan
.
mode
|=
i
;
if
(
MODE
[
i
].
args
&&
MODE
[
i
].
state
)
{
cmode
.
addmodeargs
+=
"
"
+
cmode
.
state_arg
[
cm
];
chan
.
arg
[
cm
]
=
cmode
.
state_arg
[
cm
];
cmode
.
state_arg
[
i
];
chan
.
arg
[
i
]
=
cmode
.
state_arg
[
i
];
}
}
else
if
((
cmode
.
delbits
&
cm
)
&&
(
chan
.
mode
&
cm
))
{
cmode
.
delmodes
+=
MODE
[
cm
].
modechar
;
chan
.
mode
&=
~
cm
;
if
(
MODE
[
cm
].
args
&&
MODE
[
cm
].
state
)
{
}
else
if
((
cmode
.
delbits
&
i
)
&&
(
chan
.
mode
&
i
))
{
cmode
.
delmodes
+=
MODE
[
i
].
modechar
;
chan
.
mode
&=
~
i
;
if
(
MODE
[
i
].
args
&&
MODE
[
i
].
state
)
{
cmode
.
delmodeargs
+=
"
"
+
cmode
.
state_arg
[
cm
];
chan
.
arg
[
cm
]
=
""
;
cmode
.
state_arg
[
i
];
chan
.
arg
[
i
]
=
""
;
}
}
}
...
...
@@ -436,10 +434,10 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) {
}
// Bans are a specialized case, sigh.
for
(
z
in
cmode
.
tmplist
[
CHANMODE_BAN
][
true
])
{
// +b
for
(
i
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
)
cmode
.
tmplist
[
CHANMODE_BAN
][
add
][
i
]);
if
(
(
chan
.
count_modelist
(
CHANMODE_BAN
)
>=
MAX_BANS
)
&&
!
this
.
server
&&
!
this
.
parent
)
{
...
...
@@ -454,14 +452,14 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) {
}
}
for
(
z
in
cmode
.
tmplist
[
CHANMODE_BAN
][
false
])
{
// -b
for
(
i
in
cmode
.
tmplist
[
CHANMODE_BAN
][
false
])
{
// -b
for
(
ban
in
chan
.
modelist
[
CHANMODE_BAN
])
{
if
(
cmode
.
tmplist
[
CHANMODE_BAN
][
false
][
z
].
toUpperCase
()
if
(
cmode
.
tmplist
[
CHANMODE_BAN
][
false
][
i
].
toUpperCase
()
==
chan
.
modelist
[
CHANMODE_BAN
][
ban
].
toUpperCase
()
)
{
cmode
.
delmodes
+=
"
b
"
;
cmode
.
delmodeargs
+=
"
"
+
cmode
.
tmplist
[
CHANMODE_BAN
][
false
][
z
];
cmode
.
tmplist
[
CHANMODE_BAN
][
false
][
i
];
delete
chan
.
modelist
[
CHANMODE_BAN
][
ban
];
delete
chan
.
bantime
[
ban
];
delete
chan
.
bancreator
[
ban
];
...
...
@@ -492,8 +490,8 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) {
var
mode_counter
=
0
;
var
mode_output
=
""
;
var
f_mode_args
=
""
;
for
(
marg
in
final_args
[
0
])
{
switch
(
final_args
[
0
][
marg
])
{
for
(
i
in
final_args
[
0
])
{
switch
(
final_args
[
0
][
i
])
{
case
"
+
"
:
mode_output
+=
"
+
"
;
add
=
true
;
...
...
@@ -505,7 +503,7 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) {
case
"
l
"
:
if
(
!
add
)
{
mode_counter
++
;
mode_output
+=
final_args
[
0
][
marg
];
mode_output
+=
final_args
[
0
][
i
];
break
;
}
case
"
b
"
:
// only modes with arguments
...
...
@@ -517,10 +515,10 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) {
f_mode_args
+=
"
"
+
final_args
[
arg_counter
];
default
:
mode_counter
++
;
mode_output
+=
final_args
[
0
][
marg
];
mode_output
+=
final_args
[
0
][
i
];
break
;
}
if
(
mode_counter
>=
max_modes
)
{
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
);
...
...
@@ -551,7 +549,10 @@ function IRCClient_set_chanmode(chan,modeline,bounce_modes) {
}
function
IRCClient_do_join
(
chan_name
,
join_key
)
{
chan_name
=
chan_name
.
slice
(
0
,
max_chanlen
)
chan_name
=
chan_name
.
slice
(
0
,
MAX_CHANLEN
)
if
(
!
join_key
)
join_key
=
""
;
var
uc_chan_name
=
chan_name
.
toUpperCase
();
...
...
@@ -567,7 +568,7 @@ function IRCClient_do_join(chan_name,join_key) {
}
if
(
this
.
channels
[
uc_chan_name
])
return
0
;
if
((
true_array_len
(
this
.
channels
)
>=
max_user_chans
)
&&
this
.
local
)
{
if
((
true_array_len
(
this
.
channels
)
>=
MAX_USER_CHANS
)
&&
this
.
local
)
{
this
.
numeric
(
"
405
"
,
chan_name
+
"
:You have joined too many channels.
"
);
return
0
;
}
...
...
@@ -636,7 +637,7 @@ function IRCClient_do_join(chan_name,join_key) {
if
(
chan_name
[
0
]
!=
"
&
"
)
{
this
.
bcast_to_servers_raw
(
format
(
"
:%s SJOIN %s %s %s :%s%s
"
,
s
erver
n
ame
,
S
erver
N
ame
,
chan
.
created
,
chan
.
nam
,
chan
.
chanmode
(),
...
...
@@ -684,11 +685,9 @@ function IRCClient_do_part(chan_name) {
}
function
IRCClient_part_all
()
{
var
partingChannel
;
var
i
;
for
(
thisChannel
in
this
.
channels
)
{
partingChannel
=
this
.
channels
[
thisChannel
];
this
.
do_part
(
partingChannel
.
nam
);
for
(
i
in
this
.
channels
)
{
this
.
do_part
(
this
.
channels
[
i
].
nam
);
}
}
exec/load/ircd/config.js
View file @
2c5aa02f
...
...
@@ -20,9 +20,11 @@
*/
function
parse_nline_flags
(
flags
)
{
var
i
;
var
nline_flags
=
0
;
for
(
thisflag
in
flags
)
{
switch
(
flags
[
thisflag
])
{
for
(
i
in
flags
)
{
switch
(
flags
[
i
])
{
case
"
q
"
:
nline_flags
|=
NLINE_CHECK_QWKPASSWD
;
break
;
...
...
@@ -33,8 +35,10 @@ function parse_nline_flags(flags) {
nline_flags
|=
NLINE_CHECK_WITH_QWKMASTER
;
break
;
default
:
log
(
LOG_WARNING
,
"
!WARNING Unknown N:Line flag '
"
+
flags
[
thisflag
]
+
"
' in config.
"
);
log
(
LOG_WARNING
,
format
(
"
!WARNING Unknown N:Line flag '%s' in config.
"
,
flags
[
i
]
));
break
;
}
}
...
...
@@ -42,9 +46,11 @@ function parse_nline_flags(flags) {
}
function
parse_oline_flags
(
flags
)
{
var
i
;
var
oline_flags
=
0
;
for
(
thisflag
in
flags
)
{
switch
(
flags
[
thisflag
])
{
for
(
i
in
flags
)
{
switch
(
flags
[
i
])
{
case
"
r
"
:
oline_flags
|=
OLINE_CAN_REHASH
;
break
;
...
...
@@ -105,7 +111,7 @@ function parse_oline_flags(flags) {
break
;
case
"
x
"
:
case
"
X
"
:
oline_flags
|=
OLINE_CAN_
DEBUG
;
oline_flags
|=
OLINE_CAN_
EVAL
;
break
;
case
"
O
"
:
oline_flags
|=
OLINE_IS_GOPER
;
...
...
@@ -126,39 +132,50 @@ function parse_oline_flags(flags) {
oline_flags
|=
OLINE_CAN_UMODEC
;
break
;
default
:
log
(
LOG_WARNING
,
"
!WARNING Unknown O:Line flag '
"
+
flags
[
thisflag
]
+
"
' in config.
"
);
log
(
LOG_WARNING
,
format
(
"
!WARNING Unknown O:Line flag '%s' in config.
"
,
flags
[
i
]
));
break
;
}
}
return
oline_flags
;
}
function
read_config_file
()
{
function
Read_Config_File
()
{
var
i
;
/* 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
;
if
(
typeof
CLines
!==
'
undefined
'
)
{
for
(
i
in
CLines
)
{
if
(
CLines
[
i
].
next_connect
)
js
.
clearTimeout
(
CLines
[
i
].
next_connect
);
}
}
CLines
=
[];
HLines
=
[];
ILines
=
[];
KLines
=
[];
NLines
=
[];
OLines
=
[];
PLines
=
[];
QLines
=
[];
ULines
=
[];
YLines
=
[];
ZLines
=
[];
Die_Password
=
""
;
Restart_Password
=
""
;
/* End of global variables */
var
fname
=
""
;
if
(
c
onfig_
f
ilename
&&
c
onfig_
f
ilename
.
length
)
{
if
(
c
onfig_
f
ilename
.
indexOf
(
'
/
'
)
>=
0
||
c
onfig_
f
ilename
.
indexOf
(
'
\\
'
)
>=
0
)
fname
=
c
onfig_
f
ilename
;
if
(
C
onfig_
F
ilename
&&
C
onfig_
F
ilename
.
length
)
{
if
(
C
onfig_
F
ilename
.
indexOf
(
'
/
'
)
>=
0
||
C
onfig_
F
ilename
.
indexOf
(
'
\\
'
)
>=
0
)
fname
=
C
onfig_
F
ilename
;
else
fname
=
system
.
ctrl_dir
+
c
onfig_
f
ilename
;
fname
=
system
.
ctrl_dir
+
C
onfig_
F
ilename
;
}
else
{
fname
=
system
.
ctrl_dir
+
"
ircd.
"
+
system
.
local_host_name
+
"
.conf
"
;
if
(
!
file_exists
(
fname
))
...
...
@@ -175,13 +192,13 @@ function read_config_file() {
read_conf_config
(
file_handle
);
file_handle
.
close
();
}
else
{
log
(
"
Couldn't open configuration file! Proceeding with defaults.
"
);
log
(
LOG_NOTICE
,
"
Couldn't open configuration file! Proceeding with defaults.
"
);
}
t
ime_
c
onfig_
r
ead
=
time
();
s
can_
f
or_
kli
ned_
c
lients
();
T
ime_
C
onfig_
R
ead
=
time
();
S
can_
F
or_
Ban
ned_
C
lients
();
YLines
[
0
]
=
new
YLine
(
120
,
600
,
1
,
5050000
);
/
/ d
efault
irc
class
YLines
[
0
]
=
new
YLine
(
120
,
600
,
1
,
5050000
);
/
* D
efault
IRC
class
*/
}
function
ini_sections
()
{
...
...
@@ -197,9 +214,8 @@ function ini_sections() {
}
function
ini_IRCdInfo
(
arg
,
ini
)
{
log
(
"
ircdinfo
"
+
ini
.
Hostname
);
servername
=
ini
.
Hostname
;
serverdesc
=
ini
.
Info
;
ServerName
=
ini
.
Hostname
;
ServerDesc
=
ini
.
Info
;
Admin1
=
ini
.
Admin1
;
Admin2
=
ini
.
Admin2
;
Admin3
=
ini
.
Admin3
;
...
...
@@ -207,7 +223,7 @@ function ini_IRCdInfo(arg, ini) {
/* Former M:Line */
function
ini_Port
(
arg
,
ini
)
{
mline_p
ort
=
arg
;
Default_P
ort
=
arg
;
}
/* Former Y:Line */
...
...
@@ -256,21 +272,19 @@ function ini_Hub(arg, ini) {
function
read_ini_config
(
conf
)
{
var
ini
=
conf
.
iniGetAllObjects
();
var
split
;
var
section_name
;
var
section_arg
;
var
Sections
=
new
ini_sections
();
var
i
,
s
;
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
);
for
(
var
i
in
ini
)
{
s
=
i
.
name
.
split
(
"
:
"
);
if
(
typeof
Sections
[
s
[
0
]]
===
'
function
'
)
Sections
[
s
[
0
]](
s
[
1
],
i
);
}
}
function
read_conf_config
(
conf
)
{
var
conf_line
,
arg
,
i
;
function
fancy_split
(
line
)
{
var
ret
=
[];
var
i
;
...
...
@@ -309,21 +323,15 @@ function read_conf_config(conf) {
}
while
(
!
conf
.
eof
)
{
var
conf_line
=
conf
.
readln
();
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
);
arg
=
fancy_split
(
conf_line
);
for
(
i
in
arg
)
{
arg
[
i
]
=
arg
[
i
].
replace
(
/SYSTEM_HOST_NAME/g
,
system
.
host_name
);
arg
[
i
]
=
arg
[
i
].
replace
(
/SYSTEM_NAME/g
,
system
.
name
);
arg
[
i
]
=
arg
[
i
].
replace
(
/VERSION_NOTICE/g
,
system
.
version_notice
);
if
(
typeof
system
.
qwk_id
!==
'
undefined
'
)
arg
[
i
]
=
arg
[
i
].
replace
(
/SYSTEM_QWKID/g
,
system
.
qwk_id
.
toLowerCase
());
}
switch
(
conf_line
[
0
].
toUpperCase
())
{
case
"
A
"
:
...
...
@@ -336,8 +344,7 @@ function read_conf_config(conf) {
case
"
C
"
:
if
(
!
arg
[
5
])
break
;
CLines
.
push
(
new
CLine
(
arg
[
1
],
arg
[
2
],
arg
[
3
],
arg
[
4
],
parseInt
(
arg
[
5
])
));
CLines
.
push
(
new
CLine
(
arg
[
1
],
arg
[
2
],
arg
[
3
],
arg
[
4
],
parseInt
(
arg
[
5
])));
break
;
case
"
H
"
:
if
(
!
arg
[
3
])
...
...
@@ -355,8 +362,7 @@ function read_conf_config(conf) {
break
;
var
kline_mask
=
create_ban_mask
(
arg
[
1
],
true
);
if
(
!
kline_mask
)
{
log
(
LOG_WARNING
,
"
!WARNING Invalid K:Line (
"
+
arg
[
1
]
+
"
)
"
);
log
(
LOG_WARNING
,
"
!WARNING Invalid K:Line (
"
+
arg
[
1
]
+
"
)
"
);
break
;
}
KLines
.
push
(
new
KLine
(
kline_mask
,
arg
[
2
],
"
K
"
));
...
...
@@ -364,9 +370,9 @@ function read_conf_config(conf) {
case
"
M
"
:
if
(
!
arg
[
3
])
break
;
s
erver
n
ame
=
arg
[
1
];
s
erver
d
esc
=
arg
[
3
];
mline_p
ort
=
parseInt
(
arg
[
4
]);
S
erver
N
ame
=
arg
[
1
];
S
erver
D
esc
=
arg
[
3
];
Default_P
ort
=
parseInt
(
arg
[
4
]);
break
;
case
"
N
"
:
if
(
!
arg
[
5
])
...
...
@@ -394,8 +400,8 @@ function read_conf_config(conf) {
ULines
.
push
(
arg
[
1
]);
break
;
case
"
X
"
:
d
ie
p
ass
=
arg
[
1
];
r
estart
p
ass
=
arg
[
2
];
D
ie
_P
ass
word
=
arg
[
1
];
R
estart
_P
ass
word
=
arg
[
2
];
break
;
case
"
Y
"
:
if
(
!
arg
[
5
])
...
...
exec/load/ircd/core.js
View file @
2c5aa02f
...
...
@@ -19,8 +19,8 @@
*/
/* There's no way to get the length of an associative array in JS, so here we are. */
function
true_array_len
(
my_array
)
{
var
i
;
var
counter
=
0
;
for
(
i
in
my_array
)
{
counter
++
;
...
...
@@ -28,49 +28,67 @@ function true_array_len(my_array) {
return
counter
;
}
function
terminate_everything
(
terminate_reason
,
error
)
{
log
(
error
?
LOG_ERR
:
LOG_NOTICE
,
"
Terminating:
"
+
terminate_reason
);
for
(
thisClient
in
Local_Sockets_Map
)
{
var
Client
=
Local_Sockets_Map
[
thisClient
];
Client
.
rawout
(
"
ERROR :
"
+
terminate_reason
);
Client
.
socket
.
close
();
function
terminate_everything
(
str
,
error
)
{
var
i
;
var
sendstr
;
sendstr
=
format
(
"
ERROR :%s
\r\n
"
,
str
);
log
(
error
?
LOG_ERR
:
LOG_NOTICE
,
"
Terminating:
"
+
str
);
for
(
i
in
Unregistered
)
{
Unregistered
[
i
].
socket
.
send
(
sendstr
);
Unregistered
[
i
].
socket
.
close
();
}
for
(
i
in
Local_Servers
)
{
Local_Servers
[
i
].
socket
.
send
(
sendstr
);
Local_Servers
[
i
].
socket
.
close
();
}
for
(
i
in
Local_Users
)
{
Local_Users
[
i
].
socket
.
send
(
sendstr
);
Local_Users
[
i
].
socket
.
close
();
}
js
.
do_callbacks
=
false
;
exit
(
error
);
}
function
search_server_only
(
server_name
)
{
var
i
;
if
(
!
server_name
)
return
0
;
for
(
thisServer
in
Servers
)
{
var
Server
=
Servers
[
thisServer
];
if
(
wildmatch
(
Server
.
nick
,
server_name
))
return
Server
;
}
if
(
wildmatch
(
servername
,
server_name
))
return
-
1
;
// the server passed to us is our own.
// No success.
return
0
;
for
(
i
in
Servers
)
{
if
(
wildmatch
(
Servers
[
i
].
nick
,
server_name
))
return
Servers
[
i
];
}
if
(
wildmatch
(
ServerName
,
server_name
))
return
-
1
;
/* the server passed to us is our own. */
return
0
;
/* Failure */
}
function
searchbyserver
(
servnick
)
{
var
i
;
if
(
!
servnick
)
return
0
;
var
server_try
=
search_server_only
(
servnick
);
if
(
server_try
)
{
return
server_try
;
}
else
{
for
(
thisNick
in
Users
)
{
var
Nick
=
Users
[
thisNick
];
if
(
wildmatch
(
Nick
.
nick
,
servnick
))
return
search_server_only
(
Nick
.
servername
);
}
return
false
;
i
=
search_server_only
(
servnick
);
if
(
i
)
return
i
;
for
(
i
in
Users
)
{
if
(
wildmatch
(
Users
[
i
].
nick
,
servnick
))
return
search_server_only
(
Users
[
i
].
servername
);
}
return
0
;
// looks like we failed after all that hard work :(
return
false
;
}
/
/
Only allow letters, numbers and underscore in username to a maximum of
//
9 characters for 'anonymous' users (i.e. not using PASS to authenticate.)
//
hostile characters like !,@,: etc would be bad here :)
/
*
Only allow letters, numbers and underscore in username to a maximum of
9 characters for 'anonymous' users (i.e. not using PASS to authenticate.)
hostile characters like !,@,: etc would be bad here :)
*/
function
parse_username
(
str
)
{
str
=
str
.
replace
(
/
[^\w]
/g
,
""
).
toLowerCase
();
if
(
!
str
)
...
...
@@ -79,12 +97,20 @@ function parse_username(str) {
}
function
umode_notice
(
bit
,
ntype
,
nmessage
)
{
log
(
ntype
+
"
:
"
+
nmessage
);
for
(
thisuser
in
Local_Users
)
{
var
user
=
Local_Users
[
thisuser
];
if
(
user
.
mode
&&
((
user
.
mode
&
bit
)
==
bit
))
user
.
rawout
(
"
:
"
+
servername
+
"
NOTICE
"
+
user
.
nick
+
"
:***
"
+
ntype
+
"
--
"
+
nmessage
);
var
i
,
user
;
log
(
LOG_INFO
,
format
(
"
%s: %s
"
,
ntype
,
nmessage
));
for
(
i
in
Local_Users
)
{
user
=
Local_Users
[
i
];
if
(
user
.
mode
&&
((
user
.
mode
&
bit
)
==
bit
))
{
user
.
rawout
(
format
(
"
:%s NOTICE %s :*** %s -- %s
"
,
ServerName
,
user
.
nick
,
ntype
,
nmessage
));
}
}
}
...
...
@@ -94,23 +120,24 @@ function create_ban_mask(str,kline) {
tmp_banstr
[
0
]
=
""
;
tmp_banstr
[
1
]
=
""
;
tmp_banstr
[
2
]
=
""
;
var
i
;
var
bchar_counter
=
0
;
var
part_counter
=
0
;
// BAN: 0!1@2 KLINE: 0@1
var
regexp
=
"
[A-Za-z
\
{
\
}
\
`
\
^
\
_
\
|
\\
]
\\
[
\\\\
0-9
\
-.*?
\
~:]
"
;
var
finalstr
;
for
(
bchar
in
str
)
{
if
(
str
[
bchar
].
match
(
regexp
))
{
tmp_banstr
[
part_counter
]
+=
str
[
bchar
];
for
(
i
in
str
)
{
if
(
str
[
i
].
match
(
regexp
))
{
tmp_banstr
[
part_counter
]
+=
str
[
i
];
bchar_counter
++
;
}
else
if
((
str
[
bchar
]
==
"
!
"
)
&&
(
part_counter
==
0
)
&&
}
else
if
((
str
[
i
]
==
"
!
"
)
&&
(
part_counter
==
0
)
&&
!
kline
)
{
part_counter
=
1
;
bchar_counter
=
0
;
}
else
if
((
str
[
bchar
]
==
"
@
"
)
&&
(
part_counter
==
1
)
&&
}
else
if
((
str
[
i
]
==
"
@
"
)
&&
(
part_counter
==
1
)
&&
!
kline
)
{
part_counter
=
2
;
bchar_counter
=
0
;
}
else
if
((
str
[
bchar
]
==
"
@
"
)
&&
(
part_counter
==
0
))
{
}
else
if
((
str
[
i
]
==
"
@
"
)
&&
(
part_counter
==
0
))
{
if
(
kline
)
{
part_counter
=
1
;
}
else
{
...
...
@@ -140,7 +167,7 @@ function create_ban_mask(str,kline) {
finalstr
=
tmp_banstr
[
0
].
slice
(
0
,
10
)
+
"
@
"
+
tmp_banstr
[
1
].
slice
(
0
,
80
);
else
finalstr
=
format
(
"
%s!%s@%s
"
,
tmp_banstr
[
0
].
slice
(
0
,
max_nicklen
),
tmp_banstr
[
0
].
slice
(
0
,
MAX_NICKLEN
),
tmp_banstr
[
1
].
slice
(
0
,
10
),
tmp_banstr
[
2
].
slice
(
0
,
80
)
);
...
...
@@ -151,122 +178,132 @@ function create_ban_mask(str,kline) {
}
function
isklined
(
kl_str
)
{
for
(
the_kl
in
KLines
)
{
if
(
KLines
[
the_kl
].
hostmask
&&
wildmatch
(
kl_str
,
KLines
[
the_kl
].
hostmask
)
)
{
return
KLines
[
the_kl
];
var
i
;
for
(
i
in
KLines
)
{
if
(
KLines
[
i
].
hostmask
&&
wildmatch
(
kl_str
,
KLines
[
i
].
hostmask
)
)
{
return
KLines
[
i
];
}
}
return
0
;
}
function
iszli
ned
(
zl_
ip
)
{
for
(
the_zl
in
ZLines
)
{
if
(
ZLines
[
the_zl
].
ipmask
&&
wildmatch
(
zl_ip
,
ZLines
[
the_zl
].
ipmask
)
)
{
function
IP_Ban
ned
(
ip
)
{
var
i
;
for
(
i
in
ZLines
)
{
if
(
ZLines
[
i
].
ipmask
&&
wildmatch
(
ip
,
ZLines
[
i
].
ipmask
)
)
{
return
1
;
}
}
return
0
;
}
function
scan_for_klined_clients
()
{
for
(
thisUser
in
Local_Users
)
{
var
theuser
=
Local_Users
[
thisUser
];
var
kline
=
isklined
(
theuser
.
uprefix
+
"
@
"
+
theuser
.
hostname
);
if
(
kline
)
theuser
.
quit
(
"
User has been K:Lined (
"
+
kline
.
reason
+
"
)
"
);
if
(
iszlined
(
theuser
.
ip
))
theuser
.
quit
(
"
User has been Z:Lined
"
);
function
Scan_For_Banned_Clients
()
{
var
i
,
user
;
for
(
i
in
Local_Users
)
{
user
=
Local_Users
[
i
];
if
(
isklined
(
user
.
uprefix
+
"
@
"
+
user
.
hostname
)
||
IP_Banned
(
user
.
ip
)
)
{
theuser
.
quit
(
"
User has been banned
"
);
}
}
}
function
remove_kline
(
kl_hm
)
{
for
(
the_kl
in
KLines
)
{
if
(
KLines
[
the_kl
].
hostmask
&&
wildmatch
(
kl_hm
,
KLines
[
the_kl
].
hostmask
)
)
{
KLines
[
the_kl
].
hostmask
=
""
;
KLines
[
the_kl
].
reason
=
""
;
KLines
[
the_kl
].
type
=
""
;
var
i
;
for
(
i
in
KLines
)
{
if
(
KLines
[
i
].
hostmask
&&
wildmatch
(
kl_hm
,
KLines
[
i
].
hostmask
))
{
delete
KLines
[
i
];
return
1
;
}
}
return
0
;
// failure.
return
0
;
}
function
connect_to_server
(
this
_
cline
,
the_port
)
{
var
connect_sock
;
var
new_id
;
/*
this
=
cline
*/
function
connect_to_server
(
port
)
{
var
sock
=
new
Socket
()
;
if
(
!
the_port
&&
this_cline
.
port
)
the_port
=
this_cline
.
port
;
else
if
(
!
the_port
)
the_port
=
default_port
;
// try a safe default.
if
(
js
.
global
.
ConnectedSocket
!=
undefined
)
{
try
{
connect_sock
=
new
ConnectedSocket
(
this_cline
.
host
,
the_port
,
{
timeout
:
ob_sock_timeout
,
bindaddrs
:
server
.
interface_ip_addr_list
});
}
catch
(
e
)
{
connect_sock
=
new
Socket
();
}
}
else
{
connect_sock
=
new
Socket
();
connect_sock
.
bind
(
0
,
server
.
interface_ip_address
);
connect_sock
.
connect
(
this_cline
.
host
,
the_port
,
ob_sock_timeout
);
}
sock
.
array_buffer
=
false
;
/* JS78, we want strings */
sock
.
cline
=
this
;
sock
.
outbound
=
true
;
var
sendts
=
true
;
/* Assume Bahamut */
if
(
!
port
&&
this
.
port
)
port
=
this
.
port
;
else
if
(
!
port
)
port
=
Default_Port
;
for
(
nl
in
NLines
)
{
var
mynl
=
NLines
[
nl
];
}
umode_notice
(
USERMODE_ROUTING
,
"
Routing
"
,
format
(
"
Auto-connecting to %s (%s) on port %d
"
,
this
.
servername
,
this
.
host
,
port
));
if
(
connect_sock
.
is_connected
)
{
umode_notice
(
USERMODE_ROUTING
,
"
Routing
"
,