mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-24 21:09:30 +01:00
organize like a proper go package
This commit is contained in:
parent
f04dd7c5d5
commit
b9cb539219
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,3 @@
|
|||||||
pkg
|
pkg
|
||||||
bin
|
bin
|
||||||
src/code.google.com/
|
|
||||||
src/github.com/
|
|
||||||
ergonomadic.db
|
ergonomadic.db
|
||||||
|
5
build.sh
5
build.sh
@ -1,5 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
export GOPATH="$PWD"
|
|
||||||
#go get "code.google.com/p/go.crypto/bcrypt"
|
|
||||||
#go get "github.com/mattn/go-sqlite3"
|
|
||||||
go install ergonomadic genpasswd
|
|
17
ergonomadic.go
Normal file
17
ergonomadic.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"github.com/jlatt/ergonomadic/irc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
name := flag.String("name", "localhost", "A name for the server")
|
||||||
|
listen := flag.String("listen", ":6667", "interface to listen on")
|
||||||
|
flag.BoolVar(&irc.DEBUG_NET, "dnet", false, "debug net")
|
||||||
|
flag.BoolVar(&irc.DEBUG_CLIENT, "dclient", false, "debug client")
|
||||||
|
flag.BoolVar(&irc.DEBUG_CHANNEL, "dchannel", false, "debug channel")
|
||||||
|
flag.BoolVar(&irc.DEBUG_SERVER, "dserver", false, "debug server")
|
||||||
|
flag.Parse()
|
||||||
|
irc.NewServer(*name).Listen(*listen)
|
||||||
|
}
|
@ -4,10 +4,6 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
DEBUG_CHANNEL = true
|
|
||||||
)
|
|
||||||
|
|
||||||
type Channel struct {
|
type Channel struct {
|
||||||
commands chan<- ChannelCommand
|
commands chan<- ChannelCommand
|
||||||
key string
|
key string
|
||||||
@ -59,12 +55,10 @@ func (channel *Channel) receiveReplies(replies <-chan Reply) {
|
|||||||
log.Printf("%s ← %s : %s", channel, reply.Source(), reply)
|
log.Printf("%s ← %s : %s", channel, reply.Source(), reply)
|
||||||
}
|
}
|
||||||
for client := range channel.members {
|
for client := range channel.members {
|
||||||
if client != reply.Source() {
|
|
||||||
client.replies <- reply
|
client.replies <- reply
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (channel *Channel) IsEmpty() bool {
|
func (channel *Channel) IsEmpty() bool {
|
||||||
return len(channel.members) == 0
|
return len(channel.members) == 0
|
||||||
@ -117,7 +111,6 @@ func (channel *Channel) Join(client *Client) {
|
|||||||
channel.members[client] = true
|
channel.members[client] = true
|
||||||
client.channels[channel] = true
|
client.channels[channel] = true
|
||||||
reply := RplJoin(channel, client)
|
reply := RplJoin(channel, client)
|
||||||
client.replies <- reply
|
|
||||||
channel.replies <- reply
|
channel.replies <- reply
|
||||||
channel.GetTopic(client)
|
channel.GetTopic(client)
|
||||||
channel.GetUsers(client)
|
channel.GetUsers(client)
|
@ -7,20 +7,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
DEBUG_CLIENT = false
|
|
||||||
)
|
|
||||||
|
|
||||||
type ClientCommand interface {
|
|
||||||
Command
|
|
||||||
HandleClient(*Client)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
atime time.Time
|
atime time.Time
|
||||||
away bool
|
away bool
|
||||||
channels ChannelSet
|
channels ChannelSet
|
||||||
commands chan<- ClientCommand
|
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
hostname string
|
hostname string
|
||||||
nick string
|
nick string
|
||||||
@ -37,12 +27,10 @@ type ClientSet map[*Client]bool
|
|||||||
func NewClient(server *Server, conn net.Conn) *Client {
|
func NewClient(server *Server, conn net.Conn) *Client {
|
||||||
read := StringReadChan(conn)
|
read := StringReadChan(conn)
|
||||||
write := StringWriteChan(conn)
|
write := StringWriteChan(conn)
|
||||||
commands := make(chan ClientCommand)
|
|
||||||
replies := make(chan Reply)
|
replies := make(chan Reply)
|
||||||
|
|
||||||
client := &Client{
|
client := &Client{
|
||||||
channels: make(ChannelSet),
|
channels: make(ChannelSet),
|
||||||
commands: commands,
|
|
||||||
conn: conn,
|
conn: conn,
|
||||||
hostname: LookupHostname(conn.RemoteAddr()),
|
hostname: LookupHostname(conn.RemoteAddr()),
|
||||||
replies: replies,
|
replies: replies,
|
||||||
@ -51,7 +39,6 @@ func NewClient(server *Server, conn net.Conn) *Client {
|
|||||||
|
|
||||||
go client.readConn(read)
|
go client.readConn(read)
|
||||||
go client.writeConn(write, replies)
|
go client.writeConn(write, replies)
|
||||||
go client.receiveCommands(commands)
|
|
||||||
|
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
@ -82,15 +69,6 @@ func (c *Client) writeConn(write chan<- string, replies <-chan Reply) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) receiveCommands(commands <-chan ClientCommand) {
|
|
||||||
for command := range commands {
|
|
||||||
if DEBUG_CLIENT {
|
|
||||||
log.Printf("%s → %s : %s", command.Client(), client, command)
|
|
||||||
}
|
|
||||||
command.HandleClient(client)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Client) Replies() chan<- Reply {
|
func (c *Client) Replies() chan<- Reply {
|
||||||
return c.replies
|
return c.replies
|
||||||
}
|
}
|
||||||
@ -135,17 +113,9 @@ func (c *Client) Id() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) String() string {
|
func (c *Client) String() string {
|
||||||
return c.hostname
|
return c.UserHost()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) PublicId() string {
|
func (c *Client) PublicId() string {
|
||||||
return fmt.Sprintf("%s!%s@%s", c.Nick(), c.Nick(), c.server.Id())
|
return fmt.Sprintf("%s!%s@%s", c.Nick(), c.Nick(), c.server.Id())
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// commands
|
|
||||||
//
|
|
||||||
|
|
||||||
func (m *PrivMsgCommand) HandleClient(client *Client) {
|
|
||||||
client.replies <- RplPrivMsg(m.Client(), client, m.message)
|
|
||||||
}
|
|
@ -1,7 +1,14 @@
|
|||||||
package irc
|
package irc
|
||||||
|
|
||||||
|
var (
|
||||||
|
DEBUG_NET = false
|
||||||
|
DEBUG_CLIENT = false
|
||||||
|
DEBUG_CHANNEL = false
|
||||||
|
DEBUG_SERVER = false
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
VERSION = "ergonomadic-1"
|
VERSION = "irc-1"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
@ -7,10 +7,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
DEBUG_NET = false
|
|
||||||
)
|
|
||||||
|
|
||||||
func readTrimmedLine(reader *bufio.Reader) (string, error) {
|
func readTrimmedLine(reader *bufio.Reader) (string, error) {
|
||||||
line, err := reader.ReadString('\n')
|
line, err := reader.ReadString('\n')
|
||||||
if err != nil {
|
if err != nil {
|
@ -115,20 +115,27 @@ func (reply *NamesReply) Format(client *Client, write chan<- string) {
|
|||||||
tooLong := func(names []string) bool {
|
tooLong := func(names []string) bool {
|
||||||
return (baseLen + joinedLen(names)) > MAX_REPLY_LEN
|
return (baseLen + joinedLen(names)) > MAX_REPLY_LEN
|
||||||
}
|
}
|
||||||
var start = 0
|
from, to := 0, 1
|
||||||
nicks := reply.channel.Nicks()
|
nicks := reply.channel.Nicks()
|
||||||
for i := range nicks {
|
for to < len(nicks) {
|
||||||
if (i > start) && tooLong(nicks[start:i]) {
|
if (from < (to - 1)) && tooLong(nicks[from:to]) {
|
||||||
RplNamReply(reply.channel, nicks[start:i-1]).Format(client, write)
|
RplNamReply(reply.channel, nicks[from:to-1]).Format(client, write)
|
||||||
start = i - 1
|
from, to = to-1, to
|
||||||
|
} else {
|
||||||
|
to += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if start < (len(nicks) - 1) {
|
if from < len(nicks) {
|
||||||
RplNamReply(reply.channel, nicks[start:]).Format(client, write)
|
RplNamReply(reply.channel, nicks[from:]).Format(client, write)
|
||||||
}
|
}
|
||||||
RplEndOfNames(reply.channel).Format(client, write)
|
RplEndOfNames(reply.channel).Format(client, write)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (reply *NamesReply) String() string {
|
||||||
|
return fmt.Sprintf("NamesReply(channel=%s, names=%s)",
|
||||||
|
reply.channel, reply.channel.Nicks())
|
||||||
|
}
|
||||||
|
|
||||||
// messaging replies
|
// messaging replies
|
||||||
|
|
||||||
func RplPrivMsg(source Identifier, target Identifier, message string) Reply {
|
func RplPrivMsg(source Identifier, target Identifier, message string) Reply {
|
||||||
@ -209,9 +216,9 @@ func RplNamReply(channel *Channel, names []string) *NumericReply {
|
|||||||
channel.name, strings.Join(names, " "))
|
channel.name, strings.Join(names, " "))
|
||||||
}
|
}
|
||||||
|
|
||||||
func RplEndOfNames(source Identifier) Reply {
|
func RplEndOfNames(channel *Channel) Reply {
|
||||||
return NewNumericReply(source, RPL_ENDOFNAMES,
|
return NewNumericReply(channel, RPL_ENDOFNAMES,
|
||||||
":End of NAMES list")
|
"%s :End of NAMES list", channel.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RplYoureOper(server *Server) Reply {
|
func RplYoureOper(server *Server) Reply {
|
@ -1,16 +1,11 @@
|
|||||||
package irc
|
package irc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"code.google.com/p/go.crypto/bcrypt"
|
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
DEBUG_SERVER = true
|
|
||||||
)
|
|
||||||
|
|
||||||
type ChannelNameMap map[string]*Channel
|
type ChannelNameMap map[string]*Channel
|
||||||
type ClientNameMap map[string]*Client
|
type ClientNameMap map[string]*Client
|
||||||
|
|
||||||
@ -20,7 +15,7 @@ type Server struct {
|
|||||||
ctime time.Time
|
ctime time.Time
|
||||||
hostname string
|
hostname string
|
||||||
name string
|
name string
|
||||||
password []byte
|
password string
|
||||||
clients ClientNameMap
|
clients ClientNameMap
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +49,9 @@ func (s *Server) Listen(addr string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.hostname = LookupHostname(listener.Addr())
|
s.hostname = LookupHostname(listener.Addr())
|
||||||
|
if DEBUG_SERVER {
|
||||||
log.Print("Server.Listen: listening on ", addr)
|
log.Print("Server.Listen: listening on ", addr)
|
||||||
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
conn, err := listener.Accept()
|
conn, err := listener.Accept()
|
||||||
@ -62,7 +59,9 @@ func (s *Server) Listen(addr string) {
|
|||||||
log.Print("Server.Listen: ", err)
|
log.Print("Server.Listen: ", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if DEBUG_SERVER {
|
||||||
log.Print("Server.Listen: accepted ", conn.RemoteAddr())
|
log.Print("Server.Listen: accepted ", conn.RemoteAddr())
|
||||||
|
}
|
||||||
NewClient(s, conn)
|
NewClient(s, conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,7 +93,7 @@ func (s *Server) interestedClients(fromClient *Client) ClientSet {
|
|||||||
// server functionality
|
// server functionality
|
||||||
|
|
||||||
func (s *Server) tryRegister(c *Client) {
|
func (s *Server) tryRegister(c *Client) {
|
||||||
if !c.registered && c.HasNick() && c.HasUsername() && s.CheckPassword(c) {
|
if !c.registered && c.HasNick() && c.HasUsername() && c.serverPass {
|
||||||
c.registered = true
|
c.registered = true
|
||||||
replies := []Reply{
|
replies := []Reply{
|
||||||
RplWelcome(s, c),
|
RplWelcome(s, c),
|
||||||
@ -108,10 +107,6 @@ func (s *Server) tryRegister(c *Client) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) CheckPassword(c *Client) bool {
|
|
||||||
return (s.password == nil) || c.serverPass
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Server) Id() string {
|
func (s *Server) Id() string {
|
||||||
return s.name
|
return s.name
|
||||||
}
|
}
|
||||||
@ -149,9 +144,9 @@ func (m *PongCommand) HandleServer(s *Server) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *PassCommand) HandleServer(s *Server) {
|
func (m *PassCommand) HandleServer(s *Server) {
|
||||||
err := bcrypt.CompareHashAndPassword(s.password, []byte(m.password))
|
if s.password != m.password {
|
||||||
if err != nil {
|
|
||||||
m.Client().Replies() <- ErrPasswdMismatch(s)
|
m.Client().Replies() <- ErrPasswdMismatch(s)
|
||||||
|
// TODO disconnect
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,13 +194,14 @@ func (m *QuitCommand) HandleServer(s *Server) {
|
|||||||
for client := range s.interestedClients(c) {
|
for client := range s.interestedClients(c) {
|
||||||
client.replies <- reply
|
client.replies <- reply
|
||||||
}
|
}
|
||||||
c.conn.Close()
|
|
||||||
cmd := &PartCommand{
|
cmd := &PartCommand{
|
||||||
BaseCommand: BaseCommand{c},
|
BaseCommand: BaseCommand{c},
|
||||||
}
|
}
|
||||||
for channel := range c.channels {
|
for channel := range c.channels {
|
||||||
channel.commands <- cmd
|
channel.commands <- cmd
|
||||||
}
|
}
|
||||||
|
c.conn.Close()
|
||||||
|
delete(s.clients, c.nick)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *JoinCommand) HandleServer(s *Server) {
|
func (m *JoinCommand) HandleServer(s *Server) {
|
||||||
@ -266,8 +262,7 @@ func (m *PrivMsgCommand) HandleServer(s *Server) {
|
|||||||
m.Client().replies <- ErrNoSuchNick(s, m.target)
|
m.Client().replies <- ErrNoSuchNick(s, m.target)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
target.replies <- RplPrivMsg(m.Client(), target, m.message)
|
||||||
target.commands <- m
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ModeCommand) HandleServer(s *Server) {
|
func (m *ModeCommand) HandleServer(s *Server) {
|
@ -1,13 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"irc"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
name := flag.String("name", "localhost", "A name for the server")
|
|
||||||
listen := flag.String("listen", ":6667", "interface to listen on")
|
|
||||||
flag.Parse()
|
|
||||||
irc.NewServer(*name).Listen(*listen)
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"irc"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
db := irc.NewDatabase()
|
|
||||||
defer db.Close()
|
|
||||||
irc.ExecSqlFile(db, flag.Arg(0)+".sql")
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"code.google.com/p/go.crypto/bcrypt"
|
|
||||||
"encoding/base64"
|
|
||||||
"flag"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
flag.Parse()
|
|
||||||
password := flag.Arg(0)
|
|
||||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
fmt.Println(base64.StdEncoding.EncodeToString(hash))
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user