http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/chess3.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/chess3.py b/tools/bin/pythonSrc/pexpect-4.2/examples/chess3.py new file mode 100755 index 0000000..dc02663 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/chess3.py @@ -0,0 +1,157 @@ +#!/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. + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +''' + +from __future__ import print_function + +from __future__ import absolute_import + +import pexpect +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 1: + 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 1: + 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 +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()
http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/df.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/df.py b/tools/bin/pythonSrc/pexpect-4.2/examples/df.py new file mode 100755 index 0000000..4faa038 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/df.py @@ -0,0 +1,57 @@ +#!/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. + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +''' + +from __future__ import print_function + +from __future__ import absolute_import + +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) + http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/ftp.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/ftp.py b/tools/bin/pythonSrc/pexpect-4.2/examples/ftp.py new file mode 100755 index 0000000..a1c1343 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/ftp.py @@ -0,0 +1,73 @@ +#!/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. + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +''' + +from __future__ import absolute_import +from __future__ import print_function +from __future__ import unicode_literals + +import pexpect +import sys + +# Note that, for Python 3 compatibility reasons, we are using spawnu and +# importing unicode_literals (above). spawnu accepts Unicode input and +# unicode_literals makes all string literals in this script Unicode by default. +child = pexpect.spawnu('ftp ftp.openbsd.org') + +child.expect('(?i)name .*: ') +child.sendline('anonymous') +child.expect('(?i)password') +child.sendline('[email protected]') +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.') + http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/hive.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/hive.py b/tools/bin/pythonSrc/pexpect-4.2/examples/hive.py new file mode 100755 index 0000000..00ddbea --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/hive.py @@ -0,0 +1,466 @@ +#!/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. + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +''' + +from __future__ import print_function + +from __future__ import absolute_import + +# 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 time +import getpass +import readline +import atexit +try: + import pexpect + import pxssh +except ImportError: + sys.stderr.write("You do not have 'pexpect' installed.\n") + sys.stderr.write("On Ubuntu you need the 'python-pexpect' package.\n") + sys.stderr.write(" aptitude -y install python-pexpect\n") + exit(1) + + +try: + raw_input +except NameError: + raw_input = input + + +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() + # Disable host key checking. + hive[hostname].SSH_OPTS = (hive[hostname].SSH_OPTS + + " -o 'StrictHostKeyChecking=no'" + + " -o 'UserKnownHostsFile /dev/null' ") + hive[hostname].force_password = True + hive[hostname].login(*hive_connect_info[hostname]) + print(hive[hostname].before) + hive[hostname].logfile = fout + print('- OK') + except Exception as e: + print('- ERROR', end=' ') + print(str(e)) + print('Skipping', hostname) + hive[hostname] = None + return host_names, hive + +def main (): + + global options, args, CMD_HELP + + rows = 24 + cols = 80 + + 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: + print('/' + '=' * (cols - 2)) + print('| ' + hostname) + print('\\' + '-' * (cols - 2)) + if hive[hostname] is None: + print('# DEAD: %s' % hostname) + else: + print(hive[hostname].before) + print('#' * 79) + continue + elif cmd==':resync': + resync (hive, target_hostnames, timeout=0.5) + for hostname in target_hostnames: + print('/' + '=' * (cols - 2)) + print('| ' + hostname) + print('\\' + '-' * (cols - 2)) + if hive[hostname] is None: + print('# DEAD: %s' % hostname) + else: + print(hive[hostname].before) + print('#' * 79) + 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) + print('/' + '=' * (cols - 2)) + print('| ' + hostname) + print('\\' + '-' * (cols - 2)) + if hive[hostname] is None: + print('# DEAD: %s' % hostname) + continue + try: + hive[hostname].sendline (txt) + hive[hostname].prompt(timeout=2) + 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('/' + '=' * (cols - 2)) + print('| Invalid character. Must be [a-zA-Z], @, [, ], \\, ^, _, or ?') + print('\\' + '-' * (cols - 2)) + 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: + print('/' + '=' * (cols - 2)) + print('| ' + hostname) + print('\\' + '-' * (cols - 2)) + if hive[hostname] is None: + print('# DEAD: %s' % hostname) + else: + hive[hostname].prompt(timeout=2) + 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('#' * 79) + +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: + if hive[hostname] is not None: + 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: + if hive[hostname] is not None: + for attempts in range(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__': + start_time = time.time() + parser = optparse.OptionParser(formatter=optparse.TitledHelpFormatter(), usage=globals()['__doc__'], version='$Id: hive.py 533 2012-10-20 02:19:33Z 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:', end=' ') + if options.verbose: print((time.time() - start_time) / 60.0) http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/monitor.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/monitor.py b/tools/bin/pythonSrc/pexpect-4.2/examples/monitor.py new file mode 100755 index 0000000..9cb0eaf --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/monitor.py @@ -0,0 +1,229 @@ +#!/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. + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +''' + +from __future__ import print_function + +from __future__ import absolute_import + +import os, sys, re, getopt, getpass +import pexpect + + +try: + raw_input +except NameError: + raw_input = input + + +# +# Some constants. +# +COMMAND_PROMPT = '[#$] ' ### This is way too simple for industrial use -- we will change is ASAP. +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__": + main() http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/passmass.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/passmass.py b/tools/bin/pythonSrc/pexpect-4.2/examples/passmass.py new file mode 100755 index 0000000..dc362f5 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/passmass.py @@ -0,0 +1,116 @@ +#!/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 $. + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +''' + +from __future__ import print_function + +from __future__ import absolute_import + +import pexpect +import sys, getpass + + +try: + raw_input +except NameError: + raw_input = input + + +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.logfile = 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 == 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__': + main() http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/python.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/python.py b/tools/bin/pythonSrc/pexpect-4.2/examples/python.py new file mode 100755 index 0000000..44c15e1 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/python.py @@ -0,0 +1,49 @@ +#!/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... + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +''' + +from __future__ import absolute_import +from __future__ import print_function +from __future__ import unicode_literals + +import pexpect + +# Don't do this unless you like being John Malkovich +# c = pexpect.spawnu('/usr/bin/env python ./python.py') + +# Note that, for Python 3 compatibility reasons, we are using spawnu and +# importing unicode_literals (above). spawnu accepts Unicode input and +# unicode_literals makes all string literals in this script Unicode by default. +c = pexpect.spawnu('/usr/bin/env python') + +c.expect('>>>') +print('And now for something completely different...') +print(''.join(reversed((c.before)))) +print('Yes, it\'s python, but it\'s backwards.') +print() +print('Escape character is \'^]\'.') +print(c.after, end=' ') +c.interact() +c.kill(1) +print('is alive:', c.isalive()) + http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/script.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/script.py b/tools/bin/pythonSrc/pexpect-4.2/examples/script.py new file mode 100755 index 0000000..c8b9496 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/script.py @@ -0,0 +1,114 @@ +#!/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 + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +''' + +from __future__ import print_function + +from __future__ import absolute_import + +import os, sys, time, getopt +import signal, fcntl, termios, struct +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 = open(script_filename, "ab") + else: + fout = open(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__": + main() http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/ssh_tunnel.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/ssh_tunnel.py b/tools/bin/pythonSrc/pexpect-4.2/examples/ssh_tunnel.py new file mode 100755 index 0000000..d761911 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/ssh_tunnel.py @@ -0,0 +1,105 @@ +#!/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. + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +''' + +from __future__ import print_function + +from __future__ import absolute_import + +import pexpect +import getpass +import time + + +try: + raw_input +except NameError: + raw_input = input + + +# 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 as 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(), end=' ') + 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 +#''' + http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/table_test.html ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/table_test.html b/tools/bin/pythonSrc/pexpect-4.2/examples/table_test.html new file mode 100644 index 0000000..5dba0ec --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/table_test.html @@ -0,0 +1,106 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<html> +<head> +<title>TEST</title> +</head> +<style type="text/css"> +a {color: #9f9; text-decoration: none} +a:hover {color: #0f0} +hr {color: #0f0} +html,table,body,textarea,input,form +{ +font-family: "Courier New", Courier, mono; +font-size: 8pt; +color: #0c0; +background-color: #020; +margin:0; +padding:0; +border:0; +} +input { background-color: #010; } +textarea { +border-width:1; +border-style:solid; +border-color:#0c0; +padding:3; +margin:3; +} +</style> +<script> +var foo="" + +" 123456789012345678901234567890123456789012345 789012345678901234567890123456789"+ +"0 2345678901234567890123456789012345678901234 6 89012345678901234567890123456789"+ +"01 34567890123456789012345678901234567890123 567 9012345678901234567890123456789"+ +"012 456789012345678901234567890123456789012 45678 012345678901234567890123456789"+ +"0123 5678901234567890123456789012345678901 3456789 12345678901234567890123456789"+ +"01234 67890123456789012345678901234567890 234567890 2345678901234567890123456789"+ +"012345 789012345678901234567890123456789 12345678901 345678901234567890123456789"+ +"0123456 8901234567890123456789012345678 0123456789012 45678901234567890123456789"+ +"01234567 90123456789012345678901234567 901234567890123 5678901234567890123456789"+ +"012345678 012345678901234567890123456 89012345678901234 678901234567890123456789"+ +"0123456789 1234567890123456789012345 7890123456789012345 78901234567890123456789"+ +"01234567890 23456789012345678901234 678901234567890123456 8901234567890123456789"+ +"012345678901 345678901234567890123 56789012345678901234567 901234567890123456789"+ +"0123456789012 4567890123456789012 4567890123456789012345678 0123456789012345678 "+ +"01234567890123 56789012345678901 345678901234567890123456789 12345678901234567 9"+ +"012345678901234 678901234567890 23456789012 567 01234567890 234567890123456 89"+ +"0123456789012345 7890123456789 123457789012 567 012345678901 3456789012345 789"+ +"01234567890123456 89012345678 012345678901234567890123456789012 45678901234 6789"+ +"012345678901234567 901234567 90123456789 12345678901 34567890123 567890123 56789"+ +"0123456789012345678 0123456 8901234567890 3456789 2345678901234 6789012 456789"+ +"01234567890123456789 12345 7890123456789012 0123456789012345 78901 3456789"+ +"012345678901234567890 234 67890123456789012345678901234567890123456 890 23456789"+ +"0123456789012345678901 3 5678901234567890123456789012345678901234567 9 123456789"+ +"01234567890123456789012 456789012345678901234567890123456789012345678 0123456789"; +function start2() +{ + // get the reference for the body + //var mybody = document.getElementsByTagName("body")[0]; + var mybody = document.getElementById("replace_me"); + var myroot = document.getElementById("a_parent"); + mytable = document.createElement("table"); + mytablebody = document.createElement("tbody"); + mytable.setAttribute("border","0"); + mytable.setAttribute("cellspacing","0"); + mytable.setAttribute("cellpadding","0"); + for(var j = 0; j < 24; j++) + { + mycurrent_row = document.createElement("tr"); + for(var i = 0; i < 80; i++) + { + mycurrent_cell = document.createElement("td"); + offset = (j*80)+i; + currenttext = document.createTextNode(foo.substring(offset,offset+1)); + mycurrent_cell.appendChild(currenttext); + mycurrent_row.appendChild(mycurrent_cell); + } + mytablebody.appendChild(mycurrent_row); + } + mytable.appendChild(mytablebody); + myroot.replaceChild(mytable,mybody); + //mybody.appendChild(mytable); +} +</script> +<body onload="start2();"> +<table align="LEFT" border="0" cellspacing="0" cellpadding="0"> +<div id="a_parent"> +<span id="replace_me"> +<tr align="left" valign="left"> + <td>/</td> + <td>h</td> + <td>o</td> + <td>m</td> + <td>e</td> + <td>/</td> + <td>n</td> + <td>o</td> + <td>a</td> + <td>h</td> + <td>/</td> + <td> </td> +</tr> +</table> +</span> +</div> +</body> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/topip.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/topip.py b/tools/bin/pythonSrc/pexpect-4.2/examples/topip.py new file mode 100755 index 0000000..25bd100 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/topip.py @@ -0,0 +1,299 @@ +#!/usr/bin/env python + +''' This runs netstat on a local or remote server. It calculates some simple +statistical information on the number of external inet connections. It groups +by IP address. This can be used to detect if one IP address is taking up an +excessive number of connections. It can also send an email alert if a given IP +address exceeds a threshold between runs of the script. This script can be used +as a drop-in Munin plugin or it can be used stand-alone from cron. I used this +on a busy web server that would sometimes get hit with denial of service +attacks. This made it easy to see if a script was opening many multiple +connections. A typical browser would open fewer than 10 connections at once. +A script might open over 100 simultaneous connections. + +./topip.py [-s server_hostname] [-u username] [-p password] + {-a from_addr,to_addr} {-n N} {-v} {--ipv6} + + -s : hostname of the remote server to login to. + -u : username to user for login. + -p : password to user for login. + -n : print stddev for the the number of the top 'N' ipaddresses. + -v : verbose - print stats and list of top ipaddresses. + -a : send alert if stddev goes over 20. + -l : to log message to /var/log/topip.log + --ipv6 : this parses netstat output that includes ipv6 format. + Note that this actually only works with ipv4 addresses, but for + versions of netstat that print in ipv6 format. + --stdev=N : Where N is an integer. This sets the trigger point + for alerts and logs. Default is to trigger if the + max value is over 5 standard deviations. + +Example: + + This will print stats for the top IP addresses connected to the given host: + + ./topip.py -s www.example.com -u mylogin -p mypassword -n 10 -v + + This will send an alert email if the maxip goes over the stddev trigger + value and the the current top ip is the same as the last top ip + (/tmp/topip.last): + + ./topip.py -s www.example.com -u mylogin -p mypassword \\ + -n 10 -v -a [email protected],[email protected] + + This will print the connection stats for the localhost in Munin format: + + ./topip.py + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +''' + +from __future__ import absolute_import +from __future__ import print_function +from __future__ import unicode_literals + +# See http://pexpect.sourceforge.net/ +import pexpect +import pxssh +import os +import sys +import time +import getopt +import pickle +import getpass +import smtplib +from pprint import pprint + + +try: + raw_input +except NameError: + raw_input = input + + +TOPIP_LOG_FILE = '/var/log/topip.log' +TOPIP_LAST_RUN_STATS = '/var/run/topip.last' + +def exit_with_usage(): + + print(globals()['__doc__']) + os._exit(1) + +def stats(r): + + '''This returns a dict of the median, average, standard deviation, + min and max of the given sequence. + + >>> from topip import stats + >>> print stats([5,6,8,9]) + {'med': 8, 'max': 9, 'avg': 7.0, 'stddev': 1.5811388300841898, 'min': 5} + >>> print stats([1000,1006,1008,1014]) + {'med': 1008, 'max': 1014, 'avg': 1007.0, 'stddev': 5.0, 'min': 1000} + >>> print stats([1,3,4,5,18,16,4,3,3,5,13]) + {'med': 4, 'max': 18, 'avg': 6.8181818181818183, 'stddev': 5.6216817577237475, 'min': 1} + >>> print stats([1,3,4,5,18,16,4,3,3,5,13,14,5,6,7,8,7,6,6,7,5,6,4,14,7]) + {'med': 6, 'max': 18, 'avg': 7.0800000000000001, 'stddev': 4.3259218670706474, 'min': 1} + ''' + + total = sum(r) + avg = float(total)/float(len(r)) + sdsq = sum([(i-avg)**2 for i in r]) + s = sorted(list(r)) + return dict(list(zip(['med', 'avg', 'stddev', 'min', 'max'], + (s[len(s)//2], avg, (sdsq/len(r))**.5, min(r), max(r))))) + +def send_alert (message, subject, addr_from, addr_to, smtp_server='localhost'): + + '''This sends an email alert. + ''' + + message = ( 'From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n' + % (addr_from, addr_to, subject) + message ) + server = smtplib.SMTP(smtp_server) + server.sendmail(addr_from, addr_to, message) + server.quit() + +def main(): + + # Parse the options, arguments, etc. + try: + optlist, args = getopt.getopt(sys.argv[1:], + 'h?valqs:u:p:n:', ['help','h','?','ipv6','stddev=']) + except Exception as e: + print(str(e)) + exit_with_usage() + options = dict(optlist) + + munin_flag = False + if len(args) > 0: + if args[0] == 'config': + print('graph_title Netstat Connections per IP') + print('graph_vlabel Socket connections per IP') + print('connections_max.label max') + print('connections_max.info Maximum number of connections per IP') + print('connections_avg.label avg') + print('connections_avg.info Average number of connections per IP') + print('connections_stddev.label stddev') + print('connections_stddev.info Standard deviation') + return 0 + elif args[0] != '': + print(args, len(args)) + return 0 + 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: + # if host was not specified then assume localhost munin plugin. + munin_flag = True + hostname = 'localhost' + # If localhost then don't ask for username/password. + if hostname != 'localhost' and hostname != '127.0.0.1': + if '-u' in options: + username = options['-u'] + else: + username = raw_input('username: ') + if '-p' in options: + password = options['-p'] + else: + password = getpass.getpass('password: ') + use_localhost = False + else: + use_localhost = True + + if '-l' in options: + log_flag = True + else: + log_flag = False + if '-n' in options: + average_n = int(options['-n']) + else: + average_n = None + if '-v' in options: + verbose = True + else: + verbose = False + if '-a' in options: + alert_flag = True + (alert_addr_from, alert_addr_to) = tuple(options['-a'].split(',')) + else: + alert_flag = False + if '--ipv6' in options: + ipv6_flag = True + else: + ipv6_flag = False + if '--stddev' in options: + stddev_trigger = float(options['--stddev']) + else: + stddev_trigger = 5 + + if ipv6_flag: + netstat_pattern = '(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+::ffff:(\S+):(\S+)\s+.*?\r' + else: + netstat_pattern = '(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(?:::ffff:)*(\S+):(\S+)\s+.*?\r' + #netstat_pattern = '(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+):(\S+)\s+.*?\r' + + # run netstat (either locally or via SSH). + if use_localhost: + p = pexpect.spawn('netstat -n -t') + PROMPT = pexpect.TIMEOUT + else: + p = pxssh.pxssh() + p.login(hostname, username, password) + p.sendline('netstat -n -t') + PROMPT = p.PROMPT + + # For each matching netstat_pattern put the ip address in the list. + ip_list = {} + try: + while 1: + i = p.expect([PROMPT, netstat_pattern]) + if i == 0: + break + k = p.match.groups()[4].decode('utf-8') + if k in ip_list: + ip_list[k] = ip_list[k] + 1 + else: + ip_list[k] = 1 + except: + pass + + # remove a few common, uninteresting addresses from the dictionary. + ip_list = dict([ (key,value) for key,value in ip_list.items() if '192.168.' not in key]) + ip_list = dict([ (key,value) for key,value in ip_list.items() if '127.0.0.1' not in key]) + + ip_list = list(ip_list.items()) + if len(ip_list) < 1: + if verbose: print('Warning: no networks connections worth looking at.') + return 0 + ip_list.sort(key=lambda x:x[1]) + + # generate some stats for the ip addresses found. + if average_n is not None and average_n <= 1: + average_n = None + # Reminder: the * unary operator treats the list elements as arguments. + zipped = zip(*ip_list[0:average_n]) + s = stats(list(zipped)[1]) + s['maxip'] = ip_list[0] + + # print munin-style or verbose results for the stats. + if munin_flag: + print('connections_max.value', s['max']) + print('connections_avg.value', s['avg']) + print('connections_stddev.value', s['stddev']) + return 0 + if verbose: + pprint (s) + print() + pprint (ip_list[0:average_n]) + + # load the stats from the last run. + try: + last_stats = pickle.load(file(TOPIP_LAST_RUN_STATS)) + except: + last_stats = {'maxip':None} + + if ( s['maxip'][1] > (s['stddev'] * stddev_trigger) + and s['maxip']==last_stats['maxip'] ): + if verbose: print('The maxip has been above trigger for two consecutive samples.') + if alert_flag: + if verbose: print('SENDING ALERT EMAIL') + send_alert(str(s), 'ALERT on %s' + % hostname, alert_addr_from, alert_addr_to) + if log_flag: + if verbose: print('LOGGING THIS EVENT') + fout = file(TOPIP_LOG_FILE,'a') + #dts = time.strftime('%Y:%m:%d:%H:%M:%S', time.localtime()) + dts = time.asctime() + fout.write ('%s - %d connections from %s\n' + % (dts,s['maxip'][1],str(s['maxip'][0]))) + fout.close() + + # save state to TOPIP_LAST_RUN_STATS + try: + pickle.dump(s, file(TOPIP_LAST_RUN_STATS,'w')) + os.chmod (TOPIP_LAST_RUN_STATS, 0o664) + except: + pass + # p.logout() + +if __name__ == '__main__': + main() http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/examples/uptime.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/examples/uptime.py b/tools/bin/pythonSrc/pexpect-4.2/examples/uptime.py new file mode 100755 index 0000000..659edfc --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/examples/uptime.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python + +'''This displays uptime information using uptime. This is redundant, +but it demonstrates expecting for a regular expression that uses subgroups. + +PEXPECT LICENSE + + This license is approved by the OSI and FSF as GPL-compatible. + http://opensource.org/licenses/isc-license.txt + + Copyright (c) 2012, Noah Spurrier <[email protected]> + PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY + PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE + COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +''' + +from __future__ import absolute_import +from __future__ import print_function +from __future__ import unicode_literals + +import pexpect +import re + +# There are many different styles of uptime results. I try to parse them all. Yeee! +# Examples from different machines: +# [x86] Linux 2.4 (Redhat 7.3) +# 2:06pm up 63 days, 18 min, 3 users, load average: 0.32, 0.08, 0.02 +# [x86] Linux 2.4.18-14 (Redhat 8.0) +# 3:07pm up 29 min, 1 user, load average: 2.44, 2.51, 1.57 +# [PPC - G4] MacOS X 10.1 SERVER Edition +# 2:11PM up 3 days, 13:50, 3 users, load averages: 0.01, 0.00, 0.00 +# [powerpc] Darwin v1-58.corefa.com 8.2.0 Darwin Kernel Version 8.2.0 +# 10:35 up 18:06, 4 users, load averages: 0.52 0.47 0.36 +# [Sparc - R220] Sun Solaris (8) +# 2:13pm up 22 min(s), 1 user, load average: 0.02, 0.01, 0.01 +# [x86] Linux 2.4.18-14 (Redhat 8) +# 11:36pm up 4 days, 17:58, 1 user, load average: 0.03, 0.01, 0.00 +# AIX jwdir 2 5 0001DBFA4C00 +# 09:43AM up 23:27, 1 user, load average: 0.49, 0.32, 0.23 +# OpenBSD box3 2.9 GENERIC#653 i386 +# 6:08PM up 4 days, 22:26, 1 user, load averages: 0.13, 0.09, 0.08 + +# Note that, for Python 3 compatibility reasons, we are using spawnu and +# importing unicode_literals (above). spawnu accepts Unicode input and +# unicode_literals makes all string literals in this script Unicode by default. +p = pexpect.spawnu('uptime') + +# This parses uptime output into the major groups using regex group matching. +p.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 = p.match.groups() + +# The duration is a little harder to parse because of all the different +# styles of uptime. I'm sure there is a way to do this all at once with +# one single regex, but I bet it would be hard to read and maintain. +# If anyone wants to send me a version using a single regex I'd be happy to see it. +days = '0' +hours = '0' +mins = '0' +if 'day' in duration: + p.match = re.search('([0-9]+)\s+day',duration) + days = str(int(p.match.group(1))) +if ':' in duration: + p.match = re.search('([0-9]+):([0-9]+)',duration) + hours = str(int(p.match.group(1))) + mins = str(int(p.match.group(2))) +if 'min' in duration: + p.match = re.search('([0-9]+)\s+min',duration) + mins = str(int(p.match.group(1))) + +# Print the parsed fields in CSV format. +print('days, hours, minutes, users, cpu avg 1 min, cpu avg 5 min, cpu avg 15 min') +print('%s, %s, %s, %s, %s, %s, %s' % (days, hours, mins, users, av1, av5, av15)) + http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/notes/my_forkpty.py ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/notes/my_forkpty.py b/tools/bin/pythonSrc/pexpect-4.2/notes/my_forkpty.py new file mode 100644 index 0000000..f2bef23 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/notes/my_forkpty.py @@ -0,0 +1,89 @@ +import os, fcntl, termios +import time + +def my_forkpty(): + + (master_fd, slave_fd) = os.openpty() + + if (master_fd < 0 or slave_fd < 0): + raise ExceptionPexpect("Forkpty failed") + + # slave_name = ptsname(master_fd); + + pid = os.fork(); + if pid == -1: + raise ExceptionPexpect("Forkpty failed") + elif pid == 0: # Child + if hasattr(termios, 'TIOCNOTTY'): + # Some platforms require an explicit detach of the + # current controlling tty before closing stdin, stdout, stderr. + # OpenBSD says that this is obsolete, but doesn't hurt. + try: + fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) + except: + pass + else: #if fd >= 0: + fcntl.ioctl(fd, termios.TIOCNOTTY, 0) + os.close(fd) + + # The setsid() system call will place the process into its own session + # which has the effect of disassociating it from the controlling terminal. + # This is known to be true for OpenBSD. + os.setsid() + # except: return posix_error(); + + # Verify that we are disconnected from the controlling tty. + try: + fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) + os.close(fd) + raise ExceptionPexpect("Forkpty failed") + except: + pass + if 'TIOCSCTTY' in dir(termios): + # Make the pseudo terminal the controlling terminal for this process + # (the process must not currently have a controlling terminal). + if fcntl.ioctl(slave_fd, termios.TIOCSCTTY, '') < 0: + raise ExceptionPexpect("Forkpty failed") + +# # Verify that we can open to the slave pty file. */ +# fd = os.open(slave_name, os.O_RDWR); +# if fd < 0: +# raise ExceptionPexpect("Forkpty failed") +# else: +# os.close(fd); + + # Verify that we now have a controlling tty. + fd = os.open("/dev/tty", os.O_WRONLY) + if fd < 0: + raise ExceptionPexpect("This process could not get a controlling tty.") + else: + os.close(fd) + + os.close(master_fd) + os.dup2(slave_fd, 0) + os.dup2(slave_fd, 1) + os.dup2(slave_fd, 2) + if slave_fd > 2: + os.close(slave_fd) + pid = 0 + + else: + # PARENT + os.close(slave_fd); + + if pid == -1: + raise ExceptionPexpect("This process could not get a controlling tty.") +# if (pid == 0) +# PyOS_AfterFork(); + + return (pid, master_fd) + +pid, fd = my_forkpty () +if pid == 0: # child + print 'I am not a robot!' +else: + print '(pid, fd) = (%d, %d)' % (pid, fd) + time.sleep(1) # Give the child a chance to print. + print 'Robots always say:', os.read(fd,100) + os.close(fd) + http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/notes/notes.txt ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/notes/notes.txt b/tools/bin/pythonSrc/pexpect-4.2/notes/notes.txt new file mode 100644 index 0000000..a793587 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/notes/notes.txt @@ -0,0 +1,50 @@ + +#################### +# +# NOTES +# +#################### + +## def send_human(self, text, delay_min = 0, delay_max = 1): +## pass +## def spawn2(self, command, args): +## """return pid, fd_stdio, fd_stderr +## """ +## pass + + +# Reason for double fork: +# http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC15 +# Reason for ptys: +# http://www.erlenstar.demon.co.uk/unix/faq_4.html#SEC52 + +# Nonblocking on Win32? +# Reasearch this as a way to maybe make pipe work for Win32. +# http://groups.google.com/groups?q=setraw+tty&hl=en&selm=uvgpvisvk.fsf%40roundpoint.com&rnum=7 +# +# if istty: +# if os.name=='posix': +# import tty +# tty.setraw(sys.stdin.fileno()) +# elif os.name=='nt': +# import win32file, win32con +# hstdin = win32file._get_osfhandle(sys.stdin.fileno()) +# modes = (win32file.GetConsoleMode(hstdin) +# & ~(win32con.ENABLE_LINE_INPUT +# |win32con.ENABLE_ECHO_INPUT)) +# win32file.SetConsoleMode(hstdin, modes) + +# Basic documentation: +# Explain use of lists of patterns and return index. +# Explain exceptions for non-handled special cases like EOF + +# Test bad fork +# Test ENOENT. In other words, no more TTY devices. + +#GLOBAL_SIGCHLD_RECEIVED = 0 +#def childdied (signum, frame): +# print 'Signal handler called with signal', signum +# frame.f_globals['pexpect'].GLOBAL_SIGCHLD_RECEIVED = 1 +# print str(frame.f_globals['pexpect'].GLOBAL_SIGCHLD_RECEIVED) +# GLOBAL_SIGCHLD_RECEIVED = 1 + http://git-wip-us.apache.org/repos/asf/incubator-hawq/blob/a1a2f2c5/tools/bin/pythonSrc/pexpect-4.2/notes/posixmodule.c.diff ---------------------------------------------------------------------- diff --git a/tools/bin/pythonSrc/pexpect-4.2/notes/posixmodule.c.diff b/tools/bin/pythonSrc/pexpect-4.2/notes/posixmodule.c.diff new file mode 100644 index 0000000..3bea1f9 --- /dev/null +++ b/tools/bin/pythonSrc/pexpect-4.2/notes/posixmodule.c.diff @@ -0,0 +1,233 @@ +*** Python-2.2.1.orig/Modules/posixmodule.c Tue Mar 12 16:38:31 2002 +--- Python-2.2.1/Modules/posixmodule.c Tue May 21 01:16:29 2002 +*************** +*** 1904,1910 **** + } + #endif + +! #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) + #ifdef HAVE_PTY_H + #include <pty.h> + #else +--- 1904,1913 ---- + } + #endif + +! #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(sun) +! #ifdef sun +! #include <sys/stropts.h> +! #endif + #ifdef HAVE_PTY_H + #include <pty.h> + #else +*************** +*** 1914,1920 **** + #endif /* HAVE_PTY_H */ + #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */ + +! #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) + static char posix_openpty__doc__[] = + "openpty() -> (master_fd, slave_fd)\n\ + Open a pseudo-terminal, returning open fd's for both master and slave end.\n"; +--- 1917,1923 ---- + #endif /* HAVE_PTY_H */ + #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */ + +! #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(sun) + static char posix_openpty__doc__[] = + "openpty() -> (master_fd, slave_fd)\n\ + Open a pseudo-terminal, returning open fd's for both master and slave end.\n"; +*************** +*** 1925,1932 **** + int master_fd, slave_fd; + #ifndef HAVE_OPENPTY + char * slave_name; + #endif +! + if (!PyArg_ParseTuple(args, ":openpty")) + return NULL; + +--- 1928,1941 ---- + int master_fd, slave_fd; + #ifndef HAVE_OPENPTY + char * slave_name; ++ #ifdef sun ++ void *sig_saved; + #endif +! #endif +! #if !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY) && defined(sun) +! extern char *ptsname(); +! #endif +! + if (!PyArg_ParseTuple(args, ":openpty")) + return NULL; + +*************** +*** 1933,1939 **** + #ifdef HAVE_OPENPTY + if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) + return posix_error(); +! #else + slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); + if (slave_name == NULL) + return posix_error(); +--- 1942,1948 ---- + #ifdef HAVE_OPENPTY + if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) + return posix_error(); +! #elif HAVE__GETPTY + slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); + if (slave_name == NULL) + return posix_error(); +*************** +*** 1941,1946 **** +--- 1950,1966 ---- + slave_fd = open(slave_name, O_RDWR); + if (slave_fd < 0) + return posix_error(); ++ #else ++ master_fd = open("/dev/ptmx", O_RDWR|O_NOCTTY); /* open master */ ++ sig_saved = signal(SIGCHLD, SIG_DFL); ++ grantpt(master_fd); /* change permission of slave */ ++ unlockpt(master_fd); /* unlock slave */ ++ signal(SIGCHLD,sig_saved); ++ slave_name = ptsname(master_fd); /* get name of slave */ ++ slave_fd = open(slave_name, O_RDWR); /* open slave */ ++ ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ ++ ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm*/ ++ ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat*/ + #endif /* HAVE_OPENPTY */ + + return Py_BuildValue("(ii)", master_fd, slave_fd); +*************** +*** 1948,1954 **** + } + #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */ + +! #ifdef HAVE_FORKPTY + static char posix_forkpty__doc__[] = + "forkpty() -> (pid, master_fd)\n\ + Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ +--- 1968,1974 ---- + } + #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */ + +! #if defined(HAVE_FORKPTY) || defined(sun) + static char posix_forkpty__doc__[] = + "forkpty() -> (pid, master_fd)\n\ + Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ +*************** +*** 1959,1968 **** +--- 1979,2067 ---- + posix_forkpty(PyObject *self, PyObject *args) + { + int master_fd, pid; ++ #if defined(sun) ++ int slave; ++ char * slave_name; ++ void *sig_saved; ++ int fd; ++ #endif + + if (!PyArg_ParseTuple(args, ":forkpty")) + return NULL; ++ #if defined(sun) ++ master_fd = open("/dev/ptmx", O_RDWR|O_NOCTTY); /* open master */ ++ sig_saved = signal(SIGCHLD, SIG_DFL); ++ grantpt(master_fd); /* change permission of slave */ ++ unlockpt(master_fd); /* unlock slave */ ++ signal(SIGCHLD,sig_saved); ++ slave_name = ptsname(master_fd); /* get name of slave */ ++ slave = open(slave_name, O_RDWR); /* open slave */ ++ ioctl(slave, I_PUSH, "ptem"); /* push ptem */ ++ ioctl(slave, I_PUSH, "ldterm"); /* push ldterm*/ ++ ioctl(slave, I_PUSH, "ttcompat"); /* push ttcompat*/ ++ if (master_fd < 0 || slave < 0) ++ { ++ return posix_error(); ++ } ++ switch (pid = fork()) { ++ case -1: ++ return posix_error(); ++ case 0: ++ /* First disconnect from the old controlling tty. */ ++ #ifdef TIOCNOTTY ++ fd = open("/dev/tty", O_RDWR | O_NOCTTY); ++ if (fd >= 0) { ++ (void) ioctl(fd, TIOCNOTTY, NULL); ++ close(fd); ++ } ++ #endif /* TIOCNOTTY */ ++ if (setsid() < 0) ++ return posix_error(); ++ ++ /* ++ * Verify that we are successfully disconnected from the controlling ++ * tty. ++ */ ++ fd = open("/dev/tty", O_RDWR | O_NOCTTY); ++ if (fd >= 0) { ++ return posix_error(); ++ close(fd); ++ } ++ /* Make it our controlling tty. */ ++ #ifdef TIOCSCTTY ++ if (ioctl(slave, TIOCSCTTY, NULL) < 0) ++ return posix_error(); ++ #endif /* TIOCSCTTY */ ++ fd = open(slave_name, O_RDWR); ++ if (fd < 0) { ++ return posix_error(); ++ } else { ++ close(fd); ++ } ++ /* Verify that we now have a controlling tty. */ ++ fd = open("/dev/tty", O_WRONLY); ++ if (fd < 0) ++ return posix_error(); ++ else { ++ close(fd); ++ } ++ (void) close(master_fd); ++ (void) dup2(slave, 0); ++ (void) dup2(slave, 1); ++ (void) dup2(slave, 2); ++ if (slave > 2) ++ (void) close(slave); ++ pid = 0; ++ break; ++ defautlt: ++ /* ++ * parent ++ */ ++ (void) close(slave); ++ } ++ #else + pid = forkpty(&master_fd, NULL, NULL, NULL); ++ #endif + if (pid == -1) + return posix_error(); + if (pid == 0) +*************** +*** 5607,5616 **** + #ifdef HAVE_FORK + {"fork", posix_fork, METH_VARARGS, posix_fork__doc__}, + #endif /* HAVE_FORK */ +! #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) + {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__}, + #endif /* HAVE_OPENPTY || HAVE__GETPTY */ +! #ifdef HAVE_FORKPTY + {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__}, + #endif /* HAVE_FORKPTY */ + #ifdef HAVE_GETEGID +--- 5706,5715 ---- + #ifdef HAVE_FORK + {"fork", posix_fork, METH_VARARGS, posix_fork__doc__}, + #endif /* HAVE_FORK */ +! #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(sun) + {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__}, + #endif /* HAVE_OPENPTY || HAVE__GETPTY */ +! #if defined(HAVE_FORKPTY) || defined(sun) + {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__}, + #endif /* HAVE_FORKPTY */ + #ifdef HAVE_GETEGID
