1
1
mirror of https://github.com/eblot/pybootd.git synced 2024-09-11 14:06:57 +03:00

Add support for remote file size evaluation

This commit is contained in:
Emmanuel Blot 2020-04-12 18:31:23 +02:00
parent 45f79fc53f
commit d284d5bfce

View File

@ -42,7 +42,7 @@ from time import sleep
from traceback import format_exc from traceback import format_exc
from typing import Optional from typing import Optional
from urllib.error import HTTPError, URLError from urllib.error import HTTPError, URLError
from urllib.parse import urlencode, urlunsplit from urllib.parse import urlencode, urlsplit, urlunsplit
from urllib.request import urlopen from urllib.request import urlopen
from netifaces import ifaddresses, interfaces from netifaces import ifaddresses, interfaces
from .tftpd import TftpServer from .tftpd import TftpServer
@ -295,8 +295,8 @@ class BootpServer:
# Public # Public
@classmethod @staticmethod
def find_interface(cls, address: str) -> Optional[str]: def find_interface(address: str) -> Optional[str]:
iaddress = sunpack('!I', inet_aton(address))[0] iaddress = sunpack('!I', inet_aton(address))[0]
for iface in interfaces(): for iface in interfaces():
for confs in ifaddresses(iface).values(): for confs in ifaddresses(iface).values():
@ -315,6 +315,10 @@ class BootpServer:
return iface return iface
return None return None
@staticmethod
def is_url(path):
return bool(urlsplit(path).scheme)
def get_netconfig(self): def get_netconfig(self):
return self.netconfig return self.netconfig
@ -401,16 +405,27 @@ class BootpServer:
buf += spack('!BB%ds' % len(uuid), buf += spack('!BB%ds' % len(uuid),
97, len(uuid), uuid) 97, len(uuid), uuid)
if 13 in client_params: if 13 in client_params:
bootfile_size = 0
path = self.config.get(TftpServer.TFTP_SECTION, 'root', '') path = self.config.get(TftpServer.TFTP_SECTION, 'root', '')
pathname = realpath(joinpath(path, bootfile_name = bootp_buf[BOOTP_FILE].decode()
bootp_buf[BOOTP_FILE].decode())) if not self.is_url(path):
try: pathname = realpath(joinpath(path,bootfile_name))
bootfile_size = stat(pathname).st_size try:
except OSError as exc: bootfile_size = stat(pathname).st_size
self.log.error('Cannot get size of %s: %s', pathname, exc) except OSError as exc:
self.log.error('Cannot get size of %s: %s',
pathname, exc)
else: else:
bootfile_block = (bootfile_size+511)//512 url = joinpath(path, bootp_buf[BOOTP_FILE].decode())
buf += spack('!BBH', 13, scalc('!H'), bootfile_block) try:
resource = urlopen(url)
int(resource.info()['Content-Length'])
except Exception as exc:
self.log.error('Cannot retrieve size of %s: %s',
url, exc)
if bootfile_size:
bootfile_block = (bootfile_size+511)//512
buf += spack('!BBH', 13, scalc('!H'), bootfile_block)
if 60 in client_params: if 60 in client_params:
clientclass = options[60] clientclass = options[60]
clientclass = clientclass[:clientclass.find(b':')] clientclass = clientclass[:clientclass.find(b':')]