Merge remote-tracking branch 'origin/master' into user-mask

Conflicts:
	irc/reply.go
	irc/server.go
	irc/types.go
This commit is contained in:
Jeremy Latt
2014-03-06 17:44:37 -08:00
7 changed files with 224 additions and 101 deletions
+73 -42
View File
@@ -29,7 +29,6 @@ type Server struct {
operators map[string][]byte
password []byte
signals chan os.Signal
timeout chan *Client
whoWas *WhoWasList
}
@@ -46,7 +45,6 @@ func NewServer(config *Config) *Server {
newConns: make(chan net.Conn, 16),
operators: config.Operators(),
signals: make(chan os.Signal, 1),
timeout: make(chan *Client, 16),
whoWas: NewWhoWasList(100),
}
@@ -99,14 +97,6 @@ func (server *Server) processCommand(cmd Command) {
}
switch client.phase {
case Authorization:
authCmd, ok := cmd.(AuthServerCommand)
if !ok {
client.Quit("unexpected command")
return
}
authCmd.HandleAuthServer(server)
case Registration:
regCmd, ok := cmd.(RegServerCommand)
if !ok {
@@ -115,7 +105,7 @@ func (server *Server) processCommand(cmd Command) {
}
regCmd.HandleRegServer(server)
default:
case Normal:
srvCmd, ok := cmd.(ServerCommand)
if !ok {
client.ErrUnknownCommand(cmd.Code())
@@ -159,20 +149,10 @@ func (server *Server) Run() {
case client := <-server.idle:
client.Idle()
case client := <-server.timeout:
client.Quit("connection timeout")
}
}
}
func (server *Server) InitPhase() Phase {
if server.password == nil {
return Registration
}
return Authorization
}
//
// listen goroutine
//
@@ -208,7 +188,7 @@ func (s *Server) listen(addr string) {
//
func (s *Server) tryRegister(c *Client) {
if c.HasNick() && c.HasUsername() {
if c.HasNick() && c.HasUsername() && (c.capState != CapNegotiating) {
c.Register()
c.RplWelcome()
c.RplYourHost()
@@ -268,18 +248,10 @@ func (s *Server) Nick() string {
}
//
// authorization commands
// registration commands
//
func (msg *ProxyCommand) HandleAuthServer(server *Server) {
msg.Client().hostname = msg.hostname
}
func (msg *CapCommand) HandleAuthServer(server *Server) {
// TODO
}
func (msg *PassCommand) HandleAuthServer(server *Server) {
func (msg *PassCommand) HandleRegServer(server *Server) {
client := msg.Client()
if msg.err != nil {
client.ErrPasswdMismatch()
@@ -287,27 +259,70 @@ func (msg *PassCommand) HandleAuthServer(server *Server) {
return
}
client.phase = Registration
client.authorized = true
}
func (msg *QuitCommand) HandleAuthServer(server *Server) {
msg.Client().Quit(msg.message)
}
//
// registration commands
//
func (msg *ProxyCommand) HandleRegServer(server *Server) {
msg.Client().hostname = msg.hostname
}
func (msg *CapCommand) HandleRegServer(server *Server) {
// TODO
client := msg.Client()
switch msg.subCommand {
case CAP_LS:
client.capState = CapNegotiating
client.Reply("CAP LS * :%s", SupportedCapabilities)
case CAP_LIST:
client.Reply("CAP LIST * :%s", client.capabilities)
case CAP_REQ:
client.capState = CapNegotiating
for capability := range msg.capabilities {
if !SupportedCapabilities[capability] {
client.Reply("CAP NAK * :%s", msg.capabilities)
return
}
}
for capability := range msg.capabilities {
client.capabilities[capability] = true
}
client.Reply("CAP ACK * :%s", msg.capabilities)
case CAP_CLEAR:
format := strings.TrimRight(
strings.Repeat("%s%s ", len(client.capabilities)), " ")
args := make([]interface{}, len(client.capabilities))
index := 0
for capability := range client.capabilities {
args[index] = Disable
args[index+1] = capability
index += 2
delete(client.capabilities, capability)
}
client.Reply("CAP ACK * :"+format, args...)
case CAP_END:
client.capState = CapNegotiated
server.tryRegister(client)
default:
client.ErrInvalidCapCmd(msg.subCommand)
}
}
func (m *NickCommand) HandleRegServer(s *Server) {
client := m.Client()
if !client.authorized {
client.ErrPasswdMismatch()
client.Quit("bad password")
return
}
if client.capState == CapNegotiating {
client.capState = CapNegotiated
}
if m.nickname == "" {
client.ErrNoNicknameGiven()
@@ -329,11 +344,22 @@ func (m *NickCommand) HandleRegServer(s *Server) {
}
func (msg *RFC1459UserCommand) HandleRegServer(server *Server) {
client := msg.Client()
if !client.authorized {
client.ErrPasswdMismatch()
client.Quit("bad password")
return
}
msg.setUserInfo(server)
}
func (msg *RFC2812UserCommand) HandleRegServer(server *Server) {
client := msg.Client()
if !client.authorized {
client.ErrPasswdMismatch()
client.Quit("bad password")
return
}
flags := msg.Flags()
if len(flags) > 0 {
for _, mode := range msg.Flags() {
@@ -346,9 +372,14 @@ func (msg *RFC2812UserCommand) HandleRegServer(server *Server) {
func (msg *UserCommand) setUserInfo(server *Server) {
client := msg.Client()
if client.capState == CapNegotiating {
client.capState = CapNegotiated
}
server.clients.Remove(client)
client.username, client.realname = msg.username, msg.realname
server.clients.Add(client)
server.tryRegister(client)
}