Hacky fixes with notes.

This commit is contained in:
Andrey Petrov 2014-12-12 01:15:58 -08:00
parent f11049d84d
commit 0b80aa8345
3 changed files with 44 additions and 33 deletions

View File

@ -36,6 +36,7 @@ type Client struct {
Msg chan string
Name string
Op bool
ready chan struct{}
term *terminal.Terminal
termWidth int
termHeight int
@ -48,6 +49,7 @@ func NewClient(server *Server, conn *ssh.ServerConn) *Client {
Conn: conn,
Name: conn.User(),
Msg: make(chan string, MSG_BUFFER),
ready: make(chan struct{}, 1),
}
}
@ -86,6 +88,7 @@ func (c *Client) Rename(name string) {
func (c *Client) handleShell(channel ssh.Channel) {
defer channel.Close()
c.ready <- struct{}{}
go func() {
for msg := range c.Msg {
@ -145,6 +148,8 @@ func (c *Client) handleShell(channel ssh.Channel) {
func (c *Client) handleChannels(channels <-chan ssh.NewChannel) {
prompt := fmt.Sprintf("[%s] ", c.Name)
hasShell := false
for ch := range channels {
if t := ch.ChannelType(); t != "session" {
ch.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %s", t))
@ -156,44 +161,37 @@ func (c *Client) handleChannels(channels <-chan ssh.NewChannel) {
logger.Errorf("Could not accept channel: %v", err)
continue
}
defer channel.Close()
c.term = terminal.NewTerminal(channel, prompt)
for req := range requests {
var width, height int
var ok bool
go func(in <-chan *ssh.Request) {
defer channel.Close()
hasShell := false
for req := range in {
var width, height int
var ok bool
switch req.Type {
case "shell":
if c.term != nil && !hasShell {
go c.handleShell(channel)
ok = true
hasShell = true
}
case "pty-req":
width, height, ok = parsePtyRequest(req.Payload)
if ok {
err := c.Resize(width, height)
ok = err == nil
}
case "window-change":
width, height, ok = parseWinchRequest(req.Payload)
if ok {
err := c.Resize(width, height)
ok = err == nil
}
switch req.Type {
case "shell":
if c.term != nil && !hasShell {
go c.handleShell(channel)
ok = true
hasShell = true
}
if req.WantReply {
req.Reply(ok, nil)
case "pty-req":
width, height, ok = parsePtyRequest(req.Payload)
if ok {
err := c.Resize(width, height)
ok = err == nil
}
case "window-change":
width, height, ok = parseWinchRequest(req.Payload)
if ok {
err := c.Resize(width, height)
ok = err == nil
}
}
}(requests)
// We don't care about other channels?
return
if req.WantReply {
req.Reply(ok, nil)
}
}
}
}

View File

@ -1,10 +1,13 @@
// TODO: Split this out into its own module, it's kinda neat.
package main
import "sync"
type History struct {
entries []string
head int
size int
lock sync.Mutex
}
func NewHistory(size int) *History {
@ -14,6 +17,9 @@ func NewHistory(size int) *History {
}
func (h *History) Add(entry string) {
h.lock.Lock()
defer h.lock.Unlock()
max := cap(h.entries)
h.head = (h.head + 1) % max
h.entries[h.head] = entry
@ -27,6 +33,9 @@ func (h *History) Len() int {
}
func (h *History) Get(num int) []string {
h.lock.Lock()
defer h.lock.Unlock()
max := cap(h.entries)
if num > h.size {
num = h.size

View File

@ -133,6 +133,7 @@ func (s *Server) Rename(client *Client, newName string) {
return
}
// TODO: Use a channel/goroutine for adding clients, rathern than locks?
delete(s.clients, client.Name)
oldName := client.Name
client.Rename(newName)
@ -193,7 +194,10 @@ func (s *Server) Start(laddr string) error {
go ssh.DiscardRequests(requests)
client := NewClient(s, sshConn)
client.handleChannels(channels)
go client.handleChannels(channels)
// FIXME: This is hacky, need to restructure the concurrency. Fairly sure this will leak channels.
<-client.ready
s.Add(client)
go func() {