2008-02-27 22:50:27 -07:00
|
|
|
open Irc
|
|
|
|
|
2008-03-04 21:38:19 -07:00
|
|
|
|
|
|
|
|
2008-02-27 22:50:27 -07:00
|
|
|
(* ==========================================
|
|
|
|
* Client stuff
|
|
|
|
*)
|
2008-03-04 21:38:19 -07:00
|
|
|
type t = {iobuf: Iobuf.t;
|
2008-02-28 22:00:24 -07:00
|
|
|
nick: string ref;
|
2008-03-04 21:38:19 -07:00
|
|
|
username: string;
|
|
|
|
realname: string}
|
|
|
|
|
|
|
|
exception Error of Command.t
|
2008-02-28 22:00:24 -07:00
|
|
|
|
2008-03-02 21:30:37 -07:00
|
|
|
let modes = "l"
|
|
|
|
|
2008-03-01 21:38:05 -07:00
|
|
|
let dbg msg a = prerr_endline msg; a
|
2008-02-28 22:00:24 -07:00
|
|
|
|
|
|
|
let by_file_descr = Hashtbl.create 25
|
|
|
|
let by_nick = Hashtbl.create 25
|
|
|
|
|
2008-03-04 21:38:19 -07:00
|
|
|
let error num args text =
|
|
|
|
Error (Command.create (Some !(Irc.name)) num args (Some text))
|
2008-02-28 22:00:24 -07:00
|
|
|
|
|
|
|
let close cli ues g fd =
|
|
|
|
Hashtbl.remove by_nick !(cli.nick);
|
|
|
|
Hashtbl.remove by_file_descr fd;
|
2008-02-27 22:50:27 -07:00
|
|
|
Unix.close fd;
|
|
|
|
Unixqueue.remove_resource ues g (Unixqueue.Wait_in fd);
|
|
|
|
try
|
|
|
|
Unixqueue.remove_resource ues g (Unixqueue.Wait_out fd);
|
|
|
|
with Not_found ->
|
|
|
|
()
|
|
|
|
|
2008-02-28 22:00:24 -07:00
|
|
|
let write cli cmd =
|
2008-03-04 21:38:19 -07:00
|
|
|
Iobuf.write cli.iobuf cmd
|
2008-02-27 22:50:27 -07:00
|
|
|
|
2008-03-04 21:38:19 -07:00
|
|
|
let reply cli num text =
|
|
|
|
write cli (Command.create
|
|
|
|
(Some !(Irc.name)) num [!(cli.nick)] (Some text))
|
2008-02-28 22:00:24 -07:00
|
|
|
|
2008-03-04 21:38:19 -07:00
|
|
|
let handle_command cli iobuf cmd =
|
2008-03-02 21:30:37 -07:00
|
|
|
write cli cmd
|
2008-02-27 22:50:27 -07:00
|
|
|
|
2008-03-04 21:38:19 -07:00
|
|
|
let set_nick cli nick =
|
|
|
|
if Hashtbl.mem by_nick nick then
|
|
|
|
raise (error "433" [nick] "Nickname in use");
|
|
|
|
Hashtbl.remove by_nick !(cli.nick);
|
|
|
|
Hashtbl.replace by_nick nick cli;
|
|
|
|
cli.nick := nick
|
|
|
|
|
|
|
|
let rec handle_command_prereg (nick', username', realname', password') iobuf cmd =
|
2008-02-27 22:50:27 -07:00
|
|
|
(* Handle a command during the login phase *)
|
2008-03-04 21:38:19 -07:00
|
|
|
let acc =
|
2008-03-02 21:30:37 -07:00
|
|
|
match (Command.as_tuple cmd) with
|
2008-03-04 21:38:19 -07:00
|
|
|
| (None, "PASS", [password], None) ->
|
|
|
|
(nick', username', realname', Some password)
|
2008-03-02 21:30:37 -07:00
|
|
|
| (None, "USER", [username; _; _], Some realname) ->
|
2008-03-04 21:38:19 -07:00
|
|
|
(nick', Some username, Some (Irc.truncate realname 40), password')
|
2008-03-02 21:30:37 -07:00
|
|
|
| (None, "NICK", [nick], None) ->
|
2008-03-04 21:38:19 -07:00
|
|
|
(Some nick, username', realname', password')
|
2008-03-02 21:30:37 -07:00
|
|
|
| _ ->
|
2008-03-04 21:38:19 -07:00
|
|
|
Iobuf.write iobuf (Command.create
|
|
|
|
(Some !(Irc.name))
|
|
|
|
"451" ["*"]
|
|
|
|
(Some "Register first."));
|
|
|
|
(nick', username', realname', password')
|
2008-02-29 17:16:00 -07:00
|
|
|
in
|
2008-03-04 21:38:19 -07:00
|
|
|
let welcome cli =
|
|
|
|
try
|
|
|
|
set_nick cli !(cli.nick);
|
|
|
|
reply cli "001" "Welcome to IRC.";
|
|
|
|
reply cli "002" ("I am " ^ !(Irc.name) ^
|
|
|
|
" Running version " ^ Irc.version);
|
|
|
|
reply cli "003" "This server was created sometime";
|
|
|
|
reply cli "004" (!(Irc.name) ^
|
|
|
|
" " ^ Irc.version ^
|
|
|
|
" " ^ modes ^
|
|
|
|
" " ^ Channel.modes);
|
|
|
|
Iobuf.rebind iobuf (handle_command cli)
|
|
|
|
with Error cmd ->
|
|
|
|
Iobuf.write iobuf cmd
|
2008-02-28 22:00:24 -07:00
|
|
|
in
|
2008-03-04 21:38:19 -07:00
|
|
|
match acc with
|
|
|
|
| (Some nick, Some username, Some realname, None) ->
|
|
|
|
welcome {iobuf = iobuf;
|
|
|
|
nick = ref nick;
|
|
|
|
username = username;
|
|
|
|
realname = realname}
|
|
|
|
| (Some nick, Some username, Some realname, Some password) ->
|
|
|
|
Iobuf.write iobuf (Command.create
|
|
|
|
(Some !(Irc.name))
|
|
|
|
"NOTICE" ["AUTH"]
|
|
|
|
(Some "*** Authentication unimplemented"));
|
|
|
|
welcome {iobuf = iobuf;
|
|
|
|
nick = ref nick;
|
|
|
|
username = username;
|
|
|
|
realname = realname}
|
|
|
|
| _ ->
|
|
|
|
Iobuf.rebind iobuf (handle_command_prereg acc)
|
|
|
|
|
|
|
|
let create_command_handler () =
|
|
|
|
handle_command_prereg (None, None, None, None)
|