|
@@ -0,0 +1,86 @@
|
|
|
+package main
|
|
|
+
|
|
|
+import (
|
|
|
+ "bytes"
|
|
|
+ "errors"
|
|
|
+ "fmt"
|
|
|
+ "net"
|
|
|
+ "os"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+type Client struct {
|
|
|
+ server *Server
|
|
|
+ conn net.Conn
|
|
|
+ Ip string
|
|
|
+ Line string
|
|
|
+ Prompt string
|
|
|
+ PromptWLine bool
|
|
|
+}
|
|
|
+
|
|
|
+func NewClient(server *Server, conn net.Conn) *Client {
|
|
|
+ ip := conn.RemoteAddr().String()
|
|
|
+ c := &Client{
|
|
|
+ server: server,
|
|
|
+ conn: conn,
|
|
|
+ Ip: ip,
|
|
|
+ Line: "",
|
|
|
+ Prompt: "Login: ",
|
|
|
+ PromptWLine: true,
|
|
|
+ }
|
|
|
+ go c.reader()
|
|
|
+ return c
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Client) Write(text string) {
|
|
|
+ c.conn.Write([]byte(text))
|
|
|
+}
|
|
|
+
|
|
|
+var clearLine = bytes.Repeat([]byte("\b \b"), 500)
|
|
|
+
|
|
|
+func (c *Client) InsertWrite(text string) {
|
|
|
+ c.conn.Write(clearLine)
|
|
|
+ c.Write(text)
|
|
|
+ if len(c.Prompt) != 0 {
|
|
|
+ c.Write(c.Prompt)
|
|
|
+ if c.PromptWLine {
|
|
|
+ c.Write(c.Line)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Client) reader() {
|
|
|
+ var (
|
|
|
+ buf []byte = make([]byte, 1024) // 1kb
|
|
|
+ read int
|
|
|
+ err error
|
|
|
+ )
|
|
|
+ for {
|
|
|
+ c.conn.SetReadDeadline(time.Now().Add(time.Duration(200) * time.Millisecond))
|
|
|
+ read, err = c.conn.Read(buf)
|
|
|
+ if err != nil {
|
|
|
+ if errors.Is(err, net.ErrClosed) || errors.Is(err, os.ErrClosed) {
|
|
|
+ return
|
|
|
+ } else if errors.Is(err, os.ErrDeadlineExceeded) {
|
|
|
+ if read != 0 {
|
|
|
+ c.process(string(buf[0:read]))
|
|
|
+ }
|
|
|
+ continue
|
|
|
+ } else {
|
|
|
+ fmt.Printf("%s ERR> %v", c.Ip, err)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if read != 0 {
|
|
|
+ c.process(string(buf[0:read]))
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+func (c *Client) process(input string) {
|
|
|
+ // Process the input as far as ENTER/RETURN and keys being pressed
|
|
|
+ // This will require a state machine to track where the client is (Login, Password, Sitting in their ship, Accessing computer, etc)
|
|
|
+
|
|
|
+ // For now we'll just echo it back
|
|
|
+ c.Write(input)
|
|
|
+}
|