3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-10 22:19:31 +01:00

minimal whois implementation

This commit is contained in:
Jeremy Latt 2014-02-08 17:43:59 -08:00
parent 06648393a1
commit c4f457705a
5 changed files with 81 additions and 23 deletions

View File

@ -88,15 +88,13 @@ func (client *Client) HasUsername() bool {
return client.username != ""
}
func (fromClient *Client) InterestedClients() ClientSet {
func (client *Client) InterestedClients() ClientSet {
clients := make(ClientSet)
clients[fromClient] = true
for channel := range fromClient.channels {
for client := range channel.members {
clients[client] = true
for channel := range client.channels {
for member := range channel.members {
clients[member] = true
}
}
return clients
}

View File

@ -35,6 +35,7 @@ var (
"QUIT": NewQuitCommand,
"TOPIC": NewTopicCommand,
"USER": NewUserMsgCommand,
"WHOIS": NewWhoisCommand,
}
)
@ -451,3 +452,30 @@ func NewModeCommand(args []string) (EditableCommand, error) {
return cmd, nil
}
type WhoisCommand struct {
BaseCommand
target string
masks []string
}
func NewWhoisCommand(args []string) (EditableCommand, error) {
if len(args) < 1 {
return nil, NotEnoughArgsError
}
var masks string
var target string
if len(args) > 1 {
target = args[0]
masks = args[1]
} else {
masks = args[0]
}
return &WhoisCommand{
target: target,
masks: strings.Split(masks, ","),
}, nil
}

View File

@ -25,11 +25,11 @@ func StringReadChan(conn net.Conn) <-chan string {
for {
line, err := readTrimmedLine(reader)
if err != nil {
log.Print("net: ", err)
log.Printf("%s → %s error: %s", conn.RemoteAddr(), conn.LocalAddr(), err)
break
}
if DEBUG_NET {
log.Printf("%s → %s : %s", conn.RemoteAddr(), conn.LocalAddr(), line)
log.Printf("%s → %s %s", conn.RemoteAddr(), conn.LocalAddr(), line)
}
ch <- line
}
@ -45,10 +45,10 @@ func StringWriteChan(conn net.Conn) chan<- string {
defer close(ch)
for str := range ch {
if DEBUG_NET {
log.Printf("%s ← %s : %s", conn.RemoteAddr(), conn.LocalAddr(), str)
log.Printf("%s ← %s %s", conn.RemoteAddr(), conn.LocalAddr(), str)
}
if _, err := writer.WriteString(str + "\r\n"); err != nil {
log.Print("net: ", err)
log.Printf("%s ← %s error: %s", conn.RemoteAddr(), conn.LocalAddr(), err)
break
}
writer.Flush()

View File

@ -6,6 +6,18 @@ import (
"time"
)
const (
MAX_REPLY_LEN = 510 // 512 - CRLF
)
func joinedLen(names []string) int {
var l = len(names) - 1 // " " between names
for _, name := range names {
l += len(name)
}
return l
}
type Identifier interface {
Id() string
Nick() string
@ -96,18 +108,6 @@ func NewNamesReply(channel *Channel) Reply {
}
}
const (
MAX_REPLY_LEN = 510 // 512 - CRLF
)
func joinedLen(names []string) int {
var l = len(names) - 1 // " " between names
for _, name := range names {
l += len(name)
}
return l
}
func (reply *NamesReply) Format(client *Client, write chan<- string) {
base := RplNamReply(reply.channel, []string{})
baseLen := len(base.FormatString(client))
@ -225,6 +225,15 @@ func RplYoureOper(server *Server) Reply {
":You are now an IRC operator")
}
func RplWhoisUser(server *Server, client *Client) Reply {
return NewNumericReply(server, RPL_WHOISUSER, "%s %s %s * :%s",
client.nick, client.username, client.hostname, client.realname)
}
func RplEndOfWhois(server *Server) Reply {
return NewNumericReply(server, RPL_ENDOFWHOIS, ":End of WHOIS list")
}
// errors (also numeric)
func ErrAlreadyRegistered(source Identifier) Reply {
@ -298,3 +307,7 @@ func ErrNoPrivileges(server *Server) Reply {
func ErrRestricted(server *Server) Reply {
return NewNumericReply(server, ERR_RESTRICTED, ":Your connection is restricted!")
}
func ErrNoSuchServer(server *Server, target string) Reply {
return NewNumericReply(server, ERR_NOSUCHSERVER, "%s :No such server", target)
}

View File

@ -165,6 +165,7 @@ func (m *NickCommand) HandleServer(s *Server) {
}
reply := RplNick(c, m.nickname)
c.replies <- reply
for iclient := range c.InterestedClients() {
iclient.replies <- reply
}
@ -201,7 +202,6 @@ func (m *QuitCommand) HandleServer(s *Server) {
reply := RplQuit(c, m.message)
for client := range c.InterestedClients() {
client.replies <- reply
}
}
@ -280,3 +280,22 @@ func (m *ModeCommand) HandleServer(s *Server) {
client.replies <- ErrUsersDontMatch(client)
}
func (m *WhoisCommand) HandleServer(server *Server) {
client := m.Client()
// TODO implement target query
if m.target != "" {
client.replies <- ErrNoSuchServer(server, m.target)
return
}
for _, mask := range m.masks {
// TODO implement wildcard matching
mclient := server.clients[mask]
if mclient != nil {
client.replies <- RplWhoisUser(server, mclient)
}
}
client.replies <- RplEndOfWhois(server)
}