mirror of https://github.com/nealey/spongy
Feeling like network.go is done, need some tests
This commit is contained in:
parent
c04d246d9e
commit
0e29d159f1
|
@ -96,3 +96,8 @@ func Parse(v string) (Message, error) {
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m Message) String() string {
|
||||||
|
args := strings.Join(m.Args, " ")
|
||||||
|
return fmt.Sprintf("%s %s %s %s %s :%s", m.FullSender, m.Command, m.Sender, m.Forum, args, m.Text)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/nealey/spongy/logfile"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
@ -39,6 +40,8 @@ func ReadLines(fn string) ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Network struct {
|
type Network struct {
|
||||||
|
running bool
|
||||||
|
|
||||||
basePath string
|
basePath string
|
||||||
|
|
||||||
conn io.ReadWriteCloser
|
conn io.ReadWriteCloser
|
||||||
|
@ -59,19 +62,22 @@ func NewNetwork(basePath string) (*Network, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Network{
|
return &Network{
|
||||||
|
running: true,
|
||||||
|
|
||||||
basePath: basePath,
|
basePath: basePath,
|
||||||
|
|
||||||
servers: servers,
|
servers: servers,
|
||||||
nicks: nicks,
|
nicks: nicks,
|
||||||
gecos: gecoses[0],
|
gecos: gecoses[0],
|
||||||
|
|
||||||
logq: make(chan Message),
|
logq: make(chan Message, 20),
|
||||||
inq: make(chan string),
|
|
||||||
outq: make(chan string),
|
|
||||||
}, err
|
}, err
|
||||||
|
|
||||||
|
go n.LogLoop()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Network) Close() {
|
func (n *Network) Close() {
|
||||||
|
n.conn.Close()
|
||||||
close(n.logq)
|
close(n.logq)
|
||||||
close(n.inq)
|
close(n.inq)
|
||||||
close(n.outq)
|
close(n.outq)
|
||||||
|
@ -87,7 +93,7 @@ func (n *Network) WatchOutqDirectory() {
|
||||||
defer dir.Close()
|
defer dir.Close()
|
||||||
|
|
||||||
// XXX: Do this with fsnotify
|
// XXX: Do this with fsnotify
|
||||||
for running {
|
for n.running {
|
||||||
entities, _ := dir.Readdirnames(0)
|
entities, _ := dir.Readdirnames(0)
|
||||||
for _, fn := range entities {
|
for _, fn := range entities {
|
||||||
pathname := path.Join(outqDirname, fn)
|
pathname := path.Join(outqDirname, fn)
|
||||||
|
@ -117,7 +123,16 @@ func (n *Network) HandleInfile(fn string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Network) WriteLoop() {
|
func (n *Network) LogLoop() {
|
||||||
|
logf := logfile.NewLogFile(int(maxlogsize))
|
||||||
|
defer logf.Close()
|
||||||
|
|
||||||
|
for m := range logq {
|
||||||
|
logf.Log(m.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Network) ServerWriteLoop() {
|
||||||
for v := range n.outq {
|
for v := range n.outq {
|
||||||
m, _ := Parse(v)
|
m, _ := Parse(v)
|
||||||
n.logq <- m
|
n.logq <- m
|
||||||
|
@ -125,7 +140,7 @@ func (n *Network) WriteLoop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Network) ReadLoop() {
|
func (n *Network) ServerReadLoop() {
|
||||||
scanner := bufio.NewScanner(conn)
|
scanner := bufio.NewScanner(conn)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
n.inq <- scanner.Text()
|
n.inq <- scanner.Text()
|
||||||
|
@ -133,16 +148,62 @@ func (n *Network) ReadLoop() {
|
||||||
close(n.inq)
|
close(n.inq)
|
||||||
}
|
}
|
||||||
|
|
||||||
func
|
func (n *Network) MessageDispatch() {
|
||||||
|
for line := n.inq {
|
||||||
|
m, err := NewMessage(line)
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
n.logq <- m
|
||||||
|
// XXX: Add in a handler subprocess call
|
||||||
|
|
||||||
|
switch m.Command {
|
||||||
|
case "PING":
|
||||||
|
n.outq <- "PONG: " + m.Text
|
||||||
|
case "433":
|
||||||
|
nick = nick + "_"
|
||||||
|
outq <- fmt.Sprintf("NICK %s", nick)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Network) ConnectToServer(server string) bool {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
switch (server[0]) {
|
||||||
|
case '|':
|
||||||
|
parts := strings.Split(server[1:], " ")
|
||||||
|
n.conn, err = StartStdioProcess(parts[0], parts[1:])
|
||||||
|
case '^':
|
||||||
|
n.conn, err = net.Dial("tcp", server[1:])
|
||||||
|
default:
|
||||||
|
log.Print("Not validating server certificate!")
|
||||||
|
config := &tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
}
|
||||||
|
n.conn, err = tls.Dial("tcp", host, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Print(err)
|
||||||
|
time.sleep(2 * time.Second)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func (n *Network) Connect(){
|
func (n *Network) Connect(){
|
||||||
serverIndex := 0
|
serverIndex := 0
|
||||||
for running {
|
for n.running {
|
||||||
servers, err := ReadLines(path.Join(basePath, "servers"))
|
servers, err := ReadLines(path.Join(basePath, "servers"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(err)
|
|
||||||
serverIndex := 0
|
serverIndex := 0
|
||||||
time.sleep(2 * time.Second)
|
log.Print(err)
|
||||||
|
time.sleep(8)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,18 +211,20 @@ func (n *Network) Connect(){
|
||||||
serverIndex = 0
|
serverIndex = 0
|
||||||
}
|
}
|
||||||
server := servers[serverIndex]
|
server := servers[serverIndex]
|
||||||
|
serverIndex += 1
|
||||||
|
|
||||||
switch (server[0]) {
|
if ! n.ConnectToServer(server) {
|
||||||
case '|':
|
continue
|
||||||
|
|
||||||
|
|
||||||
if dotls {
|
|
||||||
config := &tls.Config{
|
|
||||||
InsecureSkipVerify: true,
|
|
||||||
}
|
}
|
||||||
return tls.Dial("tcp", host, config)
|
|
||||||
} else {
|
n.inq = make(chan string, 20)
|
||||||
return net.Dial("tcp", host)
|
n.outq = make(chan string, 20)
|
||||||
|
|
||||||
|
go n.ServerWriteLoop()
|
||||||
|
go n.MessageDispatch()
|
||||||
|
n.ServerReadLoop()
|
||||||
|
|
||||||
|
close(n.outq)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ReadWriteCloserWrapper {
|
||||||
|
Reader io.ReadCloser
|
||||||
|
Writer io.WriteCloser
|
||||||
|
}
|
||||||
|
|
||||||
|
def NewReadWriteCloseWrapper(r io.ReadCloser, w io.WriteCloser) *ReadWriteCloserWrapper {
|
||||||
|
return &ReadWriteCloserWrapper{r, w}
|
||||||
|
}
|
||||||
|
|
||||||
|
def (w *ReadWriteCloserWrapper) Close() (error) {
|
||||||
|
err1 := w.Reader.Close()
|
||||||
|
err2 := w.Writer.Close()
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case err1 != nil:
|
||||||
|
return err1
|
||||||
|
case err2 != nil:
|
||||||
|
return err2
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
def (w *ReadWriteCloserWrapper) Read(p []byte) (n int, err error) {
|
||||||
|
n, err := w.Reader.Read(p)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
def (w *ReadWriteCloserWrapper) Write(p []byte) (n int, err error) {
|
||||||
|
n, err := w.Writer.Write(p)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
def StartStdioProcess(name string, args []string) (*ReadWriteCloserWrapper, error) {
|
||||||
|
var w ReadWriteCloserWrapper
|
||||||
|
|
||||||
|
cmd := exec.Command(name, args...)
|
||||||
|
|
||||||
|
w.Reader, err := cmd.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Writer, err := cmd.StdinPipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = cmd.Start(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
go cmd.Wait()
|
||||||
|
|
||||||
|
return &w, nil
|
||||||
|
}
|
Loading…
Reference in New Issue