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 != ""
|
return client.username != ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fromClient *Client) InterestedClients() ClientSet {
|
func (client *Client) InterestedClients() ClientSet {
|
||||||
clients := make(ClientSet)
|
clients := make(ClientSet)
|
||||||
clients[fromClient] = true
|
for channel := range client.channels {
|
||||||
for channel := range fromClient.channels {
|
for member := range channel.members {
|
||||||
for client := range channel.members {
|
clients[member] = true
|
||||||
clients[client] = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return clients
|
return clients
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ var (
|
|||||||
"QUIT": NewQuitCommand,
|
"QUIT": NewQuitCommand,
|
||||||
"TOPIC": NewTopicCommand,
|
"TOPIC": NewTopicCommand,
|
||||||
"USER": NewUserMsgCommand,
|
"USER": NewUserMsgCommand,
|
||||||
|
"WHOIS": NewWhoisCommand,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -451,3 +452,30 @@ func NewModeCommand(args []string) (EditableCommand, error) {
|
|||||||
|
|
||||||
return cmd, nil
|
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 {
|
for {
|
||||||
line, err := readTrimmedLine(reader)
|
line, err := readTrimmedLine(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print("net: ", err)
|
log.Printf("%s → %s error: %s", conn.RemoteAddr(), conn.LocalAddr(), err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if DEBUG_NET {
|
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
|
ch <- line
|
||||||
}
|
}
|
||||||
@ -45,10 +45,10 @@ func StringWriteChan(conn net.Conn) chan<- string {
|
|||||||
defer close(ch)
|
defer close(ch)
|
||||||
for str := range ch {
|
for str := range ch {
|
||||||
if DEBUG_NET {
|
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 {
|
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
|
break
|
||||||
}
|
}
|
||||||
writer.Flush()
|
writer.Flush()
|
||||||
|
37
irc/reply.go
37
irc/reply.go
@ -6,6 +6,18 @@ import (
|
|||||||
"time"
|
"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 {
|
type Identifier interface {
|
||||||
Id() string
|
Id() string
|
||||||
Nick() 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) {
|
func (reply *NamesReply) Format(client *Client, write chan<- string) {
|
||||||
base := RplNamReply(reply.channel, []string{})
|
base := RplNamReply(reply.channel, []string{})
|
||||||
baseLen := len(base.FormatString(client))
|
baseLen := len(base.FormatString(client))
|
||||||
@ -225,6 +225,15 @@ func RplYoureOper(server *Server) Reply {
|
|||||||
":You are now an IRC operator")
|
":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)
|
// errors (also numeric)
|
||||||
|
|
||||||
func ErrAlreadyRegistered(source Identifier) Reply {
|
func ErrAlreadyRegistered(source Identifier) Reply {
|
||||||
@ -298,3 +307,7 @@ func ErrNoPrivileges(server *Server) Reply {
|
|||||||
func ErrRestricted(server *Server) Reply {
|
func ErrRestricted(server *Server) Reply {
|
||||||
return NewNumericReply(server, ERR_RESTRICTED, ":Your connection is restricted!")
|
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)
|
reply := RplNick(c, m.nickname)
|
||||||
|
c.replies <- reply
|
||||||
for iclient := range c.InterestedClients() {
|
for iclient := range c.InterestedClients() {
|
||||||
iclient.replies <- reply
|
iclient.replies <- reply
|
||||||
}
|
}
|
||||||
@ -201,7 +202,6 @@ func (m *QuitCommand) HandleServer(s *Server) {
|
|||||||
reply := RplQuit(c, m.message)
|
reply := RplQuit(c, m.message)
|
||||||
for client := range c.InterestedClients() {
|
for client := range c.InterestedClients() {
|
||||||
client.replies <- reply
|
client.replies <- reply
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,3 +280,22 @@ func (m *ModeCommand) HandleServer(s *Server) {
|
|||||||
|
|
||||||
client.replies <- ErrUsersDontMatch(client)
|
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