runletapp / go-console Goto Github PK
View Code? Open in Web Editor NEWCross-platform PTY interface
License: MIT License
Cross-platform PTY interface
License: MIT License
I've been able to compile this program on Linux
// I have simplified the code to highlight the interesting bits for the purpose of the blog post:
// - windows resizing is not addressed
// - client does not catch signals (CTRL + C, etc.) to gracefully close the tcp connection
//
// Build: go build -o remote main.go
// In one terminal run: ./remote -server
// In another terminal run: ./remote
//
// Run on multiple machines:
// In the client function, replace the loopback address with IP of the machine, then rebuild
// Beware the unecrypted TCP connection!
package main
import (
"flag"
"fmt"
"golang.org/x/crypto/ssh/terminal"
"io"
"net"
"os"
"github.com/runletapp/go-console"
)
var isServer *bool
func init() {
isServer = flag.Bool("server", false, "")
}
func server() error {
// Create command
var args []string = []string{"sh"}
// Start the command with a pty.
ptmx, e := console.New(120, 60)
if e != nil {
return e
}
// Make sure to close the pty at the end.
defer func() { ptmx.Close() }() // Best effort.
ptmx.Start(args)
return listen(ptmx)
}
func listen(ptmx console.Console) error {
fmt.Println("Launching server...")
// listen on all interfaces
ln, e := net.Listen("tcp", ":8081")
if e != nil {
return e
}
// accept connection on port
conn, e := ln.Accept()
if e != nil {
return e
}
go func() { _, _ = io.Copy(ptmx, conn) }()
_, e = io.Copy(conn, ptmx)
return e
}
func client() error {
// connect to this socket
conn, e := net.Dial("tcp", "127.0.0.1:8081")
if e != nil {
return e
}
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
oldState, e := terminal.MakeRaw(int(os.Stdin.Fd()))
if e != nil {
return e
}
defer func() { _ = terminal.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort.
go func() { _, _ = io.Copy(os.Stdout, conn) }()
_, e = io.Copy(conn, os.Stdin)
fmt.Println("Bye!")
return e
}
func clientAndServer() error {
flag.Parse()
if isServer != nil && *isServer {
fmt.Println("Starting server mode")
return server()
} else {
fmt.Println("Starting client mode")
return client()
}
}
func main() {
if e := clientAndServer(); e != nil {
fmt.Println(e)
}
}```
but when I tried to compile it for Windows with ```GOOS=windows go build main.go```, I first ran into this error:
```go/src/github.com/runletapp/go-console/console_windows.go:13:2: cannot find package "github.com/iamacarpet/go-winpty" in any of:
/usr/local/go/src/github.com/iamacarpet/go-winpty (from $GOROOT)
/home/matteo/go/src/github.com/iamacarpet/go-winpty (from $GOPATH)`
then I tried ```go get github.com/iamacarpet/go-winpty```
but I got a second new error ```# github.com/iamacarpet/go-winpty
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:14:13: undefined: syscall.LazyDLL
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:17:21: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:18:21: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:19:21: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:22:35: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:23:35: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:24:35: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:25:35: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:26:35: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:29:24: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:29:24: too many errors
matteo ~ Desktop RAT PTY 2 go get "github.com/iamacarpet/go-winpty"
# github.com/iamacarpet/go-winpty
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:14:13: undefined: syscall.LazyDLL
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:17:21: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:18:21: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:19:21: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:22:35: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:23:35: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:24:35: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:25:35: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:26:35: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:29:24: undefined: syscall.LazyProc
../../../go/src/github.com/iamacarpet/go-winpty/defines.go:29:24: too many errors```
Am I forced to compile it on a Windows machine in which golang is installed?
Best;
MM
does it possible replace with https://github.com/golang/term or https://github.com/containerd/console
// Companion code for the Linux terminals blog series: https://dev.to/napicella/linux-terminals-tty-pty-and-shell-192e
// I have simplified the code to highlight the interesting bits for the purpose of the blog post:
// - windows resizing is not addressed
// - client does not catch signals (CTRL + C, etc.) to gracefully close the tcp connection
//
// Build: go build -o remote main.go
// In one terminal run: ./remote -server
// In another terminal run: ./remote
//
// Run on multiple machines:
// In the client function, replace the loopback address with IP of the machine, then rebuild
// Beware the unecrypted TCP connection!
package main
import (
"flag"
"fmt"
"golang.org/x/crypto/ssh/terminal"
"io"
"net"
"os"
"github.com/runletapp/go-console"
)
var isServer *bool
func init() {
isServer = flag.Bool("server", false, "")
}
func server() error {
// Create command
var args []string = []string{"cmd"}
// Start the command with a pty.
ptmx, e := console.New(120, 60)
if e != nil {
return e
}
// Make sure to close the pty at the end.
defer func() { ptmx.Close() }() // Best effort.
ptmx.Start(args)
return listen(ptmx)
}
func listen(ptmx console.Console) error {
fmt.Println("Launching server...")
// listen on all interfaces
ln, e := net.Listen("tcp", ":8081")
if e != nil {
return e
}
// accept connection on port
conn, e := ln.Accept()
if e != nil {
return e
}
go func() { _, _ = io.Copy(ptmx, conn) }()
_, e = io.Copy(conn, ptmx)
return e
}
func client() error {
// connect to this socket
conn, e := net.Dial("tcp", "127.0.0.1:8081")
if e != nil {
return e
}
// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
oldState, e := terminal.MakeRaw(int(os.Stdin.Fd()))
if e != nil {
return e
}
defer func() { _ = terminal.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort.
go func() { _, _ = io.Copy(os.Stdout, conn) }()
_, e = io.Copy(conn, os.Stdin)
fmt.Println("Bye!")
return e
}
func clientAndServer() error {
flag.Parse()
if isServer != nil && *isServer {
fmt.Println("Starting server mode")
return server()
} else {
fmt.Println("Starting client mode")
return client()
}
}
func main() {
if e := clientAndServer(); e != nil {
fmt.Println(e)
}
}
this is my code. I ran the client from Linux and the server from Win.
when I send "cls" command after a bunch of instructions/output lines, It has a strange behavior.
It's like it creates a new prompt for each char I type, and each prompt is very distant
before typing "dir": https://drive.google.com/file/d/1qH_jbIxXZsyKpCWEbdJ5n0mFLHIsIXZm/view?usp=sharing
before doing "cls": https://drive.google.com/file/d/1MB0-TzQCtO053cei58F1FNmFvf3Td7XA/view?usp=sharing
after doing "cls", when I try to type sth: https://drive.google.com/file/d/1go6I5YvgcR5DMk67Xr7Xr704hMDUBiZ0/view?usp=sharing
therefore It creates a new prompt for each char/action I choose: https://drive.google.com/file/d/1EXU7uZ9F-AgdC11BUggvJU4LrilwgH-L/view?usp=sharing
When I try to Start
I get %1 is not a valid Win32 application.
error. The calling process is 32bit, I believe the DLL shipped by default is 64bit.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.