diff --git a/lib/irc/msg.ml b/lib/irc/msg.ml index fd029eb..4957005 100644 --- a/lib/irc/msg.ml +++ b/lib/irc/msg.ml @@ -3,7 +3,7 @@ open Types type prefix = | No_prefix | Server_prefix of string - | User_prefix of nick * userinfo option * string option + | User_prefix of name * userinfo option * string option let pp_userinfo_opt ppf = function | None -> () diff --git a/lib/irc/msg.mli b/lib/irc/msg.mli index 40c8390..f4ead93 100644 --- a/lib/irc/msg.mli +++ b/lib/irc/msg.mli @@ -3,7 +3,7 @@ open Types type prefix = | No_prefix | Server_prefix of string - | User_prefix of nick * userinfo option * string option + | User_prefix of name * userinfo option * string option val prefix_string : prefix -> string diff --git a/lib/irc/types.ml b/lib/irc/types.ml index 930f3c7..297ee95 100644 --- a/lib/irc/types.ml +++ b/lib/irc/types.ml @@ -1,2 +1,17 @@ -type nick = string +type name = string type userinfo = { username : string; realname : string } + +let name_type s = + let rec valid i = + if i >= String.length s then true + else + match s.[i] with + | ' ' | '@' | '+' | ',' -> false + | _ -> valid (i + 1) + in + if s = "" then `invalid + else + match s.[0] with + | ':' -> `invalid + | '#' -> if valid 1 then `chan else `invalid + | _ -> if valid 0 then `nick else `invalid diff --git a/lib/server/connection.ml b/lib/server/connection.ml index dc7f050..a3dcc0f 100644 --- a/lib/server/connection.ml +++ b/lib/server/connection.ml @@ -51,11 +51,14 @@ let attempt_to_register t = | _, _ -> `ok let on_msg_nick t nick = - (* TODO: validate nick *) - if User.is_registered t.user then + if Irc.name_type nick <> `nick then + (if nick = "" then `nonicknamegiven else `erroneusnickname nick) + else if User.is_registered t.user then match User.set_nick t.user nick with | `nick_in_use -> `nicknameinuse nick - | `nick_set -> `ok + | `nick_set -> + ((* TODO: relay NICK message *)); + `ok else begin t.pending_nick <- Some nick; attempt_to_register t @@ -141,14 +144,16 @@ let rpl_names t chan_prefix chan users = rpl t "366" [chan; "End of NAMES list"] end -let err_alreadyregistered t = rpl t "462" ["Unauthorized command (already registered)"] -let err_needmoreparams t cmd = rpl t "461" [cmd; "Not enough parameters"] -let err_nicknameinuse t nick = rpl t "433" [nick; "Nickname is already in use"] -let err_norecipient t cmd = rpl t "411" [Fmt.str "No recipient given (%s)" cmd] let err_nosuchnick t tgt = rpl t "401" [tgt; "No such nick/channel"] +let err_norecipient t cmd = rpl t "411" [Fmt.str "No recipient given (%s)" cmd] let err_notexttosend t = rpl t "412" ["No text to send"] -let err_notregistered t = rpl t "451" ["You have not registered"] let err_unknowncommand t cmd = rpl t "421" [cmd; "Unknown command"] +let err_nonicknamegiven t = rpl t "431" ["No nickname given"] +let err_erroneousnickname t nick = rpl t "432" [nick; "Erroneus nickname"] +let err_nicknameinuse t nick = rpl t "433" [nick; "Nickname is already in use"] +let err_notregistered t = rpl t "451" ["You have not registered"] +let err_needmoreparams t cmd = rpl t "461" [cmd; "Not enough parameters"] +let err_alreadyregistered t = rpl t "462" ["Unauthorized command (already registered)"] (* message parsing *) @@ -158,6 +163,7 @@ let on_msg t (msg : Irc.Msg.t) : unit = match msg.command, msg.params with | "NICK", new_nick :: _ -> on_msg_nick t new_nick + | "NICK", [] -> `nonicknamegiven | "USER", username :: modestr :: _host :: realname :: _ -> on_msg_user t username modestr realname | "QUIT", why -> @@ -168,7 +174,7 @@ let on_msg t (msg : Irc.Msg.t) : unit = | "PRIVMSG", [_] -> `notexttosend | "PRIVMSG", [] -> `norecipient | "JOIN", tgt :: _ -> on_msg_join t tgt - | "NICK", _ | "USER", _ | "JOIN", _ -> `needmoreparams + | "USER", _ | "JOIN", _ -> `needmoreparams | _, _ -> `unknowncommand in match result with @@ -186,3 +192,5 @@ let on_msg t (msg : Irc.Msg.t) : unit = | `notexttosend -> err_notexttosend t | `notregistered -> err_notregistered t | `unknowncommand -> err_unknowncommand t msg.command + | `nonicknamegiven -> err_nonicknamegiven t + | `erroneusnickname n -> err_erroneousnickname t n diff --git a/lib/server/router.ml b/lib/server/router.ml index aa5c51c..8cad975 100644 --- a/lib/server/router.ml +++ b/lib/server/router.ml @@ -10,7 +10,7 @@ and user = { hostname : string; outbox : Outbox.t; mutable key : string_ci; - mutable nick : Irc.nick; + mutable nick : Irc.name; mutable userinfo : Irc.userinfo option; mutable mode : Irc.Mode.t; }