Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@ -0,0 +1,72 @@
This directory contains scripts that give examples of using Pexpect.
hive.py
This script creates SSH connections to a list of hosts that
you provide. Then you are given a command line prompt. Each
shell command that you enter is sent to all the hosts. The
response from each host is collected and printed. For example,
you could connect to a dozen different machines and reboot
them all at once.
script.py
This implements a command similar to the classic BSD "script" command.
This will start a subshell and log all input and output to a file.
This demonstrates the interact() method of Pexpect.
fix_cvs_files.py
This is for cleaning up binary files improperly added to
CVS. This script scans the given path to find binary files;
checks with CVS to see if the sticky options are set to -kb;
finally if sticky options are not -kb then uses 'cvs admin'
to set the -kb option.
ftp.py
This demonstrates an FTP "bookmark".
This connects to an ftp site; does a few ftp commands; and then gives the user
interactive control over the session. In this case the "bookmark" is to a
directory on the OpenBSD ftp server. It puts you in the i386 packages
directory. You can easily modify this for other sites.
This demonstrates the interact() method of Pexpect.
monitor.py
This runs a sequence of system status commands on a remote host using SSH.
It runs a simple system checks such as uptime and free to monitor
the state of the remote host.
passmass.py
This will login to a list of hosts and change the password of the
given user. This demonstrates scripting logins; although, you could
more easily do this using the pxssh subclass of Pexpect.
See also the "hive.py" example script for a more general example
of scripting a collection of servers.
python.py
This starts the python interpreter and prints the greeting message backwards.
It then gives the user interactive control of Python. It's pretty useless!
rippy.py
This is a wizard for mencoder. It greatly simplifies the process of
ripping a DVD to mpeg4 format (XviD, DivX). It can transcode from any
video file to another. It has options for resampling the audio stream;
removing interlace artifacts, fitting to a target file size, etc.
There are lots of options, but the process is simple and easy to use.
sshls.py
This lists a directory on a remote machine.
ssh_tunnel.py
This starts an SSH tunnel to a remote machine. It monitors the connection
and restarts the tunnel if it goes down.
uptime.py
This will run the uptime command and parse the output into python variables.
This demonstrates using a single regular expression to match the output
of a command and capturing different variable in match groups.
The regular expression takes into account a wide variety of different
formats for uptime output.
df.py
This collects filesystem capacity info using the 'df' command.
Tuples of filesystem name and percentage are stored in a list.
A simple report is printed. Filesystems over 95% capacity are highlighted.

View File

@ -0,0 +1,85 @@
#!/usr/bin/env python
"""This runs Apache Status on the remote host and returns the number of requests per second.
./astat.py [-s server_hostname] [-u username] [-p password]
-s : hostname of the remote server to login to.
-u : username to user for login.
-p : Password to user for login.
Example:
This will print information about the given host:
./astat.py -s www.example.com -u mylogin -p mypassword
"""
import os
import sys
import time
import re
import getopt
import getpass
import traceback
import pexpect
import pxssh
def exit_with_usage():
print globals()['__doc__']
os._exit(1)
def main():
######################################################################
# Parse the options, arguments, get ready, etc.
######################################################################
try:
optlist, args = getopt.getopt(
sys.argv[
1:], 'h?s:u:p:', [
'help', 'h', '?'])
except Exception as e:
print str(e)
exit_with_usage()
options = dict(optlist)
if len(args) > 1:
exit_with_usage()
if [elem for elem in options if elem in [
'-h', '--h', '-?', '--?', '--help']]:
print "Help:"
exit_with_usage()
if '-s' in options:
hostname = options['-s']
else:
hostname = raw_input('hostname: ')
if '-u' in options:
username = options['-u']
else:
username = raw_input('username: ')
if '-p' in options:
password = options['-p']
else:
password = getpass.getpass('password: ')
#
# Login via SSH
#
p = pxssh.pxssh()
p.login(hostname, username, password)
p.sendline('apachectl status')
p.expect('([0-9]+\.[0-9]+)\s*requests/sec')
requests_per_second = p.match.groups()[0]
p.logout()
print requests_per_second
if __name__ == "__main__":
try:
main()
except Exception as e:
print str(e)
traceback.print_exc()
os._exit(1)

View File

@ -0,0 +1,40 @@
#!/usr/bin/env python
"""This is a very simple client for the backdoor daemon. This is intended more
for testing rather than normal use. See bd_serv.py """
import socket
import sys
import time
import select
def recv_wrapper(s):
r, w, e = select.select([s.fileno()], [], [], 2)
if not r:
return ''
#cols = int(s.recv(4))
#rows = int(s.recv(4))
cols = 80
rows = 24
packet_size = cols * rows * 2 # double it for good measure
return s.recv(packet_size)
# HOST = '' #'localhost' # The remote host
# PORT = 1664 # The same port as used by the server
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect(sys.argv[1]) # (HOST, PORT))
time.sleep(1)
# s.setblocking(0)
#s.send('COMMAND' + '\x01' + sys.argv[1])
s.send(':sendline ' + sys.argv[2])
print recv_wrapper(s)
s.close()
sys.exit()
# while True:
# data = recv_wrapper(s)
# if data == '':
# break
# sys.stdout.write (data)
# sys.stdout.flush()
# s.close()

View File

@ -0,0 +1,339 @@
#!/usr/bin/env python
"""Back door shell server
This exposes an shell terminal on a socket.
--hostname : sets the remote host name to open an ssh connection to.
--username : sets the user name to login with
--password : (optional) sets the password to login with
--port : set the local port for the server to listen on
--watch : show the virtual screen after each client request
"""
# Having the password on the command line is not a good idea, but
# then this entire project is probably not the most security concious thing
# I've ever built. This should be considered an experimental tool -- at best.
import pxssh
import pexpect
import ANSI
import time
import sys
import os
import getopt
import getpass
import traceback
import threading
import socket
def exit_with_usage(exit_code=1):
print globals()['__doc__']
os._exit(exit_code)
class roller (threading.Thread):
"""This runs a function in a loop in a thread."""
def __init__(self, interval, function, args=[], kwargs={}):
"""The interval parameter defines time between each call to the function.
"""
threading.Thread.__init__(self)
self.interval = interval
self.function = function
self.args = args
self.kwargs = kwargs
self.finished = threading.Event()
def cancel(self):
"""Stop the roller."""
self.finished.set()
def run(self):
while not self.finished.isSet():
# self.finished.wait(self.interval)
self.function(*self.args, **self.kwargs)
def endless_poll(child, prompt, screen, refresh_timeout=0.1):
"""This keeps the screen updated with the output of the child. This runs in
a separate thread. See roller(). """
#child.logfile_read = screen
try:
s = child.read_nonblocking(4000, 0.1)
screen.write(s)
except:
pass
# while True:
# #child.prompt (timeout=refresh_timeout)
# try:
# #child.read_nonblocking(1,timeout=refresh_timeout)
# child.read_nonblocking(4000, 0.1)
# except:
# pass
def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
'''This forks the current process into a daemon. Almost none of this is
necessary (or advisable) if your daemon is being started by inetd. In that
case, stdin, stdout and stderr are all set up for you to refer to the
network connection, and the fork()s and session manipulation should not be
done (to avoid confusing inetd). Only the chdir() and umask() steps remain
as useful.
References:
UNIX Programming FAQ
1.7 How do I get my program to act like a daemon?
http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
Advanced Programming in the Unix Environment
W. Richard Stevens, 1992, Addison-Wesley, ISBN 0-201-56317-7.
The stdin, stdout, and stderr arguments are file names that will be opened
and be used to replace the standard file descriptors in sys.stdin,
sys.stdout, and sys.stderr. These arguments are optional and default to
/dev/null. Note that stderr is opened unbuffered, so if it shares a file
with stdout then interleaved output may not appear in the order that you
expect. '''
# Do first fork.
try:
pid = os.fork()
if pid > 0:
sys.exit(0) # Exit first parent.
except OSError as e:
sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
sys.exit(1)
# Decouple from parent environment.
os.chdir("/")
os.umask(0)
os.setsid()
# Do second fork.
try:
pid = os.fork()
if pid > 0:
sys.exit(0) # Exit second parent.
except OSError as e:
sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
sys.exit(1)
# Now I am a daemon!
# Redirect standard file descriptors.
si = open(stdin, 'r')
so = open(stdout, 'a+')
se = open(stderr, 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
# I now return as the daemon
return 0
def add_cursor_blink(response, row, col):
i = (row - 1) * 80 + col
return response[:i] + \
'<img src="http://www.noah.org/cursor.gif">' + response[i:]
def main():
try:
optlist, args = getopt.getopt(
sys.argv[
1:], 'h?d', [
'help', 'h', '?', 'hostname=', 'username=', 'password=', 'port=', 'watch'])
except Exception as e:
print str(e)
exit_with_usage()
command_line_options = dict(optlist)
options = dict(optlist)
# There are a million ways to cry for help. These are but a few of them.
if [elem for elem in command_line_options if elem in [
'-h', '--h', '-?', '--?', '--help']]:
exit_with_usage(0)
hostname = "127.0.0.1"
port = 1664
username = os.getenv('USER')
password = ""
daemon_mode = False
if '-d' in options:
daemon_mode = True
if '--watch' in options:
watch_mode = True
else:
watch_mode = False
if '--hostname' in options:
hostname = options['--hostname']
if '--port' in options:
port = int(options['--port'])
if '--username' in options:
username = options['--username']
print "Login for %s@%s:%s" % (username, hostname, port)
if '--password' in options:
password = options['--password']
else:
password = getpass.getpass('password: ')
if daemon_mode:
print "daemonizing server"
daemonize()
# daemonize('/dev/null','/tmp/daemon.log','/tmp/daemon.log')
sys.stdout.write('server started with pid %d\n' % os.getpid())
virtual_screen = ANSI.ANSI(24, 80)
child = pxssh.pxssh()
child.login(hostname, username, password)
print 'created shell. command line prompt is', child.PROMPT
#child.sendline ('stty -echo')
# child.setecho(False)
virtual_screen.write(child.before)
virtual_screen.write(child.after)
if os.path.exists("/tmp/mysock"):
os.remove("/tmp/mysock")
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
localhost = '127.0.0.1'
s.bind('/tmp/mysock')
os.chmod('/tmp/mysock', 0o777)
print 'Listen'
s.listen(1)
print 'Accept'
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#localhost = '127.0.0.1'
#s.bind((localhost, port))
# print 'Listen'
# s.listen(1)
r = roller(0.01, endless_poll, (child, child.PROMPT, virtual_screen))
r.start()
print "screen poll updater started in background thread"
sys.stdout.flush()
try:
while True:
conn, addr = s.accept()
print 'Connected by', addr
data = conn.recv(1024)
if data[0] != ':':
cmd = ':sendline'
arg = data.strip()
else:
request = data.split(' ', 1)
if len(request) > 1:
cmd = request[0].strip()
arg = request[1].strip()
else:
cmd = request[0].strip()
if cmd == ':exit':
r.cancel()
break
elif cmd == ':sendline':
child.sendline(arg)
# child.prompt(timeout=2)
time.sleep(0.2)
shell_window = str(virtual_screen)
elif cmd == ':send' or cmd == ':xsend':
if cmd == ':xsend':
arg = arg.decode("hex")
child.send(arg)
time.sleep(0.2)
shell_window = str(virtual_screen)
elif cmd == ':cursor':
shell_window = '%x%x' % (
virtual_screen.cur_r, virtual_screen.cur_c)
elif cmd == ':refresh':
shell_window = str(virtual_screen)
response = []
response.append(shell_window)
#response = add_cursor_blink (response, row, col)
sent = conn.send('\n'.join(response))
if watch_mode:
print '\n'.join(response)
if sent < len(response):
print "Sent is too short. Some data was cut off."
conn.close()
finally:
r.cancel()
print "cleaning up socket"
s.close()
if os.path.exists("/tmp/mysock"):
os.remove("/tmp/mysock")
print "done!"
def pretty_box(rows, cols, s):
"""This puts an ASCII text box around the given string, s.
"""
top_bot = '+' + '-' * cols + '+\n'
return top_bot + \
'\n'.join(['|' + line + '|' for line in s.split('\n')]) + '\n' + top_bot
def error_response(msg):
response = []
response.append ("""All commands start with :
:{REQUEST} {ARGUMENT}
{REQUEST} may be one of the following:
:sendline: Run the ARGUMENT followed by a line feed.
:send : send the characters in the ARGUMENT without a line feed.
:refresh : Use to catch up the screen with the shell if state gets out of sync.
Example:
:sendline ls -l
You may also leave off :command and it will be assumed.
Example:
ls -l
is equivalent to:
:sendline ls -l
""")
response.append(msg)
return '\n'.join(response)
def parse_host_connect_string(hcs):
"""This parses a host connection string in the form
username:password@hostname:port. All fields are options expcet hostname. A
dictionary is returned with all four keys. Keys that were not included are
set to empty strings ''. Note that if your password has the '@' character
then you must backslash escape it. """
if '@' in hcs:
p = re.compile(
r'(?P<username>[^@:]*)(:?)(?P<password>.*)(?!\\)@(?P<hostname>[^:]*):?(?P<port>[0-9]*)')
else:
p = re.compile(
r'(?P<username>)(?P<password>)(?P<hostname>[^:]*):?(?P<port>[0-9]*)')
m = p.search(hcs)
d = m.groupdict()
d['password'] = d['password'].replace('\\@', '@')
return d
if __name__ == "__main__":
try:
start_time = time.time()
print time.asctime()
main()
print time.asctime()
print "TOTAL TIME IN MINUTES:",
print (time.time() - start_time) / 60.0
except Exception as e:
print str(e)
tb_dump = traceback.format_exc()
print str(tb_dump)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,132 @@
#!/usr/bin/env python
'''This demonstrates controlling a screen oriented application (curses).
It starts two instances of gnuchess and then pits them against each other.
'''
import pexpect
import string
import ANSI
REGEX_MOVE = '(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)'
REGEX_MOVE_PART = '(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)'
class Chess:
def __init__(self, engine="/usr/local/bin/gnuchess -a -h 1"):
self.child = pexpect.spawn(engine)
self.term = ANSI.ANSI()
self.child.expect('Chess')
if self.child.after != 'Chess':
raise IOError, 'incompatible chess program'
self.term.process_list(self.before)
self.term.process_list(self.after)
self.last_computer_move = ''
def read_until_cursor(self, r, c)
while 1:
self.child.read(1, 60)
self.term.process(c)
if self.term.cur_r == r and self.term.cur_c == c:
return 1
def do_first_move(self, move):
self.child.expect('Your move is')
self.child.sendline(move)
self.term.process_list(self.before)
self.term.process_list(self.after)
return move
def do_move(self, move):
read_until_cursor(19, 60)
#self.child.expect ('\[19;60H')
self.child.sendline(move)
print 'do_move' move
return move
def get_first_computer_move(self):
self.child.expect('My move is')
self.child.expect(REGEX_MOVE)
# print '', self.child.after
return self.child.after
def get_computer_move(self):
print 'Here'
i = self.child.expect(['\[17;59H', '\[17;58H'])
print i
if i == 0:
self.child.expect(REGEX_MOVE)
if len(self.child.after) < 4:
self.child.after = self.child.after + \
self.last_computer_move[3]
if i == 1:
self.child.expect(REGEX_MOVE_PART)
self.child.after = self.last_computer_move[0] + self.child.after
print '', self.child.after
self.last_computer_move = self.child.after
return self.child.after
def switch(self):
self.child.sendline('switch')
def set_depth(self, depth):
self.child.sendline('depth')
self.child.expect('depth=')
self.child.sendline('%d' % depth)
def quit(self):
self.child.sendline('quit')
import sys
import os
print 'Starting...'
white = Chess()
white.child.echo = 1
white.child.expect('Your move is')
white.set_depth(2)
white.switch()
move_white = white.get_first_computer_move()
print 'first move white:', move_white
white.do_move('e7e5')
move_white = white.get_computer_move()
print 'move white:', move_white
white.do_move('f8c5')
move_white = white.get_computer_move()
print 'move white:', move_white
white.do_move('b8a6')
move_white = white.get_computer_move()
print 'move white:', move_white
sys.exit(1)
black = Chess()
white = Chess()
white.child.expect('Your move is')
white.switch()
move_white = white.get_first_computer_move()
print 'first move white:', move_white
black.do_first_move(move_white)
move_black = black.get_first_computer_move()
print 'first move black:', move_black
white.do_move(move_black)
done = 0
while not done:
move_white = white.get_computer_move()
print 'move white:', move_white
black.do_move(move_white)
move_black = black.get_computer_move()
print 'move black:', move_black
white.do_move(move_black)
print 'tail of loop'
g.quit()

View File

@ -0,0 +1,135 @@
#!/usr/bin/env python
'''This demonstrates controlling a screen oriented application (curses).
It starts two instances of gnuchess and then pits them against each other.
'''
import pexpect
import string
import ANSI
import sys
import os
import time
class Chess:
def __init__(self, engine="/usr/local/bin/gnuchess -a -h 1"):
self.child = pexpect.spawn(engine)
self.term = ANSI.ANSI()
#self.child.expect ('Chess')
# if self.child.after != 'Chess':
# raise IOError, 'incompatible chess program'
#self.term.process_list (self.child.before)
#self.term.process_list (self.child.after)
self.last_computer_move = ''
def read_until_cursor(self, r, c, e=0):
'''Eventually something like this should move into the screen class or
a subclass. Maybe a combination of pexpect and screen...
'''
fout = open('log', 'a')
while self.term.cur_r != r or self.term.cur_c != c:
try:
k = self.child.read(1, 10)
except Exception as e:
print 'EXCEPTION, (r,c):(%d,%d)\n' % (self.term.cur_r, self.term.cur_c)
sys.stdout.flush()
self.term.process(k)
fout.write('(r,c):(%d,%d)\n' % (self.term.cur_r, self.term.cur_c))
fout.flush()
if e:
sys.stdout.write(k)
sys.stdout.flush()
if self.term.cur_r == r and self.term.cur_c == c:
fout.close()
return 1
print 'DIDNT EVEN HIT.'
fout.close()
return 1
def expect_region(self):
'''This is another method that would be moved into the
screen class.
'''
pass
def do_scan(self):
fout = open('log', 'a')
while True:
c = self.child.read(1, 10)
self.term.process(c)
fout.write('(r,c):(%d,%d)\n' % (self.term.cur_r, self.term.cur_c))
fout.flush()
sys.stdout.write(c)
sys.stdout.flush()
def do_move(self, move, e=0):
time.sleep(1)
self.read_until_cursor(19, 60, e)
self.child.sendline(move)
def wait(self, color):
while True:
r = self.term.get_region(14, 50, 14, 60)[0]
r = r.strip()
if r == color:
return
time.sleep(1)
def parse_computer_move(self, s):
i = s.find('is: ')
cm = s[i + 3:i + 9]
return cm
def get_computer_move(self, e=0):
time.sleep(1)
self.read_until_cursor(19, 60, e)
time.sleep(1)
r = self.term.get_region(17, 50, 17, 62)[0]
cm = self.parse_computer_move(r)
return cm
def switch(self):
print 'switching'
self.child.sendline('switch')
def set_depth(self, depth):
self.child.sendline('depth')
self.child.expect('depth=')
self.child.sendline('%d' % depth)
def quit(self):
self.child.sendline('quit')
def LOG(s):
print s
sys.stdout.flush()
fout = open('moves.log', 'a')
fout.write(s + '\n')
fout.close()
print 'Starting...'
black = Chess()
white = Chess()
white.read_until_cursor(19, 60, 1)
white.switch()
done = 0
while not done:
white.wait('Black')
move_white = white.get_computer_move(1)
LOG('move white:' + move_white)
black.do_move(move_white)
black.wait('White')
move_black = black.get_computer_move()
LOG('move black:' + move_black)
white.do_move(move_black, 1)
g.quit()

View File

@ -0,0 +1,139 @@
#!/usr/bin/env python
'''This demonstrates controlling a screen oriented application (curses).
It starts two instances of gnuchess and then pits them against each other.
'''
import pexpect
import string
import ANSI
REGEX_MOVE = '(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)'
REGEX_MOVE_PART = '(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)'
class Chess:
def __init__(self, engine="/usr/local/bin/gnuchess -a -h 1"):
self.child = pexpect.spawn(engine)
self.term = ANSI.ANSI()
# self.child.expect ('Chess')
# if self.child.after != 'Chess':
# raise IOError, 'incompatible chess program'
# self.term.process_list (self.before)
# self.term.process_list (self.after)
self.last_computer_move = ''
def read_until_cursor(self, r, c):
fout = open('log', 'a')
while True:
k = self.child.read(1, 10)
self.term.process(k)
fout.write('(r,c):(%d,%d)\n' % (self.term.cur_r, self.term.cur_c))
fout.flush()
if self.term.cur_r == r and self.term.cur_c == c:
fout.close()
return 1
sys.stdout.write(k)
sys.stdout.flush()
def do_scan(self):
fout = open('log', 'a')
while True:
c = self.child.read(1, 10)
self.term.process(c)
fout.write('(r,c):(%d,%d)\n' % (self.term.cur_r, self.term.cur_c))
fout.flush()
sys.stdout.write(c)
sys.stdout.flush()
def do_move(self, move):
self.read_until_cursor(19, 60)
self.child.sendline(move)
return move
def get_computer_move(self):
print 'Here'
i = self.child.expect(['\[17;59H', '\[17;58H'])
print i
if i == 0:
self.child.expect(REGEX_MOVE)
if len(self.child.after) < 4:
self.child.after = self.child.after + \
self.last_computer_move[3]
if i == 1:
self.child.expect(REGEX_MOVE_PART)
self.child.after = self.last_computer_move[0] + self.child.after
print '', self.child.after
self.last_computer_move = self.child.after
return self.child.after
def switch(self):
self.child.sendline('switch')
def set_depth(self, depth):
self.child.sendline('depth')
self.child.expect('depth=')
self.child.sendline('%d' % depth)
def quit(self):
self.child.sendline('quit')
import sys
import os
print 'Starting...'
white = Chess()
white.do_move('b2b4')
white.read_until_cursor(19, 60)
c1 = white.term.get_abs(17, 58)
c2 = white.term.get_abs(17, 59)
c3 = white.term.get_abs(17, 60)
c4 = white.term.get_abs(17, 61)
fout = open('log', 'a')
fout.write('Computer:%s%s%s%s\n' % (c1, c2, c3, c4))
fout.close()
white.do_move('c2c4')
white.read_until_cursor(19, 60)
c1 = white.term.get_abs(17, 58)
c2 = white.term.get_abs(17, 59)
c3 = white.term.get_abs(17, 60)
c4 = white.term.get_abs(17, 61)
fout = open('log', 'a')
fout.write('Computer:%s%s%s%s\n' % (c1, c2, c3, c4))
fout.close()
white.do_scan()
#white.do_move ('b8a6')
#move_white = white.get_computer_move()
# print 'move white:', move_white
sys.exit(1)
black = Chess()
white = Chess()
white.child.expect('Your move is')
white.switch()
move_white = white.get_first_computer_move()
print 'first move white:', move_white
black.do_first_move(move_white)
move_black = black.get_first_computer_move()
print 'first move black:', move_black
white.do_move(move_black)
done = 0
while not done:
move_white = white.get_computer_move()
print 'move white:', move_white
black.do_move(move_white)
move_black = black.get_computer_move()
print 'move black:', move_black
white.do_move(move_black)
print 'tail of loop'
g.quit()

View File

@ -0,0 +1,33 @@
#!/usr/bin/env python
"""This collects filesystem capacity info using the 'df' command. Tuples of
filesystem name and percentage are stored in a list. A simple report is
printed. Filesystems over 95% capacity are highlighted. Note that this does not
parse filesystem names after the first space, so names with spaces in them will
be truncated. This will produce ambiguous results for automount filesystems on
Apple OSX. """
import pexpect
child = pexpect.spawn('df')
# parse 'df' output into a list.
pattern = "\n(\S+).*?([0-9]+)%"
filesystem_list = []
for dummy in range(0, 1000):
i = child.expect([pattern, pexpect.EOF])
if i == 0:
filesystem_list.append(child.match.groups())
else:
break
# Print report
print
for m in filesystem_list:
s = "Filesystem %s is at %s%%" % (m[0], m[1])
# highlight filesystems over 95% capacity
if int(m[1]) > 95:
s = '! ' + s
else:
s = ' ' + s
print s

View File

@ -0,0 +1,98 @@
#!/usr/bin/env python
"""This is for cleaning up binary files improperly added to CVS. This script
scans the given path to find binary files; checks with CVS to see if the sticky
options are set to -kb; finally if sticky options are not -kb then uses 'cvs
admin' to set the -kb option.
This script ignores CVS directories, symbolic links, and files not known under
CVS control (cvs status is 'Unknown').
Run this on a CHECKED OUT module sandbox, not on the repository itself. After
if fixes the sticky options on any files you should manually do a 'cvs commit'
to accept the changes. Then be sure to have all users do a 'cvs up -A' to
update the Sticky Option status.
Noah Spurrier
20030426
"""
import os
import sys
import time
import pexpect
VERBOSE = 1
def is_binary(filename):
"""Assume that any file with a character where the 8th bit is set is
binary. """
fin = open(filename, 'rb')
wholething = fin.read()
fin.close()
for c in wholething:
if ord(c) & 0x80:
return 1
return 0
def is_kb_sticky(filename):
"""This checks if 'cvs status' reports '-kb' for Sticky options. If the
Sticky Option status is '-ks' then this returns 1. If the status is
'Unknown' then it returns 1. Otherwise 0 is returned. """
try:
s = pexpect.spawn('cvs status %s' % filename)
i = s.expect(['Sticky Options:\s*(.*)\r\n', 'Status: Unknown'])
if i == 1 and VERBOSE:
print 'File not part of CVS repository:', filename
return 1 # Pretend it's OK.
if s.match.group(1) == '-kb':
return 1
s = None
except:
print 'Something went wrong trying to run external cvs command.'
print ' cvs status %s' % filename
print 'The cvs command returned:'
print s.before
return 0
def cvs_admin_kb(filename):
"""This uses 'cvs admin' to set the '-kb' sticky option. """
s = pexpect.run('cvs admin -kb %s' % filename)
# There is a timing issue. If I run 'cvs admin' too quickly
# cvs sometimes has trouble obtaining the directory lock.
time.sleep(1)
def walk_and_clean_cvs_binaries(arg, dirname, names):
"""This contains the logic for processing files. This is the os.path.walk
callback. This skips dirnames that end in CVS. """
if len(dirname) > 3 and dirname[-3:] == 'CVS':
return
for n in names:
fullpath = os.path.join(dirname, n)
if os.path.isdir(fullpath) or os.path.islink(fullpath):
continue
if is_binary(fullpath):
if not is_kb_sticky(fullpath):
if VERBOSE:
print fullpath
cvs_admin_kb(fullpath)
def main():
if len(sys.argv) == 1:
root = '.'
else:
root = sys.argv[1]
os.path.walk(root, walk_and_clean_cvs_binaries, None)
if __name__ == '__main__':
main()

View File

@ -0,0 +1,47 @@
#!/usr/bin/env python
"""This demonstrates an FTP "bookmark". This connects to an ftp site; does a
few ftp stuff; and then gives the user interactive control over the session. In
this case the "bookmark" is to a directory on the OpenBSD ftp server. It puts
you in the i386 packages directory. You can easily modify this for other sites.
"""
import pexpect
import sys
child = pexpect.spawn('ftp ftp.openbsd.org')
child.expect('(?i)name .*: ')
child.sendline('anonymous')
child.expect('(?i)password')
child.sendline('pexpect@sourceforge.net')
child.expect('ftp> ')
child.sendline('cd /pub/OpenBSD/3.7/packages/i386')
child.expect('ftp> ')
child.sendline('bin')
child.expect('ftp> ')
child.sendline('prompt')
child.expect('ftp> ')
child.sendline('pwd')
child.expect('ftp> ')
print("Escape character is '^]'.\n")
sys.stdout.write(child.after)
sys.stdout.flush()
child.interact() # Escape character defaults to ^]
# At this point this script blocks until the user presses the escape character
# or until the child exits. The human user and the child should be talking
# to each other now.
# At this point the script is running again.
print 'Left interactve mode.'
# The rest is not strictly necessary. This just demonstrates a few functions.
# This makes sure the child is dead; although it would be killed when
# Python exits.
if child.isalive():
child.sendline('bye') # Try to ask ftp child to exit.
child.close()
# Print the final state of the child. Normally isalive() should be FALSE.
if child.isalive():
print 'Child did not exit gracefully.'
else:
print 'Child exited gracefully.'

View File

@ -0,0 +1,472 @@
#!/usr/bin/env python
"""hive -- Hive Shell
This lets you ssh to a group of servers and control them as if they were one.
Each command you enter is sent to each host in parallel. The response of each
host is collected and printed. In normal synchronous mode Hive will wait for
each host to return the shell command line prompt. The shell prompt is used to
sync output.
Example:
$ hive.py --sameuser --samepass host1.example.com host2.example.net
username: myusername
password:
connecting to host1.example.com - OK
connecting to host2.example.net - OK
targetting hosts: 192.168.1.104 192.168.1.107
CMD (? for help) > uptime
=======================================================================
host1.example.com
-----------------------------------------------------------------------
uptime
23:49:55 up 74 days, 5:14, 2 users, load average: 0.15, 0.05, 0.01
=======================================================================
host2.example.net
-----------------------------------------------------------------------
uptime
23:53:02 up 1 day, 13:36, 2 users, load average: 0.50, 0.40, 0.46
=======================================================================
Other Usage Examples:
1. You will be asked for your username and password for each host.
hive.py host1 host2 host3 ... hostN
2. You will be asked once for your username and password.
This will be used for each host.
hive.py --sameuser --samepass host1 host2 host3 ... hostN
3. Give a username and password on the command-line:
hive.py user1:pass2@host1 user2:pass2@host2 ... userN:passN@hostN
You can use an extended host notation to specify username, password, and host
instead of entering auth information interactively. Where you would enter a
host name use this format:
username:password@host
This assumes that ':' is not part of the password. If your password contains a
':' then you can use '\\:' to indicate a ':' and '\\\\' to indicate a single
'\\'. Remember that this information will appear in the process listing. Anyone
on your machine can see this auth information. This is not secure.
This is a crude script that begs to be multithreaded. But it serves its
purpose.
Noah Spurrier
$Id: hive.py 509 2008-01-05 21:27:47Z noah $
"""
# TODO add feature to support username:password@host combination
# TODO add feature to log each host output in separate file
import sys
import os
import re
import optparse
import traceback
import types
import time
import getpass
import pexpect
import pxssh
import readline
import atexit
#histfile = os.path.join(os.environ["HOME"], ".hive_history")
# try:
# readline.read_history_file(histfile)
# except IOError:
# pass
#atexit.register(readline.write_history_file, histfile)
CMD_HELP = """Hive commands are preceded by a colon : (just think of vi).
:target name1 name2 name3 ...
set list of hosts to target commands
:target all
reset list of hosts to target all hosts in the hive.
:to name command
send a command line to the named host. This is similar to :target, but
sends only one command and does not change the list of targets for future
commands.
:sync
set mode to wait for shell prompts after commands are run. This is the
default. When Hive first logs into a host it sets a special shell prompt
pattern that it can later look for to synchronize output of the hosts. If
you 'su' to another user then it can upset the synchronization. If you need
to run something like 'su' then use the following pattern:
CMD (? for help) > :async
CMD (? for help) > sudo su - root
CMD (? for help) > :prompt
CMD (? for help) > :sync
:async
set mode to not expect command line prompts (see :sync). Afterwards
commands are send to target hosts, but their responses are not read back
until :sync is run. This is useful to run before commands that will not
return with the special shell prompt pattern that Hive uses to synchronize.
:refresh
refresh the display. This shows the last few lines of output from all hosts.
This is similar to resync, but does not expect the promt. This is useful
for seeing what hosts are doing during long running commands.
:resync
This is similar to :sync, but it does not change the mode. It looks for the
prompt and thus consumes all input from all targetted hosts.
:prompt
force each host to reset command line prompt to the special pattern used to
synchronize all the hosts. This is useful if you 'su' to a different user
where Hive would not know the prompt to match.
:send my text
This will send the 'my text' wihtout a line feed to the targetted hosts.
This output of the hosts is not automatically synchronized.
:control X
This will send the given control character to the targetted hosts.
For example, ":control c" will send ASCII 3.
:exit
This will exit the hive shell.
"""
def login(args, cli_username=None, cli_password=None):
# I have to keep a separate list of host names because Python dicts are not ordered.
# I want to keep the same order as in the args list.
host_names = []
hive_connect_info = {}
hive = {}
# build up the list of connection information (hostname, username,
# password, port)
for host_connect_string in args:
hcd = parse_host_connect_string(host_connect_string)
hostname = hcd['hostname']
port = hcd['port']
if port == '':
port = None
if len(hcd['username']) > 0:
username = hcd['username']
elif cli_username is not None:
username = cli_username
else:
username = raw_input('%s username: ' % hostname)
if len(hcd['password']) > 0:
password = hcd['password']
elif cli_password is not None:
password = cli_password
else:
password = getpass.getpass('%s password: ' % hostname)
host_names.append(hostname)
hive_connect_info[hostname] = (hostname, username, password, port)
# build up the list of hive connections using the connection information.
for hostname in host_names:
print 'connecting to', hostname
try:
fout = file("log_" + hostname, "w")
hive[hostname] = pxssh.pxssh()
hive[hostname].login(*hive_connect_info[hostname])
print hive[hostname].before
hive[hostname].logfile = fout
print '- OK'
except Exception as e:
print '- ERROR',
print str(e)
print 'Skipping', hostname
hive[hostname] = None
return host_names, hive
def main():
global options, args, CMD_HELP
if options.sameuser:
cli_username = raw_input('username: ')
else:
cli_username = None
if options.samepass:
cli_password = getpass.getpass('password: ')
else:
cli_password = None
host_names, hive = login(args, cli_username, cli_password)
synchronous_mode = True
target_hostnames = host_names[:]
print 'targetting hosts:', ' '.join(target_hostnames)
while True:
cmd = raw_input('CMD (? for help) > ')
cmd = cmd.strip()
if cmd == '?' or cmd == ':help' or cmd == ':h':
print CMD_HELP
continue
elif cmd == ':refresh':
refresh(hive, target_hostnames, timeout=0.5)
for hostname in target_hostnames:
if hive[hostname] is None:
print '/============================================================================='
print '| ' + hostname + ' is DEAD'
print '\\-----------------------------------------------------------------------------'
else:
print '/============================================================================='
print '| ' + hostname
print '\\-----------------------------------------------------------------------------'
print hive[hostname].before
print '=============================================================================='
continue
elif cmd == ':resync':
resync(hive, target_hostnames, timeout=0.5)
for hostname in target_hostnames:
if hive[hostname] is None:
print '/============================================================================='
print '| ' + hostname + ' is DEAD'
print '\\-----------------------------------------------------------------------------'
else:
print '/============================================================================='
print '| ' + hostname
print '\\-----------------------------------------------------------------------------'
print hive[hostname].before
print '=============================================================================='
continue
elif cmd == ':sync':
synchronous_mode = True
resync(hive, target_hostnames, timeout=0.5)
continue
elif cmd == ':async':
synchronous_mode = False
continue
elif cmd == ':prompt':
for hostname in target_hostnames:
try:
if hive[hostname] is not None:
hive[hostname].set_unique_prompt()
except Exception as e:
print "Had trouble communicating with %s, so removing it from the target list." % hostname
print str(e)
hive[hostname] = None
continue
elif cmd[:5] == ':send':
cmd, txt = cmd.split(None, 1)
for hostname in target_hostnames:
try:
if hive[hostname] is not None:
hive[hostname].send(txt)
except Exception as e:
print "Had trouble communicating with %s, so removing it from the target list." % hostname
print str(e)
hive[hostname] = None
continue
elif cmd[:3] == ':to':
cmd, hostname, txt = cmd.split(None, 2)
if hive[hostname] is None:
print '/============================================================================='
print '| ' + hostname + ' is DEAD'
print '\\-----------------------------------------------------------------------------'
continue
try:
hive[hostname].sendline(txt)
hive[hostname].prompt(timeout=2)
print '/============================================================================='
print '| ' + hostname
print '\\-----------------------------------------------------------------------------'
print hive[hostname].before
except Exception as e:
print "Had trouble communicating with %s, so removing it from the target list." % hostname
print str(e)
hive[hostname] = None
continue
elif cmd[:7] == ':expect':
cmd, pattern = cmd.split(None, 1)
print 'looking for', pattern
try:
for hostname in target_hostnames:
if hive[hostname] is not None:
hive[hostname].expect(pattern)
print hive[hostname].before
except Exception as e:
print "Had trouble communicating with %s, so removing it from the target list." % hostname
print str(e)
hive[hostname] = None
continue
elif cmd[:7] == ':target':
target_hostnames = cmd.split()[1:]
if len(target_hostnames) == 0 or target_hostnames[0] == all:
target_hostnames = host_names[:]
print 'targetting hosts:', ' '.join(target_hostnames)
continue
elif cmd == ':exit' or cmd == ':q' or cmd == ':quit':
break
elif cmd[:8] == ':control' or cmd[:5] == ':ctrl':
cmd, c = cmd.split(None, 1)
if ord(c) - 96 < 0 or ord(c) - 96 > 255:
print '/============================================================================='
print '| Invalid character. Must be [a-zA-Z], @, [, ], \\, ^, _, or ?'
print '\\-----------------------------------------------------------------------------'
continue
for hostname in target_hostnames:
try:
if hive[hostname] is not None:
hive[hostname].sendcontrol(c)
except Exception as e:
print "Had trouble communicating with %s, so removing it from the target list." % hostname
print str(e)
hive[hostname] = None
continue
elif cmd == ':esc':
for hostname in target_hostnames:
if hive[hostname] is not None:
hive[hostname].send(chr(27))
continue
#
# Run the command on all targets in parallel
#
for hostname in target_hostnames:
try:
if hive[hostname] is not None:
hive[hostname].sendline(cmd)
except Exception as e:
print "Had trouble communicating with %s, so removing it from the target list." % hostname
print str(e)
hive[hostname] = None
#
# print the response for each targeted host.
#
if synchronous_mode:
for hostname in target_hostnames:
try:
if hive[hostname] is None:
print '/============================================================================='
print '| ' + hostname + ' is DEAD'
print '\\-----------------------------------------------------------------------------'
else:
hive[hostname].prompt(timeout=2)
print '/============================================================================='
print '| ' + hostname
print '\\-----------------------------------------------------------------------------'
print hive[hostname].before
except Exception as e:
print "Had trouble communicating with %s, so removing it from the target list." % hostname
print str(e)
hive[hostname] = None
print '=============================================================================='
def refresh(hive, hive_names, timeout=0.5):
"""This waits for the TIMEOUT on each host.
"""
# TODO This is ideal for threading.
for hostname in hive_names:
hive[hostname].expect([pexpect.TIMEOUT, pexpect.EOF], timeout=timeout)
def resync(hive, hive_names, timeout=2, max_attempts=5):
"""This waits for the shell prompt for each host in an effort to try to get
them all to the same state. The timeout is set low so that hosts that are
already at the prompt will not slow things down too much. If a prompt match
is made for a hosts then keep asking until it stops matching. This is a
best effort to consume all input if it printed more than one prompt. It's
kind of kludgy. Note that this will always introduce a delay equal to the
timeout for each machine. So for 10 machines with a 2 second delay you will
get AT LEAST a 20 second delay if not more. """
# TODO This is ideal for threading.
for hostname in hive_names:
for attempts in xrange(0, max_attempts):
if not hive[hostname].prompt(timeout=timeout):
break
def parse_host_connect_string(hcs):
"""This parses a host connection string in the form
username:password@hostname:port. All fields are options expcet hostname. A
dictionary is returned with all four keys. Keys that were not included are
set to empty strings ''. Note that if your password has the '@' character
then you must backslash escape it. """
if '@' in hcs:
p = re.compile(
r'(?P<username>[^@:]*)(:?)(?P<password>.*)(?!\\)@(?P<hostname>[^:]*):?(?P<port>[0-9]*)')
else:
p = re.compile(
r'(?P<username>)(?P<password>)(?P<hostname>[^:]*):?(?P<port>[0-9]*)')
m = p.search(hcs)
d = m.groupdict()
d['password'] = d['password'].replace('\\@', '@')
return d
if __name__ == '__main__':
try:
start_time = time.time()
parser = optparse.OptionParser(
formatter=optparse.TitledHelpFormatter(),
usage=globals()['__doc__'],
version='$Id: hive.py 509 2008-01-05 21:27:47Z noah $',
conflict_handler="resolve")
parser.add_option(
'-v',
'--verbose',
action='store_true',
default=False,
help='verbose output')
parser.add_option(
'--samepass',
action='store_true',
default=False,
help='Use same password for each login.')
parser.add_option(
'--sameuser',
action='store_true',
default=False,
help='Use same username for each login.')
(options, args) = parser.parse_args()
if len(args) < 1:
parser.error('missing argument')
if options.verbose:
print time.asctime()
main()
if options.verbose:
print time.asctime()
if options.verbose:
print 'TOTAL TIME IN MINUTES:',
if options.verbose:
print (time.time() - start_time) / 60.0
sys.exit(0)
except KeyboardInterrupt as e: # Ctrl-C
raise e
except SystemExit as e: # sys.exit()
raise e
except Exception as e:
print 'ERROR, UNEXPECTED EXCEPTION'
print str(e)
traceback.print_exc()
os._exit(1)

View File

@ -0,0 +1,222 @@
#!/usr/bin/env python
""" This runs a sequence of commands on a remote host using SSH. It runs a
simple system checks such as uptime and free to monitor the state of the remote
host.
./monitor.py [-s server_hostname] [-u username] [-p password]
-s : hostname of the remote server to login to.
-u : username to user for login.
-p : Password to user for login.
Example:
This will print information about the given host:
./monitor.py -s www.example.com -u mylogin -p mypassword
It works like this:
Login via SSH (This is the hardest part).
Run and parse 'uptime'.
Run 'iostat'.
Run 'vmstat'.
Run 'netstat'
Run 'free'.
Exit the remote host.
"""
import os
import sys
import time
import re
import getopt
import getpass
import traceback
import pexpect
#
# Some constants.
#
# This is way too simple for industrial use -- we will change is ASAP.
COMMAND_PROMPT = '[#$] '
TERMINAL_PROMPT = '(?i)terminal type\?'
TERMINAL_TYPE = 'vt100'
# This is the prompt we get if SSH does not have the remote host's public
# key stored in the cache.
SSH_NEWKEY = '(?i)are you sure you want to continue connecting'
def exit_with_usage():
print globals()['__doc__']
os._exit(1)
def main():
global COMMAND_PROMPT, TERMINAL_PROMPT, TERMINAL_TYPE, SSH_NEWKEY
######################################################################
# Parse the options, arguments, get ready, etc.
######################################################################
try:
optlist, args = getopt.getopt(
sys.argv[
1:], 'h?s:u:p:', [
'help', 'h', '?'])
except Exception as e:
print str(e)
exit_with_usage()
options = dict(optlist)
if len(args) > 1:
exit_with_usage()
if [elem for elem in options if elem in [
'-h', '--h', '-?', '--?', '--help']]:
print "Help:"
exit_with_usage()
if '-s' in options:
host = options['-s']
else:
host = raw_input('hostname: ')
if '-u' in options:
user = options['-u']
else:
user = raw_input('username: ')
if '-p' in options:
password = options['-p']
else:
password = getpass.getpass('password: ')
#
# Login via SSH
#
child = pexpect.spawn('ssh -l %s %s' % (user, host))
i = child.expect([pexpect.TIMEOUT, SSH_NEWKEY,
COMMAND_PROMPT, '(?i)password'])
if i == 0: # Timeout
print 'ERROR! could not login with SSH. Here is what SSH said:'
print child.before, child.after
print str(child)
sys.exit(1)
if i == 1: # In this case SSH does not have the public key cached.
child.sendline('yes')
child.expect('(?i)password')
if i == 2:
# This may happen if a public key was setup to automatically login.
# But beware, the COMMAND_PROMPT at this point is very trivial and
# could be fooled by some output in the MOTD or login message.
pass
if i == 3:
child.sendline(password)
# Now we are either at the command prompt or
# the login process is asking for our terminal type.
i = child.expect([COMMAND_PROMPT, TERMINAL_PROMPT])
if i == 1:
child.sendline(TERMINAL_TYPE)
child.expect(COMMAND_PROMPT)
#
# Set command prompt to something more unique.
#
COMMAND_PROMPT = "\[PEXPECT\]\$ "
child.sendline("PS1='[PEXPECT]\$ '") # In case of sh-style
i = child.expect([pexpect.TIMEOUT, COMMAND_PROMPT], timeout=10)
if i == 0:
print "# Couldn't set sh-style prompt -- trying csh-style."
child.sendline("set prompt='[PEXPECT]\$ '")
i = child.expect([pexpect.TIMEOUT, COMMAND_PROMPT], timeout=10)
if i == 0:
print "Failed to set command prompt using sh or csh style."
print "Response was:"
print child.before
sys.exit(1)
# Now we should be at the command prompt and ready to run some commands.
print '---------------------------------------'
print 'Report of commands run on remote host.'
print '---------------------------------------'
# Run uname.
child.sendline('uname -a')
child.expect(COMMAND_PROMPT)
print child.before
if 'linux' in child.before.lower():
LINUX_MODE = 1
else:
LINUX_MODE = 0
# Run and parse 'uptime'.
child.sendline('uptime')
child.expect(
'up\s+(.*?),\s+([0-9]+) users?,\s+load averages?: ([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9])')
duration, users, av1, av5, av15 = child.match.groups()
days = '0'
hours = '0'
mins = '0'
if 'day' in duration:
child.match = re.search('([0-9]+)\s+day', duration)
days = str(int(child.match.group(1)))
if ':' in duration:
child.match = re.search('([0-9]+):([0-9]+)', duration)
hours = str(int(child.match.group(1)))
mins = str(int(child.match.group(2)))
if 'min' in duration:
child.match = re.search('([0-9]+)\s+min', duration)
mins = str(int(child.match.group(1)))
print
print 'Uptime: %s days, %s users, %s (1 min), %s (5 min), %s (15 min)' % (
duration, users, av1, av5, av15)
child.expect(COMMAND_PROMPT)
# Run iostat.
child.sendline('iostat')
child.expect(COMMAND_PROMPT)
print child.before
# Run vmstat.
child.sendline('vmstat')
child.expect(COMMAND_PROMPT)
print child.before
# Run free.
if LINUX_MODE:
child.sendline('free') # Linux systems only.
child.expect(COMMAND_PROMPT)
print child.before
# Run df.
child.sendline('df')
child.expect(COMMAND_PROMPT)
print child.before
# Run lsof.
child.sendline('lsof')
child.expect(COMMAND_PROMPT)
print child.before
# # Run netstat
# child.sendline ('netstat')
# child.expect (COMMAND_PROMPT)
# print child.before
# # Run MySQL show status.
# child.sendline ('mysql -p -e "SHOW STATUS;"')
# child.expect (PASSWORD_PROMPT_MYSQL)
# child.sendline (password_mysql)
# child.expect (COMMAND_PROMPT)
# print
# print child.before
# Now exit the remote host.
child.sendline('exit')
index = child.expect([pexpect.EOF, "(?i)there are stopped jobs"])
if index == 1:
child.sendline("exit")
child.expect(EOF)
if __name__ == "__main__":
try:
main()
except Exception as e:
print str(e)
traceback.print_exc()
os._exit(1)

View File

@ -0,0 +1,95 @@
#!/usr/bin/env python
"""Change passwords on the named machines. passmass host1 host2 host3 . . .
Note that login shell prompt on remote machine must end in # or $. """
import pexpect
import sys
import getpass
USAGE = '''passmass host1 host2 host3 . . .'''
COMMAND_PROMPT = '[$#] '
TERMINAL_PROMPT = r'Terminal type\?'
TERMINAL_TYPE = 'vt100'
SSH_NEWKEY = r'Are you sure you want to continue connecting \(yes/no\)\?'
def login(host, user, password):
child = pexpect.spawn('ssh -l %s %s' % (user, host))
fout = file("LOG.TXT", "wb")
child.setlog(fout)
i = child.expect([pexpect.TIMEOUT, SSH_NEWKEY, '[Pp]assword: '])
if i == 0: # Timeout
print 'ERROR!'
print 'SSH could not login. Here is what SSH said:'
print child.before, child.after
sys.exit(1)
if i == 1: # SSH does not have the public key. Just accept it.
child.sendline('yes')
child.expect('[Pp]assword: ')
child.sendline(password)
# Now we are either at the command prompt or
# the login process is asking for our terminal type.
i = child.expect(['Permission denied', TERMINAL_PROMPT, COMMAND_PROMPT])
if i == 0:
print 'Permission denied on host:', host
sys.exit(1)
if i == 1:
child.sendline(TERMINAL_TYPE)
child.expect(COMMAND_PROMPT)
return child
# (current) UNIX password:
def change_password(child, user, oldpassword, newpassword):
child.sendline('passwd')
i = child.expect(
['[Oo]ld [Pp]assword', '.current.*password', '[Nn]ew [Pp]assword'])
# Root does not require old password, so it gets to bypass the next step.
if i == 0 or i == 1:
child.sendline(oldpassword)
child.expect('[Nn]ew [Pp]assword')
child.sendline(newpassword)
i = child.expect(['[Nn]ew [Pp]assword', '[Rr]etype', '[Rr]e-enter'])
if i == 0:
print 'Host did not like new password. Here is what it said...'
print child.before
child.send(chr(3)) # Ctrl-C
child.sendline('') # This should tell remote passwd command to quit.
return
child.sendline(newpassword)
def main():
if len(sys.argv) <= 1:
print USAGE
return 1
user = raw_input('Username: ')
password = getpass.getpass('Current Password: ')
newpassword = getpass.getpass('New Password: ')
newpasswordconfirm = getpass.getpass('Confirm New Password: ')
if newpassword != newpasswordconfirm:
print 'New Passwords do not match.'
return 1
for host in sys.argv[1:]:
child = login(host, user, password)
if child is None:
print 'Could not login to host:', host
continue
print 'Changing password on host:', host
change_password(child, user, password, newpassword)
child.expect(COMMAND_PROMPT)
child.sendline('exit')
if __name__ == '__main__':
try:
main()
except pexpect.ExceptionPexpect as e:
print str(e)

View File

@ -0,0 +1,21 @@
#!/usr/bin/env python
"""This starts the python interpreter; captures the startup message; then gives
the user interactive control over the session. Why? For fun... """
# Don't do this unless you like being John Malkovich
# c = pexpect.spawn ('/usr/bin/env python ./python.py')
import pexpect
c = pexpect.spawn('/usr/bin/env python')
c.expect('>>>')
print 'And now for something completely different...'
f = lambda s: s and f(s[1:]) + s[0] # Makes a function to reverse a string.
print f(c.before)
print 'Yes, it\'s python, but it\'s backwards.'
print
print 'Escape character is \'^]\'.'
print c.after,
c.interact()
c.kill(1)
print 'is alive:', c.isalive()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,115 @@
#!/usr/bin/env python
"""This spawns a sub-shell (bash) and gives the user interactive control. The
entire shell session is logged to a file called script.log. This behaves much
like the classic BSD command 'script'.
./script.py [-a] [-c command] {logfilename}
logfilename : This is the name of the log file. Default is script.log.
-a : Append to log file. Default is to overwrite log file.
-c : spawn command. Default is to spawn the sh shell.
Example:
This will start a bash shell and append to the log named my_session.log:
./script.py -a -c bash my_session.log
"""
import os
import sys
import time
import getopt
import signal
import fcntl
import termios
import struct
import traceback
import pexpect
global_pexpect_instance = None # Used by signal handler
def exit_with_usage():
print globals()['__doc__']
os._exit(1)
def main():
######################################################################
# Parse the options, arguments, get ready, etc.
######################################################################
try:
optlist, args = getopt.getopt(
sys.argv[
1:], 'h?ac:', [
'help', 'h', '?'])
except Exception as e:
print str(e)
exit_with_usage()
options = dict(optlist)
if len(args) > 1:
exit_with_usage()
if [elem for elem in options if elem in [
'-h', '--h', '-?', '--?', '--help']]:
print "Help:"
exit_with_usage()
if len(args) == 1:
script_filename = args[0]
else:
script_filename = "script.log"
if '-a' in options:
fout = file(script_filename, "ab")
else:
fout = file(script_filename, "wb")
if '-c' in options:
command = options['-c']
else:
command = "sh"
# Begin log with date/time in the form CCCCyymm.hhmmss
fout.write('# %4d%02d%02d.%02d%02d%02d \n' % time.localtime()[:-3])
######################################################################
# Start the interactive session
######################################################################
p = pexpect.spawn(command)
p.logfile = fout
global global_pexpect_instance
global_pexpect_instance = p
signal.signal(signal.SIGWINCH, sigwinch_passthrough)
print "Script recording started. Type ^] (ASCII 29) to escape from the script shell."
p.interact(chr(29))
fout.close()
return 0
def sigwinch_passthrough(sig, data):
# Check for buggy platforms (see pexpect.setwinsize()).
if 'TIOCGWINSZ' in dir(termios):
TIOCGWINSZ = termios.TIOCGWINSZ
else:
TIOCGWINSZ = 1074295912 # assume
s = struct.pack("HHHH", 0, 0, 0, 0)
a = struct.unpack('HHHH', fcntl.ioctl(sys.stdout.fileno(), TIOCGWINSZ, s))
global global_pexpect_instance
global_pexpect_instance.setwinsize(a[0], a[1])
if __name__ == "__main__":
try:
main()
except SystemExit as e:
raise e
except Exception as e:
print "ERROR"
print str(e)
traceback.print_exc()
os._exit(1)

View File

@ -0,0 +1,93 @@
#
# Eric S. Raymond
#
# Greatly modified by Nigel W. Moriarty
# April 2003
#
from pexpect import *
import os
import sys
import getpass
import time
class ssh_session:
"Session with extra state including the password to be used."
def __init__(self, user, host, password=None, verbose=0):
self.user = user
self.host = host
self.verbose = verbose
self.password = password
self.keys = [
'authenticity',
'assword:',
'@@@@@@@@@@@@',
'Command not found.',
EOF,
]
self.f = open('ssh.out', 'w')
def __repr__(self):
outl = 'class :' + self.__class__.__name__
for attr in self.__dict__:
if attr == 'password':
outl += '\n\t' + attr + ' : ' + '*' * len(self.password)
else:
outl += '\n\t' + attr + ' : ' + str(getattr(self, attr))
return outl
def __exec(self, command):
"Execute a command on the remote host. Return the output."
child = spawn(command,
# timeout=10,
)
if self.verbose:
sys.stderr.write("-> " + command + "\n")
seen = child.expect(self.keys)
self.f.write(str(child.before) + str(child.after) + '\n')
if seen == 0:
child.sendline('yes')
seen = child.expect(self.keys)
if seen == 1:
if not self.password:
self.password = getpass.getpass('Remote password: ')
child.sendline(self.password)
child.readline()
time.sleep(5)
# Added to allow the background running of remote process
if not child.isalive():
seen = child.expect(self.keys)
if seen == 2:
lines = child.readlines()
self.f.write(lines)
if self.verbose:
sys.stderr.write("<- " + child.before + "|\n")
try:
self.f.write(str(child.before) + str(child.after) + '\n')
except:
pass
self.f.close()
return child.before
def ssh(self, command):
return self.__exec("ssh -l %s %s \"%s\""
% (self.user, self.host, command))
def scp(self, src, dst):
return self.__exec("scp %s %s@%s:%s"
% (src, session.user, session.host, dst))
def exists(self, file):
"Retrieve file permissions of specified remote file."
seen = self.ssh("/bin/ls -ld %s" % file)
if string.find(seen, "No such file") > -1:
return None # File doesn't exist
else:
return seen.split()[0] # Return permission field of listing.

View File

@ -0,0 +1,76 @@
#!/usr/bin/env python
"""This starts an SSH tunnel to a given host. If the SSH process ever dies then
this script will detect that and restart it. I use this under Cygwin to keep
open encrypted tunnels to port 25 (SMTP), port 143 (IMAP4), and port 110
(POP3). I set my mail client to talk to localhost and I keep this script
running in the background.
Note that this is a rather stupid script at the moment because it just looks to
see if any ssh process is running. It should really make sure that our specific
ssh process is running. The problem is that ssh is missing a very useful
feature. It has no way to report the process id of the background daemon that
it creates with the -f command. This would be a really useful script if I could
figure a way around this problem. """
import pexpect
import getpass
import time
# SMTP:25 IMAP4:143 POP3:110
tunnel_command = 'ssh -C -N -f -L 25:127.0.0.1:25 -L 143:127.0.0.1:143 -L 110:127.0.0.1:110 %(user)@%(host)'
host = raw_input('Hostname: ')
user = raw_input('Username: ')
X = getpass.getpass('Password: ')
def get_process_info():
# This seems to work on both Linux and BSD, but should otherwise be
# considered highly UNportable.
ps = pexpect.run('ps ax -O ppid')
pass
def start_tunnel():
try:
ssh_tunnel = pexpect.spawn(tunnel_command % globals())
ssh_tunnel.expect('password:')
time.sleep(0.1)
ssh_tunnel.sendline(X)
time.sleep(60) # Cygwin is slow to update process status.
ssh_tunnel.expect(pexpect.EOF)
except Exception, e:
print str(e)
def main():
while True:
ps = pexpect.spawn('ps')
time.sleep(1)
index = ps.expect(['/usr/bin/ssh', pexpect.EOF, pexpect.TIMEOUT])
if index == 2:
print 'TIMEOUT in ps command...'
print str(ps)
time.sleep(13)
if index == 1:
print time.asctime(),
print 'restarting tunnel'
start_tunnel()
time.sleep(11)
print 'tunnel OK'
else:
# print 'tunnel OK'
time.sleep(7)
if __name__ == '__main__':
main()
# This was for older SSH versions that didn't have -f option
#tunnel_command = 'ssh -C -n -L 25:%(host)s:25 -L 110:%(host)s:110 %(user)s@%(host)s -f nothing.sh'
# nothing_script = """#!/bin/sh
# while true; do sleep 53; done
#"""

View File

@ -0,0 +1,57 @@
#!/usr/bin/env python
"""This runs 'ls -l' on a remote host using SSH. At the prompts enter hostname,
user, and password.
$Id: sshls.py 489 2007-11-28 23:40:34Z noah $
"""
import pexpect
import getpass
import os
def ssh_command(user, host, password, command):
"""This runs a command on the remote host. This could also be done with the
pxssh class, but this demonstrates what that class does at a simpler level.
This returns a pexpect.spawn object. This handles the case when you try to
connect to a new host and ssh asks you if you want to accept the public key
fingerprint and continue connecting. """
ssh_newkey = 'Are you sure you want to continue connecting'
child = pexpect.spawn('ssh -l %s %s %s' % (user, host, command))
i = child.expect([pexpect.TIMEOUT, ssh_newkey, 'password: '])
if i == 0: # Timeout
print 'ERROR!'
print 'SSH could not login. Here is what SSH said:'
print child.before, child.after
return None
if i == 1: # SSH does not have the public key. Just accept it.
child.sendline('yes')
child.expect('password: ')
i = child.expect([pexpect.TIMEOUT, 'password: '])
if i == 0: # Timeout
print 'ERROR!'
print 'SSH could not login. Here is what SSH said:'
print child.before, child.after
return None
child.sendline(password)
return child
def main():
host = raw_input('Hostname: ')
user = raw_input('User: ')
password = getpass.getpass('Password: ')
child = ssh_command(user, host, password, '/bin/ls -l')
child.expect(pexpect.EOF)
print child.before
if __name__ == '__main__':
try:
main()
except Exception as e:
print str(e)
traceback.print_exc()
os._exit(1)

Some files were not shown because too many files have changed in this diff Show More