Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
Synchronet
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Main
Synchronet
Commits
2cb31a39
Commit
2cb31a39
authored
21 years ago
by
cyan
Browse files
Options
Downloads
Patches
Plain Diff
Portion of the IRCd v1.1b that handles server connections.
parent
07c7d7d2
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
exec/load/ircd_server.js
+1106
-0
1106 additions, 0 deletions
exec/load/ircd_server.js
with
1106 additions
and
0 deletions
exec/load/ircd_server.js
0 → 100644
+
1106
−
0
View file @
2cb31a39
// $Id$
//
// 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 Randolph Erwin Sommerfeld <sysop@rrx.ca>
//
// ** Server to server operation is governed here.
//
////////// Constants / Defines //////////
const
SERVER_REVISION
=
"
$Revision$
"
.
split
(
'
'
)[
1
];
// 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
////////// Objects //////////
function
IRC_Server
()
{
////////// VARIABLES
// Bools/Flags that change depending on connection state.
this
.
hub
=
false
;
// are we a hub?
this
.
local
=
true
;
// are we a local socket?
this
.
pinged
=
false
;
// have we sent a PING?
this
.
server
=
true
;
// yep, we're a server.
this
.
uline
=
false
;
// are we services?
// Variables containing user/server information as we receive it.
this
.
flags
=
0
;
this
.
hops
=
0
;
this
.
hostname
=
""
;
this
.
id
=
0
;
this
.
ip
=
""
;
this
.
ircclass
=
0
;
this
.
linkparent
=
""
;
this
.
nick
=
""
;
this
.
parent
=
0
;
this
.
info
=
""
;
this
.
idletime
=
time
();
// Variables (consts, really) that point to various state information
this
.
socket
=
""
;
////////// FUNCTIONS
// Functions we use to control clients (specific)
this
.
quit
=
Server_Quit
;
this
.
work
=
Server_Work
;
this
.
netsplit
=
IRCClient_netsplit
;
// Socket functions
this
.
ircout
=
ircout
;
this
.
originatorout
=
originatorout
;
this
.
rawout
=
rawout
;
// IRC protocol sending functions
this
.
bcast_to_channel
=
IRCClient_bcast_to_channel
;
this
.
bcast_to_servers
=
IRCClient_bcast_to_servers
;
this
.
bcast_to_servers_raw
=
IRCClient_bcast_to_servers_raw
;
this
.
bcast_to_uchans_unique
=
IRCClient_bcast_to_uchans_unique
;
// Output helpers
this
.
server_nick_info
=
IRCClient_server_nick_info
;
this
.
server_chan_info
=
IRCClient_server_chan_info
;
this
.
server_info
=
IRCClient_server_info
;
this
.
synchronize
=
IRCClient_synchronize
;
this
.
reintroduce_nick
=
IRCClient_reintroduce_nick
;
this
.
finalize_server_connect
=
IRCClient_finalize_server_connect
;
// Global Functions
this
.
check_timeout
=
IRCClient_check_timeout
;
this
.
set_chanmode
=
IRCClient_set_chanmode
;
// Output helper functions (shared)
}
////////// Command Parser //////////
function
Server_Work
()
{
var
command
;
var
cmdline
;
var
origin
;
if
(
!
this
.
socket
.
is_connected
)
{
this
.
quit
(
"
Connection reset by peer
"
);
return
0
;
}
cmdline
=
this
.
socket
.
recvline
(
4096
,
0
)
if
(
cmdline
==
null
)
return
0
;
if
(
debug
)
log
(
format
(
"
[%s<-%s]: %s
"
,
servername
,
this
.
nick
,
cmdline
));
cmd
=
cmdline
.
split
(
"
"
);
if
(
cmdline
[
0
]
==
"
:
"
)
{
// Silently ignore NULL originator commands.
if
(
!
cmd
[
1
])
return
0
;
origin
=
cmd
[
0
].
slice
(
1
);
command
=
cmd
[
1
].
toUpperCase
();
cmdline
=
cmdline
.
slice
(
cmdline
.
indexOf
(
"
"
)
+
1
);
// resplit cmd[]
cmd
=
cmdline
.
split
(
"
"
);
}
else
{
command
=
cmd
[
0
].
toUpperCase
();
origin
=
this
.
nick
;
}
var
killtype
;
var
ThisOrigin
;
if
(
origin
.
match
(
/
[
.
]
/
))
{
ThisOrigin
=
Servers
[
origin
.
toLowerCase
()];
killtype
=
"
SQUIT
"
;
}
else
{
ThisOrigin
=
Users
[
origin
.
toUpperCase
()];
killtype
=
"
KILL
"
;
}
if
(
!
ThisOrigin
)
{
umode_notice
(
USERMODE_OPER
,
"
Notice
"
,
"
Server
"
+
this
.
nick
+
"
trying to pass message for non-existent origin:
"
+
origin
);
this
.
rawout
(
killtype
+
"
"
+
origin
+
"
:
"
+
servername
+
"
(
"
+
origin
+
"
(?) <-
"
+
this
.
nick
+
"
)
"
);
return
0
;
}
this
.
idletime
=
time
();
if
(
command
.
match
(
/^
[
0-9
]
+/
))
{
// passing on a numeric to the client
if
(
!
cmd
[
1
])
return
0
;
// uh...?
var
destination
=
Users
[
cmd
[
1
].
toUpperCase
()];
if
(
!
destination
)
return
0
;
destination
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
"
+
cmdline
);
return
1
;
}
switch
(
command
)
{
// PING at the top thanks to RFC1459
case
"
PING
"
:
if
(
!
cmd
[
1
])
break
;
if
(
cmd
[
2
]
&&
(
cmd
[
2
][
0
]
==
"
:
"
))
cmd
[
2
]
=
cmd
[
2
].
slice
(
1
);
var
tmp_server
;
if
(
cmd
[
2
])
tmp_server
=
searchbyserver
(
cmd
[
2
]);
if
(
tmp_server
&&
(
tmp_server
!=
-
1
)
&&
(
tmp_server
.
id
!=
ThisOrigin
.
id
))
{
tmp_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
PING
"
+
ThisOrigin
.
nick
+
"
:
"
+
tmp_server
.
nick
);
break
;
}
if
(
cmd
[
1
][
0
]
==
"
:
"
)
cmd
[
1
]
=
cmd
[
1
].
slice
(
1
);
if
(
!
cmd
[
2
])
this
.
ircout
(
"
PONG
"
+
servername
+
"
:
"
+
cmd
[
1
]);
else
this
.
ircout
(
"
PONG
"
+
cmd
[
2
]
+
"
:
"
+
cmd
[
1
]);
break
;
case
"
ADMIN
"
:
if
(
!
cmd
[
1
])
break
;
if
(
cmd
[
1
][
0
]
==
"
:
"
)
cmd
[
1
]
=
cmd
[
1
].
slice
(
1
);
if
(
IRC_match
(
servername
,
cmd
[
1
]))
{
ThisOrigin
.
do_admin
();
}
else
{
var
dest_server
=
searchbyserver
(
cmd
[
1
]);
if
(
!
dest_server
)
break
;
dest_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
ADMIN :
"
+
dest_server
.
nick
);
}
break
;
case
"
AKILL
"
:
var
this_uh
;
if
(
!
cmd
[
6
])
break
;
if
(
!
ThisOrigin
.
uline
)
{
umode_notice
(
USERMODE_OPER
,
"
Notice
"
,
"
Non-U:Lined server
"
+
ThisOrigin
.
nick
+
"
trying to utilize AKILL.
"
);
break
;
}
this_uh
=
cmd
[
2
]
+
"
@
"
+
cmd
[
1
];
if
(
isklined
(
this_uh
))
break
;
KLines
.
push
(
new
KLine
(
this_uh
,
IRC_string
(
cmdline
),
"
A
"
));
this
.
bcast_to_servers_raw
(
"
:
"
+
ThisOrigin
.
nick
+
"
"
+
cmdline
);
scan_for_klined_clients
();
break
;
case
"
AWAY
"
:
if
(
!
cmd
[
1
])
ThisOrigin
.
away
=
""
;
else
ThisOrigin
.
away
=
IRC_string
(
cmdline
);
break
;
case
"
CHATOPS
"
:
if
(
!
cmd
[
1
])
break
;
var
my_ircstr
=
IRC_string
(
cmdline
);
umode_notice
(
USERMODE_CHATOPS
,
"
ChatOps
"
,
"
from
"
+
ThisOrigin
.
nick
+
"
:
"
+
my_ircstr
);
this
.
bcast_to_servers_raw
(
"
:
"
+
ThisOrigin
.
nick
+
"
"
+
"
CHATOPS :
"
+
my_ircstr
);
break
;
case
"
CONNECT
"
:
if
(
!
cmd
[
3
]
||
!
this
.
hub
)
break
;
if
(
IRC_match
(
servername
,
cmd
[
3
]))
{
ThisOrigin
.
do_connect
(
cmd
[
1
],
cmd
[
2
]);
}
else
{
var
dest_server
=
searchbyserver
(
cmd
[
3
]);
if
(
!
dest_server
)
break
;
dest_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
CONNECT
"
+
cmd
[
1
]
+
"
"
+
cmd
[
2
]
+
"
"
+
dest_server
.
nick
);
}
break
;
case
"
GLOBOPS
"
:
if
(
!
cmd
[
1
])
break
;
var
my_ircstr
=
IRC_string
(
cmdline
);
ThisOrigin
.
globops
(
my_ircstr
);
this
.
bcast_to_servers_raw
(
"
:
"
+
ThisOrigin
.
nick
+
"
"
+
"
GLOBOPS :
"
+
my_ircstr
);
break
;
case
"
GNOTICE
"
:
if
(
!
cmd
[
1
])
break
;
var
my_ircstr
=
IRC_string
(
cmdline
);
umode_notice
(
USERMODE_ROUTING
,
"
Routing
"
,
"
from
"
+
ThisOrigin
.
nick
+
"
:
"
+
my_ircstr
);
this
.
bcast_to_servers_raw
(
"
:
"
+
ThisOrigin
.
nick
+
"
"
+
"
GNOTICE :
"
+
my_ircstr
);
break
;
case
"
ERROR
"
:
umode_notice
(
USERMODE_ROUTING
,
"
Notice
"
,
"
ERROR from
"
+
this
.
nick
+
"
[(+)0@
"
+
this
.
hostname
+
"
] --
"
+
IRC_string
(
cmdline
));
ThisOrigin
.
quit
(
IRC_string
(
cmdline
));
break
;
case
"
INFO
"
:
if
(
!
cmd
[
1
])
break
;
if
(
cmd
[
1
][
0
]
==
"
:
"
)
cmd
[
1
]
=
cmd
[
1
].
slice
(
1
);
if
(
IRC_match
(
servername
,
cmd
[
1
]))
{
ThisOrigin
.
do_info
();
}
else
{
var
dest_server
=
searchbyserver
(
cmd
[
1
]);
if
(
!
dest_server
)
break
;
dest_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
INFO :
"
+
dest_server
.
nick
);
}
break
;
case
"
INVITE
"
:
if
(
!
cmd
[
2
])
break
;
if
(
cmd
[
2
][
0
]
==
"
:
"
)
cmd
[
2
]
=
cmd
[
2
].
slice
(
1
);
var
chan
=
Channels
[
cmd
[
2
].
toUpperCase
()];
if
(
!
chan
)
break
;
if
(
!
chan
.
modelist
[
CHANMODE_OP
][
ThisOrigin
.
id
])
break
;
var
nick
=
Users
[
cmd
[
1
].
toUpperCase
()];
if
(
!
nick
)
break
;
if
(
!
nick
.
channels
[
chan
.
nam
.
toUpperCase
()])
break
;
nick
.
originatorout
(
"
INVITE
"
+
nick
.
nick
+
"
:
"
+
chan
.
nam
,
ThisOrigin
);
nick
.
invited
=
chan
.
nam
.
toUpperCase
();
break
;
case
"
JOIN
"
:
if
(
!
cmd
[
1
])
break
;
if
(
cmd
[
1
][
0
]
==
"
:
"
)
cmd
[
1
]
=
cmd
[
1
].
slice
(
1
);
var
the_channels
=
cmd
[
1
].
split
(
"
,
"
);
for
(
jchan
in
the_channels
)
{
if
(
the_channels
[
jchan
][
0
]
!=
"
#
"
)
break
;
ThisOrigin
.
do_join
(
the_channels
[
jchan
].
slice
(
0
,
max_chanlen
),
""
);
}
break
;
case
"
KICK
"
:
var
chanid
;
var
nickid
;
var
str
;
var
kick_reason
;
if
(
!
cmd
[
2
])
break
;
chanid
=
Channels
[
cmd
[
1
].
toUpperCase
()];
if
(
!
chanid
)
break
;
nickid
=
Users
[
cmd
[
2
].
toUpperCase
()];
if
(
!
nickid
)
nickid
=
search_nickbuf
(
cmd
[
2
]);
if
(
!
nickid
)
break
;
if
(
!
nickid
.
channels
[
chan
.
nam
.
toUpperCase
()])
break
;
if
(
cmd
[
3
])
kick_reason
=
IRC_string
(
cmdline
).
slice
(
0
,
max_kicklen
);
else
kick_reason
=
ThisOrigin
.
nick
;
str
=
"
KICK
"
+
chanid
.
nam
+
"
"
+
nickid
.
nick
+
"
:
"
+
kick_reason
;
ThisOrigin
.
bcast_to_channel
(
chanid
,
str
,
false
);
this
.
bcast_to_servers_raw
(
"
:
"
+
ThisOrigin
.
nick
+
"
"
+
str
);
nickid
.
rmchan
(
chanid
);
break
;
case
"
KILL
"
:
if
(
!
cmd
[
1
]
||
!
cmd
[
2
])
break
;
if
(
cmd
[
1
].
match
(
/
[
.
]
/
))
break
;
if
(
cmd
[
2
]
==
"
:
"
)
break
;
var
reason
=
IRC_string
(
cmdline
);
var
kills
=
cmd
[
1
].
split
(
"
,
"
);
for
(
kill
in
kills
)
{
var
target
=
Users
[
kills
[
kill
].
toUpperCase
()];
if
(
!
target
)
target
=
search_nickbuf
(
kills
[
kill
]);
if
(
target
&&
(
this
.
hub
||
(
target
.
parent
==
this
.
id
))
)
{
umode_notice
(
USERMODE_KILL
,
"
Notice
"
,
"
Received KILL message for
"
+
target
.
nuh
+
"
. From
"
+
ThisOrigin
.
nick
+
"
Path: target!Synchronet!
"
+
ThisOrigin
.
nick
+
"
(
"
+
reason
+
"
)
"
);
this
.
bcast_to_servers_raw
(
"
:
"
+
ThisOrigin
.
nick
+
"
KILL
"
+
target
.
nick
+
"
:
"
+
reason
);
target
.
quit
(
"
KILLED by
"
+
ThisOrigin
.
nick
+
"
(
"
+
reason
+
"
)
"
,
true
);
}
else
if
(
target
&&
!
this
.
hub
)
{
umode_notice
(
USERMODE_OPER
,
"
Notice
"
,
"
Non-Hub server
"
+
this
.
nick
+
"
trying to KILL
"
+
target
.
nick
);
this
.
reintroduce_nick
(
target
);
}
}
break
;
case
"
LINKS
"
:
if
(
!
cmd
[
1
]
||
!
cmd
[
2
])
break
;
if
(
match_irc_mask
(
servername
,
cmd
[
1
]))
{
ThisOrigin
.
do_links
(
cmd
[
2
]);
}
else
{
var
dest_server
=
searchbyserver
(
cmd
[
1
]);
if
(
!
dest_server
)
break
;
dest_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
LINKS
"
+
dest_server
.
nick
+
"
"
+
cmd
[
2
]);
}
break
;
case
"
MODE
"
:
if
(
!
cmd
[
1
]
||
!
cmd
[
2
])
break
;
if
(
cmd
[
1
][
0
]
==
"
#
"
)
{
var
chan
=
Channels
[
cmd
[
1
].
toUpperCase
()];
if
(
!
chan
)
break
;
var
modeline
;
// Detect if this is a TSMODE. If so, handle.
if
(
parseInt
(
cmd
[
2
])
==
cmd
[
2
])
{
// desynchronized MODE command.
if
(
parseInt
(
cmd
[
2
])
>
chan
.
created
)
break
;
cmd
.
shift
();
}
cmd
.
shift
();
cmd
.
shift
();
var
modeline
=
cmd
.
join
(
"
"
);
ThisOrigin
.
set_chanmode
(
chan
,
modeline
,
false
);
}
else
{
// assume it's for a user
ThisOrigin
.
setusermode
(
cmd
[
2
]);
this
.
bcast_to_servers_raw
(
"
:
"
+
ThisOrigin
.
nick
+
"
MODE
"
+
ThisOrigin
.
nick
+
"
"
+
cmd
[
2
]);
}
break
;
case
"
MOTD
"
:
if
(
!
cmd
[
1
])
break
;
if
(
cmd
[
1
][
0
]
==
"
:
"
)
cmd
[
1
]
=
cmd
[
1
].
slice
(
1
);
if
(
IRC_match
(
servername
,
cmd
[
1
]))
{
umode_notice
(
USERMODE_SPY
,
"
Spy
"
,
"
MOTD requested by
"
+
ThisOrigin
.
nick
+
"
(
"
+
ThisOrigin
.
uprefix
+
"
@
"
+
ThisOrigin
.
hostname
+
"
) [
"
+
ThisOrigin
.
servername
+
"
]
"
);
ThisOrigin
.
motd
();
}
else
{
var
dest_server
=
searchbyserver
(
cmd
[
1
]);
if
(
!
dest_server
)
break
;
dest_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
MOTD :
"
+
dest_server
.
nick
);
}
break
;
case
"
NICK
"
:
if
(
!
cmd
[
2
]
||
(
!
cmd
[
8
]
&&
(
cmd
[
2
][
0
]
!=
"
:
"
))
)
break
;
var
collide
=
Users
[
cmd
[
1
].
toUpperCase
()];
if
((
collide
)
&&
(
parseInt
(
collide
.
created
)
>
parseInt
(
cmd
[
3
])
)
&&
this
.
hub
)
{
// Nuke our side of things, allow this newly
// introduced nick to overrule.
collide
.
numeric
(
436
,
collide
.
nick
+
"
:Nickname Collision KILL.
"
);
this
.
bcast_to_servers
(
"
KILL
"
+
collide
.
nick
+
"
:Nickname Collision.
"
);
collide
.
quit
(
"
Nickname Collision
"
,
true
);
}
else
if
(
collide
&&
!
this
.
hub
)
{
umode_notice
(
USERMODE_OPER
,
"
Notice
"
,
"
Server
"
+
this
.
nick
+
"
trying to collide nick
"
+
collide
.
nick
+
"
forwards, reversing.
"
);
// Don't collide our side of things from a leaf
this
.
ircout
(
"
KILL
"
+
cmd
[
1
]
+
"
:Inverse Nickname Collision.
"
);
// Reintroduce our nick, because the remote end
// probably killed it already on our behalf.
this
.
reintroduce_nick
(
collide
);
break
;
}
else
if
(
collide
&&
this
.
hub
)
{
break
;
}
if
(
cmd
[
2
][
0
]
==
"
:
"
)
{
cmd
[
2
]
=
cmd
[
2
].
slice
(
1
);
ThisOrigin
.
created
=
parseInt
(
cmd
[
2
]);
ThisOrigin
.
bcast_to_uchans_unique
(
"
NICK
"
+
cmd
[
1
]);
this
.
bcast_to_servers_raw
(
"
:
"
+
ThisOrigin
.
nick
+
"
NICK
"
+
cmd
[
1
]
+
"
:
"
+
cmd
[
2
]);
push_nickbuf
(
ThisOrigin
.
nick
,
cmd
[
1
]);
Users
[
cmd
[
1
].
toUpperCase
()]
=
ThisOrigin
;
delete
Users
[
ThisOrigin
.
nick
.
toUpperCase
()];
ThisOrigin
.
nick
=
cmd
[
1
];
}
else
if
(
cmd
[
10
])
{
if
(
!
this
.
hub
)
{
if
(
!
this
.
check_nickname
(
cmd
[
1
]))
{
umode_notice
(
USERMODE_OPER
,
"
Notice
"
,
"
Server
"
+
this
.
nick
+
"
trying to introduce invalid nickname:
"
+
cmd
[
1
]
+
"
, killed.
"
);
this
.
ircout
(
"
KILL
"
+
cmd
[
1
]
+
"
:Bogus Nickname.
"
);
break
;
}
cmd
[
2
]
=
1
;
// Force hops to 1.
cmd
[
3
]
=
time
();
// Force TS on nick.
cmd
[
7
]
=
this
.
nick
// Force server name
}
else
{
// if we're a hub
var
test_server
=
searchbyserver
(
cmd
[
7
]);
if
(
!
test_server
||
(
this
.
nick
!=
test_server
.
parent
))
{
umode_notice
(
USERMODE_OPER
,
"
Notice
"
,
"
Server
"
+
this
.
nick
+
"
trying to introduce nick from server not behind it:
"
+
cmd
[
1
]
+
"
@
"
+
cmd
[
7
]);
this
.
ircout
(
"
KILL
"
+
cmd
[
1
]
+
"
:Invalid Origin.
"
);
break
;
}
}
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
.
nick
=
cmd
[
1
];
NewNick
.
hops
=
cmd
[
2
];
NewNick
.
created
=
cmd
[
3
];
NewNick
.
uprefix
=
cmd
[
5
];
NewNick
.
hostname
=
cmd
[
6
];
NewNick
.
servername
=
cmd
[
7
];
NewNick
.
realname
=
IRC_string
(
cmdline
,
10
);
NewNick
.
parent
=
this
.
nick
.
toLowerCase
();
NewNick
.
ip
=
int_to_ip
(
cmd
[
9
]);
NewNick
.
setusermode
(
cmd
[
4
]);
NewNick
.
local
=
false
;
// not local. duh.
for
(
u
in
ULines
)
{
if
(
ULines
[
u
]
==
cmd
[
7
])
{
NewNick
.
uline
=
true
;
break
;
}
}
var
true_hops
=
parseInt
(
NewNick
.
hops
)
+
1
;
this
.
bcast_to_servers_raw
(
"
NICK
"
+
NewNick
.
nick
+
"
"
+
true_hops
+
"
"
+
NewNick
.
created
+
"
"
+
NewNick
.
get_usermode
(
true
)
+
"
"
+
NewNick
.
uprefix
+
"
"
+
NewNick
.
hostname
+
"
"
+
NewNick
.
servername
+
"
0
"
+
cmd
[
9
]
+
"
:
"
+
NewNick
.
realname
);
}
break
;
case
"
NOTICE
"
:
if
(
!
cmd
[
1
])
break
;
var
my_ircstr
=
IRC_string
(
cmdline
);
if
(
!
cmd
[
2
]
||
(
!
cmd
[
3
]
&&
(
(
cmd
[
2
]
==
"
:
"
)
&&
(
my_ircstr
==
""
)
)
)
)
break
;
var
targets
=
cmd
[
1
].
split
(
"
,
"
);
for
(
nt
in
targets
)
{
if
(
targets
[
nt
][
0
]
!=
"
&
"
)
ThisOrigin
.
do_msg
(
targets
[
nt
],
"
NOTICE
"
,
my_ircstr
);
}
break
;
case
"
PART
"
:
if
(
!
cmd
[
1
])
break
;
var
the_channels
=
cmd
[
1
].
split
(
"
,
"
);
for
(
pchan
in
the_channels
)
{
ThisOrigin
.
do_part
(
the_channels
[
pchan
]);
}
break
;
case
"
PASS
"
:
var
result
;
if
(
!
this
.
hub
||
!
cmd
[
3
])
break
;
if
(
cmd
[
3
]
!=
"
QWK
"
)
break
;
if
(
cmd
[
2
][
0
]
==
"
:
"
)
cmd
[
2
]
=
cmd
[
2
].
slice
(
1
);
if
(
cmd
[
4
])
{
// pass the message on to target.
var
dest_server
=
searchbyserver
(
cmd
[
4
]);
if
(
!
dest_server
)
{
break
;
}
else
if
((
dest_server
==
-
1
)
&&
(
this
.
flags
&
NLINE_IS_QWKMASTER
))
{
var
qwkid
=
cmd
[
2
].
toLowerCase
();
var
hunt
=
qwkid
+
"
.synchro.net
"
;
var
my_server
=
0
;
for
(
ur
in
Unregistered
)
{
if
(
Unregistered
[
ur
].
nick
==
hunt
)
{
my_server
=
Unregistered
[
ur
];
break
;
}
}
if
(
!
my_server
)
break
;
if
(
cmd
[
1
]
!=
"
OK
"
)
{
my_server
.
quit
(
"
Server not configured.
"
);
break
;
}
Servers
[
my_server
.
nick
.
toLowerCase
()]
=
new
IRC_Server
();
var
ns
=
Servers
[
my_server
.
id
];
ns
.
id
=
my_server
.
id
;
ns
.
nick
=
my_server
.
nick
;
ns
.
info
=
my_server
.
realname
;
ns
.
socket
=
my_server
.
socket
;
delete
Unregistered
[
my_server
.
id
];
ns
.
finalize_server_connect
(
"
QWK
"
);
break
;
}
else
if
(
dest_server
)
{
if
(
dest_server
==
-
1
)
break
;
// security trap
dest_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
PASS
"
+
cmd
[
1
]
+
"
:
"
+
cmd
[
2
]
+
"
QWK
"
+
dest_server
.
nick
);
}
break
;
}
// Are we passing this on to our qwk-master?
for
(
nl
in
NLines
)
{
if
(
NLines
[
nl
].
flags
&
NLINE_IS_QWKMASTER
)
{
var
qwk_master
=
searchbyserver
(
NLines
[
nl
].
servername
);
if
(
qwk_master
)
{
qwk_master
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
PASS
"
+
cmd
[
1
]
+
"
:
"
+
cmd
[
2
]
+
"
QWK
"
);
return
0
;
}
}
}
// If we got here, we must be the qwk master. Process.
if
(
check_qwk_passwd
(
cmd
[
2
],
cmd
[
1
]))
result
=
"
OK
"
;
else
result
=
"
VOID
"
;
this
.
rawout
(
"
:
"
+
servername
+
"
PASS
"
+
result
+
"
:
"
+
cmd
[
2
]
+
"
QWK
"
+
ThisOrigin
.
nick
);
break
;
case
"
PONG
"
:
if
(
cmd
[
2
])
{
if
(
cmd
[
2
][
0
]
==
"
:
"
)
cmd
[
2
]
=
cmd
[
2
].
slice
(
1
);
var
my_server
=
searchbyserver
(
cmd
[
2
]);
if
(
!
my_server
)
{
break
;
}
else
if
(
my_server
==
-
1
)
{
var
my_nick
=
Users
[
cmd
[
2
].
toUpperCase
()];
if
(
my_nick
)
my_nick
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
PONG
"
+
cmd
[
1
]
+
"
:
"
+
my_nick
.
nick
);
else
this
.
pinged
=
false
;
break
;
}
else
if
(
my_server
)
{
my_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
PONG
"
+
cmd
[
1
]
+
"
:
"
+
cmd
[
2
]);
break
;
}
}
this
.
pinged
=
false
;
break
;
case
"
PRIVMSG
"
:
if
(
!
cmd
[
1
])
break
;
var
my_ircstr
=
IRC_string
(
cmdline
);
if
(
!
cmd
[
2
]
||
(
!
cmd
[
3
]
&&
(
(
cmd
[
2
]
==
"
:
"
)
&&
(
my_ircstr
==
""
)
)
)
)
break
;
var
targets
=
cmd
[
1
].
split
(
"
,
"
);
for
(
pm
in
targets
)
{
if
(
targets
[
pm
][
0
]
!=
"
&
"
)
ThisOrigin
.
do_msg
(
targets
[
pm
],
"
PRIVMSG
"
,
my_ircstr
);
}
break
;
case
"
QUIT
"
:
ThisOrigin
.
quit
(
IRC_string
(
cmdline
));
break
;
case
"
SERVER
"
:
if
(
!
cmd
[
3
])
break
;
// FIXME: when on Earth does this happen? :P?
if
((
cmd
[
2
]
==
1
)
&&
!
this
.
info
)
{
umode_notice
(
USERMODE_OPER
,
"
Notice
"
,
"
This wasn't supposed to happen!
"
);
this
.
nick
=
cmd
[
1
];
this
.
hops
=
1
;
this
.
info
=
IRC_string
(
cmdline
);
this
.
linkparent
=
servername
;
this
.
parent
=
this
.
nick
.
toLowerCase
();
var
newsrv
=
this
;
}
else
if
(
parseInt
(
cmd
[
2
])
>
1
)
{
if
(
this
.
hub
)
{
var
new_id
=
"
id
"
+
next_client_id
;
next_client_id
++
;
Servers
[
cmd
[
1
].
toLowerCase
()]
=
new
IRC_Server
;
var
newsrv
=
Servers
[
cmd
[
1
].
toLowerCase
()];
newsrv
.
hops
=
cmd
[
2
];
newsrv
.
nick
=
cmd
[
1
];
newsrv
.
info
=
IRC_string
(
cmdline
);
newsrv
.
parent
=
this
.
nick
.
toLowerCase
();
newsrv
.
linkparent
=
ThisOrigin
.
nick
;
newsrv
.
local
=
false
;
for
(
u
in
ULines
)
{
if
(
ULines
[
u
]
==
cmd
[
1
])
{
newsrv
.
uline
=
true
;
break
;
}
}
}
else
{
umode_notice
(
USERMODE_ROUTING
,
"
Routing
"
,
"
from
"
+
servername
+
"
: Non-Hub link
"
+
this
.
nick
+
"
introduced
"
+
cmd
[
1
]
+
"
(*).
"
);
this
.
quit
(
"
Too many servers. You have no H:Line to introduce
"
+
cmd
[
1
]
+
"
.
"
,
true
);
return
0
;
}
}
else
{
break
;
}
this
.
bcast_to_servers_raw
(
"
:
"
+
newsrv
.
linkparent
+
"
SERVER
"
+
newsrv
.
nick
+
"
"
+
(
parseInt
(
newsrv
.
hops
)
+
1
)
+
"
:
"
+
newsrv
.
realname
);
break
;
case
"
SJOIN
"
:
if
(
!
cmd
[
2
])
break
;
if
(
cmd
[
2
][
0
]
!=
"
#
"
)
break
;
var
chan_members
;
var
cm_array
;
if
(
cmd
[
3
])
{
var
mode_args
=
""
;
var
tmp_modeargs
=
0
;
for
(
tmpmc
in
cmd
[
3
])
{
if
((
cmd
[
3
][
tmpmc
]
==
"
k
"
)
||
(
cmd
[
3
][
tmpmc
]
==
"
l
"
))
{
tmp_modeargs
++
;
mode_args
+=
cmd
[
3
+
tmp_modeargs
];
}
}
if
((
cmd
[
4
]
==
""
)
&&
cmd
[
5
])
tmp_modeargs
++
;
chan_members
=
IRC_string
(
cmdline
,
4
+
tmp_modeargs
).
split
(
'
'
);
if
(
chan_members
==
""
)
{
umode_notice
(
USERMODE_OPER
,
"
Notice
"
,
"
Server
"
+
this
.
nick
+
"
trying to SJOIN empty channel
"
+
cmd
[
2
]
+
"
before processing.
"
);
break
;
}
cm_array
=
new
Array
;
for
(
cm
in
chan_members
)
{
var
isop
=
false
;
var
isvoice
=
false
;
if
(
chan_members
[
cm
][
0
]
==
"
@
"
)
{
isop
=
true
;
chan_members
[
cm
]
=
chan_members
[
cm
].
slice
(
1
);
}
if
(
chan_members
[
cm
][
0
]
==
"
+
"
)
{
isvoice
=
true
;
chan_members
[
cm
]
=
chan_members
[
cm
].
slice
(
1
);
}
var
tmp_nick
=
Users
[
chan_members
[
cm
].
toUpperCase
()];
if
(
!
tmp_nick
)
continue
;
cm_array
.
push
(
new
SJOIN_Nick
(
tmp_nick
,
isop
,
isvoice
));
}
if
(
cm_array
.
length
<
1
)
{
umode_notice
(
USERMODE_OPER
,
"
Notice
"
,
"
Server
"
+
this
.
nick
+
"
trying to SJOIN empty channel
"
+
cmd
[
2
]
+
"
post processing.
"
);
break
;
}
}
var
cn_tuc
=
cmd
[
2
].
toUpperCase
();
var
chan
=
Channels
[
cmd
[
2
].
toUpperCase
()];
if
(
!
chan
)
{
Channels
[
cn_tuc
]
=
new
Channel
(
cn_tuc
);
chan
=
Channels
[
cn_tuc
];
chan
.
nam
=
cmd
[
2
];
chan
.
created
=
parseInt
(
cmd
[
1
]);
chan
.
topic
=
""
;
chan
.
users
=
new
Array
;
chan
.
modelist
[
CHANMODE_BAN
]
=
new
Array
;
chan
.
modelist
[
CHANMODE_VOICE
]
=
new
Array
;
chan
.
modelist
[
CHANMODE_OP
]
=
new
Array
;
chan
.
mode
=
CHANMODE_NONE
;
}
if
(
cmd
[
3
])
{
var
bounce_modes
=
true
;
if
(
!
ThisOrigin
.
local
||
(
chan
.
created
==
parseInt
(
cmd
[
1
])))
bounce_modes
=
false
;
if
(
chan
.
created
>=
parseInt
(
cmd
[
1
]))
{
if
(
mode_args
)
this
.
set_chanmode
(
chan
,
cmd
[
3
]
+
"
"
+
mode_args
,
bounce_modes
);
else
this
.
set_chanmode
(
chan
,
cmd
[
3
],
bounce_modes
);
}
var
num_sync_modes
=
0
;
var
push_sync_modes
=
"
+
"
;
var
push_sync_args
=
""
;
var
new_chan_members
=
""
;
for
(
member
in
cm_array
)
{
if
(
new_chan_members
)
new_chan_members
+=
"
"
;
var
member_obj
=
cm_array
[
member
].
nick
;
var
is_voice
=
cm_array
[
member
].
isvoice
;
var
is_op
=
cm_array
[
member
].
isop
;
if
(
member_obj
.
channels
[
chan
.
nam
.
toUpperCase
()])
continue
;
member_obj
.
channels
[
chan
.
nam
.
toUpperCase
()]
=
chan
;
chan
.
users
[
member_obj
.
id
]
=
member_obj
;
member_obj
.
bcast_to_channel
(
chan
,
"
JOIN
"
+
chan
.
nam
,
false
);
if
(
chan
.
created
>=
parseInt
(
cmd
[
1
]))
{
if
(
is_op
)
{
chan
.
modelist
[
CHANMODE_OP
][
member_obj
.
id
]
=
member_obj
.
id
;
push_sync_modes
+=
"
o
"
;
push_sync_args
+=
"
"
+
member_obj
.
nick
;
num_sync_modes
++
;
new_chan_members
+=
"
@
"
;
}
if
(
num_sync_modes
>=
max_modes
)
{
this
.
bcast_to_channel
(
chan
,
"
MODE
"
+
chan
.
nam
+
"
"
+
push_sync_modes
+
push_sync_args
);
push_sync_modes
=
"
+
"
;
push_sync_args
=
""
;
num_sync_modes
=
0
;
}
if
(
is_voice
)
{
chan
.
modelist
[
CHANMODE_VOICE
][
member_obj
.
id
]
=
member_obj
;
push_sync_modes
+=
"
v
"
;
push_sync_args
+=
"
"
+
member_obj
.
nick
;
num_sync_modes
++
;
new_chan_members
+=
"
+
"
;
}
if
(
num_sync_modes
>=
max_modes
)
{
this
.
bcast_to_channel
(
chan
,
"
MODE
"
+
chan
.
nam
+
"
"
+
push_sync_modes
+
push_sync_args
);
push_sync_modes
=
"
+
"
;
push_sync_args
=
""
;
num_sync_modes
=
0
;
}
}
new_chan_members
+=
member_obj
.
nick
;
}
if
(
num_sync_modes
)
this
.
bcast_to_channel
(
chan
,
"
MODE
"
+
chan
.
nam
+
"
"
+
push_sync_modes
+
push_sync_args
);
// Synchronize the TS to what we received.
if
(
chan
.
created
>
parseInt
(
cmd
[
1
]))
chan
.
created
=
parseInt
(
cmd
[
1
]);
this
.
bcast_to_servers_raw
(
"
:
"
+
ThisOrigin
.
nick
+
"
SJOIN
"
+
chan
.
created
+
"
"
+
chan
.
nam
+
"
"
+
chan
.
chanmode
(
true
)
+
"
:
"
+
new_chan_members
)
}
else
{
if
(
ThisOrigin
.
channels
[
chan
.
nam
.
toUpperCase
()])
break
;
ThisOrigin
.
channels
[
chan
.
nam
.
toUpperCase
()]
=
chan
;
chan
.
users
[
ThisOrigin
.
id
]
=
ThisOrigin
;
ThisOrigin
.
bcast_to_channel
(
chan
,
"
JOIN
"
+
chan
.
nam
,
false
);
this
.
bcast_to_servers_raw
(
"
:
"
+
ThisOrigin
.
nick
+
"
SJOIN
"
+
chan
.
created
+
"
"
+
chan
.
nam
);
}
break
;
case
"
SQUIT
"
:
var
sq_server
;
var
reason
;
if
(
!
cmd
[
1
]
||
!
this
.
hub
)
sq_server
=
this
;
else
sq_server
=
searchbyserver
(
cmd
[
1
]);
if
(
!
sq_server
)
break
;
reason
=
IRC_string
(
cmdline
);
if
(
!
reason
||
!
cmd
[
2
])
reason
=
ThisOrigin
.
nick
;
if
(
sq_server
==
-
1
)
{
this
.
bcast_to_servers_raw
(
"
SQUIT
"
+
this
.
nick
+
"
:Forwards SQUIT.
"
);
this
.
quit
(
"
Forwards SQUIT.
"
,
true
);
break
;
}
// message from our uplink telling us a server is gone
if
(
this
.
id
==
sq_server
.
parent
)
{
sq_server
.
quit
(
reason
,
false
,
false
,
ThisOrigin
);
break
;
}
// oper or server going for squit of a server
if
(
!
sq_server
.
local
)
{
sq_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
SQUIT
"
+
sq_server
.
nick
+
"
:
"
+
reason
);
break
;
}
var
msg
=
"
Received SQUIT
"
+
cmd
[
1
]
+
"
from
"
+
ThisOrigin
.
nick
+
"
(
"
+
reason
+
"
)
"
;
server_bcast_to_servers
(
"
GNOTICE :
"
+
msg
);
umode_notice
(
USERMODE_ROUTING
,
"
Routing
"
,
"
from
"
+
servername
+
"
:
"
+
msg
);
sq_server
.
quit
(
reason
);
break
;
case
"
STATS
"
:
if
(
!
cmd
[
2
])
break
;
if
(
cmd
[
2
][
0
]
==
"
:
"
)
cmd
[
2
]
=
cmd
[
2
].
slice
(
1
);
if
(
IRC_match
(
servername
,
cmd
[
2
]))
{
ThisOrigin
.
do_stats
(
cmd
[
1
][
0
]);
}
else
{
var
dest_server
=
searchbyserver
(
cmd
[
2
]);
if
(
!
dest_server
)
break
;
dest_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
STATS
"
+
cmd
[
1
][
0
]
+
"
:
"
+
dest_server
.
nick
);
}
break
;
case
"
SUMMON
"
:
if
(
!
cmd
[
2
])
break
;
if
(
cmd
[
2
][
0
]
==
"
:
"
)
cmd
[
2
]
=
cmd
[
2
].
slice
(
1
);
if
(
IRC_match
(
servername
,
cmd
[
2
]))
{
if
(
enable_users_summon
)
{
ThisOrigin
.
do_summon
(
cmd
[
1
]);
}
else
{
ThisOrigin
.
numeric445
();
break
;
}
}
else
{
var
dest_server
=
searchbyserver
(
cmd
[
1
]);
if
(
!
dest_server
)
break
;
dest_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
SUMMON
"
+
cmd
[
1
]
+
"
:
"
+
dest_server
.
nick
);
}
break
;
case
"
TIME
"
:
if
(
!
cmd
[
1
])
break
;
if
(
cmd
[
1
][
0
]
==
"
:
"
)
cmd
[
1
]
=
cmd
[
1
].
slice
(
1
);
if
(
IRC_match
(
servername
,
cmd
[
1
]))
{
ThisOrigin
.
numeric391
();
}
else
{
var
dest_server
=
searchbyserver
(
cmd
[
1
]);
if
(
!
dest_server
)
break
;
dest_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
TIME :
"
+
dest_server
.
nick
);
}
break
;
case
"
TOPIC
"
:
if
(
!
cmd
[
4
])
break
;
var
chan
=
Channels
[
cmd
[
1
].
toUpperCase
()];
if
(
!
chan
)
break
;
var
the_topic
=
IRC_string
(
cmdline
);
if
(
the_topic
==
chan
.
topic
)
break
;
chan
.
topic
=
the_topic
;
if
(
this
.
hub
)
chan
.
topictime
=
cmd
[
3
];
else
chan
.
topictime
=
time
();
chan
.
topicchangedby
=
cmd
[
2
];
var
str
=
"
TOPIC
"
+
chan
.
nam
+
"
:
"
+
chan
.
topic
;
ThisOrigin
.
bcast_to_channel
(
chan
,
str
,
false
);
this
.
bcast_to_servers_raw
(
"
:
"
+
ThisOrigin
.
nick
+
"
TOPIC
"
+
chan
.
nam
+
"
"
+
ThisOrigin
.
nick
+
"
"
+
chan
.
topictime
+
"
:
"
+
chan
.
topic
);
break
;
case
"
TRACE
"
:
if
(
!
cmd
[
1
])
break
;
ThisOrigin
.
do_trace
(
cmd
[
1
]);
break
;
case
"
USERS
"
:
if
(
!
cmd
[
1
])
break
;
if
(
cmd
[
1
][
0
]
==
"
:
"
)
cmd
[
1
]
=
cmd
[
1
].
slice
(
1
);
if
(
IRC_match
(
servername
,
cmd
[
1
]))
{
ThisOrigin
.
numeric351
();
}
else
{
// psst, pass it on
var
dest_server
=
searchbyserver
(
cmd
[
1
]);
if
(
!
dest_server
)
break
;
dest_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
VERSION :
"
+
dest_server
.
nick
);
}
break
;
case
"
VERSION
"
:
if
(
!
cmd
[
1
])
break
;
if
(
cmd
[
1
][
0
]
==
"
:
"
)
cmd
[
1
]
=
cmd
[
1
].
slice
(
1
);
if
(
IRC_match
(
servername
,
cmd
[
1
]))
{
// it's for us, return the message
ThisOrigin
.
numeric351
();
}
else
{
// psst, pass it on
var
dest_server
=
searchbyserver
(
cmd
[
1
]);
if
(
!
dest_server
)
break
;
// someone messed up.
dest_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
VERSION :
"
+
dest_server
.
nick
);
}
break
;
case
"
WALLOPS
"
:
if
(
!
cmd
[
1
])
break
;
var
str
=
"
:
"
+
ThisOrigin
.
nick
+
"
WALLOPS :
"
+
IRC_string
(
cmdline
);
wallopers
(
str
);
this
.
bcast_to_servers_raw
(
str
);
break
;
case
"
WHOIS
"
:
if
(
!
cmd
[
2
])
break
;
if
(
cmd
[
2
][
0
]
==
"
:
"
)
cmd
[
2
]
=
cmd
[
2
].
slice
(
1
);
if
(
IRC_match
(
servername
,
cmd
[
2
]))
{
var
wi_nicks
=
cmd
[
1
].
split
(
"
,
"
);
for
(
wi_nick
in
wi_nicks
)
{
var
wi
=
Users
[
wi_nicks
[
wi_nick
].
toUpperCase
()];
if
(
wi
)
ThisOrigin
.
do_whois
(
wi
);
else
ThisOrigin
.
numeric401
(
wi_nicks
[
wi_nick
]);
}
ThisOrigin
.
numeric
(
318
,
wi_nicks
[
0
]
+
"
:End of /WHOIS list.
"
);
}
else
{
var
dest_server
=
searchbyserver
(
cmd
[
2
]);
if
(
!
dest_server
)
break
;
dest_server
.
rawout
(
"
:
"
+
ThisOrigin
.
nick
+
"
WHOIS
"
+
cmd
[
1
]
+
"
"
+
dest_server
.
nick
);
}
break
;
default
:
umode_notice
(
USERMODE_OPER
,
"
Notice
"
,
"
Server
"
+
ThisOrigin
.
nick
+
"
sent unrecognized command:
"
+
cmdline
);
break
;
}
}
////////// Functions //////////
function
server_bcast_to_servers
(
str
)
{
for
(
thisClient
in
Local_Servers
)
{
Local_Servers
[
thisClient
].
rawout
(
str
);
}
}
function
IRCClient_bcast_to_servers
(
str
)
{
for
(
thisClient
in
Local_Servers
)
{
if
(
Local_Servers
[
thisClient
].
nick
!=
this
.
parent
)
Local_Servers
[
thisClient
].
originatorout
(
str
,
this
);
}
}
function
IRCClient_bcast_to_servers_raw
(
str
)
{
for
(
thisClient
in
Local_Servers
)
{
if
(
Local_Servers
[
thisClient
].
nick
!=
this
.
parent
)
Local_Servers
[
thisClient
].
rawout
(
str
);
}
}
function
Server_Quit
(
str
,
suppress_bcast
,
is_netsplit
,
origin
)
{
var
tmp
;
if
(
!
str
)
str
=
this
.
nick
;
if
(
is_netsplit
)
{
this
.
netsplit
(
str
);
}
else
if
(
this
.
local
)
{
if
(
!
suppress_bcast
)
this
.
bcast_to_servers_raw
(
"
SQUIT
"
+
this
.
nick
+
"
:
"
+
str
);
this
.
netsplit
(
servername
+
"
"
+
this
.
nick
);
}
else
if
(
origin
)
{
if
(
!
suppress_bcast
)
this
.
bcast_to_servers_raw
(
"
:
"
+
origin
.
nick
+
"
SQUIT
"
+
this
.
nick
+
"
:
"
+
str
);
this
.
netsplit
(
origin
.
nick
+
"
"
+
this
.
nick
);
}
else
{
umode_notice
(
USERMODE_OPER
,
"
Notice
"
,
"
Netspliting a server which isn't local and doesn't
"
+
"
have an origin?!
"
);
if
(
!
suppress_bcast
)
this
.
bcast_to_servers_raw
(
"
SQUIT
"
+
this
.
nick
+
"
:
"
+
str
);
this
.
netsplit
();
}
if
((
server
.
client_remove
!=
undefined
)
&&
this
.
local
)
server
.
client_remove
(
this
.
socket
);
if
(
this
.
local
)
{
this
.
rawout
(
"
ERROR :Closing Link: [
"
+
this
.
uprefix
+
"
@
"
+
this
.
hostname
+
"
] (
"
+
str
+
"
)
"
);
// FIXME: wrong phrasing below
umode_notice
(
USERMODE_CLIENT
,
"
Client
"
,
"
SERVER exiting:
"
+
this
.
nick
+
"
(
"
+
this
.
uprefix
+
"
@
"
+
this
.
hostname
+
"
) [
"
+
str
+
"
] [
"
+
this
.
ip
+
"
]
"
);
if
(
this
.
socket
!=
undefined
)
this
.
socket
.
close
();
delete
Local_Sockets
[
this
.
id
];
}
delete
Local_Sockets
[
this
.
id
];
delete
Local_Sockets_Map
[
this
.
id
];
delete
Local_Servers
[
this
.
id
];
delete
Servers
[
this
.
nick
.
toLowerCase
()];
delete
this
;
rebuild_socksel_array
();
}
function
IRCClient_synchronize
()
{
this
.
rawout
(
"
BURST
"
);
// warn of impending synchronization
for
(
my_server
in
Servers
)
{
if
(
Servers
[
my_server
].
id
!=
this
.
id
)
this
.
server_info
(
Servers
[
my_server
]);
}
for
(
my_client
in
Users
)
{
this
.
server_nick_info
(
Users
[
my_client
]);
}
for
(
my_channel
in
Channels
)
{
if
(
my_channel
[
0
]
==
"
#
"
)
this
.
server_chan_info
(
Channels
[
my_channel
]);
}
umode_notice
(
USERMODE_ROUTING
,
"
Routing
"
,
"
from
"
+
servername
+
"
:
"
+
this
.
nick
+
"
has processed user/channel burst,
"
+
"
sending topic burst.
"
);
for
(
my_channel
in
Channels
)
{
if
((
my_channel
[
0
]
==
"
#
"
)
&&
Channels
[
my_channel
].
topic
)
{
var
chan
=
Channels
[
my_channel
];
this
.
rawout
(
"
TOPIC
"
+
chan
.
nam
+
"
"
+
chan
.
topicchangedby
+
"
"
+
chan
.
topictime
+
"
:
"
+
chan
.
topic
);
}
}
this
.
rawout
(
"
BURST 0
"
);
// burst completed.
umode_notice
(
USERMODE_ROUTING
,
"
Routing
"
,
"
from
"
+
servername
+
"
:
"
+
this
.
nick
+
"
has processed topic burst
"
+
"
(synched to network data).
"
);
}
function
IRCClient_server_info
(
sni_server
)
{
var
realhops
=
parseInt
(
sni_server
.
hops
)
+
1
;
this
.
rawout
(
"
:
"
+
sni_server
.
linkparent
+
"
SERVER
"
+
sni_server
.
nick
+
"
"
+
realhops
+
"
:
"
+
sni_server
.
info
);
}
function
IRCClient_server_nick_info
(
sni_client
)
{
var
actual_hops
=
parseInt
(
sni_client
.
hops
)
+
1
;
this
.
rawout
(
"
NICK
"
+
sni_client
.
nick
+
"
"
+
actual_hops
+
"
"
+
sni_client
.
created
+
"
"
+
sni_client
.
get_usermode
(
true
)
+
"
"
+
sni_client
.
uprefix
+
"
"
+
sni_client
.
hostname
+
"
"
+
sni_client
.
servername
+
"
0
"
+
ip_to_int
(
sni_client
.
ip
)
+
"
:
"
+
sni_client
.
realname
);
if
(
sni_client
.
away
)
this
.
rawout
(
"
:
"
+
sni_client
.
nick
+
"
AWAY :
"
+
sni_client
.
away
);
}
function
IRCClient_reintroduce_nick
(
nick
)
{
var
chan
;
var
cmodes
;
this
.
server_nick_info
(
nick
);
for
(
uchan
in
nick
.
channels
)
{
cmodes
=
""
;
chan
=
nick
.
channels
[
uchan
];
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
);
if
(
chan
.
topic
)
this
.
rawout
(
"
TOPIC
"
+
chan
.
nam
+
"
"
+
chan
.
topicchangedby
+
"
"
+
chan
.
topictime
+
"
:
"
+
chan
.
topic
);
}
}
function
IRCClient_server_chan_info
(
sni_chan
)
{
this
.
rawout
(
"
SJOIN
"
+
sni_chan
.
created
+
"
"
+
sni_chan
.
nam
+
"
"
+
sni_chan
.
chanmode
(
true
)
+
"
:
"
+
sni_chan
.
occupants
())
var
modecounter
=
0
;
var
modestr
=
"
+
"
;
var
modeargs
=
""
;
for
(
aBan
in
sni_chan
.
modelist
[
CHANMODE_BAN
])
{
modecounter
++
;
modestr
+=
"
b
"
;
if
(
modeargs
)
modeargs
+=
"
"
;
modeargs
+=
sni_chan
.
modelist
[
CHANMODE_BAN
][
aBan
];
if
(
modecounter
>=
max_modes
)
{
this
.
ircout
(
"
MODE
"
+
sni_chan
.
nam
+
"
"
+
modestr
+
"
"
+
modeargs
);
modecounter
=
0
;
modestr
=
"
+
"
;
modeargs
=
""
;
}
}
if
(
modeargs
)
this
.
ircout
(
"
MODE
"
+
sni_chan
.
nam
+
"
"
+
modestr
+
"
"
+
modeargs
);
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment