From baf83e73d28432bed1f8aa46cd73cdda8db91855 Mon Sep 17 00:00:00 2001 From: Jeremy Latt Date: Mon, 17 Feb 2014 22:10:48 -0800 Subject: [PATCH] support USER from both RFCs 1459 and 2812 --- irc/client.go | 1 + irc/commands.go | 68 ++++++++++++++++++++++++++++++++++++------------- irc/server.go | 22 +++++++++++++--- 3 files changed, 71 insertions(+), 20 deletions(-) diff --git a/irc/client.go b/irc/client.go index 3eaa0d68..7058c8e1 100644 --- a/irc/client.go +++ b/irc/client.go @@ -254,5 +254,6 @@ func (client *Client) Quit(message string) { channel.Quit(client) } + client.Reply(RplError(client.server, client)) client.Destroy() } diff --git a/irc/commands.go b/irc/commands.go index db9724d3..9662f91a 100644 --- a/irc/commands.go +++ b/irc/commands.go @@ -39,7 +39,7 @@ var ( PROXY: NewProxyCommand, QUIT: NewQuitCommand, TOPIC: NewTopicCommand, - USER: NewUserMsgCommand, + USER: NewUserCommand, WHO: NewWhoCommand, WHOIS: NewWhoisCommand, } @@ -223,34 +223,68 @@ func NewNickCommand(args []string) (editableCommand, error) { }, nil } -// USER - -type UserMsgCommand struct { +type UserCommand struct { BaseCommand - user string - mode uint8 - unused string + username string realname string } -func (cmd *UserMsgCommand) String() string { - return fmt.Sprintf("USER(user=%s, mode=%o, unused=%s, realname=%s)", - cmd.user, cmd.mode, cmd.unused, cmd.realname) +// USER +type RFC1459UserCommand struct { + UserCommand + hostname string + servername string } -func NewUserMsgCommand(args []string) (editableCommand, error) { +func (cmd *RFC1459UserCommand) String() string { + return fmt.Sprintf("USER(username=%s, hostname=%s, servername=%s, realname=%s)", + cmd.username, cmd.hostname, cmd.servername, cmd.realname) +} + +// USER +type RFC2812UserCommand struct { + UserCommand + mode uint8 + unused string +} + +func (cmd *RFC2812UserCommand) String() string { + return fmt.Sprintf("USER(username=%s, mode=%d, unused=%s, realname=%s)", + cmd.username, cmd.mode, cmd.unused, cmd.realname) +} + +func (cmd *RFC2812UserCommand) Flags() []UserMode { + flags := make([]UserMode, 0) + if (cmd.mode & 4) == 4 { + flags = append(flags, WallOps) + } + if (cmd.mode & 8) == 8 { + flags = append(flags, Invisible) + } + return flags +} + +func NewUserCommand(args []string) (editableCommand, error) { if len(args) != 4 { return nil, NotEnoughArgsError } - msg := &UserMsgCommand{ - user: args[0], - unused: args[2], - realname: args[3], - } mode, err := strconv.ParseUint(args[1], 10, 8) if err == nil { - msg.mode = uint8(mode) + msg := &RFC2812UserCommand{ + mode: uint8(mode), + unused: args[2], + } + msg.username = args[0] + msg.realname = args[3] + return msg, nil } + + msg := &RFC1459UserCommand{ + hostname: args[1], + servername: args[2], + } + msg.username = args[0] + msg.realname = args[3] return msg, nil } diff --git a/irc/server.go b/irc/server.go index 6c59145b..80188e9f 100644 --- a/irc/server.go +++ b/irc/server.go @@ -283,9 +283,25 @@ func (m *NickCommand) HandleRegServer(s *Server) { s.tryRegister(client) } -func (msg *UserMsgCommand) HandleRegServer(server *Server) { +func (msg *RFC1459UserCommand) HandleRegServer(server *Server) { + msg.HandleRegServer2(server) +} + +func (msg *RFC2812UserCommand) HandleRegServer(server *Server) { client := msg.Client() - client.username, client.realname = msg.user, msg.realname + flags := msg.Flags() + if len(flags) > 0 { + for _, mode := range msg.Flags() { + client.flags[mode] = true + } + client.Reply(RplUModeIs(server, client)) + } + msg.HandleRegServer2(server) +} + +func (msg *UserCommand) HandleRegServer2(server *Server) { + client := msg.Client() + client.username, client.realname = msg.username, msg.realname server.tryRegister(client) } @@ -323,7 +339,7 @@ func (msg *NickCommand) HandleServer(server *Server) { server.clients.Add(client) } -func (m *UserMsgCommand) HandleServer(s *Server) { +func (m *UserCommand) HandleServer(s *Server) { m.Client().Reply(ErrAlreadyRegistered(s)) }