Added Host struct.

This commit is contained in:
Andrey Petrov 2014-12-25 00:09:43 -08:00
parent c1406dda55
commit d3b0a56d78
4 changed files with 104 additions and 57 deletions

View File

@ -28,5 +28,5 @@ debug: $(BINARY) $(KEY)
./$(BINARY) --pprof 6060 -i $(KEY) --bind ":$(PORT)" -vv
test:
go test .
golint
go test ./...
golint ./...

5
cmd.go
View File

@ -71,7 +71,7 @@ func main() {
}
privateKeyPath := options.Identity
if strings.HasPrefix(privateKeyPath, "~") {
if strings.HasPrefix(privateKeyPath, "~/") {
user, err := user.Current()
if err == nil {
privateKeyPath = strings.Replace(privateKeyPath, "~", user.HomeDir, 1)
@ -101,7 +101,8 @@ func main() {
}
defer s.Close()
go Serve(s)
host := NewHost(s)
go host.Serve()
/* TODO:
for _, fingerprint := range options.Admin {

99
host.go Normal file
View File

@ -0,0 +1,99 @@
package main
import (
"fmt"
"io"
"github.com/shazow/ssh-chat/chat"
"github.com/shazow/ssh-chat/sshd"
)
// Host is the bridge between sshd and chat modules
// TODO: Should be easy to add support for multiple channels, if we want.
type Host struct {
listener *sshd.SSHListener
channel *chat.Channel
}
// NewHost creates a Host on top of an existing listener
func NewHost(listener *sshd.SSHListener) *Host {
h := Host{
listener: listener,
channel: chat.NewChannel(),
}
return &h
}
// Connect a specific Terminal to this host and its channel
func (h *Host) Connect(term *sshd.Terminal) {
defer term.Close()
name := term.Conn.User()
term.SetPrompt(fmt.Sprintf("[%s] ", name))
// TODO: term.AutoCompleteCallback = ...
user := chat.NewUserScreen(name, term)
defer user.Close()
err := h.channel.Join(user)
if err != nil {
logger.Errorf("Failed to join: %s", err)
return
}
for {
// TODO: Handle commands etc?
line, err := term.ReadLine()
if err == io.EOF {
// Closed
break
} else if err != nil {
logger.Errorf("Terminal reading error: %s", err)
break
}
m := chat.NewMessage(line).From(user)
h.channel.Send(*m)
}
err = h.channel.Leave(user)
if err != nil {
logger.Errorf("Failed to leave: %s", err)
return
}
}
// Serve our chat channel onto the listener
func (h *Host) Serve() {
terminals := h.listener.ServeTerminal()
for term := range terminals {
go h.Connect(term)
}
}
/* TODO: ...
func (h *Host) AutoCompleteFunction(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
if key != 9 {
return
}
shortLine := strings.Split(line[:pos], " ")
partialNick := shortLine[len(shortLine)-1]
nicks := h.channel.users.ListPrefix(&partialNick)
if len(nicks) == 0 {
return
}
nick := nicks[len(nicks)-1]
posPartialNick := pos - len(partialNick)
if len(shortLine) < 2 {
nick += ": "
} else {
nick += " "
}
newLine = strings.Replace(line[posPartialNick:], partialNick, nick, 1)
newLine = line[:posPartialNick] + newLine
newPos = pos + (len(nick) - len(partialNick))
ok = true
return
}
*/

View File

@ -1,53 +0,0 @@
package main
import (
"fmt"
"github.com/shazow/ssh-chat/chat"
"github.com/shazow/ssh-chat/sshd"
)
func HandleTerminal(term *sshd.Terminal, channel *chat.Channel) {
defer term.Close()
name := term.Conn.User()
term.SetPrompt(fmt.Sprintf("[%s] ", name))
// TODO: term.AutoCompleteCallback = ...
user := chat.NewUserScreen(name, term)
defer user.Close()
err := channel.Join(user)
if err != nil {
logger.Errorf("Failed to join: %s", err)
return
}
defer func() {
err := channel.Leave(user)
if err != nil {
logger.Errorf("Failed to leave: %s", err)
}
}()
for {
// TODO: Handle commands etc?
line, err := term.ReadLine()
if err != nil {
// TODO: Catch EOF specifically?
logger.Errorf("Terminal reading error: %s", err)
return
}
m := chat.NewMessage(line).From(user)
channel.Send(*m)
}
}
// Serve a chat service onto the sshd server.
func Serve(listener *sshd.SSHListener) {
terminals := listener.ServeTerminal()
channel := chat.NewChannel()
for term := range terminals {
go HandleTerminal(term, channel)
}
}