mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-26 05:49:25 +01:00
minimal whois implementation
This commit is contained in:
parent
06648393a1
commit
c4f457705a
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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()
|
||||
|
37
irc/reply.go
37
irc/reply.go
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user