mirror of
https://github.com/shazow/ssh-chat.git
synced 2025-04-13 15:47: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
|
Msg chan string
|
||||||
Name string
|
Name string
|
||||||
Op bool
|
Op bool
|
||||||
|
ready chan struct{}
|
||||||
term *terminal.Terminal
|
term *terminal.Terminal
|
||||||
termWidth int
|
termWidth int
|
||||||
termHeight int
|
termHeight int
|
||||||
@ -48,6 +49,7 @@ func NewClient(server *Server, conn *ssh.ServerConn) *Client {
|
|||||||
Conn: conn,
|
Conn: conn,
|
||||||
Name: conn.User(),
|
Name: conn.User(),
|
||||||
Msg: make(chan string, MSG_BUFFER),
|
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) {
|
func (c *Client) handleShell(channel ssh.Channel) {
|
||||||
defer channel.Close()
|
defer channel.Close()
|
||||||
|
c.ready <- struct{}{}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for msg := range c.Msg {
|
for msg := range c.Msg {
|
||||||
@ -145,6 +148,8 @@ func (c *Client) handleShell(channel ssh.Channel) {
|
|||||||
func (c *Client) handleChannels(channels <-chan ssh.NewChannel) {
|
func (c *Client) handleChannels(channels <-chan ssh.NewChannel) {
|
||||||
prompt := fmt.Sprintf("[%s] ", c.Name)
|
prompt := fmt.Sprintf("[%s] ", c.Name)
|
||||||
|
|
||||||
|
hasShell := false
|
||||||
|
|
||||||
for ch := range channels {
|
for ch := range channels {
|
||||||
if t := ch.ChannelType(); t != "session" {
|
if t := ch.ChannelType(); t != "session" {
|
||||||
ch.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %s", t))
|
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)
|
logger.Errorf("Could not accept channel: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
defer channel.Close()
|
||||||
|
|
||||||
c.term = terminal.NewTerminal(channel, prompt)
|
c.term = terminal.NewTerminal(channel, prompt)
|
||||||
|
for req := range requests {
|
||||||
|
var width, height int
|
||||||
|
var ok bool
|
||||||
|
|
||||||
go func(in <-chan *ssh.Request) {
|
switch req.Type {
|
||||||
defer channel.Close()
|
case "shell":
|
||||||
hasShell := false
|
if c.term != nil && !hasShell {
|
||||||
for req := range in {
|
go c.handleShell(channel)
|
||||||
var width, height int
|
ok = true
|
||||||
var ok bool
|
hasShell = true
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
case "pty-req":
|
||||||
if req.WantReply {
|
width, height, ok = parsePtyRequest(req.Payload)
|
||||||
req.Reply(ok, nil)
|
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?
|
if req.WantReply {
|
||||||
return
|
req.Reply(ok, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
// TODO: Split this out into its own module, it's kinda neat.
|
// TODO: Split this out into its own module, it's kinda neat.
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
type History struct {
|
type History struct {
|
||||||
entries []string
|
entries []string
|
||||||
head int
|
head int
|
||||||
size int
|
size int
|
||||||
|
lock sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHistory(size int) *History {
|
func NewHistory(size int) *History {
|
||||||
@ -14,6 +17,9 @@ func NewHistory(size int) *History {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *History) Add(entry string) {
|
func (h *History) Add(entry string) {
|
||||||
|
h.lock.Lock()
|
||||||
|
defer h.lock.Unlock()
|
||||||
|
|
||||||
max := cap(h.entries)
|
max := cap(h.entries)
|
||||||
h.head = (h.head + 1) % max
|
h.head = (h.head + 1) % max
|
||||||
h.entries[h.head] = entry
|
h.entries[h.head] = entry
|
||||||
@ -27,6 +33,9 @@ func (h *History) Len() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *History) Get(num int) []string {
|
func (h *History) Get(num int) []string {
|
||||||
|
h.lock.Lock()
|
||||||
|
defer h.lock.Unlock()
|
||||||
|
|
||||||
max := cap(h.entries)
|
max := cap(h.entries)
|
||||||
if num > h.size {
|
if num > h.size {
|
||||||
num = h.size
|
num = h.size
|
||||||
|
@ -133,6 +133,7 @@ func (s *Server) Rename(client *Client, newName string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Use a channel/goroutine for adding clients, rathern than locks?
|
||||||
delete(s.clients, client.Name)
|
delete(s.clients, client.Name)
|
||||||
oldName := client.Name
|
oldName := client.Name
|
||||||
client.Rename(newName)
|
client.Rename(newName)
|
||||||
@ -193,7 +194,10 @@ func (s *Server) Start(laddr string) error {
|
|||||||
go ssh.DiscardRequests(requests)
|
go ssh.DiscardRequests(requests)
|
||||||
|
|
||||||
client := NewClient(s, sshConn)
|
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)
|
s.Add(client)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user