mirror of
https://github.com/eblot/pybootd.git
synced 2024-09-11 22:17:44 +03:00
More cleanup and removing old useless stuff
This commit is contained in:
parent
d1231d55c0
commit
02c32b412c
@ -18,33 +18,8 @@
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def _get_package_name(default='', version='1.6.0'):
|
||||
try:
|
||||
from pkg_resources import WorkingSet
|
||||
except ImportError:
|
||||
ws = []
|
||||
else:
|
||||
ws = WorkingSet()
|
||||
_path, _ = os.path.split(os.path.dirname(
|
||||
sys.modules['pybootd'].__file__))
|
||||
_path = os.path.normpath(_path)
|
||||
if 'nt' not in os.name:
|
||||
for dist in ws:
|
||||
if os.path.samefile(os.path.normpath(dist.location), _path):
|
||||
return dist.project_name, dist.version
|
||||
else: # tweak for windows
|
||||
_path = os.path.abspath(_path).lower()
|
||||
for dist in ws:
|
||||
if 'pybootd' in dist.location:
|
||||
if _path == os.path.abspath(dist.location).lower():
|
||||
return dist.project_name, dist.version
|
||||
return default, version
|
||||
|
||||
|
||||
PRODUCT_NAME, __version__ = _get_package_name('pybootd')
|
||||
__version__ = '1.7.0'
|
||||
|
||||
|
||||
def pybootd_path(path):
|
||||
@ -61,9 +36,9 @@ def pybootd_path(path):
|
||||
except ImportError:
|
||||
raise IOError('pkg_resources module not available')
|
||||
try:
|
||||
newpath = resource_filename(Requirement.parse(PRODUCT_NAME), path)
|
||||
newpath = resource_filename(Requirement.parse('pybootd'), path)
|
||||
if not newpath:
|
||||
localpath = get_distribution(PRODUCT_NAME).location
|
||||
localpath = get_distribution('pybootd').location
|
||||
newpath = os.path.join(localpath, path)
|
||||
except DistributionNotFound:
|
||||
newpath = path
|
||||
|
@ -24,7 +24,7 @@
|
||||
from os.path import isfile
|
||||
from threading import Thread
|
||||
from sys import exit as sysexit, modules, stderr
|
||||
from . import pybootd_path, PRODUCT_NAME, __version__ as VERSION
|
||||
from . import pybootd_path, __version__
|
||||
from .pxed import BootpServer
|
||||
from .tftpd import TftpServer
|
||||
from .util import logger_factory, EasyConfigParser
|
||||
@ -94,7 +94,7 @@ def main():
|
||||
logfile=cfgparser.get('logger', 'file'),
|
||||
level=cfgparser.get('logger', 'level',
|
||||
'info'))
|
||||
logger.info('-'.join((PRODUCT_NAME, VERSION)))
|
||||
logger.info('-'.join(('pybootd', __version__)))
|
||||
|
||||
daemon = None
|
||||
if not args.tftp:
|
||||
|
@ -5,7 +5,8 @@ level = info
|
||||
[bootp]
|
||||
address = 0.0.0.0
|
||||
; pool_start should be in a valid subnet
|
||||
pool_start = 192.168.25.100
|
||||
; pool_start = 192.168.25.100
|
||||
pool_start = 10.113.116.245
|
||||
pool_count = 5
|
||||
domain = localdomain
|
||||
server_name = debug
|
||||
|
100
pybootd/pxed.py
100
pybootd/pxed.py
@ -17,15 +17,15 @@
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
import re
|
||||
import select
|
||||
import socket
|
||||
import string
|
||||
import struct
|
||||
import sys
|
||||
import time
|
||||
from binascii import hexlify
|
||||
from . import PRODUCT_NAME
|
||||
from re import compile as recompile
|
||||
from select import select
|
||||
from socket import (inet_aton, inet_ntoa, socket,
|
||||
AF_INET, SOCK_DGRAM, IPPROTO_UDP, SOL_SOCKET,
|
||||
SO_BROADCAST, SO_REUSEADDR)
|
||||
from struct import calcsize as scalc, pack as spack, unpack as sunpack
|
||||
from time import sleep
|
||||
from traceback import format_exc
|
||||
from .util import hexline, to_bool, iptoint, inttoip, get_iface_config
|
||||
|
||||
BOOTP_PORT_REQUEST = 67
|
||||
@ -35,9 +35,9 @@ BOOTREQUEST = 1
|
||||
BOOTREPLY = 2
|
||||
|
||||
BOOTPFORMAT = '!4bIHH4s4s4s4s16s64s128s64s'
|
||||
BOOTPFORMATSIZE = struct.calcsize(BOOTPFORMAT)
|
||||
BOOTPFORMATSIZE = scalc(BOOTPFORMAT)
|
||||
DHCPFORMAT = '!4bIHH4s4s4s4s16s64s128s4s'
|
||||
DHCPFORMATSIZE = struct.calcsize(DHCPFORMAT)
|
||||
DHCPFORMATSIZE = scalc(DHCPFORMAT)
|
||||
|
||||
(BOOTP_OP, BOOTP_HTYPE, BOOTP_HLEN, BOOTP_HOPS, BOOTP_XID, BOOTP_SECS,
|
||||
BOOTP_FLAGS, BOOTP_CIADDR, BOOTP_YIADDR, BOOTP_SIADDR, BOOTP_GIADDR,
|
||||
@ -177,9 +177,7 @@ class BootpServer:
|
||||
self.ippool = {} # key MAC address string, value assigned IP string
|
||||
self.filepool = {} # key IP string, value pathname
|
||||
self.states = {} # key MAC address string, value client state
|
||||
name_ = PRODUCT_NAME.split('-')
|
||||
name_[0] = 'bootp'
|
||||
self.bootp_section = '_'.join(name_)
|
||||
self.bootp_section = 'bootp'
|
||||
self.pool_start = self.config.get(self.bootp_section, 'pool_start')
|
||||
if not self.pool_start:
|
||||
raise BootpError('Missing pool_start definition')
|
||||
@ -236,7 +234,7 @@ class BootpServer:
|
||||
msg = ','.join([notice, uuid_str, mac_str, ip])
|
||||
else:
|
||||
msg = ','.join([notice, mac_str, ip])
|
||||
notify_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
notify_sock = socket(AF_INET, SOCK_DGRAM)
|
||||
for n in self.notify:
|
||||
self.log.info('Notifying %s with %s' % (n, msg))
|
||||
notify_sock.sendto(msg, n)
|
||||
@ -249,10 +247,9 @@ class BootpServer:
|
||||
host = self.config.get(self.bootp_section, 'address', '0.0.0.0')
|
||||
port = self.config.get(self.bootp_section, 'port',
|
||||
str(BOOTP_PORT_REQUEST))
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
|
||||
socket.IPPROTO_UDP)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
|
||||
sock.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
|
||||
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
|
||||
self.sock.append(sock)
|
||||
self.log.info('Listening to %s:%s' % (host, port))
|
||||
sock.bind((host, int(port)))
|
||||
@ -260,14 +257,13 @@ class BootpServer:
|
||||
def forever(self):
|
||||
while True:
|
||||
try:
|
||||
r, w, e = select.select(self.sock, [], self.sock)
|
||||
r, w, e = select(self.sock, [], self.sock)
|
||||
for sock in r:
|
||||
data, addr = sock.recvfrom(556)
|
||||
self.handle(sock, addr, data)
|
||||
except Exception as exc:
|
||||
import traceback
|
||||
self.log.critical('%s\n%s' % (exc, traceback.format_exc()))
|
||||
time.sleep(1)
|
||||
self.log.critical('%s\n%s' % (exc, format_exc()))
|
||||
sleep(1)
|
||||
|
||||
def parse_options(self, tail):
|
||||
self.log.debug('Parsing DHCP options')
|
||||
@ -280,7 +276,7 @@ class BootpServer:
|
||||
if tag == 0xff:
|
||||
return dhcp_tags
|
||||
length = ord(tail[1])
|
||||
(value, ) = struct.unpack('!%ss' % length, tail[2:2+length])
|
||||
(value, ) = sunpack('!%ss' % length, tail[2:2+length])
|
||||
tail = tail[2+length:]
|
||||
try:
|
||||
option = DHCP_OPTIONS[tag]
|
||||
@ -296,25 +292,25 @@ class BootpServer:
|
||||
try:
|
||||
buf = ''
|
||||
uuid = options[97]
|
||||
buf += struct.pack('!BB%ds' % len(uuid),
|
||||
buf += spack('!BB%ds' % len(uuid),
|
||||
97, len(uuid), uuid)
|
||||
clientclass = options[60]
|
||||
clientclass = clientclass[:clientclass.find(':')]
|
||||
buf += struct.pack('!BB%ds' % len(clientclass),
|
||||
buf += spack('!BB%ds' % len(clientclass),
|
||||
60, len(clientclass), clientclass)
|
||||
vendor = ''
|
||||
vendor += struct.pack('!BBB', PXE_DISCOVERY_CONTROL, 1, 0x0A)
|
||||
vendor += struct.pack('!BBHB4s', PXE_BOOT_SERVERS, 2+1+4,
|
||||
vendor += spack('!BBB', PXE_DISCOVERY_CONTROL, 1, 0x0A)
|
||||
vendor += spack('!BBHB4s', PXE_BOOT_SERVERS, 2+1+4,
|
||||
0, 1, server)
|
||||
srvstr = 'Python'
|
||||
vendor += struct.pack('!BBHB%ds' % len(srvstr), PXE_BOOT_MENU,
|
||||
vendor += spack('!BBHB%ds' % len(srvstr), PXE_BOOT_MENU,
|
||||
2+1+len(srvstr), 0, len(srvstr), srvstr)
|
||||
prompt = 'Stupid PXE'
|
||||
vendor += struct.pack('!BBB%ds' % len(prompt), PXE_MENU_PROMPT,
|
||||
vendor += spack('!BBB%ds' % len(prompt), PXE_MENU_PROMPT,
|
||||
1+len(prompt), len(prompt), prompt)
|
||||
buf += struct.pack('!BB%ds' % len(vendor), 43,
|
||||
buf += spack('!BB%ds' % len(vendor), 43,
|
||||
len(vendor), vendor)
|
||||
buf += struct.pack('!BBB', 255, 0, 0)
|
||||
buf += spack('!BBB', 255, 0, 0)
|
||||
return buf
|
||||
except KeyError as exc:
|
||||
self.log.error('Missing options, cancelling: %s' % exc)
|
||||
@ -324,7 +320,7 @@ class BootpServer:
|
||||
buf = ''
|
||||
if not clientname:
|
||||
return buf
|
||||
buf += struct.pack('!BB%ds' % len(clientname),
|
||||
buf += spack('!BB%ds' % len(clientname),
|
||||
12, len(clientname), clientname)
|
||||
return buf
|
||||
|
||||
@ -333,7 +329,7 @@ class BootpServer:
|
||||
if len(data) < DHCPFORMATSIZE:
|
||||
self.log.error('Cannot be a DHCP or BOOTP request - too small!')
|
||||
tail = data[DHCPFORMATSIZE:]
|
||||
buf = list(struct.unpack(DHCPFORMAT, data[:DHCPFORMATSIZE]))
|
||||
buf = list(sunpack(DHCPFORMAT, data[:DHCPFORMATSIZE]))
|
||||
if buf[BOOTP_OP] != BOOTREQUEST:
|
||||
self.log.warn('Not a BOOTREQUEST')
|
||||
return
|
||||
@ -477,7 +473,7 @@ class BootpServer:
|
||||
# construct reply
|
||||
buf[BOOTP_HOPS] = 0
|
||||
buf[BOOTP_OP] = BOOTREPLY
|
||||
self.log.info('Client IP: %s' % socket.inet_ntoa(buf[7]))
|
||||
self.log.info('Client IP: %s' % inet_ntoa(buf[7]))
|
||||
if buf[BOOTP_CIADDR] == '\x00\x00\x00\x00':
|
||||
self.log.debug('Client needs its address')
|
||||
ipaddr = iptoint(self.pool_start)
|
||||
@ -501,20 +497,20 @@ class BootpServer:
|
||||
self.bootp_section, 'netmask', self.netconfig['mask']))
|
||||
reply_broadcast = iptoint(ip) & mask
|
||||
reply_broadcast |= (~mask) & ((1 << 32)-1)
|
||||
buf[BOOTP_YIADDR] = socket.inet_aton(ip)
|
||||
buf[BOOTP_YIADDR] = inet_aton(ip)
|
||||
buf[BOOTP_SECS] = 0
|
||||
buf[BOOTP_FLAGS] = BOOTP_FLAGS_BROADCAST
|
||||
|
||||
relay = buf[BOOTP_GIADDR]
|
||||
if relay != b'\x00\x00\x00\x00':
|
||||
addr = (socket.inet_ntoa(relay), addr[1])
|
||||
addr = (inet_ntoa(relay), addr[1])
|
||||
else:
|
||||
addr = (inttoip(reply_broadcast), addr[1])
|
||||
self.log.info('Reply to: %s:%s' % addr)
|
||||
else:
|
||||
buf[BOOTP_YIADDR] = buf[BOOTP_CIADDR]
|
||||
ip = socket.inet_ntoa(buf[BOOTP_YIADDR])
|
||||
buf[BOOTP_SIADDR] = socket.inet_aton(server_addr)
|
||||
ip = inet_ntoa(buf[BOOTP_YIADDR])
|
||||
buf[BOOTP_SIADDR] = inet_aton(server_addr)
|
||||
# sname
|
||||
buf[BOOTP_SNAME] = \
|
||||
'.'.join([self.config.get(self.bootp_section,
|
||||
@ -567,38 +563,38 @@ class BootpServer:
|
||||
else:
|
||||
self.log.debug('No filename defined for IP %s' % ip)
|
||||
|
||||
pkt = struct.pack(DHCPFORMAT, *buf)
|
||||
pkt += struct.pack('!BBB', DHCP_MSG, 1, dhcp_reply)
|
||||
server = socket.inet_aton(server_addr)
|
||||
pkt += struct.pack('!BB4s', DHCP_SERVER, 4, server)
|
||||
pkt = spack(DHCPFORMAT, *buf)
|
||||
pkt += spack('!BBB', DHCP_MSG, 1, dhcp_reply)
|
||||
server = inet_aton(server_addr)
|
||||
pkt += spack('!BB4s', DHCP_SERVER, 4, server)
|
||||
|
||||
mask = socket.inet_aton(self.config.get(
|
||||
mask = inet_aton(self.config.get(
|
||||
self.bootp_section, 'netmask', self.netconfig['mask']))
|
||||
|
||||
pkt += struct.pack('!BB4s', DHCP_IP_MASK, 4, mask)
|
||||
pkt += spack('!BB4s', DHCP_IP_MASK, 4, mask)
|
||||
|
||||
gateway_addr = self.config.get(self.bootp_section, 'gateway', '')
|
||||
if gateway_addr:
|
||||
gateway = socket.inet_aton(gateway_addr)
|
||||
gateway = inet_aton(gateway_addr)
|
||||
else:
|
||||
gateway = server
|
||||
pkt += struct.pack('!BB4s', DHCP_IP_GATEWAY, 4, gateway)
|
||||
pkt += spack('!BB4s', DHCP_IP_GATEWAY, 4, gateway)
|
||||
|
||||
dns = self.config.get(self.bootp_section,
|
||||
'dns', None)
|
||||
if dns:
|
||||
if dns.lower() == 'auto':
|
||||
dns_list = self.get_dns_servers() or [socket.inet_ntoa(server)]
|
||||
dns_list = self.get_dns_servers() or [inet_ntoa(server)]
|
||||
else:
|
||||
dns_list = dns.split(';')
|
||||
for dns_str in dns_list:
|
||||
dns_ip = socket.inet_aton(dns_str)
|
||||
pkt += struct.pack('!BB4s', DHCP_IP_DNS, 4, dns_ip)
|
||||
pkt += struct.pack('!BBI', DHCP_LEASE_TIME, 4,
|
||||
dns_ip = inet_aton(dns_str)
|
||||
pkt += spack('!BB4s', DHCP_IP_DNS, 4, dns_ip)
|
||||
pkt += spack('!BBI', DHCP_LEASE_TIME, 4,
|
||||
int(self.config.get(self.bootp_section,
|
||||
'lease_time',
|
||||
str(24*3600))))
|
||||
pkt += struct.pack('!BB', DHCP_END, 0)
|
||||
pkt += spack('!BB', DHCP_END, 0)
|
||||
|
||||
# do not attempt to produce a PXE-augmented response for
|
||||
# regular DHCP requests
|
||||
@ -623,7 +619,7 @@ class BootpServer:
|
||||
self.states[mac_str] = newstate
|
||||
|
||||
def get_dns_servers(self):
|
||||
nscre = re.compile(r'nameserver\s+(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\s')
|
||||
nscre = recompile(r'nameserver\s+(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\s')
|
||||
result = []
|
||||
try:
|
||||
with open('/etc/resolv.conf', 'r') as resolv:
|
||||
|
@ -18,22 +18,21 @@
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
import os
|
||||
import re
|
||||
import select
|
||||
import socket
|
||||
import string
|
||||
import struct
|
||||
import sys
|
||||
import time
|
||||
from configparser import NoSectionError
|
||||
from io import StringIO
|
||||
from re import compile as recompile, sub as resub
|
||||
from select import select
|
||||
from socket import socket, AF_INET, SOCK_DGRAM
|
||||
from struct import pack as spack, unpack as sunpack
|
||||
from sys import argv, exc_info
|
||||
from threading import Thread
|
||||
from time import time as now
|
||||
from traceback import print_exc
|
||||
from urllib.parse import urlparse
|
||||
from urllib.request import urlopen
|
||||
from . import pybootd_path
|
||||
from .util import hexline
|
||||
|
||||
__all__ = ['TftpServer']
|
||||
|
||||
TFTP_PORT = 69
|
||||
|
||||
@ -86,7 +85,7 @@ class TftpConnection(object):
|
||||
timeout = self.timeout
|
||||
retry = self.server.retry
|
||||
while retry:
|
||||
r, w, e = select.select([fno], [], [fno], timeout)
|
||||
r, w, e = select([fno], [], [fno], timeout)
|
||||
if not r:
|
||||
# We timed out -- retransmit
|
||||
retry = retry - 1
|
||||
@ -121,13 +120,13 @@ class TftpConnection(object):
|
||||
path = self.server.bootpd.get_filename(client_ip)
|
||||
return path
|
||||
|
||||
def parse(self, data, unpack=struct.unpack):
|
||||
def parse(self, data, unpack=sunpack):
|
||||
self.log.debug('parse')
|
||||
buf = buffer(data)
|
||||
pkt = {}
|
||||
opcode = pkt['opcode'] = unpack('!h', buf[:2])[0]
|
||||
if (opcode == self.RRQ) or (opcode == self.WRQ):
|
||||
resource, mode, options = string.split(data[2:], '\000', 2)
|
||||
resource, mode, options = data[2:].split('\000', 2)
|
||||
resource = self.server.fcre.sub(self._filter_file, resource)
|
||||
if self.server.root and self.is_url(self.server.root):
|
||||
resource = '%s/%s' % (self.server.root, resource)
|
||||
@ -138,7 +137,7 @@ class TftpConnection(object):
|
||||
if not self.server.genfilecre.match(resource):
|
||||
if resource.startswith('^%s' % os.sep):
|
||||
resource = os.path.join(
|
||||
os.path.dirname(sys.argv[0]),
|
||||
os.path.dirname(argv[0]),
|
||||
resource.lstrip('^%s' % os.sep))
|
||||
elif self.server.root:
|
||||
if self.server.root.startswith(os.sep):
|
||||
@ -147,7 +146,7 @@ class TftpConnection(object):
|
||||
resource)
|
||||
else:
|
||||
# Relative root directory, from the daemon path
|
||||
daemonpath = os.path.dirname(sys.argv[0])
|
||||
daemonpath = os.path.dirname(argv[0])
|
||||
if not daemonpath.startswith(os.sep):
|
||||
daemonpath = os.path.normpath(
|
||||
os.path.join(os.getcwd(), daemonpath))
|
||||
@ -220,8 +219,7 @@ class TftpConnection(object):
|
||||
except TftpError as exc:
|
||||
self.send_error(exc[0], exc[1])
|
||||
except:
|
||||
import traceback
|
||||
self.log.error(traceback.format_exc())
|
||||
self.log.error(format_exc())
|
||||
self.log.debug('Ending connection %s:%s' % addr)
|
||||
|
||||
def recv_ack(self, pkt):
|
||||
@ -245,19 +243,19 @@ class TftpConnection(object):
|
||||
self.handle_err(pkt)
|
||||
self.retransmit()
|
||||
|
||||
def send_data(self, data, pack=struct.pack):
|
||||
def send_data(self, data, pack=spack):
|
||||
self.log.debug('send_data')
|
||||
if not self.time:
|
||||
self.time = time.time()
|
||||
self.time = now()
|
||||
blocksize = self.blocksize
|
||||
block = self.blockNumber = self.blockNumber + 1
|
||||
lendata = len(data)
|
||||
format = '!hh%ds' % lendata
|
||||
pkt = pack(format, self.DATA, block, data)
|
||||
fmt = '!hh%ds' % lendata
|
||||
pkt = pack(fmt, self.DATA, block, data)
|
||||
self.send(pkt)
|
||||
self.active = (len(data) == blocksize)
|
||||
if not self.active and self.time:
|
||||
total = time.time()-self.time
|
||||
total = now()-self.time
|
||||
self.time = 0
|
||||
try:
|
||||
name = self.file.name
|
||||
@ -271,26 +269,24 @@ class TftpConnection(object):
|
||||
# StringIO does not have a 'name' attribute
|
||||
pass
|
||||
except Exception:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
pass
|
||||
print_exc()
|
||||
|
||||
def send_ack(self, pack=struct.pack):
|
||||
def send_ack(self, pack=spack):
|
||||
self.log.debug('send_ack')
|
||||
block = self.blockNumber
|
||||
self.blockNumber = self.blockNumber + 1
|
||||
format = '!hh'
|
||||
pkt = pack(format, self.ACK, block)
|
||||
fmt = '!hh'
|
||||
pkt = pack(fmt, self.ACK, block)
|
||||
self.send(pkt)
|
||||
|
||||
def send_error(self, errnum, errtext, pack=struct.pack):
|
||||
def send_error(self, errnum, errtext, pack=spack):
|
||||
self.log.debug('send_error')
|
||||
errtext = errtext + '\000'
|
||||
format = '!hh%ds' % len(errtext)
|
||||
outdata = pack(format, self.ERR, errnum, errtext)
|
||||
fmt = '!hh%ds' % len(errtext)
|
||||
outdata = pack(fmt, self.ERR, errnum, errtext)
|
||||
self.sock.sendto(outdata, self.client_addr)
|
||||
|
||||
def send_oack(self, options, pack=struct.pack):
|
||||
def send_oack(self, options, pack=spack):
|
||||
self.log.debug('send_oack')
|
||||
pkt = pack('!h', self.OACK)
|
||||
for k, v in options:
|
||||
@ -341,7 +337,7 @@ class TftpConnection(object):
|
||||
except Exception:
|
||||
self.send_error(1, 'Cannot open resource')
|
||||
self.log.warn('Cannot open file for reading %s: %s' %
|
||||
sys.exc_info()[:2])
|
||||
exc_info()[:2])
|
||||
return
|
||||
if 'tsize' not in pkt:
|
||||
self.send_data(self.file.read(self.blocksize))
|
||||
@ -359,7 +355,7 @@ class TftpConnection(object):
|
||||
except:
|
||||
self.send_error(1, 'Cannot open file')
|
||||
self.log.error('Cannot open file for writing %s: %s' %
|
||||
sys.exc_info()[:2])
|
||||
exc_info()[:2])
|
||||
return
|
||||
self.send_ack()
|
||||
|
||||
@ -398,7 +394,7 @@ class TftpServer:
|
||||
self.retry = int(self.config.get('tftp', 'blocksize', '5'))
|
||||
self.root = self.config.get('tftp', 'root', os.getcwd())
|
||||
self.fcre, self.filepatterns = self.get_file_filters()
|
||||
self.genfilecre = re.compile(r'\[(?P<name>[\w\.\-]+)\]')
|
||||
self.genfilecre = recompile(r'\[(?P<name>[\w\.\-]+)\]')
|
||||
|
||||
def bind(self):
|
||||
netconfig = self.bootpd and self.bootpd.get_netconfig()
|
||||
@ -407,7 +403,7 @@ class TftpServer:
|
||||
if not host:
|
||||
raise TftpError('TFTP address no defined')
|
||||
port = int(self.config.get('tftp', 'port', str(TFTP_PORT)))
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
sock = socket(AF_INET, SOCK_DGRAM)
|
||||
self.sock.append(sock)
|
||||
sock.bind((host, port))
|
||||
|
||||
@ -417,7 +413,7 @@ class TftpServer:
|
||||
if not self.bootpd.is_alive():
|
||||
self.log.info('Bootp daemon is dead, exiting')
|
||||
break
|
||||
r, w, e = select.select(self.sock, [], self.sock)
|
||||
r, w, e = select(self.sock, [], self.sock)
|
||||
for sock in r:
|
||||
data, addr = sock.recvfrom(516)
|
||||
tc = TftpConnection(self)
|
||||
@ -433,7 +429,7 @@ class TftpServer:
|
||||
if not filename:
|
||||
continue
|
||||
filepattern = self.filepatterns[group]
|
||||
return re.sub(r'\{(\w+)\}', connexion._dynreplace, filepattern)
|
||||
return resub(r'\{(\w+)\}', connexion._dynreplace, filepattern)
|
||||
raise TftpError('Internal error, file matching pattern issue')
|
||||
|
||||
def get_file_filters(self):
|
||||
@ -451,4 +447,4 @@ class TftpServer:
|
||||
xre = r'^(?:\./)?(?:%s)$' % r'|'.join(patterns)
|
||||
except NoSectionError:
|
||||
xre = r'^$'
|
||||
return (re.compile(xre), replacements)
|
||||
return (recompile(xre), replacements)
|
||||
|
@ -17,7 +17,6 @@
|
||||
# License along with this library; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
from array import array
|
||||
from configparser import SafeConfigParser, InterpolationSyntaxError
|
||||
from logging import (DEBUG, INFO, ERROR, CRITICAL, WARNING,
|
||||
Formatter, FileHandler, StreamHandler, getLogger)
|
||||
@ -29,7 +28,6 @@ from subprocess import run
|
||||
from struct import pack as spack, unpack as sunpack
|
||||
from sys import stderr
|
||||
|
||||
|
||||
try:
|
||||
import netifaces
|
||||
except ImportError:
|
||||
@ -112,7 +110,7 @@ def hexline(data, sep=' '):
|
||||
of the buffer data
|
||||
"""
|
||||
try:
|
||||
if isinstance(data, (bytes, array)):
|
||||
if isinstance(data, bytes):
|
||||
src = bytearray(data)
|
||||
elif isinstance(data, bytearray):
|
||||
src = data
|
||||
|
Loading…
Reference in New Issue
Block a user