-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtcpterm
executable file
·102 lines (72 loc) · 2.33 KB
/
tcpterm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/usr/bin/env python
# TCP Terminal Utility - Andrew Klofas <[email protected]> - Dec 2008
import argparse, socket, sys, tty, termios, signal, errno, os
from threading import Thread, Event
# Quit code
cmdQUIT = (0x18, "Ctrl-x")
returnSTATUS = 0
# Parse args
p = argparse.ArgumentParser(description='Open a terminal over a raw tcp socket')
p.add_argument('--cmd', '-c', action='append', default=[], help='Commands to be executed at the beginning of the session')
p.add_argument('host', help='Specifies a host to contact over the network.')
p.add_argument('port', type=int, help='Specifies a port number to contact.')
a = p.parse_args()
# Connect to server
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((a.host, a.port))
# Write commands list first
for c in a.cmd:
s.sendall(c + '\n')
except socket.error as e:
sys.stderr.write("%s.\n" % (os.strerror(e.errno)))
sys.exit(e.errno)
# Read from socket and dump to stdout
def sock2stdout(qe):
while True:
data = s.recv(1024)
if not data: break
sys.stdout.write(data)
sys.stdout.flush()
# Flag the quit event
qe.set()
# Read from stdin and dump to socket
def stdin2sock(qe):
while True:
try:
c = sys.stdin.read(1)
if ord(c) == cmdQUIT[0]: break
s.send(c)
except IOError as e:
# Ignore if errno is one of these
if e.errno in [errno.EINTR]: continue
# Cleanly exit if errno is one of these
if e.errno in [errno.EPIPE, errno.EBADF]: break
sys.stderr.write("%s.\n" % (os.strerror(e.errno)))
returnSTATUS = e.errno
break
# Flag the quit event
qe.set()
eventQUIT = Event()
stdoutTHREAD = Thread(target=sock2stdout, args=(eventQUIT,))
stdinTHREAD = Thread(target=stdin2sock, args=(eventQUIT,))
# Forward terminal control signals
signal.signal(signal.SIGINT, lambda _1, _2: s.send(chr(0x03)))
signal.signal(signal.SIGTSTP, lambda _1, _2: s.send(chr(0x1A)))
signal.signal(signal.SIGQUIT, lambda _1, _2: s.send(chr(0x1C)))
# Print header
sys.stdout.write("> Welcome to TCPTerm. Press %s to quit.\n" % (cmdQUIT[1]))
# Get 1 byte at a time from stdin
old = termios.tcgetattr(sys.stdin)
try:
tty.setcbreak(sys.stdin.fileno())
# Start the threads
stdoutTHREAD.start()
stdinTHREAD.start()
# Wait for quit event
eventQUIT.wait()
finally:
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old)
# Close down
s.close()
sys.exit(returnSTATUS)