From a040abe0e88b74fad07c05a59e477adce5e3edbf Mon Sep 17 00:00:00 2001 From: redscaresu Date: Mon, 21 Mar 2022 20:59:04 +0000 Subject: [PATCH 01/37] shellspy progress --- shellspy.go | 11 +++++------ shellspy_test.go | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/shellspy.go b/shellspy.go index cdc88b1..83ea487 100644 --- a/shellspy.go +++ b/shellspy.go @@ -64,8 +64,6 @@ func RunCLI(cliArgs []string, w io.Writer) { os.Exit(1) } - fmt.Println(len(cliArgs)) - fmt.Println(cliArgs) if len(cliArgs) == 1 { RunLocally(s, w) } @@ -73,10 +71,12 @@ func RunCLI(cliArgs []string, w io.Writer) { fs := flag.NewFlagSet("cmd", flag.ContinueOnError) fs.Parse(os.Args[1:]) + fmt.Println(os.Args) switch os.Args[1] { case "port": args := fs.Args() s.Port = args[1] + fmt.Println("bollox") RunRemotely(s, w) } @@ -94,13 +94,12 @@ func RunLocally(s *session, w io.Writer) { func RunRemotely(s *session, w io.Writer) error { - port := s.Port buf := &bytes.Buffer{} - buf.WriteString("shellspy is running remotely " + port + "\n") + buf.WriteString("shellspy is running remotely " + s.Port + "\n") fmt.Fprint(w, buf) - s.TranscriptOutput = buf + s.TranscriptOutput = w - address := "localhost:" + port + address := "localhost:" + s.Port listener, err := net.Listen("tcp", address) if err != nil { diff --git a/shellspy_test.go b/shellspy_test.go index c467ccf..02dcdd5 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -98,6 +98,16 @@ func TestRunWithoutPortFlagRunInteractively(t *testing.T) { // func TestPortFlagStartsNetListener(t *testing.T) { -// flagArgs := []string{"port", "9999"} -// shellspy.RunCLI(flagArgs) +// buf := &bytes.Buffer{} + +// flagArgs := []string{"/var/folders/1v/4mmgcg8s51362djr4g9s9sfw0000gn/T/go-build3590226918/b001/exe/main", "port", "6666"} + +// shellspy.RunCLI(flagArgs, buf) +// got := buf.String() + +// want := "shellspy is running remotely on port 6666\n" + +// if !cmp.Equal(want, got) { +// t.Error(cmp.Diff(want, got)) +// } // } From 7e0c26b45cbc72ee506cebbf3a03b497539df55c Mon Sep 17 00:00:00 2001 From: redscaresu Date: Tue, 5 Apr 2022 13:30:21 +0100 Subject: [PATCH 02/37] fix bug --- shellspy.go | 4 ++-- shellspy_test.go | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/shellspy.go b/shellspy.go index 83ea487..777ab5a 100644 --- a/shellspy.go +++ b/shellspy.go @@ -182,8 +182,8 @@ func CommandFromString(line string) *exec.Cmd { trim := strings.TrimSuffix(line, "\n") name := strings.Fields(trim) args := name[1:] - join := strings.Join(args, " ") - cmd := exec.Command(name[0], join) + cmd := exec.Command(name[0], args...) + fmt.Println(cmd.Args) return cmd } diff --git a/shellspy_test.go b/shellspy_test.go index 02dcdd5..35b2772 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -26,6 +26,14 @@ func TestCommandFromString(t *testing.T) { t.Error(cmp.Diff(want, got)) } } +func TestCommandFromStringArgs(t *testing.T) { + input := "ls" + want := []string{"ls"} + got := shellspy.CommandFromString(input).Args + if !cmp.Equal(want, got) { + t.Error(cmp.Diff(want, got)) + } +} func TestRunCommand(t *testing.T) { From e81d1830b5123ed82bbad2dc93b4c1d708c8b342 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Tue, 5 Apr 2022 21:57:16 +0100 Subject: [PATCH 03/37] comment out the tests for now --- shellspy.go | 86 ++++++++---------------- shellspy_test.go | 168 ++++++++++++++++++++++------------------------- 2 files changed, 105 insertions(+), 149 deletions(-) diff --git a/shellspy.go b/shellspy.go index 777ab5a..d140e37 100644 --- a/shellspy.go +++ b/shellspy.go @@ -15,42 +15,43 @@ import ( ) type session struct { - Input io.Reader - Output io.Writer - TranscriptOutput io.Writer - File *os.File - Port string + Input io.Reader + Output io.Writer + Terminal io.Writer + Transcript io.Writer + Port string } type Option func(*session) func WithOutput(output io.Writer) Option { return func(s *session) { - s.Output = output + s.Terminal = output } } func WithTranscriptOutput(TranscriptOutput io.Writer) Option { return func(s *session) { - s.TranscriptOutput = TranscriptOutput + s.Transcript = TranscriptOutput } } func NewSession(opts ...Option) (*session, error) { - session := &session{} + s := &session{} for _, o := range opts { - o(session) + o(s) } file, err := CreateTranscriptFile() if err != nil { - return session, err + return s, err } - session.File = file - - return session, nil + s.Transcript = file + s.Input = os.Stdin + s.Output = io.MultiWriter(s.Terminal, s.Transcript) + return s, nil } func RunCLI(cliArgs []string, w io.Writer) { @@ -65,7 +66,8 @@ func RunCLI(cliArgs []string, w io.Writer) { } if len(cliArgs) == 1 { - RunLocally(s, w) + fmt.Fprint(s.Output, "shellspy is running locally\n") + s.Start() } fs := flag.NewFlagSet("cmd", flag.ContinueOnError) @@ -82,22 +84,12 @@ func RunCLI(cliArgs []string, w io.Writer) { } -func RunLocally(s *session, w io.Writer) { - - buf := &bytes.Buffer{} - buf.WriteString("shellspy is running locally\n") - fmt.Fprint(w, buf) - s.Output = w - input := io.Reader(os.Stdin) - Input(input, s) -} - func RunRemotely(s *session, w io.Writer) error { buf := &bytes.Buffer{} buf.WriteString("shellspy is running remotely " + s.Port + "\n") fmt.Fprint(w, buf) - s.TranscriptOutput = w + s.Transcript = w address := "localhost:" + s.Port @@ -123,46 +115,24 @@ func RunRemotely(s *session, w io.Writer) error { func handleConn(c net.Conn, s *session) { fmt.Fprintf(c, "hello, welcome to shellspy"+"\n") - input := io.Reader(c) - exitStatus := Input(input, s) - if exitStatus == "0" { - c.Close() - } + // input := io.Reader(c) + // exitStatus := Input(input, s) + // if exitStatus == "0" { + // c.Close() + // } c.Close() } -func Input(input io.Reader, s *session) string { +func (s *session) Start() { - scanner := bufio.NewScanner(input) + scanner := bufio.NewScanner(s.Input) for scanner.Scan() { - s.Input = strings.NewReader(scanner.Text()) - exitStatus := s.Run() - if exitStatus == "0" { - return "0" - } - } - return "" -} + cmd := CommandFromString(scanner.Text()) + cmd.Stdout = s.Output + cmd.Stderr = s.Output + cmd.Run() -func (s *session) Run() string { - - writer := &bytes.Buffer{} - twriter := &bytes.Buffer{} - iReader := &bytes.Buffer{} - fmt.Fprint(iReader, s.Input) - file := s.File - input := iReader.String() - input = strings.TrimPrefix(input, "&{") - input = strings.TrimSuffix(input, " 0 -1}") - stdOut, exitStatus := RunServer(input, file) - if exitStatus == "0" { - return "0" } - s.Output = writer - s.TranscriptOutput = twriter - fmt.Fprint(writer, stdOut) - fmt.Fprint(twriter, stdOut) - return "" } func RunServer(line string, file *os.File) (string, string) { diff --git a/shellspy_test.go b/shellspy_test.go index 35b2772..f8986fa 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -1,121 +1,107 @@ package shellspy_test -import ( - "bytes" - "fmt" - "os" - "os/exec" - "strings" - "testing" - "time" +// func TestCommandFromString(t *testing.T) { - "github.com/redscaresu/shellspy" +// cmdWant := &exec.Cmd{} +// cmdWant.Args = []string{"/bin/echo", "hello", "world"} +// wantCmd := cmdWant.String() +// want := strings.TrimPrefix(wantCmd, " ") +// got := shellspy.CommandFromString(want).String() - "github.com/google/go-cmp/cmp" -) - -func TestCommandFromString(t *testing.T) { - - cmdWant := &exec.Cmd{} - cmdWant.Args = []string{"/bin/echo", "hello", "world"} - wantCmd := cmdWant.String() - want := strings.TrimPrefix(wantCmd, " ") - got := shellspy.CommandFromString(want).String() - - if !cmp.Equal(want, got) { - t.Error(cmp.Diff(want, got)) - } -} -func TestCommandFromStringArgs(t *testing.T) { - input := "ls" - want := []string{"ls"} - got := shellspy.CommandFromString(input).Args - if !cmp.Equal(want, got) { - t.Error(cmp.Diff(want, got)) - } -} - -func TestRunCommand(t *testing.T) { - - cmd := exec.Command("echo", "hello world") - want := "hello world\n" - got, _ := shellspy.RunFromCmd(cmd) - - if !cmp.Equal(want, got) { - t.Error(cmp.Diff(want, got)) - } - - cmd = exec.Command("pwd", "-x") - want = "pwd: illegal option -- x\nusage: pwd [-L | -P]\n" - - _, got = shellspy.RunFromCmd(cmd) - if !cmp.Equal(want, got) { - t.Error(cmp.Diff(want, got)) - } - -} - -func TestWriteShellScript(t *testing.T) { +// if !cmp.Equal(want, got) { +// t.Error(cmp.Diff(want, got)) +// } +// } +// func TestCommandFromStringArgs(t *testing.T) { +// input := "ls" +// want := []string{"ls"} +// got := shellspy.CommandFromString(input).Args +// if !cmp.Equal(want, got) { +// t.Error(cmp.Diff(want, got)) +// } +// } - wantBuf := &bytes.Buffer{} - gotBuf := &bytes.Buffer{} - wantBuf.WriteString("hello world\n") - session, _ := shellspy.NewSession( - shellspy.WithTranscriptOutput(wantBuf), - ) +// func TestRunCommand(t *testing.T) { - session.Input = strings.NewReader("echo hello world") - tempDir := t.TempDir() +// cmd := exec.Command("echo", "hello world") +// want := "hello world\n" +// got, _ := shellspy.RunFromCmd(cmd) - now := time.Now() - filename := tempDir + "shellspy-" + now.Format("2006-01-02-15:04:05") + ".txt" - file, err := os.OpenFile(filename, - os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - t.Fatal("unable to create file") - } +// if !cmp.Equal(want, got) { +// t.Error(cmp.Diff(want, got)) +// } - session.File = file - session.Run() - fmt.Fprint(gotBuf, session.TranscriptOutput) +// cmd = exec.Command("pwd", "-x") +// want = "pwd: illegal option -- x\nusage: pwd [-L | -P]\n" - want := wantBuf.String() - got := gotBuf.String() +// _, got = shellspy.RunFromCmd(cmd) +// if !cmp.Equal(want, got) { +// t.Error(cmp.Diff(want, got)) +// } - if !cmp.Equal(want, got) { - t.Error(cmp.Diff(want, got)) - } -} +// } -func TestRunWithoutPortFlagRunInteractively(t *testing.T) { +// func TestWriteShellScript(t *testing.T) { - buf := &bytes.Buffer{} +// wantBuf := &bytes.Buffer{} +// gotBuf := &bytes.Buffer{} +// wantBuf.WriteString("hello world\n") +// session, _ := shellspy.NewSession( +// shellspy.WithTranscriptOutput(wantBuf), +// ) - flagArgs := []string{"/var/folders/1v/4mmgcg8s51362djr4g9s9sfw0000gn/T/go-build3590226918/b001/exe/main"} +// session.Input = strings.NewReader("echo hello world") +// tempDir := t.TempDir() - shellspy.RunCLI(flagArgs, buf) - got := buf.String() +// now := time.Now() +// filename := tempDir + "shellspy-" + now.Format("2006-01-02-15:04:05") + ".txt" +// file, err := os.OpenFile(filename, +// os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) +// if err != nil { +// t.Fatal("unable to create file") +// } - want := "shellspy is running locally\n" +// session.File = file +// session.Run() +// fmt.Fprint(gotBuf, session.Transcript) - if !cmp.Equal(want, got) { - t.Error(cmp.Diff(want, got)) - } +// want := wantBuf.String() +// got := gotBuf.String() -} +// if !cmp.Equal(want, got) { +// t.Error(cmp.Diff(want, got)) +// } +// } -// func TestPortFlagStartsNetListener(t *testing.T) { +// func TestRunWithoutPortFlagRunInteractively(t *testing.T) { // buf := &bytes.Buffer{} -// flagArgs := []string{"/var/folders/1v/4mmgcg8s51362djr4g9s9sfw0000gn/T/go-build3590226918/b001/exe/main", "port", "6666"} +// flagArgs := []string{"/var/folders/1v/4mmgcg8s51362djr4g9s9sfw0000gn/T/go-build3590226918/b001/exe/main"} // shellspy.RunCLI(flagArgs, buf) // got := buf.String() -// want := "shellspy is running remotely on port 6666\n" +// want := "shellspy is running locally\n" // if !cmp.Equal(want, got) { // t.Error(cmp.Diff(want, got)) // } + // } + +// // func TestPortFlagStartsNetListener(t *testing.T) { + +// // buf := &bytes.Buffer{} + +// // flagArgs := []string{"/var/folders/1v/4mmgcg8s51362djr4g9s9sfw0000gn/T/go-build3590226918/b001/exe/main", "port", "6666"} + +// // shellspy.RunCLI(flagArgs, buf) +// // got := buf.String() + +// // want := "shellspy is running remotely on port 6666\n" + +// // if !cmp.Equal(want, got) { +// // t.Error(cmp.Diff(want, got)) +// // } +// // } From a818f164dd4bdd595c5a27984904474fa950e1af Mon Sep 17 00:00:00 2001 From: redscaresu Date: Fri, 8 Apr 2022 14:58:06 +0100 Subject: [PATCH 04/37] remove functional operators --- shellspy.go | 109 ++--------------------------------------------- shellspy_test.go | 49 ++++++++++++--------- 2 files changed, 32 insertions(+), 126 deletions(-) diff --git a/shellspy.go b/shellspy.go index d140e37..54d4928 100644 --- a/shellspy.go +++ b/shellspy.go @@ -2,14 +2,10 @@ package shellspy import ( "bufio" - "bytes" - "flag" "fmt" "io" - "net" "os" "os/exec" - "os/signal" "strings" "time" ) @@ -22,43 +18,23 @@ type session struct { Port string } -type Option func(*session) - -func WithOutput(output io.Writer) Option { - return func(s *session) { - s.Terminal = output - } -} - -func WithTranscriptOutput(TranscriptOutput io.Writer) Option { - return func(s *session) { - s.Transcript = TranscriptOutput - } -} - -func NewSession(opts ...Option) (*session, error) { - +func NewSession(output io.Writer) (*session, error) { s := &session{} - for _, o := range opts { - o(s) - } - file, err := CreateTranscriptFile() if err != nil { return s, err } s.Transcript = file s.Input = os.Stdin + s.Terminal = output s.Output = io.MultiWriter(s.Terminal, s.Transcript) return s, nil } func RunCLI(cliArgs []string, w io.Writer) { - s, err := NewSession( - WithOutput(w), - ) + s, err := NewSession(w) if err != nil { fmt.Printf("%v", err) @@ -70,57 +46,6 @@ func RunCLI(cliArgs []string, w io.Writer) { s.Start() } - fs := flag.NewFlagSet("cmd", flag.ContinueOnError) - fs.Parse(os.Args[1:]) - - fmt.Println(os.Args) - switch os.Args[1] { - case "port": - args := fs.Args() - s.Port = args[1] - fmt.Println("bollox") - RunRemotely(s, w) - } - -} - -func RunRemotely(s *session, w io.Writer) error { - - buf := &bytes.Buffer{} - buf.WriteString("shellspy is running remotely " + s.Port + "\n") - fmt.Fprint(w, buf) - s.Transcript = w - - address := "localhost:" + s.Port - - listener, err := net.Listen("tcp", address) - if err != nil { - return err - } - killSignal := make(chan os.Signal, 1) - signal.Notify(killSignal, os.Interrupt) - for { - conn, err := listener.Accept() - if err != nil { - return err - } - go handleConn(conn, s) - - <-killSignal - fmt.Println("\nconnection terminated by server!") - listener.Close() - } -} - -func handleConn(c net.Conn, s *session) { - - fmt.Fprintf(c, "hello, welcome to shellspy"+"\n") - // input := io.Reader(c) - // exitStatus := Input(input, s) - // if exitStatus == "0" { - // c.Close() - // } - c.Close() } func (s *session) Start() { @@ -135,42 +60,14 @@ func (s *session) Start() { } } -func RunServer(line string, file *os.File) (string, string) { - - cmd := CommandFromString(line) - - if strings.HasPrefix(line, "exit") { - return "", "0" - } - - stdOut, stdErr := RunFromCmd(cmd) - WriteTranscript(stdOut, stdErr, cmd, file) - return stdOut, "" -} - func CommandFromString(line string) *exec.Cmd { trim := strings.TrimSuffix(line, "\n") name := strings.Fields(trim) args := name[1:] cmd := exec.Command(name[0], args...) - fmt.Println(cmd.Args) return cmd } -func RunFromCmd(cmd *exec.Cmd) (string, string) { - var outb bytes.Buffer - var errb bytes.Buffer - cmd.Stdout = &outb - cmd.Stderr = &errb - - cmd.Run() - - stdOut := outb.String() - stdErr := errb.String() - - return stdOut, stdErr -} - func CreateTranscriptFile() (*os.File, error) { now := time.Now() filename := ".shellspy-" + now.Format("2006-01-02-15:04:05") + ".txt" diff --git a/shellspy_test.go b/shellspy_test.go index f8986fa..b6735c4 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -1,25 +1,34 @@ package shellspy_test -// func TestCommandFromString(t *testing.T) { - -// cmdWant := &exec.Cmd{} -// cmdWant.Args = []string{"/bin/echo", "hello", "world"} -// wantCmd := cmdWant.String() -// want := strings.TrimPrefix(wantCmd, " ") -// got := shellspy.CommandFromString(want).String() - -// if !cmp.Equal(want, got) { -// t.Error(cmp.Diff(want, got)) -// } -// } -// func TestCommandFromStringArgs(t *testing.T) { -// input := "ls" -// want := []string{"ls"} -// got := shellspy.CommandFromString(input).Args -// if !cmp.Equal(want, got) { -// t.Error(cmp.Diff(want, got)) -// } -// } +import ( + "os/exec" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/redscaresu/shellspy" +) + +func TestCommandFromString(t *testing.T) { + + cmdWant := &exec.Cmd{} + cmdWant.Args = []string{"/bin/echo", "hello", "world"} + wantCmd := cmdWant.String() + want := strings.TrimPrefix(wantCmd, " ") + got := shellspy.CommandFromString(want).String() + + if !cmp.Equal(want, got) { + t.Error(cmp.Diff(want, got)) + } +} +func TestCommandFromStringArgs(t *testing.T) { + input := "ls" + want := []string{"ls"} + got := shellspy.CommandFromString(input).Args + if !cmp.Equal(want, got) { + t.Error(cmp.Diff(want, got)) + } +} // func TestRunCommand(t *testing.T) { From cd9c71df0a9308d443c6c891f9b4aa84ca461904 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Sat, 9 Apr 2022 15:39:09 +0100 Subject: [PATCH 05/37] im confused --- shellspy.go | 14 ++++++-------- shellspy_test.go | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/shellspy.go b/shellspy.go index 54d4928..c32c281 100644 --- a/shellspy.go +++ b/shellspy.go @@ -10,7 +10,7 @@ import ( "time" ) -type session struct { +type Session struct { Input io.Reader Output io.Writer Terminal io.Writer @@ -18,8 +18,8 @@ type session struct { Port string } -func NewSession(output io.Writer) (*session, error) { - s := &session{} +func NewSession(output io.Writer) (*Session, error) { + s := &Session{} file, err := CreateTranscriptFile() if err != nil { @@ -32,9 +32,9 @@ func NewSession(output io.Writer) (*session, error) { return s, nil } -func RunCLI(cliArgs []string, w io.Writer) { +func RunCLI(cliArgs []string, output io.Writer) { - s, err := NewSession(w) + s, err := NewSession(output) if err != nil { fmt.Printf("%v", err) @@ -45,10 +45,9 @@ func RunCLI(cliArgs []string, w io.Writer) { fmt.Fprint(s.Output, "shellspy is running locally\n") s.Start() } - } -func (s *session) Start() { +func (s *Session) Start() { scanner := bufio.NewScanner(s.Input) for scanner.Scan() { @@ -56,7 +55,6 @@ func (s *session) Start() { cmd.Stdout = s.Output cmd.Stderr = s.Output cmd.Run() - } } diff --git a/shellspy_test.go b/shellspy_test.go index b6735c4..9ed487a 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -1,6 +1,9 @@ package shellspy_test import ( + "bytes" + "fmt" + "os" "os/exec" "strings" "testing" @@ -30,6 +33,21 @@ func TestCommandFromStringArgs(t *testing.T) { } } +func TestRunCommand(t *testing.T) { + + wantBuf := &bytes.Buffer{} + gotBuf := &bytes.Buffer{} + s, err := shellspy.NewSession(os.Stdout) + if err != nil { + t.Fatal("unable to create file") + } + s.Start() + fmt.Fprint(wantBuf, "shellspy is running locally\n") + fmt.Fprint(gotBuf, s.Output) + fmt.Println(gotBuf) + +} + // func TestRunCommand(t *testing.T) { // cmd := exec.Command("echo", "hello world") From 0cf16e55df1ec606d088d2cf4b5efb97fefbb523 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Wed, 13 Apr 2022 13:44:33 +0100 Subject: [PATCH 06/37] fix the test for getting output from a command --- shellspy_test.go | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/shellspy_test.go b/shellspy_test.go index 9ed487a..459ea2f 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -7,6 +7,7 @@ import ( "os/exec" "strings" "testing" + "time" "github.com/google/go-cmp/cmp" "github.com/redscaresu/shellspy" @@ -37,15 +38,30 @@ func TestRunCommand(t *testing.T) { wantBuf := &bytes.Buffer{} gotBuf := &bytes.Buffer{} - s, err := shellspy.NewSession(os.Stdout) + s, err := shellspy.NewSession(gotBuf) + s.Input = strings.NewReader("echo hello world") if err != nil { t.Fatal("unable to create file") } + tempDir := t.TempDir() + + now := time.Now() + filename := tempDir + "shellspy-" + now.Format("2006-01-02-15:04:05") + ".txt" + file, err := os.OpenFile(filename, + os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + t.Fatal("unable to create file") + } + s.Transcript = file + s.Start() - fmt.Fprint(wantBuf, "shellspy is running locally\n") - fmt.Fprint(gotBuf, s.Output) - fmt.Println(gotBuf) + fmt.Fprint(wantBuf, s.Terminal) + want := wantBuf.String() + got := "hello world\n" + if !cmp.Equal(want, got) { + t.Error(cmp.Diff(want, got)) + } } // func TestRunCommand(t *testing.T) { From 42d742260cd82092cd9824ce9e43bad8699ce3ef Mon Sep 17 00:00:00 2001 From: redscaresu Date: Wed, 13 Apr 2022 13:45:38 +0100 Subject: [PATCH 07/37] remove unnecessary tests --- shellspy_test.go | 52 ------------------------------------------------ 1 file changed, 52 deletions(-) diff --git a/shellspy_test.go b/shellspy_test.go index 459ea2f..aa76d72 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -64,58 +64,6 @@ func TestRunCommand(t *testing.T) { } } -// func TestRunCommand(t *testing.T) { - -// cmd := exec.Command("echo", "hello world") -// want := "hello world\n" -// got, _ := shellspy.RunFromCmd(cmd) - -// if !cmp.Equal(want, got) { -// t.Error(cmp.Diff(want, got)) -// } - -// cmd = exec.Command("pwd", "-x") -// want = "pwd: illegal option -- x\nusage: pwd [-L | -P]\n" - -// _, got = shellspy.RunFromCmd(cmd) -// if !cmp.Equal(want, got) { -// t.Error(cmp.Diff(want, got)) -// } - -// } - -// func TestWriteShellScript(t *testing.T) { - -// wantBuf := &bytes.Buffer{} -// gotBuf := &bytes.Buffer{} -// wantBuf.WriteString("hello world\n") -// session, _ := shellspy.NewSession( -// shellspy.WithTranscriptOutput(wantBuf), -// ) - -// session.Input = strings.NewReader("echo hello world") -// tempDir := t.TempDir() - -// now := time.Now() -// filename := tempDir + "shellspy-" + now.Format("2006-01-02-15:04:05") + ".txt" -// file, err := os.OpenFile(filename, -// os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) -// if err != nil { -// t.Fatal("unable to create file") -// } - -// session.File = file -// session.Run() -// fmt.Fprint(gotBuf, session.Transcript) - -// want := wantBuf.String() -// got := gotBuf.String() - -// if !cmp.Equal(want, got) { -// t.Error(cmp.Diff(want, got)) -// } -// } - // func TestRunWithoutPortFlagRunInteractively(t *testing.T) { // buf := &bytes.Buffer{} From 0dd5cfb4d540fd401742b6b40e49156be3aecea3 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Thu, 14 Apr 2022 16:18:02 +0100 Subject: [PATCH 08/37] run remotely --- shellspy.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/shellspy.go b/shellspy.go index c32c281..9c4be47 100644 --- a/shellspy.go +++ b/shellspy.go @@ -2,8 +2,11 @@ package shellspy import ( "bufio" + "bytes" + "flag" "fmt" "io" + "net" "os" "os/exec" "strings" @@ -45,6 +48,45 @@ func RunCLI(cliArgs []string, output io.Writer) { fmt.Fprint(s.Output, "shellspy is running locally\n") s.Start() } + + fs := flag.NewFlagSet("cmd", flag.ContinueOnError) + fs.Parse(os.Args[1:]) + + switch os.Args[1] { + case "port": + args := fs.Args() + s.Port = args[1] + RunRemotely(s, output) + } +} + +func RunRemotely(s *Session, output io.Writer) error { + + buf := &bytes.Buffer{} + buf.WriteString("shellspy is running remotely " + s.Port + "\n") + fmt.Fprint(output, buf) + s.Transcript = output + + address := "localhost:" + s.Port + + listener, err := net.Listen("tcp", address) + if err != nil { + return err + } + for { + conn, err := listener.Accept() + if err != nil { + return err + } + go handleConn(conn, s) + } +} + +func handleConn(c net.Conn, s *Session) { + + fmt.Fprintf(c, "hello, welcome to shellspy"+"\n") + s.Input = io.Reader(c) + s.Start() } func (s *Session) Start() { From fb5f6abf06a1e48fec4e7fade84634d0d41f791c Mon Sep 17 00:00:00 2001 From: redscaresu Date: Tue, 19 Apr 2022 10:26:58 +0100 Subject: [PATCH 09/37] tweak --- shellspy_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/shellspy_test.go b/shellspy_test.go index aa76d72..9dde874 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -81,18 +81,18 @@ func TestRunCommand(t *testing.T) { // } -// // func TestPortFlagStartsNetListener(t *testing.T) { +// func TestPortFlagStartsNetListener(t *testing.T) { -// // buf := &bytes.Buffer{} +// buf := &bytes.Buffer{} -// // flagArgs := []string{"/var/folders/1v/4mmgcg8s51362djr4g9s9sfw0000gn/T/go-build3590226918/b001/exe/main", "port", "6666"} +// flagArgs := []string{"/var/folders/1v/4mmgcg8s51362djr4g9s9sfw0000gn/T/go-build3590226918/b001/exe/main", "port", "6666"} -// // shellspy.RunCLI(flagArgs, buf) -// // got := buf.String() +// shellspy.RunCLI(flagArgs, buf) +// got := buf.String() -// // want := "shellspy is running remotely on port 6666\n" +// want := "shellspy is running remotely on port 6666\n" -// // if !cmp.Equal(want, got) { -// // t.Error(cmp.Diff(want, got)) -// // } -// // } +// if !cmp.Equal(want, got) { +// t.Error(cmp.Diff(want, got)) +// } +// } From b279224bf6fb9d78d1924eacd78ace1deff7485a Mon Sep 17 00:00:00 2001 From: redscaresu Date: Tue, 19 Apr 2022 14:01:51 +0100 Subject: [PATCH 10/37] fix the tests --- shellspy.go | 15 +++++---------- shellspy_test.go | 25 +++++++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/shellspy.go b/shellspy.go index 9c4be47..f22bd6e 100644 --- a/shellspy.go +++ b/shellspy.go @@ -2,7 +2,6 @@ package shellspy import ( "bufio" - "bytes" "flag" "fmt" "io" @@ -50,23 +49,19 @@ func RunCLI(cliArgs []string, output io.Writer) { } fs := flag.NewFlagSet("cmd", flag.ContinueOnError) - fs.Parse(os.Args[1:]) + fs.Parse(cliArgs[1:]) - switch os.Args[1] { + switch cliArgs[1] { case "port": args := fs.Args() s.Port = args[1] - RunRemotely(s, output) + RunRemotely(s) } } -func RunRemotely(s *Session, output io.Writer) error { - - buf := &bytes.Buffer{} - buf.WriteString("shellspy is running remotely " + s.Port + "\n") - fmt.Fprint(output, buf) - s.Transcript = output +func RunRemotely(s *Session) error { + fmt.Fprint(s.Output, "shellspy is running remotely on port "+s.Port+"\n") address := "localhost:" + s.Port listener, err := net.Listen("tcp", address) diff --git a/shellspy_test.go b/shellspy_test.go index 9dde874..a7bcf90 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -81,18 +81,23 @@ func TestRunCommand(t *testing.T) { // } -// func TestPortFlagStartsNetListener(t *testing.T) { +func TestPortFlagStartsNetListener(t *testing.T) { -// buf := &bytes.Buffer{} + buf := &bytes.Buffer{} -// flagArgs := []string{"/var/folders/1v/4mmgcg8s51362djr4g9s9sfw0000gn/T/go-build3590226918/b001/exe/main", "port", "6666"} + flagArgs := []string{"/var/folders/1v/4mmgcg8s51362djr4g9s9sfw0000gn/T/go-build3590226918/b001/exe/main", "port", "6666"} -// shellspy.RunCLI(flagArgs, buf) -// got := buf.String() + go shellspy.RunCLI(flagArgs, buf) -// want := "shellspy is running remotely on port 6666\n" + for buf.String() == "" { + } -// if !cmp.Equal(want, got) { -// t.Error(cmp.Diff(want, got)) -// } -// } + got := buf.String() + fmt.Println(got) + + want := "shellspy is running remotely on port 6666\n" + + if !cmp.Equal(want, got) { + t.Error(cmp.Diff(want, got)) + } +} From caedbdec3e93b250b59ac58e7ce55350a133e11a Mon Sep 17 00:00:00 2001 From: redscaresu Date: Tue, 19 Apr 2022 14:33:12 +0100 Subject: [PATCH 11/37] working tests --- cmd/shellspy/main.go | 3 +-- shellspy.go | 16 ++++++++-------- shellspy_test.go | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/cmd/shellspy/main.go b/cmd/shellspy/main.go index 7201e58..0714726 100644 --- a/cmd/shellspy/main.go +++ b/cmd/shellspy/main.go @@ -8,6 +8,5 @@ import ( func main() { - cliArgs := os.Args - shellspy.RunCLI(cliArgs, os.Stdout) + shellspy.RunCLI(os.Args[1:], os.Stdout) } diff --git a/shellspy.go b/shellspy.go index f22bd6e..4ccee29 100644 --- a/shellspy.go +++ b/shellspy.go @@ -17,7 +17,7 @@ type Session struct { Output io.Writer Terminal io.Writer Transcript io.Writer - Port string + Port int } func NewSession(output io.Writer) (*Session, error) { @@ -49,20 +49,20 @@ func RunCLI(cliArgs []string, output io.Writer) { } fs := flag.NewFlagSet("cmd", flag.ContinueOnError) - fs.Parse(cliArgs[1:]) + portFlag := fs.Int("port", 2000, "-port 3000") - switch cliArgs[1] { - case "port": - args := fs.Args() - s.Port = args[1] + fs.Parse(cliArgs) + + if portFlag != nil { + s.Port = *portFlag RunRemotely(s) } } func RunRemotely(s *Session) error { - fmt.Fprint(s.Output, "shellspy is running remotely on port "+s.Port+"\n") - address := "localhost:" + s.Port + fmt.Fprintf(s.Output, "shellspy is running remotely on port %d\n", s.Port) + address := fmt.Sprintf("localhost:%d", s.Port) listener, err := net.Listen("tcp", address) if err != nil { diff --git a/shellspy_test.go b/shellspy_test.go index a7bcf90..a6c02f9 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -85,7 +85,7 @@ func TestPortFlagStartsNetListener(t *testing.T) { buf := &bytes.Buffer{} - flagArgs := []string{"/var/folders/1v/4mmgcg8s51362djr4g9s9sfw0000gn/T/go-build3590226918/b001/exe/main", "port", "6666"} + flagArgs := []string{"-port", "6666"} go shellspy.RunCLI(flagArgs, buf) From cc6521df6fd48c3c8b69c32fec1edb38f237be19 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Wed, 20 Apr 2022 19:09:54 +0100 Subject: [PATCH 12/37] add sleep in --- shellspy_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shellspy_test.go b/shellspy_test.go index a6c02f9..c3a161c 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -90,10 +90,10 @@ func TestPortFlagStartsNetListener(t *testing.T) { go shellspy.RunCLI(flagArgs, buf) for buf.String() == "" { + time.Sleep(1 * time.Second) } got := buf.String() - fmt.Println(got) want := "shellspy is running remotely on port 6666\n" From aa8f791d4eb61b142344d34d84908b3a4a4b2852 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Thu, 21 Apr 2022 17:45:59 +0100 Subject: [PATCH 13/37] fix broken testcase --- shellspy.go | 16 ++++++++++------ shellspy_test.go | 24 ++++++++++++++---------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/shellspy.go b/shellspy.go index 4ccee29..fd7bb71 100644 --- a/shellspy.go +++ b/shellspy.go @@ -48,15 +48,19 @@ func RunCLI(cliArgs []string, output io.Writer) { s.Start() } - fs := flag.NewFlagSet("cmd", flag.ContinueOnError) - portFlag := fs.Int("port", 2000, "-port 3000") + if len(cliArgs) == 2 { - fs.Parse(cliArgs) + fs := flag.NewFlagSet("cmd", flag.ExitOnError) + portFlag := fs.Int("port", 2000, "-port 3000") - if portFlag != nil { - s.Port = *portFlag - RunRemotely(s) + fs.Parse(cliArgs) + + if portFlag != nil { + s.Port = *portFlag + RunRemotely(s) + } } + } func RunRemotely(s *Session) error { diff --git a/shellspy_test.go b/shellspy_test.go index c3a161c..7fea6ce 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -64,22 +64,26 @@ func TestRunCommand(t *testing.T) { } } -// func TestRunWithoutPortFlagRunInteractively(t *testing.T) { +func TestRunWithoutPortFlagRunInteractively(t *testing.T) { -// buf := &bytes.Buffer{} + buf := &bytes.Buffer{} -// flagArgs := []string{"/var/folders/1v/4mmgcg8s51362djr4g9s9sfw0000gn/T/go-build3590226918/b001/exe/main"} + flagArgs := []string{""} -// shellspy.RunCLI(flagArgs, buf) -// got := buf.String() + go shellspy.RunCLI(flagArgs, buf) -// want := "shellspy is running locally\n" + for buf.String() == "" { + time.Sleep(1 * time.Second) + } -// if !cmp.Equal(want, got) { -// t.Error(cmp.Diff(want, got)) -// } + got := buf.String() -// } + want := "shellspy is running locally\n" + + if !cmp.Equal(want, got) { + t.Error(cmp.Diff(want, got)) + } +} func TestPortFlagStartsNetListener(t *testing.T) { From 14b731ebe97e2c762bb98f5dd3211f1d43b6b54d Mon Sep 17 00:00:00 2001 From: redscaresu Date: Fri, 22 Apr 2022 10:31:03 +0100 Subject: [PATCH 14/37] fix broken test --- shellspy.go | 3 +-- shellspy_test.go | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/shellspy.go b/shellspy.go index fd7bb71..4cea381 100644 --- a/shellspy.go +++ b/shellspy.go @@ -43,13 +43,12 @@ func RunCLI(cliArgs []string, output io.Writer) { os.Exit(1) } - if len(cliArgs) == 1 { + if len(cliArgs) == 0 { fmt.Fprint(s.Output, "shellspy is running locally\n") s.Start() } if len(cliArgs) == 2 { - fs := flag.NewFlagSet("cmd", flag.ExitOnError) portFlag := fs.Int("port", 2000, "-port 3000") diff --git a/shellspy_test.go b/shellspy_test.go index 7fea6ce..f54260a 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -66,9 +66,10 @@ func TestRunCommand(t *testing.T) { func TestRunWithoutPortFlagRunInteractively(t *testing.T) { + var flagArgs []string buf := &bytes.Buffer{} - flagArgs := []string{""} + fmt.Println(len(flagArgs)) go shellspy.RunCLI(flagArgs, buf) From be3931daf5c9a4332ea336704ed4b3e071de75bf Mon Sep 17 00:00:00 2001 From: redscaresu Date: Fri, 22 Apr 2022 10:31:52 +0100 Subject: [PATCH 15/37] remove debug print statements --- shellspy_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/shellspy_test.go b/shellspy_test.go index f54260a..46bd2d6 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -69,8 +69,6 @@ func TestRunWithoutPortFlagRunInteractively(t *testing.T) { var flagArgs []string buf := &bytes.Buffer{} - fmt.Println(len(flagArgs)) - go shellspy.RunCLI(flagArgs, buf) for buf.String() == "" { From 27a1c2b48e755c4a4a085de6f42fa679f0e2dc6f Mon Sep 17 00:00:00 2001 From: redscaresu Date: Fri, 22 Apr 2022 13:43:50 +0100 Subject: [PATCH 16/37] create or append file --- shellspy.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/shellspy.go b/shellspy.go index 4cea381..f67c00f 100644 --- a/shellspy.go +++ b/shellspy.go @@ -5,11 +5,11 @@ import ( "flag" "fmt" "io" + "log" "net" "os" "os/exec" "strings" - "time" ) type Session struct { @@ -107,10 +107,10 @@ func CommandFromString(line string) *exec.Cmd { } func CreateTranscriptFile() (*os.File, error) { - now := time.Now() - filename := ".shellspy-" + now.Format("2006-01-02-15:04:05") + ".txt" - file, err := os.OpenFile(filename, - os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + file, err := os.OpenFile("shellspy.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + log.Fatal(err) + } if err != nil { return nil, err } From b755eb519603704f1fe0589900feed7c2aa810f6 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Fri, 22 Apr 2022 13:45:16 +0100 Subject: [PATCH 17/37] update gitignore --- .gitignore | 1 + shellspy.go | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index f85659c..612bf58 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .shellspy-*.txt shellspy-*.txt +shellspy.txt dist/ diff --git a/shellspy.go b/shellspy.go index f67c00f..b919fc2 100644 --- a/shellspy.go +++ b/shellspy.go @@ -5,7 +5,6 @@ import ( "flag" "fmt" "io" - "log" "net" "os" "os/exec" @@ -108,12 +107,10 @@ func CommandFromString(line string) *exec.Cmd { func CreateTranscriptFile() (*os.File, error) { file, err := os.OpenFile("shellspy.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - log.Fatal(err) - } if err != nil { return nil, err } + return file, nil } From 1216439a40e464b61c4fc1c339dc7b00115a5838 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Fri, 22 Apr 2022 14:10:23 +0100 Subject: [PATCH 18/37] lol, no need to refactor when you can delete the whole function --- shellspy.go | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/shellspy.go b/shellspy.go index b919fc2..2e34daa 100644 --- a/shellspy.go +++ b/shellspy.go @@ -110,27 +110,5 @@ func CreateTranscriptFile() (*os.File, error) { if err != nil { return nil, err } - return file, nil } - -func WriteTranscript(stdOut, stdErr string, cmd *exec.Cmd, file *os.File) os.File { - - if _, err := file.WriteString(cmd.String()); err != nil { - err = fmt.Errorf("unable to write cmd to disk due to error; %w", err) - file.WriteString(err.Error()) - } - - file.WriteString("\n") - - if stdErr != "" { - file.WriteString(stdErr) - } - - if _, err := file.WriteString(stdOut); err != nil { - err = fmt.Errorf("unable to write stdOut to disk due to error; %w", err) - file.WriteString(err.Error()) - } - - return *file -} From 983b14bcf60b48704141b78473fd89011400c72f Mon Sep 17 00:00:00 2001 From: redscaresu Date: Fri, 22 Apr 2022 14:56:20 +0100 Subject: [PATCH 19/37] code style --- shellspy.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shellspy.go b/shellspy.go index 2e34daa..1c94d6c 100644 --- a/shellspy.go +++ b/shellspy.go @@ -20,6 +20,7 @@ type Session struct { } func NewSession(output io.Writer) (*Session, error) { + s := &Session{} file, err := CreateTranscriptFile() @@ -98,6 +99,7 @@ func (s *Session) Start() { } func CommandFromString(line string) *exec.Cmd { + trim := strings.TrimSuffix(line, "\n") name := strings.Fields(trim) args := name[1:] @@ -106,6 +108,7 @@ func CommandFromString(line string) *exec.Cmd { } func CreateTranscriptFile() (*os.File, error) { + file, err := os.OpenFile("shellspy.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { return nil, err From 64ccbb21cc0ea78b2a57c1b6c98ca38ed4b08b07 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Wed, 27 Apr 2022 23:51:21 +0100 Subject: [PATCH 20/37] io.pipe looks interesting, time to delete the git hook. its annoying --- .githooks/pre-commit | 3 --- shellspy.go | 51 +++++++++++++++++++++++--------------------- 2 files changed, 27 insertions(+), 27 deletions(-) delete mode 100755 .githooks/pre-commit diff --git a/.githooks/pre-commit b/.githooks/pre-commit deleted file mode 100755 index 043729d..0000000 --- a/.githooks/pre-commit +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -go test diff --git a/shellspy.go b/shellspy.go index 1c94d6c..9014d0f 100644 --- a/shellspy.go +++ b/shellspy.go @@ -19,21 +19,6 @@ type Session struct { Port int } -func NewSession(output io.Writer) (*Session, error) { - - s := &Session{} - - file, err := CreateTranscriptFile() - if err != nil { - return s, err - } - s.Transcript = file - s.Input = os.Stdin - s.Terminal = output - s.Output = io.MultiWriter(s.Terminal, s.Transcript) - return s, nil -} - func RunCLI(cliArgs []string, output io.Writer) { s, err := NewSession(output) @@ -62,6 +47,31 @@ func RunCLI(cliArgs []string, output io.Writer) { } +func NewSession(output io.Writer) (*Session, error) { + + s := &Session{} + + file, err := CreateTranscriptFile() + if err != nil { + return s, err + } + + s.Transcript = file + s.Input = os.Stdin + s.Terminal = output + s.Output = io.MultiWriter(s.Terminal, s.Transcript) + return s, nil +} + +func CreateTranscriptFile() (*os.File, error) { + + file, err := os.OpenFile("shellspy.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return nil, err + } + return file, nil +} + func RunRemotely(s *Session) error { fmt.Fprintf(s.Output, "shellspy is running remotely on port %d\n", s.Port) @@ -89,6 +99,8 @@ func handleConn(c net.Conn, s *Session) { func (s *Session) Start() { + s.Input, s.Output = io.Pipe() + scanner := bufio.NewScanner(s.Input) for scanner.Scan() { cmd := CommandFromString(scanner.Text()) @@ -106,12 +118,3 @@ func CommandFromString(line string) *exec.Cmd { cmd := exec.Command(name[0], args...) return cmd } - -func CreateTranscriptFile() (*os.File, error) { - - file, err := os.OpenFile("shellspy.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return nil, err - } - return file, nil -} From b837d7ae878a1b7bfd6055168f269e7478d53663 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Tue, 3 May 2022 18:45:01 +0100 Subject: [PATCH 21/37] almost.... --- shellspy.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/shellspy.go b/shellspy.go index 9014d0f..4518b55 100644 --- a/shellspy.go +++ b/shellspy.go @@ -12,11 +12,12 @@ import ( ) type Session struct { - Input io.Reader - Output io.Writer - Terminal io.Writer - Transcript io.Writer - Port int + Input io.Reader + Output io.Writer + Terminal io.Writer + Transcript io.Writer + Port int + InputWriter io.Writer } func RunCLI(cliArgs []string, output io.Writer) { @@ -56,10 +57,11 @@ func NewSession(output io.Writer) (*Session, error) { return s, err } + s.InputWriter = os.Stdin s.Transcript = file s.Input = os.Stdin s.Terminal = output - s.Output = io.MultiWriter(s.Terminal, s.Transcript) + s.Output = io.MultiWriter(s.Terminal, s.Transcript, s.InputWriter) return s, nil } @@ -99,11 +101,11 @@ func handleConn(c net.Conn, s *Session) { func (s *Session) Start() { - s.Input, s.Output = io.Pipe() - scanner := bufio.NewScanner(s.Input) + for scanner.Scan() { cmd := CommandFromString(scanner.Text()) + s.InputWriter.Write(scanner.Bytes()) cmd.Stdout = s.Output cmd.Stderr = s.Output cmd.Run() From 3bd1cbc473949a38ebfd1966ff5c74169f7ed988 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Tue, 10 May 2022 19:21:28 +0100 Subject: [PATCH 22/37] write the input to the file --- shellspy.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shellspy.go b/shellspy.go index 4518b55..8f425c3 100644 --- a/shellspy.go +++ b/shellspy.go @@ -17,7 +17,7 @@ type Session struct { Terminal io.Writer Transcript io.Writer Port int - InputWriter io.Writer + InputWriter string } func RunCLI(cliArgs []string, output io.Writer) { @@ -57,11 +57,10 @@ func NewSession(output io.Writer) (*Session, error) { return s, err } - s.InputWriter = os.Stdin s.Transcript = file s.Input = os.Stdin s.Terminal = output - s.Output = io.MultiWriter(s.Terminal, s.Transcript, s.InputWriter) + s.Output = io.MultiWriter(s.Terminal, s.Transcript) return s, nil } @@ -105,9 +104,10 @@ func (s *Session) Start() { for scanner.Scan() { cmd := CommandFromString(scanner.Text()) - s.InputWriter.Write(scanner.Bytes()) + input := scanner.Text() + "\n" cmd.Stdout = s.Output cmd.Stderr = s.Output + s.Transcript.Write([]byte(input)) cmd.Run() } } From 5b60b1955ac8390cadc3309ba6c65ad92994fca9 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Tue, 10 May 2022 19:22:12 +0100 Subject: [PATCH 23/37] remove unused struct value --- shellspy.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/shellspy.go b/shellspy.go index 8f425c3..04f69bc 100644 --- a/shellspy.go +++ b/shellspy.go @@ -12,12 +12,11 @@ import ( ) type Session struct { - Input io.Reader - Output io.Writer - Terminal io.Writer - Transcript io.Writer - Port int - InputWriter string + Input io.Reader + Output io.Writer + Terminal io.Writer + Transcript io.Writer + Port int } func RunCLI(cliArgs []string, output io.Writer) { From c33c0ad93e69b433e62c8785089684ffe990fd36 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Thu, 12 May 2022 19:55:58 +0100 Subject: [PATCH 24/37] show where the file is outputted --- shellspy.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shellspy.go b/shellspy.go index 04f69bc..b711160 100644 --- a/shellspy.go +++ b/shellspy.go @@ -74,7 +74,7 @@ func CreateTranscriptFile() (*os.File, error) { func RunRemotely(s *Session) error { - fmt.Fprintf(s.Output, "shellspy is running remotely on port %d\n", s.Port) + fmt.Fprintf(s.Output, "shellspy is running remotely on port %d and the output file is shellspy.txt\n", s.Port) address := fmt.Sprintf("localhost:%d", s.Port) listener, err := net.Listen("tcp", address) @@ -92,7 +92,7 @@ func RunRemotely(s *Session) error { func handleConn(c net.Conn, s *Session) { - fmt.Fprintf(c, "hello, welcome to shellspy"+"\n") + fmt.Fprintf(c, "welcome to shellspy, output file is shellspy.txt"+"\n") s.Input = io.Reader(c) s.Start() } From b4683affdd41051676f4b8435094c6e2a4bbc077 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Sun, 15 May 2022 19:57:24 +0100 Subject: [PATCH 25/37] print out errors as well --- shellspy.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/shellspy.go b/shellspy.go index b711160..d267266 100644 --- a/shellspy.go +++ b/shellspy.go @@ -2,6 +2,7 @@ package shellspy import ( "bufio" + "bytes" "flag" "fmt" "io" @@ -100,6 +101,7 @@ func handleConn(c net.Conn, s *Session) { func (s *Session) Start() { scanner := bufio.NewScanner(s.Input) + buf := &bytes.Buffer{} for scanner.Scan() { cmd := CommandFromString(scanner.Text()) @@ -107,7 +109,13 @@ func (s *Session) Start() { cmd.Stdout = s.Output cmd.Stderr = s.Output s.Transcript.Write([]byte(input)) - cmd.Run() + err := cmd.Run() + if err != nil { + fmt.Println(err) + fmt.Fprint(buf, err) + bbytes := buf.Bytes() + s.Transcript.Write(bbytes) + } } } From bc8b666100f86125d5471662361e98b51c876051 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Sun, 15 May 2022 20:02:54 +0100 Subject: [PATCH 26/37] exit program if it detects exit string --- shellspy.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shellspy.go b/shellspy.go index d267266..68e5292 100644 --- a/shellspy.go +++ b/shellspy.go @@ -109,6 +109,9 @@ func (s *Session) Start() { cmd.Stdout = s.Output cmd.Stderr = s.Output s.Transcript.Write([]byte(input)) + if scanner.Text() == "exit" { + os.Exit(0) + } err := cmd.Run() if err != nil { fmt.Println(err) From 6eb0bd658631317b9e0cec218aa218f98cc7af6f Mon Sep 17 00:00:00 2001 From: redscaresu Date: Fri, 20 May 2022 11:06:56 +0100 Subject: [PATCH 27/37] trying to send the terminate message to users --- shellspy.go | 45 +++++++++++++++++++++++++++++++++++---------- shellspy_test.go | 2 +- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/shellspy.go b/shellspy.go index 68e5292..da2060f 100644 --- a/shellspy.go +++ b/shellspy.go @@ -9,7 +9,9 @@ import ( "net" "os" "os/exec" + "os/signal" "strings" + "syscall" ) type Session struct { @@ -78,24 +80,47 @@ func RunRemotely(s *Session) error { fmt.Fprintf(s.Output, "shellspy is running remotely on port %d and the output file is shellspy.txt\n", s.Port) address := fmt.Sprintf("localhost:%d", s.Port) + signalChanel := make(chan os.Signal, 1) + signal.Notify(signalChanel, syscall.SIGINT) + + exit_chan := make(chan int) + listener, err := net.Listen("tcp", address) if err != nil { return err } - for { - conn, err := listener.Accept() - if err != nil { - return err + + go func() { + for { + sc := <-signalChanel + switch sc { + // kill -SIGHUP XXXX [XXXX - PID for your program] + case syscall.SIGINT: + conn, _ := listener.Accept() + go handleConn(conn, s, true) + default: + conn, _ := listener.Accept() + go handleConn(conn, s, false) + } } - go handleConn(conn, s) - } + }() + exitCode := <-exit_chan + os.Exit(exitCode) + return nil } -func handleConn(c net.Conn, s *Session) { +func handleConn(c net.Conn, s *Session, terminate bool) { - fmt.Fprintf(c, "welcome to shellspy, output file is shellspy.txt"+"\n") - s.Input = io.Reader(c) - s.Start() + if !terminate { + fmt.Fprintf(c, "welcome to shellspy, output file is shellspy.txt"+"\n") + s.Input = io.Reader(c) + s.Start() + } else { + fmt.Fprintf(c, "Server has terminated this process"+"\n") + s.Input = io.Reader(c) + os.Exit(1) + s.Start() + } } func (s *Session) Start() { diff --git a/shellspy_test.go b/shellspy_test.go index 46bd2d6..f1da4e8 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -98,7 +98,7 @@ func TestPortFlagStartsNetListener(t *testing.T) { got := buf.String() - want := "shellspy is running remotely on port 6666\n" + want := "shellspy is running remotely on port 6666 and the output file is shellspy.txt\n" if !cmp.Equal(want, got) { t.Error(cmp.Diff(want, got)) From cc73903bd0bfb023e838b6a61dfc581959185828 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Sat, 21 May 2022 20:51:07 +0100 Subject: [PATCH 28/37] exit chan --- shellspy.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shellspy.go b/shellspy.go index da2060f..f9c6cc7 100644 --- a/shellspy.go +++ b/shellspy.go @@ -94,13 +94,14 @@ func RunRemotely(s *Session) error { for { sc := <-signalChanel switch sc { - // kill -SIGHUP XXXX [XXXX - PID for your program] case syscall.SIGINT: conn, _ := listener.Accept() go handleConn(conn, s, true) + exit_chan <- 0 default: conn, _ := listener.Accept() go handleConn(conn, s, false) + exit_chan <- 0 } } }() From deb4346eb277a3c28291762da32036716cdb3301 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Mon, 27 Jun 2022 20:32:43 +0100 Subject: [PATCH 29/37] its a start --- shellspy.go | 45 ++++++++------------------------------------- 1 file changed, 8 insertions(+), 37 deletions(-) diff --git a/shellspy.go b/shellspy.go index f9c6cc7..12f915a 100644 --- a/shellspy.go +++ b/shellspy.go @@ -9,9 +9,7 @@ import ( "net" "os" "os/exec" - "os/signal" "strings" - "syscall" ) type Session struct { @@ -47,7 +45,6 @@ func RunCLI(cliArgs []string, output io.Writer) { RunRemotely(s) } } - } func NewSession(output io.Writer) (*Session, error) { @@ -80,48 +77,22 @@ func RunRemotely(s *Session) error { fmt.Fprintf(s.Output, "shellspy is running remotely on port %d and the output file is shellspy.txt\n", s.Port) address := fmt.Sprintf("localhost:%d", s.Port) - signalChanel := make(chan os.Signal, 1) - signal.Notify(signalChanel, syscall.SIGINT) - - exit_chan := make(chan int) - listener, err := net.Listen("tcp", address) if err != nil { return err } - go func() { - for { - sc := <-signalChanel - switch sc { - case syscall.SIGINT: - conn, _ := listener.Accept() - go handleConn(conn, s, true) - exit_chan <- 0 - default: - conn, _ := listener.Accept() - go handleConn(conn, s, false) - exit_chan <- 0 - } - } - }() - exitCode := <-exit_chan - os.Exit(exitCode) - return nil + for { + conn, _ := listener.Accept() + handleConn(conn, s) + } } -func handleConn(c net.Conn, s *Session, terminate bool) { +func handleConn(c net.Conn, s *Session) { - if !terminate { - fmt.Fprintf(c, "welcome to shellspy, output file is shellspy.txt"+"\n") - s.Input = io.Reader(c) - s.Start() - } else { - fmt.Fprintf(c, "Server has terminated this process"+"\n") - s.Input = io.Reader(c) - os.Exit(1) - s.Start() - } + fmt.Fprintf(c, "hello, welcome to shellspy"+"\n") + s.Input = io.Reader(c) + s.Start() } func (s *Session) Start() { From 2b6a55c230b0ba81e7a5ac6906de463027cefb6a Mon Sep 17 00:00:00 2001 From: redscaresu Date: Tue, 28 Jun 2022 13:55:23 +0100 Subject: [PATCH 30/37] commit test --- shellspy_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/shellspy_test.go b/shellspy_test.go index f1da4e8..c1dcb62 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -14,6 +14,7 @@ import ( ) func TestCommandFromString(t *testing.T) { + t.Parallel() cmdWant := &exec.Cmd{} cmdWant.Args = []string{"/bin/echo", "hello", "world"} @@ -26,6 +27,8 @@ func TestCommandFromString(t *testing.T) { } } func TestCommandFromStringArgs(t *testing.T) { + t.Parallel() + input := "ls" want := []string{"ls"} got := shellspy.CommandFromString(input).Args @@ -35,6 +38,7 @@ func TestCommandFromStringArgs(t *testing.T) { } func TestRunCommand(t *testing.T) { + t.Parallel() wantBuf := &bytes.Buffer{} gotBuf := &bytes.Buffer{} @@ -65,6 +69,7 @@ func TestRunCommand(t *testing.T) { } func TestRunWithoutPortFlagRunInteractively(t *testing.T) { + t.Parallel() var flagArgs []string buf := &bytes.Buffer{} @@ -85,6 +90,7 @@ func TestRunWithoutPortFlagRunInteractively(t *testing.T) { } func TestPortFlagStartsNetListener(t *testing.T) { + t.Parallel() buf := &bytes.Buffer{} From e1bf0badd39b0a527b0ce0e2d15010e90e136beb Mon Sep 17 00:00:00 2001 From: redscaresu Date: Tue, 28 Jun 2022 14:09:42 +0100 Subject: [PATCH 31/37] do something useful with the error --- shellspy.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/shellspy.go b/shellspy.go index 12f915a..6a3ee5c 100644 --- a/shellspy.go +++ b/shellspy.go @@ -25,7 +25,7 @@ func RunCLI(cliArgs []string, output io.Writer) { s, err := NewSession(output) if err != nil { - fmt.Printf("%v", err) + fmt.Fprintln(os.Stderr, err) os.Exit(1) } @@ -53,7 +53,7 @@ func NewSession(output io.Writer) (*Session, error) { file, err := CreateTranscriptFile() if err != nil { - return s, err + return nil, err } s.Transcript = file @@ -83,7 +83,10 @@ func RunRemotely(s *Session) error { } for { - conn, _ := listener.Accept() + conn, err := listener.Accept() + if err != nil { + return err + } handleConn(conn, s) } } From f7816e613a3a09f8fb993844ff17d4634a792404 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Tue, 28 Jun 2022 14:44:21 +0100 Subject: [PATCH 32/37] incerase coverage --- shellspy.go | 2 +- shellspy_test.go | 25 +++++++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/shellspy.go b/shellspy.go index 6a3ee5c..cad0b01 100644 --- a/shellspy.go +++ b/shellspy.go @@ -94,7 +94,7 @@ func RunRemotely(s *Session) error { func handleConn(c net.Conn, s *Session) { fmt.Fprintf(c, "hello, welcome to shellspy"+"\n") - s.Input = io.Reader(c) + s.Input = c s.Start() } diff --git a/shellspy_test.go b/shellspy_test.go index c1dcb62..67d4cf2 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -1,8 +1,11 @@ package shellspy_test import ( + "bufio" "bytes" "fmt" + "io" + "net" "os" "os/exec" "strings" @@ -89,22 +92,28 @@ func TestRunWithoutPortFlagRunInteractively(t *testing.T) { } } -func TestPortFlagStartsNetListener(t *testing.T) { +func TestPortFlagListensOnPort(t *testing.T) { t.Parallel() - buf := &bytes.Buffer{} - flagArgs := []string{"-port", "6666"} - go shellspy.RunCLI(flagArgs, buf) + go shellspy.RunCLI(flagArgs, io.Discard) - for buf.String() == "" { - time.Sleep(1 * time.Second) + conn, err := net.Dial("tcp", "127.0.0.1:6666") + for err != nil { + t.Log("retrying network connection") + time.Sleep(10 * time.Millisecond) + conn, err = net.Dial("tcp", "127.0.0.1:6666") } - got := buf.String() + scanner := bufio.NewScanner(conn) + if !scanner.Scan() { + t.Fatal("nothing has been returned by the scanner") + } + + got := scanner.Text() - want := "shellspy is running remotely on port 6666 and the output file is shellspy.txt\n" + want := "hello, welcome to shellspy" if !cmp.Equal(want, got) { t.Error(cmp.Diff(want, got)) From f3edcb6e1ed5de6ff3fc3473cb8faedf257947e5 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Wed, 29 Jun 2022 19:48:47 +0100 Subject: [PATCH 33/37] adding foo to things --- shellspy.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/shellspy.go b/shellspy.go index cad0b01..146a6ce 100644 --- a/shellspy.go +++ b/shellspy.go @@ -2,7 +2,6 @@ package shellspy import ( "bufio" - "bytes" "flag" "fmt" "io" @@ -101,23 +100,20 @@ func handleConn(c net.Conn, s *Session) { func (s *Session) Start() { scanner := bufio.NewScanner(s.Input) - buf := &bytes.Buffer{} for scanner.Scan() { cmd := CommandFromString(scanner.Text()) input := scanner.Text() + "\n" cmd.Stdout = s.Output cmd.Stderr = s.Output - s.Transcript.Write([]byte(input)) + fmt.Fprint(s.Transcript, input) if scanner.Text() == "exit" { os.Exit(0) } err := cmd.Run() if err != nil { - fmt.Println(err) - fmt.Fprint(buf, err) - bbytes := buf.Bytes() - s.Transcript.Write(bbytes) + fmt.Fprintln(os.Stderr, err) + fmt.Fprint(s.Transcript, err) } } } From 6c5c6e89a47d1719c6f2cd0bdd1ec99a417ecb53 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Wed, 13 Jul 2022 15:59:53 +0100 Subject: [PATCH 34/37] write the output to the file --- shellspy.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/shellspy.go b/shellspy.go index 146a6ce..dbf50aa 100644 --- a/shellspy.go +++ b/shellspy.go @@ -2,6 +2,7 @@ package shellspy import ( "bufio" + "bytes" "flag" "fmt" "io" @@ -92,9 +93,17 @@ func RunRemotely(s *Session) error { func handleConn(c net.Conn, s *Session) { + userOutput := make(chan io.Writer) + + buf := &bytes.Buffer{} fmt.Fprintf(c, "hello, welcome to shellspy"+"\n") s.Input = c - s.Start() + go s.Start() + userOutput <- s.Output + for output := range userOutput { + fmt.Fprint(buf, output) + fmt.Println(buf.String()) + } } func (s *Session) Start() { From 75dc50855b20c2794f7f11f114bf69c31d1fa895 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Mon, 18 Jul 2022 18:46:17 +0100 Subject: [PATCH 35/37] send message to client that server is closed --- shellspy.go | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/shellspy.go b/shellspy.go index dbf50aa..f4168d4 100644 --- a/shellspy.go +++ b/shellspy.go @@ -2,14 +2,15 @@ package shellspy import ( "bufio" - "bytes" "flag" "fmt" "io" "net" "os" "os/exec" + "os/signal" "strings" + "syscall" ) type Session struct { @@ -83,33 +84,37 @@ func RunRemotely(s *Session) error { } for { + + killSignal := make(chan os.Signal, 1) + signal.Notify(killSignal, syscall.SIGINT, syscall.SIGTERM) + conn, err := listener.Accept() if err != nil { return err } - handleConn(conn, s) + + go func() { + <-killSignal + fmt.Fprintf(conn, "connection closed on the server, goodbye"+"\n") + conn.Close() + os.Exit(0) + }() + + go handleConn(conn, s) + } } func handleConn(c net.Conn, s *Session) { - userOutput := make(chan io.Writer) - - buf := &bytes.Buffer{} fmt.Fprintf(c, "hello, welcome to shellspy"+"\n") s.Input = c go s.Start() - userOutput <- s.Output - for output := range userOutput { - fmt.Fprint(buf, output) - fmt.Println(buf.String()) - } } func (s *Session) Start() { scanner := bufio.NewScanner(s.Input) - for scanner.Scan() { cmd := CommandFromString(scanner.Text()) input := scanner.Text() + "\n" From a531e9cfce34185dc27c91f7df99691958755295 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Tue, 19 Jul 2022 19:35:10 +0100 Subject: [PATCH 36/37] add command prompt --- shellspy.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/shellspy.go b/shellspy.go index f4168d4..a16b29f 100644 --- a/shellspy.go +++ b/shellspy.go @@ -19,6 +19,7 @@ type Session struct { Terminal io.Writer Transcript io.Writer Port int + C net.Conn } func RunCLI(cliArgs []string, output io.Writer) { @@ -31,7 +32,7 @@ func RunCLI(cliArgs []string, output io.Writer) { } if len(cliArgs) == 0 { - fmt.Fprint(s.Output, "shellspy is running locally\n") + fmt.Fprint(s.Output, "\n") s.Start() } @@ -107,14 +108,16 @@ func RunRemotely(s *Session) error { func handleConn(c net.Conn, s *Session) { - fmt.Fprintf(c, "hello, welcome to shellspy"+"\n") + fmt.Fprintf(c, "hello, welcome to shellspy"+"\n"+"$ ") s.Input = c - go s.Start() + s.C = c + s.Start() } func (s *Session) Start() { scanner := bufio.NewScanner(s.Input) + for scanner.Scan() { cmd := CommandFromString(scanner.Text()) input := scanner.Text() + "\n" @@ -129,6 +132,7 @@ func (s *Session) Start() { fmt.Fprintln(os.Stderr, err) fmt.Fprint(s.Transcript, err) } + fmt.Fprintf(s.C, "$ ") } } From 442c90e48f24d2da5d741d7eee18fdbabdcb1875 Mon Sep 17 00:00:00 2001 From: redscaresu Date: Wed, 27 Jul 2022 10:08:34 +0100 Subject: [PATCH 37/37] updates --- README.md | 6 ++++- shellspy.go | 67 ++++++++++++++++++++++++++---------------------- shellspy_test.go | 14 +++++----- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 700963f..81cc49e 100644 --- a/README.md +++ b/README.md @@ -24,4 +24,8 @@ OR ``` > go run cmd/main.go --mode local shellspy is running locally -``` \ No newline at end of file +``` + +TODO +- per session readmefile +- authentication \ No newline at end of file diff --git a/shellspy.go b/shellspy.go index a16b29f..3e0d2e6 100644 --- a/shellspy.go +++ b/shellspy.go @@ -18,22 +18,17 @@ type Session struct { Output io.Writer Terminal io.Writer Transcript io.Writer - Port int - C net.Conn } -func RunCLI(cliArgs []string, output io.Writer) { - - s, err := NewSession(output) +type Server struct { + Port int + C net.Conn +} - if err != nil { - fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } +func RunCLI(cliArgs []string, output io.Writer) { if len(cliArgs) == 0 { - fmt.Fprint(s.Output, "\n") - s.Start() + RunLocally(output) } if len(cliArgs) == 2 { @@ -43,8 +38,7 @@ func RunCLI(cliArgs []string, output io.Writer) { fs.Parse(cliArgs) if portFlag != nil { - s.Port = *portFlag - RunRemotely(s) + RunRemotely(*portFlag) } } } @@ -74,10 +68,10 @@ func CreateTranscriptFile() (*os.File, error) { return file, nil } -func RunRemotely(s *Session) error { +func RunRemotely(port int) error { - fmt.Fprintf(s.Output, "shellspy is running remotely on port %d and the output file is shellspy.txt\n", s.Port) - address := fmt.Sprintf("localhost:%d", s.Port) + fmt.Printf("shellspy is running remotely on port %v and the output file is shellspy.txt\n", port) + address := fmt.Sprintf("localhost:%d", port) listener, err := net.Listen("tcp", address) if err != nil { @@ -89,33 +83,47 @@ func RunRemotely(s *Session) error { killSignal := make(chan os.Signal, 1) signal.Notify(killSignal, syscall.SIGINT, syscall.SIGTERM) - conn, err := listener.Accept() - if err != nil { - return err - } - go func() { <-killSignal - fmt.Fprintf(conn, "connection closed on the server, goodbye"+"\n") - conn.Close() os.Exit(0) }() - go handleConn(conn, s) + conn, err := listener.Accept() + if err != nil { + return err + } + + go handleConn(conn) } } -func handleConn(c net.Conn, s *Session) { +func handleConn(c net.Conn) { + s, err := NewSession(c) + if err != nil { + fmt.Fprint(c, err) + c.Close() + fmt.Printf("connection is closed due to: %v", err) + } - fmt.Fprintf(c, "hello, welcome to shellspy"+"\n"+"$ ") + fmt.Printf("new connection established %s and the file is shellspy.txt ", c.RemoteAddr()) s.Input = c - s.C = c + s.Start() +} + +func RunLocally(output io.Writer) { + s, err := NewSession(output) + if err != nil { + fmt.Println("cannot create transcript file") + os.Exit(1) + } s.Start() } func (s *Session) Start() { + fmt.Fprintln(s.Output, "welcome to shellspy") + fmt.Fprintf(s.Output, "$ ") scanner := bufio.NewScanner(s.Input) for scanner.Scan() { @@ -129,10 +137,9 @@ func (s *Session) Start() { } err := cmd.Run() if err != nil { - fmt.Fprintln(os.Stderr, err) - fmt.Fprint(s.Transcript, err) + fmt.Fprint(s.Output, err) } - fmt.Fprintf(s.C, "$ ") + fmt.Fprintf(s.Output, "$ ") } } diff --git a/shellspy_test.go b/shellspy_test.go index 67d4cf2..8fd20e4 100644 --- a/shellspy_test.go +++ b/shellspy_test.go @@ -3,7 +3,6 @@ package shellspy_test import ( "bufio" "bytes" - "fmt" "io" "net" "os" @@ -43,7 +42,6 @@ func TestCommandFromStringArgs(t *testing.T) { func TestRunCommand(t *testing.T) { t.Parallel() - wantBuf := &bytes.Buffer{} gotBuf := &bytes.Buffer{} s, err := shellspy.NewSession(gotBuf) s.Input = strings.NewReader("echo hello world") @@ -62,9 +60,9 @@ func TestRunCommand(t *testing.T) { s.Transcript = file s.Start() - fmt.Fprint(wantBuf, s.Terminal) - want := wantBuf.String() - got := "hello world\n" + // fmt.Fprint(wantBuf, s.Terminal) + got := gotBuf.String() + want := "welcome to shellspy\n$ hello world\n$ " if !cmp.Equal(want, got) { t.Error(cmp.Diff(want, got)) @@ -80,12 +78,12 @@ func TestRunWithoutPortFlagRunInteractively(t *testing.T) { go shellspy.RunCLI(flagArgs, buf) for buf.String() == "" { - time.Sleep(1 * time.Second) + time.Sleep(5 * time.Millisecond) } got := buf.String() - want := "shellspy is running locally\n" + want := "welcome to shellspy\n$ " if !cmp.Equal(want, got) { t.Error(cmp.Diff(want, got)) @@ -113,7 +111,7 @@ func TestPortFlagListensOnPort(t *testing.T) { got := scanner.Text() - want := "hello, welcome to shellspy" + want := "welcome to shellspy" if !cmp.Equal(want, got) { t.Error(cmp.Diff(want, got))