├── README.md └── seashells.go /README.md: -------------------------------------------------------------------------------- 1 | ### Seashells in Go 2 | 3 | A Golang port of the awesome [seashells client](https://github.com/anishathalye/seashells), for use with [seashells.io](https://seashells.io). 4 | 5 | ## Install 6 | 7 | ``` 8 | go get github.com/hans-strudle/seashells 9 | ``` 10 | 11 | ## Usage 12 | 13 | ``` 14 | $> seashells --help 15 | -d int 16 | Delay 17 | -i string 18 | URL/IP to use (default "seashells.io") 19 | -p string 20 | Port to use (default "1337") 21 | -q Suppress writing to stdout 22 | ``` 23 | 24 | -------------------------------------------------------------------------------- /seashells.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "log" 9 | "net" 10 | "os" 11 | "syscall" 12 | "time" 13 | ) 14 | 15 | var ( 16 | url = flag.String("i", "seashells.io", "URL/IP to use") 17 | port = flag.String("p", "1337", "Port to use") 18 | output = flag.Bool("q", false, "Suppress writing to stdout") 19 | delay = flag.Int("d", 0, "Delay") 20 | ) 21 | 22 | func main() { 23 | flag.Parse() 24 | 25 | fullUrl := *url + ":" + *port 26 | conn, err := net.Dial("tcp", fullUrl) 27 | if err != nil { 28 | log.Fatal(err) 29 | } 30 | 31 | serverUrl, err := bufio.NewReader(conn).ReadString('\n') 32 | fmt.Fprint(os.Stderr, serverUrl) // write url to sderr 33 | 34 | if *delay > 0 { 35 | time.Sleep(time.Duration(*delay) * time.Second) 36 | } 37 | 38 | scan := bufio.NewReader(os.Stdin) 39 | var both io.Writer 40 | if *output == true { 41 | both = conn 42 | } else { 43 | both = io.MultiWriter(os.Stdout, conn) // will write to stdout and the net connection 44 | } 45 | 46 | done := make(chan error) 47 | 48 | go func() { 49 | for { 50 | err := syscall.Select(1, &syscall.FdSet{[32]int32{1}}, nil, nil, nil) // check for data on stdin 51 | done <- err 52 | 53 | _, err = io.Copy(both, scan) // send the scan data to the multiwriter 54 | done <- err 55 | 56 | _, _, err = scan.ReadLine() // just want to see if we get an EOF 57 | if err == io.EOF { 58 | os.Exit(0) 59 | } 60 | done <- err 61 | } 62 | }() 63 | for { 64 | select { 65 | case err := <-done: 66 | if err != nil { 67 | log.Fatal(err) 68 | } 69 | } 70 | } 71 | } 72 | --------------------------------------------------------------------------------