# Path: sshproxy/util.py
# class SSHProxyPluginError(SSHProxyError):
#     def __init__(self, msg):
#         import log
#         log.error("PLUG: "+msg)
#         Exception.__init__(self, "Plugin error: "+msg)
# 
# Path: sshproxy/ptywrap.py
# class PTYWrapper(object):
#     def __init__(self, chan, code, address, handler, *args, **kwargs):
#         self.chan = chan
#         try:
#             self.ipc = ipc.IPCServer(address, handler=handler)
#         except:
#             log.exception('Exception:')
#             raise
#         pid, self.master_fd = pty.fork()
#         if not pid: # child process
#             cipc = ipc.IPCClient(address)
#             try:
#                 code(cipc, *args, **kwargs)
#             except Exception, e:
#                 log.exception('ERROR: cannot execute function %s' %
#                                                             code.__name__)
#                 pass
#             cipc.terminate()
#             cipc.close()
#             sys.stdout.close()
#             #chan.transport.atfork() # close only the socket
#             # Here the child process exits
#             os.abort()
# 
#         # Let's wait for the client to connect
#         r, w, e = select.select([self.ipc], [], [], 5)
#         if not r:
#             self.ipc.terminate()
#             self.ipc.close()
#         else:
#             self.ipc.accept()
# 
#     def loop(self):
#         chan = self.chan
#         master_fd = self.master_fd
#         fds = [master_fd, chan]
#         while master_fd or chan.active:
#             try:
#                 rfds, wfds, xfds = select.select(
#                         fds, [], [], 5)
#             except:
#                 log.exception('Exception in PTYWrapper.loop():')
#                 break
#             
#             if master_fd in rfds:
#                 try:
#                     data = pty._read(master_fd)
#                 except OSError:
#                     break
#                 if data == '':
#                     break
#                 chan.send(data)
#             if chan in rfds:
#                 data = chan.recv(10240)
#                 if data == '':
#                     break
#                 pty._writen(master_fd, data)
#                 if chan.closed or chan.eof_received:
#                     del fds[fds.index(chan)]
#                     pty._writen(master_fd, '\004') # CTRL-D
#                     continue


import os.path, re, StringIO, time, select, socket
import pexpect
from sshproxy.util import SSHProxyPluginError
from sshproxy.ptywrap import PTYWrapper

class PluginSPexpect(object):
    def __init__(self, console, chan, scriptname, sitedata):
        self.console = console
        self.chan = chan
        self.xp = spawn(0)
        self.xp.set_channel(chan)
        self.xp.set_console(console)
        if not scriptname:
            scriptname = 'script'
        self.scriptname = scriptname
        self.sd = sitedata

#    def loop(self):
        chan = self.chan
        xp = self.xp
        console = self.console
    
        # send CTRL-U to delete the current line + enter to get the prompt
        #xp.send('\x15\n')
        # send ESC + '#' to comment the current line + enter to get the prompt
        #xp.send('\x1b#\n')
        # send CTRL-C to discard the current line + enter to get the prompt
        xp.send('\x03')
        script = open(os.path.join('scripts', self.scriptname), 'r')
    
        for line in script.readlines():
            if line.startswith('wait:'):
                print 'EXPECT:' + line[5:].strip()
                if xp.expect(line[5:].strip(), timeout=None) < 0:

# Path: sshproxy/util.py
# class SSHProxyPluginError(SSHProxyError):
#     def __init__(self, msg):
#         import log
#         log.error("PLUG: "+msg)
#         Exception.__init__(self, "Plugin error: "+msg)
# 
# Path: sshproxy/ptywrap.py
# class PTYWrapper(object):
#     def __init__(self, chan, code, address, handler, *args, **kwargs):
#         self.chan = chan
#         try:
#             self.ipc = ipc.IPCServer(address, handler=handler)
#         except:
#             log.exception('Exception:')
#             raise
#         pid, self.master_fd = pty.fork()
#         if not pid: # child process
#             cipc = ipc.IPCClient(address)
#             try:
#                 code(cipc, *args, **kwargs)
#             except Exception, e:
#                 log.exception('ERROR: cannot execute function %s' %
#                                                             code.__name__)
#                 pass
#             cipc.terminate()
#             cipc.close()
#             sys.stdout.close()
#             #chan.transport.atfork() # close only the socket
#             # Here the child process exits
#             os.abort()
# 
#         # Let's wait for the client to connect
#         r, w, e = select.select([self.ipc], [], [], 5)
#         if not r:
#             self.ipc.terminate()
#             self.ipc.close()
#         else:
#             self.ipc.accept()
# 
#     def loop(self):
#         chan = self.chan
#         master_fd = self.master_fd
#         fds = [master_fd, chan]
#         while master_fd or chan.active:
#             try:
#                 rfds, wfds, xfds = select.select(
#                         fds, [], [], 5)
#             except:
#                 log.exception('Exception in PTYWrapper.loop():')
#                 break
#             
#             if master_fd in rfds:
#                 try:
#                     data = pty._read(master_fd)
#                 except OSError:
#                     break
#                 if data == '':
#                     break
#                 chan.send(data)
#             if chan in rfds:
#                 data = chan.recv(10240)
#                 if data == '':
#                     break
#                 pty._writen(master_fd, data)
#                 if chan.closed or chan.eof_received:
#                     del fds[fds.index(chan)]
#                     pty._writen(master_fd, '\004') # CTRL-D
#                     continue


# Path: lib/spexpect/spexpect.py
import os.path, re, StringIO, time, select, socket
import pexpect
from sshproxy.util import SSHProxyPluginError
from sshproxy.ptywrap import PTYWrapper


class PluginSPexpect(object):
    def __init__(self, console, chan, scriptname, sitedata):
        self.console = console
        self.chan = chan
        self.xp = spawn(0)
        self.xp.set_channel(chan)
        self.xp.set_console(console)
        if not scriptname:
            scriptname = 'script'
        self.scriptname = scriptname
        self.sd = sitedata

#    def loop(self):
        chan = self.chan
        xp = self.xp
        console = self.console
    
        # send CTRL-U to delete the current line + enter to get the prompt
        #xp.send('\x15\n')
        # send ESC + '#' to comment the current line + enter to get the prompt
        #xp.send('\x1b#\n')
        # send CTRL-C to discard the current line + enter to get the prompt
        xp.send('\x03')
        script = open(os.path.join('scripts', self.scriptname), 'r')
    
        for line in script.readlines():
            if line.startswith('wait:'):
                print 'EXPECT:' + line[5:].strip()
                if xp.expect(line[5:].strip(), timeout=None) < 0:

                    raise SSHProxyPluginError("Timeout waiting for pattern: %s" % line)