blob: 2f3bbbc756d8a306b9385c098406514212fa98b7 [file] [log] [blame]
#! /usr/bin/python
# Copyright 2016 Google Inc. All Rights Reserved.
"""Chat with cpss on port 4455.
Send stdin, wait for Console# prompt.
"""
__author__ = 'edjames@google.com (Ed James)'
import getopt
import os
import re
import select
import socket
import subprocess
import sys
# arg defaults
def_host = 'localhost'
def_port = 4455
def on_alarm(unused_, dummy_):
raise IOError('timed out waiting for prompt')
def usage():
print ('Usage: %s [-h)ost hostname] [-p)ort port] < command'
% sys.argv[0])
print ' defaults: hostname=%s port=%d' % (def_host, def_port)
print ' Sends commands one line at a time, waits for Console...# prompts.'
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], 'h:p:f',
['host=', 'port=', 'force'])
except getopt.GetoptError as err:
print str(err)
usage()
sys.exit(1)
host = def_host
port = def_port
force = False
for o, a in opts:
if o in ('-h', '--host'):
host = a
elif o in ('-p', '--port'):
port = int(a)
elif o in ('-f', '--force'):
force = True
else:
print 'unknown option: %s' % o
usage()
sys.exit(1)
if args:
print 'extra args found'
usage()
sys.exit(1)
# check for cpss_ready file
readyfile = '/tmp/cpss_ready'
if not force and not os.path.isfile(readyfile):
print '"%s" not found, cpss not ready. Use -f to bypass.' % readyfile
sys.exit(1)
print '!!! connecting to %s:%d' % (host, port)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s_fd = s.fileno()
stdin_fd = sys.stdin.fileno()
timeout = 30
isatty = os.isatty(sys.stdin.fileno())
# put tty in interactive mode
if isatty:
print '!!! type ^C or ^D to quit'
timeout = None
subprocess.call('stty raw'.split())
subprocess.call('stty noecho'.split())
stdin_eof = False
need_prompt = False
lines = []
if isatty:
lines.append('\n')
while True:
# feed a line to server and flag that we need a prompt
if not need_prompt and lines:
line = lines.pop(0)
try:
os.write(s_fd, line)
except OSError as err:
print '!!! write to server exception: %s' % str(err)
break
if not isatty:
need_prompt = True
rlist = [s_fd]
if not stdin_eof:
rlist.append(stdin_fd)
# wait for more input
rready, unused_, unused_ = select.select(rlist, [], [], timeout)
if not rready:
print '!!! timeout'
break
# read from stdin and push lines to queue
if stdin_fd in rready:
try:
data = os.read(stdin_fd, 102400)
except OSError as err:
print '!!! stdin exception: %s' % str(err)
if not data:
print '!!! stdin eof'
stdin_eof = True
else:
# exit on ^C or ^D. Kills server if we pass ^C
if '\x03' in data or '\x04' in data:
break
lines.extend(data.splitlines(True))
# read from server and check for prompts
if s_fd in rready:
try:
data = os.read(s_fd, 102400)
except OSError as err:
print '!!! read from server exception: %s' % str(err)
break
if not data:
break
sys.stdout.write(data)
sys.stdout.flush()
if re.search(r'Console(\([^)]*\))?# ', data):
need_prompt = False
# quit if no more lines and not interactive
if not need_prompt and not lines and not isatty:
break
# reset tty
if isatty:
subprocess.call('stty sane'.split())
# exit with error if we didn't get the expected prompts
if not isatty and need_prompt:
sys.exit(1)
sys.exit(0)
if __name__ == '__main__':
main()