# Path: sshuttle/helpers.py
# def b(s):
#     return s.encode("ASCII")
# 
# def log(s):
#     global logprefix
#     try:
#         sys.stdout.flush()
#         # Put newline at end of string if line doesn't have one.
#         if not s.endswith("\n"):
#             s = s+"\n"
# 
#         prefix = logprefix
#         s = s.rstrip("\n")
#         for line in s.split("\n"):
#             # We output with \r\n instead of \n because when we use
#             # sudo with the use_pty option, the firewall process, the
#             # other processes printing to the terminal will have the
#             # \n move to the next line, but they will fail to reset
#             # cursor to the beginning of the line. Printing output
#             # with \r\n endings fixes that problem and does not appear
#             # to cause problems elsewhere.
#             sys.stderr.write(prefix + line + "\r\n")
#             prefix = "    "
#         sys.stderr.flush()
#     except IOError:
#         # this could happen if stderr gets forcibly disconnected, eg. because
#         # our tty closes.  That sucks, but it's no reason to abort the program.
#         pass
# 
# def debug1(s):
#     if verbose >= 1:
#         log(s)
# 
# def debug2(s):
#     if verbose >= 2:
#         log(s)
# 
# def debug3(s):
#     if verbose >= 3:
#         log(s)
# 
# class Fatal(Exception):
#     pass


import sys
import struct
import socket
import errno
import select
import os
import fcntl
from sshuttle.helpers import b, log, debug1, debug2, debug3, Fatal

    def handle(self):
        self.fill()
        # log('inbuf is: (%d,%d) %r'
        #     % (self.want, len(self.inbuf), self.inbuf))
        while 1:
            if len(self.inbuf) >= (self.want or HDR_LEN):
                (s1, s2, channel, cmd, datalen) = \
                    struct.unpack('!ccHHH', self.inbuf[:HDR_LEN])
                assert(s1 == b('S'))
                assert(s2 == b('S'))
                self.want = datalen + HDR_LEN
            if self.want and len(self.inbuf) >= self.want:
                data = self.inbuf[HDR_LEN:self.want]
                self.inbuf = self.inbuf[self.want:]
                self.want = 0
                self.got_packet(channel, cmd, data)
            else:
                break

    def pre_select(self, r, w, x):
        _add(r, self.rfile)
        if self.outbuf:
            _add(w, self.wfile)

    def callback(self, sock):
        (r, w, _) = select.select([self.rfile], [self.wfile], [], 0)
        if self.rfile in r:
            self.handle()
        if self.outbuf and self.wfile in w:

# Path: sshuttle/helpers.py
# def b(s):
#     return s.encode("ASCII")
# 
# def log(s):
#     global logprefix
#     try:
#         sys.stdout.flush()
#         # Put newline at end of string if line doesn't have one.
#         if not s.endswith("\n"):
#             s = s+"\n"
# 
#         prefix = logprefix
#         s = s.rstrip("\n")
#         for line in s.split("\n"):
#             # We output with \r\n instead of \n because when we use
#             # sudo with the use_pty option, the firewall process, the
#             # other processes printing to the terminal will have the
#             # \n move to the next line, but they will fail to reset
#             # cursor to the beginning of the line. Printing output
#             # with \r\n endings fixes that problem and does not appear
#             # to cause problems elsewhere.
#             sys.stderr.write(prefix + line + "\r\n")
#             prefix = "    "
#         sys.stderr.flush()
#     except IOError:
#         # this could happen if stderr gets forcibly disconnected, eg. because
#         # our tty closes.  That sucks, but it's no reason to abort the program.
#         pass
# 
# def debug1(s):
#     if verbose >= 1:
#         log(s)
# 
# def debug2(s):
#     if verbose >= 2:
#         log(s)
# 
# def debug3(s):
#     if verbose >= 3:
#         log(s)
# 
# class Fatal(Exception):
#     pass


# Path: sshuttle/ssnet.py
import sys
import struct
import socket
import errno
import select
import os
import fcntl
from sshuttle.helpers import b, log, debug1, debug2, debug3, Fatal


    def handle(self):
        self.fill()
        # log('inbuf is: (%d,%d) %r'
        #     % (self.want, len(self.inbuf), self.inbuf))
        while 1:
            if len(self.inbuf) >= (self.want or HDR_LEN):
                (s1, s2, channel, cmd, datalen) = \
                    struct.unpack('!ccHHH', self.inbuf[:HDR_LEN])
                assert(s1 == b('S'))
                assert(s2 == b('S'))
                self.want = datalen + HDR_LEN
            if self.want and len(self.inbuf) >= self.want:
                data = self.inbuf[HDR_LEN:self.want]
                self.inbuf = self.inbuf[self.want:]
                self.want = 0
                self.got_packet(channel, cmd, data)
            else:
                break

    def pre_select(self, r, w, x):
        _add(r, self.rfile)
        if self.outbuf:
            _add(w, self.wfile)

    def callback(self, sock):
        (r, w, _) = select.select([self.rfile], [self.wfile], [], 0)
        if self.rfile in r:
            self.handle()
        if self.outbuf and self.wfile in w:

            self.flush()