mirror of
https://github.com/shazow/ssh-chat.git
synced 2025-04-12 23:27:17 +03:00
Hacky fixes with notes.
This commit is contained in:
parent
f11049d84d
commit
0b80aa8345
62
client.go
62
client.go
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user