telnet.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. package main
  2. import (
  3. "fmt"
  4. "io"
  5. "log"
  6. "net"
  7. "os"
  8. "os/signal"
  9. "strings"
  10. "syscall"
  11. "unsafe"
  12. )
  13. const NCCS = 32
  14. type (
  15. cc_t byte
  16. speed_t uint32
  17. tcflag_t uint32
  18. termios struct {
  19. c_iflag, c_oflag, c_cflag, c_lflag tcflag_t
  20. c_line cc_t
  21. c_cc [NCCS]cc_t
  22. c_ispeed, c_ospeed speed_t
  23. }
  24. winsize struct {
  25. ws_row, ws_col uint16
  26. ws_xpixel, ws_ypixel uint16
  27. }
  28. )
  29. // termios constants
  30. const (
  31. t_IGNBRK = tcflag_t(0000001)
  32. t_BRKINT = tcflag_t(0000002)
  33. t_PARMRK = tcflag_t(0000010)
  34. t_ISTRIP = tcflag_t(0000040)
  35. t_INLCR = tcflag_t(0000100)
  36. t_IGNCR = tcflag_t(0000200)
  37. t_ICRNL = tcflag_t(0000400)
  38. t_IXON = tcflag_t(0002000)
  39. t_OPOST = tcflag_t(0000001)
  40. t_ECHO = tcflag_t(0000010)
  41. t_ECHONL = tcflag_t(0000100)
  42. t_ICANON = tcflag_t(0000002)
  43. t_ISIG = tcflag_t(0000001)
  44. t_IEXTEN = tcflag_t(0100000)
  45. t_CSIZE = tcflag_t(0000060)
  46. t_CS8 = tcflag_t(0000060)
  47. t_PARENB = tcflag_t(0000400)
  48. t_VTIME = 5
  49. t_VMIN = 6
  50. )
  51. // ioctl constants
  52. const (
  53. i_TCGETS = 0x5401
  54. i_TCSETS = 0x5402
  55. i_TIOCGWINSZ = 0x5413
  56. i_TIOCSWINSZ = 0x5414
  57. )
  58. var unrawterm termios
  59. func getTermios(fd uintptr) (*termios, error) {
  60. term := new(termios)
  61. if err := term.get(fd); err != nil {
  62. return nil, err
  63. }
  64. return term, nil
  65. }
  66. func (self *termios) get(fd uintptr) error {
  67. r1, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
  68. fd, uintptr(i_TCGETS),
  69. uintptr(unsafe.Pointer(self)))
  70. if errno != 0 || r1 != 0 {
  71. return fmt.Errorf("termios.get: r1 %v, errno %v", r1, errno)
  72. }
  73. return nil
  74. }
  75. func (self *termios) set(fd uintptr) error {
  76. r1, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
  77. fd, uintptr(i_TCSETS),
  78. uintptr(unsafe.Pointer(self)))
  79. if errno != 0 || r1 != 0 {
  80. return fmt.Errorf("termios.get: r1 %v, errno %v", r1, errno)
  81. }
  82. return nil
  83. }
  84. func (self *termios) setRaw(fd uintptr) error {
  85. self.c_iflag &= ^(t_IGNBRK | t_BRKINT | t_PARMRK | t_ISTRIP |
  86. t_INLCR | t_IGNCR | t_ICRNL | t_IXON)
  87. self.c_oflag &= ^t_OPOST
  88. self.c_lflag &= ^(t_ECHO | t_ECHONL | t_ICANON | t_ISIG | t_IEXTEN)
  89. self.c_cflag &= ^(t_CSIZE | t_PARENB)
  90. self.c_cflag |= t_CS8
  91. self.c_cc[t_VMIN] = 1
  92. self.c_cc[t_VTIME] = 0
  93. return self.set(fd)
  94. }
  95. func getWinsize(fd uintptr) (*winsize, error) {
  96. size := new(winsize)
  97. if err := size.get(fd); err != nil {
  98. return nil, err
  99. }
  100. return size, nil
  101. }
  102. func (self *winsize) get(fd uintptr) error {
  103. r1, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
  104. fd, uintptr(i_TIOCGWINSZ),
  105. uintptr(unsafe.Pointer(self)))
  106. if errno != 0 || r1 != 0 {
  107. return fmt.Errorf("termios.get: r1 %v, errno %v", r1, errno)
  108. }
  109. return nil
  110. }
  111. func (self *winsize) set(fd uintptr) error {
  112. r1, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
  113. fd, uintptr(i_TIOCSWINSZ),
  114. uintptr(unsafe.Pointer(self)))
  115. if errno != 0 || r1 != 0 {
  116. return fmt.Errorf("termios.get: r1 %v, errno %v", r1, errno)
  117. }
  118. return nil
  119. }
  120. func raw() {
  121. // we don't set raw until the very last, so if they see an issue they can hit ^C
  122. t, err := getTermios(1)
  123. if err != nil {
  124. log.Fatalf(err.Error())
  125. }
  126. unrawterm = *t
  127. if err = t.setRaw(1); err != nil {
  128. log.Fatalf(err.Error())
  129. }
  130. }
  131. func unraw() {
  132. unrawterm.set(1)
  133. }
  134. // Copyright 2012 the u-root Authors. All rights reserved
  135. // Use of this source code is governed by a BSD-style
  136. // license that can be found in the LICENSE file.
  137. /*
  138. Wget reads one file from the argument and writes it on the standard output.
  139. */
  140. func main() {
  141. a := os.Args
  142. if len(a) < 2 {
  143. os.Exit(1)
  144. }
  145. var tcpc []*net.TCPConn
  146. for _, a := range os.Args[1:] {
  147. port := "1522"
  148. if !strings.Contains(a, ":") {
  149. a = a + ":" + port
  150. }
  151. tcpdst, err := net.ResolveTCPAddr("tcp", a)
  152. if err != nil {
  153. fmt.Printf("%v\n", err)
  154. os.Exit(1)
  155. }
  156. c, err := net.DialTCP("tcp", nil, tcpdst)
  157. if err != nil {
  158. fmt.Printf("%v\n", err)
  159. os.Exit(1)
  160. }
  161. tcpc = append(tcpc, c)
  162. }
  163. raw()
  164. defer unraw()
  165. sigc := make(chan os.Signal, 1)
  166. signal.Notify(sigc, os.Interrupt, os.Kill, syscall.SIGTERM)
  167. go func() {
  168. for _ = range sigc {
  169. unraw()
  170. os.Exit(1)
  171. }
  172. }()
  173. go func() {
  174. b := make([]byte, 1024)
  175. for {
  176. n, err := os.Stdin.Read(b)
  177. if err != nil {
  178. if err != io.EOF {
  179. fmt.Printf("%v\n", err)
  180. }
  181. for _, c := range tcpc {
  182. c.CloseWrite() // I know, I know.. but it is handy sometimes.
  183. }
  184. break
  185. }
  186. for i := range b[:n] {
  187. fmt.Printf("%s", string(b[i]))
  188. if b[i] == '\r' {
  189. b[i] = '\n'
  190. fmt.Printf("\n")
  191. }
  192. }
  193. for _, c := range tcpc {
  194. if _, err := c.Write(b[:n]); err != nil {
  195. fmt.Printf("%v\n", err)
  196. break
  197. }
  198. }
  199. }
  200. }()
  201. xchan := make(chan int)
  202. outchan := make(chan string)
  203. for i, c := range tcpc {
  204. go func(i int, c *net.TCPConn) {
  205. b := make([]byte, 256)
  206. var out []byte
  207. for {
  208. n, err := c.Read(b)
  209. if err != nil {
  210. if err != io.EOF {
  211. fmt.Printf("%v\n", err)
  212. }
  213. c.Close()
  214. xchan <- 1
  215. break
  216. }
  217. if n == 0 {
  218. continue
  219. }
  220. for _, v := range b[:n] {
  221. out = append(out, v)
  222. if v == '\n' {
  223. outchan <- fmt.Sprintf("[%d]:%s\r", i, out)
  224. out = nil
  225. }
  226. }
  227. }
  228. }(i, c)
  229. }
  230. go func() {
  231. for {
  232. line := <-outchan
  233. fmt.Printf("%s", line)
  234. }
  235. }()
  236. for _ = range tcpc {
  237. <-xchan
  238. }
  239. }