mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-21 17:16:35 +03:00
203 lines
5.5 KiB
Python
203 lines
5.5 KiB
Python
#!/usr/bin/env python
|
|
|
|
"""
|
|
Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
|
|
See the file 'LICENSE' for copying permission
|
|
"""
|
|
|
|
from __future__ import division
|
|
|
|
import errno
|
|
import os
|
|
import subprocess
|
|
import time
|
|
|
|
from lib.core.compat import buffer
|
|
from lib.core.convert import getBytes
|
|
from lib.core.settings import IS_WIN
|
|
|
|
if IS_WIN:
|
|
try:
|
|
from win32file import ReadFile, WriteFile
|
|
from win32pipe import PeekNamedPipe
|
|
except ImportError:
|
|
pass
|
|
import msvcrt
|
|
else:
|
|
import select
|
|
import fcntl
|
|
|
|
def blockingReadFromFD(fd):
|
|
# Quick twist around original Twisted function
|
|
# Blocking read from a non-blocking file descriptor
|
|
output = b""
|
|
|
|
while True:
|
|
try:
|
|
output += os.read(fd, 8192)
|
|
except (OSError, IOError) as ioe:
|
|
if ioe.args[0] in (errno.EAGAIN, errno.EINTR):
|
|
# Uncomment the following line if the process seems to
|
|
# take a huge amount of cpu time
|
|
# time.sleep(0.01)
|
|
continue
|
|
else:
|
|
raise
|
|
break
|
|
|
|
if not output:
|
|
raise EOFError("fd %s has been closed." % fd)
|
|
|
|
return output
|
|
|
|
def blockingWriteToFD(fd, data):
|
|
# Another quick twist
|
|
while True:
|
|
try:
|
|
data_length = len(data)
|
|
wrote_data = os.write(fd, data)
|
|
except (OSError, IOError) as io:
|
|
if io.errno in (errno.EAGAIN, errno.EINTR):
|
|
continue
|
|
else:
|
|
raise
|
|
|
|
if wrote_data < data_length:
|
|
blockingWriteToFD(fd, data[wrote_data:])
|
|
|
|
break
|
|
|
|
# the following code is taken from http://code.activestate.com/recipes/440554-module-to-allow-asynchronous-subprocess-use-on-win/
|
|
class Popen(subprocess.Popen):
|
|
def recv(self, maxsize=None):
|
|
return self._recv('stdout', maxsize)
|
|
|
|
def recv_err(self, maxsize=None):
|
|
return self._recv('stderr', maxsize)
|
|
|
|
def send_recv(self, input='', maxsize=None):
|
|
return self.send(input), self.recv(maxsize), self.recv_err(maxsize)
|
|
|
|
def get_conn_maxsize(self, which, maxsize):
|
|
if maxsize is None:
|
|
maxsize = 1024
|
|
elif maxsize < 1:
|
|
maxsize = 1
|
|
return getattr(self, which), maxsize
|
|
|
|
def _close(self, which):
|
|
getattr(self, which).close()
|
|
setattr(self, which, None)
|
|
|
|
if IS_WIN:
|
|
def send(self, input):
|
|
if not self.stdin:
|
|
return None
|
|
|
|
try:
|
|
x = msvcrt.get_osfhandle(self.stdin.fileno())
|
|
(_, written) = WriteFile(x, input)
|
|
except ValueError:
|
|
return self._close('stdin')
|
|
except Exception as ex:
|
|
if getattr(ex, "args", None) and ex.args[0] in (109, errno.ESHUTDOWN):
|
|
return self._close('stdin')
|
|
raise
|
|
|
|
return written
|
|
|
|
def _recv(self, which, maxsize):
|
|
conn, maxsize = self.get_conn_maxsize(which, maxsize)
|
|
if conn is None:
|
|
return None
|
|
|
|
try:
|
|
x = msvcrt.get_osfhandle(conn.fileno())
|
|
(read, nAvail, _) = PeekNamedPipe(x, 0)
|
|
if maxsize < nAvail:
|
|
nAvail = maxsize
|
|
if nAvail > 0:
|
|
(_, read) = ReadFile(x, nAvail, None)
|
|
except (ValueError, NameError):
|
|
return self._close(which)
|
|
except Exception as ex:
|
|
if getattr(ex, "args", None) and ex.args[0] in (109, errno.ESHUTDOWN):
|
|
return self._close(which)
|
|
raise
|
|
|
|
if self.universal_newlines:
|
|
read = self._translate_newlines(read)
|
|
return read
|
|
else:
|
|
def send(self, input):
|
|
if not self.stdin:
|
|
return None
|
|
|
|
if not select.select([], [self.stdin], [], 0)[1]:
|
|
return 0
|
|
|
|
try:
|
|
written = os.write(self.stdin.fileno(), input)
|
|
except OSError as ex:
|
|
if ex.args[0] == errno.EPIPE: # broken pipe
|
|
return self._close('stdin')
|
|
raise
|
|
|
|
return written
|
|
|
|
def _recv(self, which, maxsize):
|
|
conn, maxsize = self.get_conn_maxsize(which, maxsize)
|
|
if conn is None:
|
|
return None
|
|
|
|
flags = fcntl.fcntl(conn, fcntl.F_GETFL)
|
|
if not conn.closed:
|
|
fcntl.fcntl(conn, fcntl.F_SETFL, flags | os.O_NONBLOCK)
|
|
|
|
try:
|
|
if not select.select([conn], [], [], 0)[0]:
|
|
return ''
|
|
|
|
r = conn.read(maxsize)
|
|
if not r:
|
|
return self._close(which)
|
|
|
|
if self.universal_newlines:
|
|
r = self._translate_newlines(r)
|
|
return r
|
|
finally:
|
|
if not conn.closed:
|
|
fcntl.fcntl(conn, fcntl.F_SETFL, flags)
|
|
|
|
def recv_some(p, t=.1, e=1, tr=5, stderr=0):
|
|
if tr < 1:
|
|
tr = 1
|
|
x = time.time() + t
|
|
y = []
|
|
r = ''
|
|
if stderr:
|
|
pr = p.recv_err
|
|
else:
|
|
pr = p.recv
|
|
while time.time() < x or r:
|
|
r = pr()
|
|
if r is None:
|
|
break
|
|
elif r:
|
|
y.append(r)
|
|
else:
|
|
time.sleep(max((x - time.time()) / tr, 0))
|
|
return b''.join(y)
|
|
|
|
def send_all(p, data):
|
|
if not data:
|
|
return
|
|
|
|
data = getBytes(data)
|
|
|
|
while len(data):
|
|
sent = p.send(data)
|
|
if not isinstance(sent, int):
|
|
break
|
|
data = buffer(data[sent:])
|