initial commit

This commit is contained in:
Jeremy Latt 2012-04-07 11:44:59 -07:00
commit a427e2bb47
6 changed files with 175 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
pkg
bin
goircd

11
goircd.go Normal file
View File

@ -0,0 +1,11 @@
package main
// http://tools.ietf.org/html/rfc1459
import (
"irc"
)
func main() {
server := irc.NewServer()
server.Listen(":6697")
}

28
src/irc/client.go Normal file
View File

@ -0,0 +1,28 @@
package irc
import (
"net"
)
type Client struct {
conn net.Conn
ch chan Message
}
func NewClient(conn net.Conn) *Client {
return &Client{conn, NewMessageChan(NewStringChan(conn))}
}
// Write messages from the client to the server.
func (c *Client) Communicate(server chan Message) {
for message := range c.ch {
message.client = c
server <- message
}
c.Close()
}
func (c *Client) Close() {
c.conn.Close()
}

46
src/irc/net.go Normal file
View File

@ -0,0 +1,46 @@
package irc
import (
"bufio"
"log"
"net"
)
// Adapt `net.Conn` to a `chan string`.
func NewStringChan(conn net.Conn) chan string {
ch := make(chan string)
rw := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
done := make(chan bool)
go func() {
<- done
close(ch)
}()
// conn -> ch
go func() {
for {
line, err := rw.ReadString('\n')
if err != nil {
log.Print("StringChan[read]: %v", err)
break
}
ch <- line
}
done <- true
}()
// ch -> conn
go func() {
for str := range ch {
if _, err := rw.WriteString(str + "\r\n"); err != nil {
log.Print("StringChan[write]: %v", err)
break
}
rw.Flush()
}
done <- true
}()
return ch
}

43
src/irc/protocol.go Normal file
View File

@ -0,0 +1,43 @@
package irc
import (
)
type Message struct {
line string
client *Client
}
func (m *Message) Encode() string {
return m.line
}
// Adapt `chan string` to a `chan Message`.
func NewMessageChan(strch chan string) chan Message {
msgch := make(chan Message)
done := make(chan bool)
go func() {
<- done
close(msgch)
}()
// str -> msg
go func() {
for str := range strch {
msgch <- Message{str, nil}
}
done <- true
}()
// msg -> str
go func() {
for message := range msgch {
strch <- message.Encode()
}
done <- true
}()
return msgch
}

44
src/irc/server.go Normal file
View File

@ -0,0 +1,44 @@
package irc
import (
"log"
"net"
)
type Server struct {
ch chan Message
}
func NewServer() *Server {
server := Server{make(chan Message)}
go server.Receive()
return &server
}
func (s *Server) Listen(addr string) {
listener, err := net.Listen("tcp", addr)
if err != nil {
log.Fatal("Server.Listen: %v", err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Print("Server.Listen: %v", err)
continue
}
client := NewClient(conn)
go client.Communicate(s.ch)
}
}
func (s *Server) Receive() {
for message := range s.ch {
log.Print("Server.Receive: %v", message.line)
message.client.ch <- Message{"pong: " + message.line, nil}
}
}
func (s *Server) Close() {
close(s.ch)
}