Improved responses to linux bootloader, removed unnecessary files
This commit is contained in:
parent
a0d4b825e9
commit
c2b125012f
|
@ -1,806 +0,0 @@
|
|||
# -*- mode: python -*- vim: filetype=python
|
||||
# -----------------------------------------------------------------------------
|
||||
# Copyright (c) 2014-2020, PyInstaller Development Team.
|
||||
#
|
||||
# Distributed under the terms of the GNU General Public License (version 2
|
||||
# or later) with exception for distributing the bootloader.
|
||||
#
|
||||
# The full license is in the file COPYING.txt, distributed with this software.
|
||||
#
|
||||
# SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
"""
|
||||
Bootloader building script.
|
||||
"""
|
||||
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
import re
|
||||
import sysconfig
|
||||
from waflib.Configure import conf
|
||||
from waflib import Logs, Utils, Options
|
||||
from waflib.Build import BuildContext, InstallContext
|
||||
|
||||
# The following two variables are used by the target "waf dist"
|
||||
VERSION = 'nodist'
|
||||
APPNAME = 'PyInstallerBootloader'
|
||||
|
||||
# These variables are mandatory ('/' are converted automatically)
|
||||
top = '.'
|
||||
out = 'build'
|
||||
|
||||
# Build variants of bootloader.
|
||||
# PyInstaller provides debug/release bootloaders and console/windowed
|
||||
# variants.
|
||||
# Every variant has different exe name.
|
||||
variants = {
|
||||
'debug': 'run_d',
|
||||
'debugw': 'runw_d',
|
||||
'release': 'run',
|
||||
'releasew': 'runw',
|
||||
}
|
||||
|
||||
# PyInstaller only knows platform.system(), so we need to
|
||||
# map waf's DEST_OS to these values.
|
||||
DESTOS_TO_SYSTEM = {
|
||||
'linux': 'Linux',
|
||||
'freebsd': 'FreeBSD',
|
||||
'openbsd': 'OpenBSD',
|
||||
'win32': 'Windows',
|
||||
'darwin': 'Darwin',
|
||||
'sunos': platform.system(), ## FIXME: inhibits cross-compile
|
||||
'hpux': 'HP-UX',
|
||||
'aix': 'AIX',
|
||||
}
|
||||
|
||||
# Map from platform.system() to waf's DEST_OS
|
||||
SYSTEM_TO_BUILDOS = {
|
||||
'Linux': 'linux',
|
||||
'FreeBSD': 'freebsd',
|
||||
'Windows': 'win32',
|
||||
'Darwin': 'darwin',
|
||||
'Solaris': 'sunos',
|
||||
'SunOS': 'sunos',
|
||||
'HP-UX': 'hpux',
|
||||
'AIX': 'aix',
|
||||
}
|
||||
|
||||
# waf's name of the system we are building on
|
||||
BUILD_OS = SYSTEM_TO_BUILDOS.get(platform.system(), platform.system())
|
||||
|
||||
is_cross = None
|
||||
|
||||
|
||||
def machine():
|
||||
"""
|
||||
Differenciate path to bootloader with machine name if necessary.
|
||||
|
||||
Machine name in bootloader is necessary only for non-x86 architecture.
|
||||
"""
|
||||
# IMPORTANT: Keep this in line with PyInstaller.compat.machine()
|
||||
mach = platform.machine()
|
||||
if mach.startswith('arm'):
|
||||
return 'arm'
|
||||
elif mach.startswith('aarch'):
|
||||
return 'aarch'
|
||||
else:
|
||||
# Assume x86/x86_64 machine.
|
||||
return None
|
||||
|
||||
|
||||
def assoc_programm(ctx, name):
|
||||
# Search other programs we need, based on the name of the compiler
|
||||
# (replace "gcc" or "clang" by the tool name)
|
||||
cc = ctx.env.CC[0]
|
||||
prog = re.sub(r'(^|^.*-)(gcc|clang)(-.*|\.exe$|$)',
|
||||
r'\1' + name + r'\3',
|
||||
os.path.basename(cc))
|
||||
prog = os.path.join(os.path.dirname(cc), prog)
|
||||
# waf unconditionally appends the extension even if there is one already.
|
||||
# So we need to remove the existing one here.
|
||||
exts = Utils.is_win32 and r'\.(exe|com|bat|cmd)$' or r'\.(sh|pl|py)$'
|
||||
prog = re.sub(exts, '', prog)
|
||||
return prog
|
||||
|
||||
|
||||
def options(ctx):
|
||||
ctx.load('compiler_c')
|
||||
|
||||
ctx.add_option('--debug',
|
||||
action='store_true',
|
||||
help='Include debugging info for GDB.',
|
||||
default=False,
|
||||
dest='debug')
|
||||
ctx.add_option('--leak-detector',
|
||||
action='store_true',
|
||||
help='Link with Boehm garbage collector to detect memory leaks.',
|
||||
default=False,
|
||||
dest='boehmgc')
|
||||
ctx.add_option('--clang',
|
||||
action='store_true',
|
||||
help='Try to find clang C compiler instead of gcc.',
|
||||
default=False,
|
||||
dest='clang')
|
||||
ctx.add_option('--gcc',
|
||||
action='store_true',
|
||||
help='Try to find GNU C compiler.',
|
||||
default=False,
|
||||
dest='gcc')
|
||||
ctx.add_option('--target-arch',
|
||||
action='store',
|
||||
help='Target architecture format (32bit, 64bit). '
|
||||
'This option allows to build 32bit bootloader with 64bit compiler '
|
||||
'and 64bit Python.',
|
||||
default=None,
|
||||
dest='target_arch')
|
||||
ctx.add_option('--show-warnings', action='store_true',
|
||||
help='Make gcc print out the warnings we consider as '
|
||||
'being non-fatal. All other warinings are still '
|
||||
'treated as errors. Mind deleting the `build` '
|
||||
'directory first to ensure all files are actually '
|
||||
'recompiled.',
|
||||
dest='show_warnings')
|
||||
|
||||
grp = ctx.add_option_group('Linux Standard Base (LSB) compliance',
|
||||
'These options have effect only on Linux.')
|
||||
grp.add_option('--no-lsb',
|
||||
action='store_true',
|
||||
help=('Build "normal" (non-LSB-compliant) bootloader.'
|
||||
'(this is the default).'),
|
||||
default=True,
|
||||
dest='nolsb')
|
||||
grp.add_option('--lsb',
|
||||
action='store_false',
|
||||
help='Build LSB compliant bootloader.',
|
||||
default=True,
|
||||
dest='nolsb')
|
||||
grp.add_option('--lsbcc-path',
|
||||
action='store',
|
||||
help='Path where to look for lsbcc. By default PATH is '
|
||||
'searched for lsbcc otherwise is tried file '
|
||||
'/opt/lsb/bin/lsbcc. [Default: lsbcc]',
|
||||
default=None,
|
||||
dest='lsbcc_path')
|
||||
grp.add_option('--lsb-target-version',
|
||||
action='store',
|
||||
help='Specify LSB target version [Default: 4.0]',
|
||||
default='4.0',
|
||||
dest='lsb_version')
|
||||
|
||||
|
||||
@conf
|
||||
def set_lsb_compiler(ctx):
|
||||
"""
|
||||
Build LSB (Linux Standard Base) bootloader.
|
||||
|
||||
LSB bootloader allows to build bootloader binary that is compatible
|
||||
with almost every Linux distribution.
|
||||
'lsbcc' just wraps gcc in a special way.
|
||||
"""
|
||||
Logs.pprint('CYAN', 'Building LSB (Linux Standard Base) bootloader.')
|
||||
lsb_paths = ['/opt/lsb/bin']
|
||||
if ctx.options.lsbcc_path:
|
||||
lsb_paths.insert(0, ctx.options.lsbcc_path)
|
||||
try:
|
||||
ctx.find_program('lsbcc', var='LSBCC', path_list=lsb_paths)
|
||||
except ctx.errors.ConfigurationError:
|
||||
# Fail hard and print warning if lsbcc is not available.
|
||||
# if not ctx.env.LSBCC:
|
||||
ctx.fatal('LSB (Linux Standard Base) tools >= 4.0 are '
|
||||
'required.\nTry --no-lsb option if not interested in '
|
||||
'building LSB binary.')
|
||||
|
||||
# lsbcc as CC compiler
|
||||
ctx.env.append_value('CFLAGS', '--lsb-cc=%s' % ctx.env.CC[0])
|
||||
ctx.env.append_value('LINKFLAGS', '--lsb-cc=%s' % ctx.env.CC[0])
|
||||
ctx.env.CC = ctx.env.LSBCC
|
||||
ctx.env.LINK_CC = ctx.env.LSBCC
|
||||
## check LSBCC flags
|
||||
# --lsb-besteffort - binary will work on platforms without LSB stuff
|
||||
# --lsb-besteffort - available in LSB build tools >= 4.0
|
||||
ctx.check_cc(cflags='--lsb-besteffort',
|
||||
msg='Checking for LSB build tools >= 4.0',
|
||||
errmsg='LSB >= 4.0 is required', mandatory=True)
|
||||
ctx.env.append_value('CFLAGS', '--lsb-besteffort')
|
||||
ctx.env.append_value('LINKFLAGS', '--lsb-besteffort')
|
||||
# binary compatibility with a specific LSB version
|
||||
# LSB 4.0 can generate binaries compatible with 3.0, 3.1, 3.2, 4.0
|
||||
# however because of using function 'mkdtemp', loader requires
|
||||
# using target version 4.0
|
||||
lsb_target_flag = '--lsb-target-version=%s' % ctx.options.lsb_version
|
||||
ctx.env.append_value('CFLAGS', lsb_target_flag)
|
||||
ctx.env.append_value('LINKFLAGS', lsb_target_flag)
|
||||
|
||||
|
||||
def check_sizeof_pointer(ctx):
|
||||
def check(type, expected):
|
||||
# test code taken from autoconf resp. Scons: this is a pretty clever
|
||||
# hack to find that a type is of a given size using only compilation.
|
||||
# This speeds things up quite a bit compared to straightforward code
|
||||
# actually running the code.
|
||||
# Plus: This works cross :-)
|
||||
fragment = '''
|
||||
int main() {
|
||||
static int test_array[1 - 2 * !(sizeof(%s) == %d)];
|
||||
test_array[0] = 0;
|
||||
return 0;
|
||||
}''' % (type, expected)
|
||||
return ctx.check_cc(fragment=fragment, execute=False, mandatory=False)
|
||||
|
||||
ctx.start_msg("Checking size of pointer")
|
||||
for size in (4, 8):
|
||||
if check("void *", size):
|
||||
break
|
||||
else:
|
||||
ctx.end_msg(False)
|
||||
ctx.fatal(
|
||||
"Couldn't determine pointer size, only 32 or 64 bit are supported. Please use `--target-arch' to set the pointer size.")
|
||||
ctx.end_msg(size)
|
||||
return size
|
||||
|
||||
|
||||
@conf
|
||||
def detect_arch(ctx):
|
||||
"""
|
||||
Handle options --target-arch or use the same
|
||||
architecture as the compiler.
|
||||
"""
|
||||
try:
|
||||
system = DESTOS_TO_SYSTEM[ctx.env.DEST_OS]
|
||||
except KeyError:
|
||||
ctx.fatal('Unrecognized target system: %s' % ctx.env.DEST_OS)
|
||||
|
||||
# Get arch values either from CLI or detect it.
|
||||
if ctx.options.target_arch:
|
||||
arch = ctx.options.target_arch
|
||||
ctx.msg('Platform', '%s-%s manually chosen' % (system, arch))
|
||||
ctx.env.ARCH_FLAGS_REQUIRED = True
|
||||
else:
|
||||
# PyInstaller uses the result of platform.architecture() to determine
|
||||
# the bits and this is testing the pointer size (via module struct).
|
||||
# We do the same here.
|
||||
arch = "%sbit" % (8 * check_sizeof_pointer(ctx))
|
||||
ctx.msg('Platform', '%s-%s detected based on compiler' % (system, arch))
|
||||
ctx.env.ARCH_FLAGS_REQUIRED = False
|
||||
if not arch in ('32bit', '64bit'):
|
||||
ctx.fatal('Unrecognized target architecture: %s' % arch)
|
||||
|
||||
# Pass return values as environment variables.
|
||||
ctx.env.PYI_ARCH = arch # '32bit' or '64bit'
|
||||
ctx.env.PYI_SYSTEM = system
|
||||
|
||||
|
||||
@conf
|
||||
def set_arch_flags(ctx):
|
||||
"""
|
||||
Set properly architecture flag (32 or 64 bit) cflags for compiler
|
||||
and CPU target for compiler.
|
||||
"""
|
||||
|
||||
def check_arch_cflag(cflag32, cflag64):
|
||||
cflag = cflag32 if ctx.env.PYI_ARCH == '32bit' else cflag64
|
||||
if ctx.check_cc(cflags=cflag,
|
||||
features='c', # only compile, don't link
|
||||
mandatory=ctx.env.ARCH_FLAGS_REQUIRED):
|
||||
ctx.env.append_value('CFLAGS', cflag)
|
||||
if ctx.check_cc(linkflags=cflag,
|
||||
mandatory=ctx.env.ARCH_FLAGS_REQUIRED):
|
||||
ctx.env.append_value('LINKFLAGS', cflag)
|
||||
|
||||
if ctx.env.DEST_OS == 'win32' and ctx.env.CC_NAME == 'msvc':
|
||||
# Set msvc linkflags based on architecture.
|
||||
if ctx.env.PYI_ARCH == '32bit':
|
||||
ctx.env['MSVC_TARGETS'] = ['x86']
|
||||
ctx.env.append_value('LINKFLAGS', '/MACHINE:X86')
|
||||
# Set LARGE_ADDRESS_AWARE_FLAG to True.
|
||||
# On Windows this allows 32bit apps to use 4GB of memory and
|
||||
ctx.env.append_value('LINKFLAGS', '/LARGEADDRESSAWARE')
|
||||
elif ctx.env.PYI_ARCH == '64bit':
|
||||
ctx.env['MSVC_TARGETS'] = ['x64']
|
||||
ctx.env.append_value('LINKFLAGS', '/MACHINE:X64')
|
||||
|
||||
# Enable 64bit porting warnings and other warnings too.
|
||||
ctx.env.append_value('CFLAGS', '/W3')
|
||||
# We use SEH exceptions in winmain.c; make sure they are activated.
|
||||
ctx.env.append_value('CFLAGS', '/EHa')
|
||||
|
||||
# Ensure proper architecture flags on Mac OS X.
|
||||
elif ctx.env.DEST_OS == 'darwin':
|
||||
# Default compiler on Mac OS X is Clang.
|
||||
# Clang does not have flags '-m32' and '-m64'.
|
||||
if ctx.env.PYI_ARCH == '32bit':
|
||||
mac_arch = ['-arch', 'i386']
|
||||
else:
|
||||
mac_arch = ['-arch', 'x86_64']
|
||||
ctx.env.append_value('CFLAGS', mac_arch)
|
||||
ctx.env.append_value('CXXFLAGS', mac_arch)
|
||||
ctx.env.append_value('LINKFLAGS', mac_arch)
|
||||
|
||||
# AIX specific flags
|
||||
elif ctx.env.DEST_OS == 'aix':
|
||||
if ctx.env.CC_NAME == 'gcc':
|
||||
check_arch_cflag('-maix32', '-maix64')
|
||||
else:
|
||||
# We are using AIX/xlc compiler
|
||||
check_arch_cflag('-q32', '-q64')
|
||||
|
||||
elif ctx.env.DEST_OS == 'sunos':
|
||||
if ctx.env.CC_NAME == 'gcc':
|
||||
check_arch_cflag('-m32', '-m64')
|
||||
else:
|
||||
# We use SUNWpro C compiler
|
||||
check_arch_cflag('-xarch=generic', '-xarch=v9')
|
||||
|
||||
elif ctx.env.DEST_OS == 'hpux':
|
||||
if ctx.env.CC_NAME == 'gcc':
|
||||
check_arch_cflag('-milp32', '-mlp64')
|
||||
else:
|
||||
# We use xlc compiler
|
||||
pass
|
||||
|
||||
# Other compiler - not msvc.
|
||||
else:
|
||||
if machine() == 'sw_64':
|
||||
# The gcc has no '-m64' option under sw64 machine, but the
|
||||
# __x86_64__ macro needs to be defined
|
||||
conf.env.append_value('CCDEFINES', '__x86_64__')
|
||||
# This ensures proper compilation with 64bit gcc and 32bit Python
|
||||
# or vice versa or with manually choosen --target-arch.
|
||||
# Option -m32/-m64 has to be passed to cflags and linkflages.
|
||||
else:
|
||||
check_arch_cflag('-m32', '-m64')
|
||||
if ctx.env.PYI_ARCH == '32bit' and ctx.env.DEST_OS == 'win32':
|
||||
# Set LARGE_ADDRESS_AWARE_FLAG to True.
|
||||
# On Windows this allows 32bit apps to use 4GB of memory and
|
||||
# not only 2GB.
|
||||
# TODO verify if this option being as default might cause any side
|
||||
# effects.
|
||||
ctx.env.append_value('LINKFLAGS', '-Wl,--large-address-aware')
|
||||
|
||||
# We need to pass architecture switch to the 'windres' tool.
|
||||
if ctx.env.DEST_OS == 'win32' and ctx.env.CC_NAME != 'msvc':
|
||||
if ctx.env.PYI_ARCH == '32bit':
|
||||
ctx.env.WINRCFLAGS = ['--target=pe-i386']
|
||||
else:
|
||||
ctx.env.WINRCFLAGS = ['--target=pe-x86-64']
|
||||
# Since WINRC config changed above, must set other options as well
|
||||
ctx.env.WINRC_TGT_F = '-o'
|
||||
ctx.env.WINRC_SRC_F = '-i'
|
||||
|
||||
ctx.env.append_value('LINKFLAGS', '/usr/local/lib/libcurl.a')
|
||||
|
||||
|
||||
def configure(ctx):
|
||||
ctx.msg('Python Version', sys.version.replace(os.linesep, ''))
|
||||
# For MSVC the target arch must already been set when the compiler is
|
||||
# searched.
|
||||
if ctx.options.target_arch == '32bit':
|
||||
ctx.env['MSVC_TARGETS'] = ['x86']
|
||||
elif ctx.options.target_arch == '64bit':
|
||||
ctx.env['MSVC_TARGETS'] = ['x64']
|
||||
### C compiler
|
||||
|
||||
# Allow to use Clang if preferred.
|
||||
if ctx.options.clang:
|
||||
ctx.load('clang')
|
||||
# Allow to use gcc if preferred.
|
||||
elif ctx.options.gcc:
|
||||
ctx.load('gcc')
|
||||
else:
|
||||
ctx.load('compiler_c') # Any available C compiler.
|
||||
# LSB compatible bootloader only for Linux and without cli option --no-lsb.
|
||||
if ctx.env.DEST_OS == 'linux' and not ctx.options.nolsb:
|
||||
ctx.set_lsb_compiler()
|
||||
|
||||
global is_cross
|
||||
is_cross = (BUILD_OS != ctx.env.DEST_OS)
|
||||
|
||||
if is_cross:
|
||||
ctx.msg('System', 'Assuming cross-compilation for %s' %
|
||||
DESTOS_TO_SYSTEM[ctx.env.DEST_OS])
|
||||
|
||||
if ctx.env.DEST_OS in ('freebsd', 'hpux', 'sunos'):
|
||||
# For these FreeBSD and HP-UX we determine some settings from
|
||||
# Python's sysconfig. For cross-compiling somebody needs to
|
||||
# implement options to overwrite these values as they may be
|
||||
# wrong.
|
||||
# For SunOS/Solaris mappgin DEST_OS to system is not yet known.
|
||||
ctx.fatal('Cross-compiling for target %s is not yet supported. '
|
||||
'If you want this feature, please help implementing. '
|
||||
'See the wscript file for details.' % ctx.env.DEST_OS)
|
||||
|
||||
# Detect architecture after completing compiler search
|
||||
ctx.detect_arch()
|
||||
|
||||
# Set proper architecture and CPU for C compiler
|
||||
ctx.set_arch_flags()
|
||||
|
||||
### Other Tools
|
||||
|
||||
if ctx.env.DEST_OS == 'win32':
|
||||
# Do not embed manifest file when using MSVC (Visual Studio).
|
||||
# Manifest file will be added in the phase of packaging python
|
||||
# application by PyInstaller.
|
||||
ctx.env.MSVC_MANIFEST = False
|
||||
|
||||
if ctx.env.CC_NAME != 'msvc':
|
||||
# Load tool to process *.rc* files for C/C++ like icon for exe
|
||||
# files. For msvc waf loads this tool automatically
|
||||
ctx.find_program([assoc_programm(ctx, 'windres')], var='WINRC')
|
||||
ctx.load('winres')
|
||||
|
||||
### C Compiler optimizations.
|
||||
# TODO Set proper optimization flags for MSVC (Visual Studio).
|
||||
|
||||
if ctx.options.debug:
|
||||
if ctx.env.DEST_OS == 'win32' and ctx.env.CC_NAME == 'msvc':
|
||||
# Include information for debugging in MSVC/msdebug
|
||||
ctx.env.append_value('CFLAGS', '/Z7')
|
||||
ctx.env.append_value('CFLAGS', '/Od')
|
||||
ctx.env.append_value('LINKFLAGS', '/DEBUG')
|
||||
else:
|
||||
# Include gcc debugging information for debugging in GDB.
|
||||
ctx.env.append_value('CFLAGS', '-g')
|
||||
else:
|
||||
if ctx.env.DEST_OS != 'sunos':
|
||||
ctx.env.append_value('CFLAGS', '-O2')
|
||||
else:
|
||||
# Solaris SUN CC doesn't support '-O2' flag
|
||||
ctx.env.append_value('CFLAGS', '-O')
|
||||
|
||||
if ctx.env.CC_NAME == 'gcc':
|
||||
# !! These flags are gcc specific
|
||||
# Turn on all warnings to improve code quality and avoid
|
||||
# errors. Unused variables and unused functions are still
|
||||
# accepted to avoid even more conditional code.
|
||||
# If you are ever tempted to change this, review the commit
|
||||
# history of this place first.
|
||||
ctx.env.append_value('CFLAGS', ['-Wall',
|
||||
'-Werror',
|
||||
'-Wno-error=unused-variable',
|
||||
'-Wno-error=unused-function'])
|
||||
if not ctx.options.show_warnings:
|
||||
ctx.env.append_value('CFLAGS', ['-Wno-unused-variable',
|
||||
'-Wno-unused-function'])
|
||||
|
||||
### Defines, Includes
|
||||
|
||||
if not ctx.env.DEST_OS == 'win32':
|
||||
# Defines common for Unix and Unix-like platforms.
|
||||
# For details see:
|
||||
# http://man.he.net/man7/feature_test_macros
|
||||
ctx.env.append_value('DEFINES', '_REENTRANT')
|
||||
|
||||
# mkdtemp() is available only if _BSD_SOURCE is defined.
|
||||
ctx.env.append_value('DEFINES', '_BSD_SOURCE')
|
||||
|
||||
if ctx.env.DEST_OS == 'linux':
|
||||
# Recent GCC 5.x complains about _BSD_SOURCE under Linux:
|
||||
# _BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE
|
||||
ctx.env.append_value('DEFINES', '_DEFAULT_SOURCE')
|
||||
|
||||
# TODO What other platforms support _FORTIFY_SOURCE macro? OS X?
|
||||
# TODO OS X's CLang appears to support this macro as well. See:
|
||||
# https://marc.info/?l=cfe-dev&m=122032133830183
|
||||
|
||||
# For security, enable the _FORTIFY_SOURCE macro detecting buffer
|
||||
# overflows in various string and memory manipulation functions.
|
||||
if ctx.options.debug:
|
||||
ctx.env.append_value('CFLAGS', '-U_FORTIFY_SOURCE')
|
||||
elif ctx.env.CC_NAME == 'gcc':
|
||||
# Undefine this macro if already defined by default to avoid
|
||||
# "macro redefinition" errors.
|
||||
ctx.env.append_value('CFLAGS', '-U_FORTIFY_SOURCE')
|
||||
|
||||
# Define this macro.
|
||||
ctx.env.append_value('DEFINES', '_FORTIFY_SOURCE=2')
|
||||
# On Mac OS X, mkdtemp() is available only with _DARWIN_C_SOURCE.
|
||||
elif ctx.env.DEST_OS == 'darwin':
|
||||
ctx.env.append_value('DEFINES', '_DARWIN_C_SOURCE')
|
||||
|
||||
if ctx.env.DEST_OS == 'win32':
|
||||
ctx.env.append_value('DEFINES', 'WIN32')
|
||||
ctx.env.append_value('CPPPATH', '../zlib')
|
||||
|
||||
elif ctx.env.DEST_OS == 'sunos':
|
||||
ctx.env.append_value('DEFINES', 'SUNOS')
|
||||
if ctx.env.CC_NAME == 'gcc':
|
||||
# On Solaris using gcc the linker options for shared and static
|
||||
# libraries are slightly different from other platforms.
|
||||
ctx.env['SHLIB_MARKER'] = '-Wl,-Bdynamic'
|
||||
ctx.env['STLIB_MARKER'] = '-Wl,-Bstatic'
|
||||
# On Solaris using gcc, the compiler needs to be gnu99
|
||||
ctx.env.append_value('CFLAGS', '-std=gnu99')
|
||||
|
||||
elif ctx.env.DEST_OS == 'aix':
|
||||
ctx.env.append_value('DEFINES', 'AIX')
|
||||
# On AIX some APIs are restricted if _ALL_SOURCE is not defined.
|
||||
# In the case of PyInstaller, we need the AIX specific flag RTLD_MEMBER
|
||||
# for dlopen() which is used to load a shared object from a library
|
||||
# archive. We need to load the Python library like this:
|
||||
# dlopen("libpython2.7.a(libpython2.7.so)", RTLD_MEMBER)
|
||||
ctx.env.append_value('DEFINES', '_ALL_SOURCE')
|
||||
|
||||
# On AIX using gcc the linker options for shared and static
|
||||
# libraries are slightly different from other platforms.
|
||||
ctx.env['SHLIB_MARKER'] = '-Wl,-bdynamic'
|
||||
ctx.env['STLIB_MARKER'] = '-Wl,-bstatic'
|
||||
|
||||
elif ctx.env.DEST_OS == 'hpux':
|
||||
ctx.env.append_value('DEFINES', 'HPUX')
|
||||
if ctx.env.CC_NAME == 'gcc':
|
||||
if ctx.env.PYI_ARCH == '32bit':
|
||||
ctx.env.append_value('LIBPATH', '/usr/local/lib/hpux32')
|
||||
ctx.env.append_value('STATICLIBPATH', '/usr/local/lib/hpux32')
|
||||
else:
|
||||
ctx.env.append_value('LIBPATH', '/usr/local/lib/hpux64')
|
||||
ctx.env.append_value('STATICLIBPATH', '/usr/local/lib/hpux64')
|
||||
|
||||
|
||||
elif ctx.env.DEST_OS == 'darwin':
|
||||
# OS X 10.7 might not understand some load commands.
|
||||
# The following variable fixes 10.7 compatibility.
|
||||
# According to OS X doc this variable is equivalent to gcc option:
|
||||
# -mmacosx-version-min=10.7
|
||||
os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7'
|
||||
|
||||
### Libraries
|
||||
|
||||
if ctx.env.DEST_OS == 'win32':
|
||||
if ctx.env.CC_NAME == 'msvc':
|
||||
ctx.check_libs_msvc('user32 comctl32 kernel32 advapi32 ws2_32',
|
||||
mandatory=True)
|
||||
else:
|
||||
ctx.check_cc(lib='user32', mandatory=True)
|
||||
ctx.check_cc(lib='comctl32', mandatory=True)
|
||||
ctx.check_cc(lib='kernel32', mandatory=True)
|
||||
ctx.check_cc(lib='advapi32', mandatory=True)
|
||||
ctx.check_cc(lib='ws2_32', mandatory=True)
|
||||
else:
|
||||
# Mac OS X and FreeBSD do not need libdl.
|
||||
# https://stackoverflow.com/questions/20169660/where-is-libdl-so-on-mac-os-x
|
||||
if ctx.env.DEST_OS not in ('darwin', 'freebsd', 'openbsd'):
|
||||
ctx.check_cc(lib='dl', mandatory=True)
|
||||
if ctx.env.DEST_OS == 'freebsd' and sysconfig.get_config_var('HAVE_PTHREAD_H'):
|
||||
# On FreeBSD if python has threads: libthr needs to be loaded in
|
||||
# the main process, so the bootloader needs to be link to thr.
|
||||
ctx.check_cc(lib='thr', mandatory=True)
|
||||
ctx.check_cc(lib='z', mandatory=True, uselib_store='Z')
|
||||
# This uses Boehm GC to manage memory - it replaces malloc() / free()
|
||||
# functions. Some messages are printed if memory is not deallocated.
|
||||
if ctx.options.boehmgc:
|
||||
ctx.check_cc(lib='gc', mandatory=True)
|
||||
ctx.env.append_value('DEFINES', 'PYI_LEAK_DETECTOR')
|
||||
ctx.env.append_value('DEFINES', 'GC_FIND_LEAK')
|
||||
ctx.env.append_value('DEFINES', 'GC_DEBUG')
|
||||
ctx.env.append_value('DEFINES', 'SAVE_CALL_CHAIN')
|
||||
|
||||
### Functions
|
||||
|
||||
# The old ``function_name`` parameter to ``check_cc`` is no longer
|
||||
# supported. This code is based on old waf source at
|
||||
# https://gitlab.com/ita1024/waf/commit/62fe305d04ed37b1be1a3327a74b2fee6c458634#255b2344e5268e6a34bedd2f8c4680798344fec7.
|
||||
SNIP_FUNCTION = '''
|
||||
#include <%s>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
void (*p)();
|
||||
|
||||
(void)argc; (void)argv;
|
||||
p=(void(*)())(%s);
|
||||
return !p;
|
||||
}
|
||||
'''
|
||||
# OS support for these functions varies.
|
||||
for header, function_name in (('stdlib.h', 'unsetenv'),
|
||||
('stdlib.h', 'mkdtemp'),
|
||||
('string.h', 'strndup'),
|
||||
('string.h', 'strnlen')):
|
||||
ctx.check(
|
||||
fragment=SNIP_FUNCTION % (header, function_name),
|
||||
mandatory=False,
|
||||
define_name=ctx.have_define(function_name),
|
||||
msg='Checking for function %s' % function_name)
|
||||
# ctx.check(lib=["crypto", "ssl", "curl"])
|
||||
### CFLAGS
|
||||
|
||||
if ctx.env.DEST_OS == 'win32':
|
||||
if ctx.env.CC_NAME == 'msvc':
|
||||
# Use Unicode entry point wmain/wWinMain and wchar_t WinAPI
|
||||
ctx.env.append_value('CFLAGS', '-DUNICODE')
|
||||
ctx.env.append_value('CFLAGS', '-D_UNICODE')
|
||||
# set XP target as minimal target OS ver. when using Windows w/MSVC
|
||||
# https://blogs.msdn.microsoft.com/vcblog/2012/10/08/windows-xp-targeting-with-c-in-visual-studio-2012/
|
||||
ctx.env.append_value('LINKFLAGS', '/SUBSYSTEM:CONSOLE,%s' % (
|
||||
'5.01' if ctx.env.PYI_ARCH == '32bit' else '5.02'))
|
||||
else:
|
||||
# Use Visual C++ compatible alignment
|
||||
ctx.env.append_value('CFLAGS', '-mms-bitfields')
|
||||
|
||||
# Define UNICODE and _UNICODE for wchar_t WinAPI
|
||||
ctx.env.append_value('CFLAGS', '-municode')
|
||||
|
||||
# Use Unicode entry point wmain/wWinMain
|
||||
ctx.env.append_value('LINKFLAGS', '-municode')
|
||||
if ctx.env.DEST_OS == 'darwin':
|
||||
ctx.env.append_value('CFLAGS', '-mmacosx-version-min=10.7')
|
||||
ctx.env.append_value('LINKFLAGS', '-mmacosx-version-min=10.7')
|
||||
|
||||
# On linux link only with needed libraries.
|
||||
# -Wl,--as-needed is on some platforms detected during configure but
|
||||
# fails during build. (Mac OS X, Solaris, AIX)
|
||||
if ctx.env.DEST_OS == 'linux' and ctx.check_cc(cflags='-Wl,--as-needed'):
|
||||
ctx.env.append_value('LINKFLAGS', '-Wl,--as-needed')
|
||||
|
||||
if ctx.env.CC_NAME != 'msvc':
|
||||
# This tool allows reducing the size of executables.
|
||||
ctx.find_program([assoc_programm(ctx, 'strip')], var='STRIP')
|
||||
ctx.load('strip', tooldir='tools')
|
||||
# There is a strip flag for AIX environment
|
||||
if ctx.env.DEST_OS == 'aix':
|
||||
if ctx.env.PYI_ARCH == '32bit':
|
||||
ctx.env.append_value('STRIPFLAGS', '-X32')
|
||||
elif ctx.env.PYI_ARCH == '64bit':
|
||||
ctx.env.append_value('STRIPFLAGS', '-X64')
|
||||
|
||||
ctx.env.append_value('LINKFLAGS', '-pthread')
|
||||
|
||||
def windowed(name, baseenv):
|
||||
"""Setup windowed environment based on `baseenv`."""
|
||||
ctx.setenv(name, baseenv) # Inherit from `baseenv`.
|
||||
ctx.env.append_value('DEFINES', 'WINDOWED')
|
||||
|
||||
if ctx.env.DEST_OS == 'win32':
|
||||
if ctx.env.CC_NAME != 'msvc':
|
||||
# For MinGW disable console window on Windows - MinGW option
|
||||
# TODO Is it necessary to have -mwindows for C and LINK flags?
|
||||
ctx.env.append_value('LINKFLAGS', '-mwindows')
|
||||
ctx.env.append_value('CFLAGS', '-mwindows')
|
||||
else:
|
||||
_link_flags = ctx.env._get_list_value_for_modification('LINKFLAGS')
|
||||
_subsystem = [x for x in _link_flags if x.startswith('/SUBSYSTEM:')]
|
||||
for parameter in _subsystem:
|
||||
_link_flags.remove(parameter)
|
||||
ctx.env.append_value('LINKFLAGS', '/SUBSYSTEM:WINDOWS,%s' % (
|
||||
'5.01' if ctx.env.PYI_ARCH == '32bit' else '5.02'))
|
||||
elif ctx.env.DEST_OS == 'darwin':
|
||||
# To support catching AppleEvents and running as ordinary OSX GUI
|
||||
# app, we have to link against the Carbon framework.
|
||||
# This linkage only needs to be there for the windowed bootloaders.
|
||||
ctx.env.append_value('LINKFLAGS', '-framework')
|
||||
ctx.env.append_value('LINKFLAGS', 'Carbon')
|
||||
# TODO Do we need to link with this framework?
|
||||
# conf.env.append_value('LINKFLAGS', '-framework')
|
||||
# conf.env.append_value('LINKFLAGS', 'ApplicationServices')
|
||||
|
||||
### DEBUG and RELEASE environments
|
||||
basic_env = ctx.env
|
||||
|
||||
## setup DEBUG environment
|
||||
ctx.setenv('debug', basic_env) # Ensure env contains shared values.
|
||||
debug_env = ctx.env
|
||||
# This defines enable verbose console output of the bootloader.
|
||||
ctx.env.append_value('DEFINES', ['LAUNCH_DEBUG'])
|
||||
ctx.env.append_value('DEFINES', 'NDEBUG')
|
||||
|
||||
## setup windowed DEBUG environment
|
||||
windowed('debugw', debug_env)
|
||||
|
||||
## setup RELEASE environment
|
||||
ctx.setenv('release', basic_env) # Ensure env contains shared values.
|
||||
release_env = ctx.env
|
||||
ctx.env.append_value('DEFINES', 'NDEBUG')
|
||||
|
||||
## setup windowed RELEASE environment
|
||||
windowed('releasew', release_env)
|
||||
|
||||
|
||||
# TODO Use 'strip' command to decrease the size of compiled bootloaders.
|
||||
def build(ctx):
|
||||
if not ctx.variant:
|
||||
ctx.fatal('Call "python waf all" to compile all bootloaders.')
|
||||
exe_name = variants[ctx.variant]
|
||||
|
||||
install_path = os.path.join(os.getcwd(), '../PyInstaller/bootloader',
|
||||
ctx.env.PYI_SYSTEM + "-" + ctx.env.PYI_ARCH)
|
||||
install_path = os.path.normpath(install_path)
|
||||
|
||||
if machine():
|
||||
install_path += '-' + machine()
|
||||
|
||||
if not ctx.env.LIB_Z:
|
||||
# If the operating system does not provide zlib, build our own. The
|
||||
# configure phase defines whether or not zlib is mandatory for a
|
||||
# platform.
|
||||
ctx.stlib(
|
||||
source=ctx.path.ant_glob('zlib/*.c'),
|
||||
target='static_zlib',
|
||||
name='Z',
|
||||
includes='zlib')
|
||||
|
||||
# By default strip final executables to make them smaller.
|
||||
features = 'strip'
|
||||
if ctx.env.CC_NAME == 'msvc':
|
||||
# Do not strip bootloaders when using MSVC.
|
||||
features = ''
|
||||
|
||||
if ctx.env.DEST_OS == 'win32':
|
||||
# Use different RC file (icon) for console/windowed mode - remove '_d'
|
||||
icon_rc = 'windows/' + exe_name.replace('_d', '') + '.rc'
|
||||
# On Windows we need to link library zlib statically.
|
||||
ctx.program(
|
||||
source=ctx.path.ant_glob(['src/*.c', icon_rc]),
|
||||
target=exe_name,
|
||||
install_path=install_path,
|
||||
use='USER32 COMCTL32 KERNEL32 ADVAPI32 WS2_32 Z',
|
||||
includes='src windows zlib',
|
||||
features=features,
|
||||
)
|
||||
else:
|
||||
# Linux, Darwin (MacOSX), ...
|
||||
# Only the libs found will actually be used, so it's safe to list all
|
||||
# here. The decision if a lib is required for a specific platform is
|
||||
# made in the configure phase.
|
||||
libs = ['DL', 'M', 'Z', # 'z' - zlib, 'm' - math,
|
||||
'THR', 'pthread'] # may be used on FreBSD
|
||||
# staticlibs = ['curl']
|
||||
staticlibs = ['curl', 'ssl', 'crypto', 'z']
|
||||
if ctx.env.DEST_OS == 'aix':
|
||||
# link statically with zlib, case sensitive
|
||||
libs.remove('Z')
|
||||
staticlibs.append('z')
|
||||
if ctx.options.boehmgc:
|
||||
libs.append('GC')
|
||||
|
||||
ctx.program(
|
||||
source=ctx.path.ant_glob('src/*.c'),
|
||||
target=exe_name,
|
||||
includes='src',
|
||||
use=libs,
|
||||
stlib=staticlibs,
|
||||
stlibpath=['/usr/local/lib/', '/usr/lib/x86_64-linux-gnu/'],
|
||||
install_path=install_path,
|
||||
features=features)
|
||||
|
||||
|
||||
class make_all(BuildContext):
|
||||
"""
|
||||
Do build and install in one step.
|
||||
"""
|
||||
cmd = 'make_all'
|
||||
|
||||
def execute_build(ctx):
|
||||
Options.commands = ['build_debug', 'build_release']
|
||||
# On Windows and Mac OS X we also need console/windowed bootloaders.
|
||||
# On other platforms they make no sense.
|
||||
if ctx.env.DEST_OS in ('win32', 'darwin'):
|
||||
Options.commands += ['build_debugw', 'build_releasew']
|
||||
# Install bootloaders.
|
||||
Options.commands += ['install_debug', 'install_release']
|
||||
if ctx.env.DEST_OS in ('win32', 'darwin'):
|
||||
Options.commands += ['install_debugw', 'install_releasew']
|
||||
|
||||
|
||||
def all(ctx):
|
||||
"""
|
||||
Do configure, build and install in one step.
|
||||
"""
|
||||
# `all` is run prior to `configure`, thus it does not get a build context.
|
||||
# Thus another command `make_all` is required which gets the build
|
||||
# context and can make decisions based on the outcome of `configure`.
|
||||
Options.commands = ['distclean', 'configure', 'make_all']
|
||||
|
||||
|
||||
# Set up building several variants of bootloader.
|
||||
for x in variants:
|
||||
class BootloaderContext(BuildContext):
|
||||
cmd = 'build' + '_' + x
|
||||
variant = x
|
||||
|
||||
|
||||
class BootloaderInstallContext(InstallContext):
|
||||
cmd = 'install' + '_' + x
|
||||
variant = x
|
|
@ -1,189 +0,0 @@
|
|||
#include <windows.h>
|
||||
#include <wininet.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#pragma comment ( lib, "wininet" )
|
||||
#pragma comment ( lib, "Wininet.lib" )
|
||||
|
||||
#define minVersion 6.1
|
||||
|
||||
// Replaces a single occurrence of substring
|
||||
wchar_t* replaceSubstringOnce(wchar_t* str, wchar_t* to_be_replaced, wchar_t* replacement) {
|
||||
size_t str_size = wcslen(str);
|
||||
size_t to_be_replaced_size = wcslen(to_be_replaced);
|
||||
size_t replacement_size = wcslen(replacement);
|
||||
size_t result_size = str_size - to_be_replaced_size + replacement_size;
|
||||
wchar_t *result_string = (wchar_t*)malloc(sizeof(wchar_t) * (result_size));
|
||||
|
||||
for (int i = 0; i < (int)result_size; i++ ){
|
||||
result_string[i] = str[i];
|
||||
if(str[i] == to_be_replaced[0] && replacement_size != 0){
|
||||
BOOL should_replace = TRUE;
|
||||
// Check if started iterating over string that will be replaced
|
||||
for (int j = i; j < (i + to_be_replaced_size); j++){
|
||||
if(str[j] != to_be_replaced[j - i]) {
|
||||
should_replace = FALSE;
|
||||
}
|
||||
}
|
||||
// If string that needs to be replaced is found - replace it
|
||||
if (should_replace) {
|
||||
for (int j = i; j < (i + replacement_size); j++){
|
||||
result_string[j] = replacement[j - i];
|
||||
}
|
||||
i += to_be_replaced_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
result_string[result_size] = '\0';
|
||||
return result_string;
|
||||
}
|
||||
|
||||
struct versionInfo {
|
||||
DWORD MajorVersion;
|
||||
DWORD MinorVersion;
|
||||
DWORD Build;
|
||||
wchar_t* versionStr;
|
||||
};
|
||||
|
||||
struct versionInfo getWindowsVersion(int size){
|
||||
|
||||
DWORD dwVersion = 0;
|
||||
DWORD dwMajorVersion = 0;
|
||||
DWORD dwMinorVersion = 0;
|
||||
DWORD dwBuild = 0;
|
||||
|
||||
dwVersion = GetVersion();
|
||||
|
||||
// Get the Windows version.
|
||||
dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
|
||||
dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
|
||||
|
||||
// Get the build number.
|
||||
if (dwVersion < 0x80000000)
|
||||
dwBuild = (DWORD)(HIWORD(dwVersion));
|
||||
|
||||
wchar_t* versionStr = (wchar_t*)malloc(sizeof(wchar_t) * (size));
|
||||
snprintf(versionStr,
|
||||
size,
|
||||
"W%d.%d (%d)\n",
|
||||
dwMajorVersion,
|
||||
dwMinorVersion,
|
||||
dwBuild);
|
||||
struct versionInfo winVersionInfo = {dwMajorVersion, dwMinorVersion, dwBuild, versionStr};
|
||||
return winVersionInfo;
|
||||
}
|
||||
|
||||
int sendRequest(wchar_t* server, wchar_t* tunnel, BOOL tunnelUsed, wchar_t* windowsVersion){
|
||||
|
||||
wchar_t _page[] = L"/";
|
||||
HINTERNET hInternet, hConnect, hRequest;
|
||||
DWORD bytes_read;
|
||||
int finished = 0;
|
||||
if (tunnelUsed){
|
||||
hInternet = InternetOpen("Mozilla/5.0", INTERNET_OPEN_TYPE_PROXY, tunnel, NULL, 0);
|
||||
} else {
|
||||
hInternet = InternetOpen("Mozilla/5.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
if (hInternet == NULL) {
|
||||
printf("InternetOpen error : <%lu>\n", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
hConnect = InternetConnect(hInternet, server, 5001, "", "", INTERNET_SERVICE_HTTP, 0, 0);
|
||||
if (hConnect == NULL) {
|
||||
printf("hConnect error : <%lu>\n", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
hRequest = HttpOpenRequest(hConnect, L"POST", _page, NULL, NULL, NULL, NULL, 0);
|
||||
if (hRequest == NULL) {
|
||||
printf("hRequest error : <%lu>\n", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
BOOL isSend = HttpSendRequest(hRequest, NULL, 0, windowsVersion, sizeof(windowsVersion));
|
||||
if (!isSend){
|
||||
printf("HttpSendRequest error : (%lu)\n", GetLastError());
|
||||
return 1;
|
||||
}
|
||||
DWORD dwFileSize;
|
||||
dwFileSize = BUFSIZ;
|
||||
|
||||
char buffer[BUFSIZ+1];
|
||||
|
||||
while (1) {
|
||||
DWORD dwBytesRead;
|
||||
BOOL bRead;
|
||||
|
||||
bRead = InternetReadFile(
|
||||
hRequest,
|
||||
buffer,
|
||||
dwFileSize + 1,
|
||||
&dwBytesRead);
|
||||
|
||||
if (dwBytesRead == 0) break;
|
||||
|
||||
if (!bRead) {
|
||||
printf("InternetReadFile error : <%lu>\n", GetLastError());
|
||||
}
|
||||
else {
|
||||
buffer[dwBytesRead] = 0;
|
||||
printf("Retrieved %lu data bytes: %s\n", dwBytesRead, buffer);
|
||||
}
|
||||
}
|
||||
// close request
|
||||
InternetCloseHandle(hRequest);
|
||||
InternetCloseHandle(hConnect);
|
||||
InternetCloseHandle(hInternet);
|
||||
|
||||
return strcmp(buffer, "{\"status\":\"OK\"}\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
int ping_island(int argc, char * argv[])
|
||||
{
|
||||
|
||||
struct versionInfo windowsVersion = getWindowsVersion(20);
|
||||
|
||||
// Find which argument is tunnel flag
|
||||
int i, tunnel_i=0, server_i=0;
|
||||
char t_flag[] = "-t";
|
||||
char s_flag[] = "-s";
|
||||
for(i=1;i<argc;i++)
|
||||
{
|
||||
if(strcmp(argv[i],t_flag) == 0){
|
||||
tunnel_i = i+1;
|
||||
} else if(strcmp(argv[i],s_flag) == 0){
|
||||
server_i = i+1;
|
||||
}
|
||||
}
|
||||
|
||||
int request_failed = 1;
|
||||
// Convert server argument string to wchar_t
|
||||
wchar_t * server = (wchar_t*)malloc(sizeof(wchar_t) * (strlen(argv[server_i])+1));
|
||||
if (server_i != 0){
|
||||
mbstowcs_s(NULL, server, strlen(argv[server_i])+1, argv[server_i], strlen(argv[server_i]));
|
||||
wprintf(L"Server: %s\n", server);
|
||||
server = replaceSubstringOnce(server, L":5000", L"");
|
||||
request_failed = sendRequest(server, L"", FALSE, windowsVersion.versionStr);
|
||||
}
|
||||
|
||||
// Convert tunnel argument string to wchar_t
|
||||
if (tunnel_i != 0 && request_failed){
|
||||
wchar_t * tunnel = (wchar_t*)malloc(sizeof(wchar_t) * (strlen(argv[tunnel_i])+1));
|
||||
mbstowcs_s(NULL, tunnel, strlen(argv[tunnel_i])+1, argv[tunnel_i], strlen(argv[tunnel_i]));
|
||||
wprintf(L"Tunnel: %s\n", tunnel);
|
||||
request_failed = sendRequest(server, tunnel, TRUE, windowsVersion.versionStr);
|
||||
}
|
||||
|
||||
float OS_version = (float)windowsVersion.MajorVersion + ((float)windowsVersion.MinorVersion / 10);
|
||||
if (OS_version > minVersion) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
#include <windows.h>
|
||||
#include <wininet.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#pragma comment( lib, "wininet" )
|
||||
#pragma comment (lib, "Wininet.lib")
|
||||
|
||||
int ping_island(int argc, char * argv[]);
|
|
@ -1,213 +0,0 @@
|
|||
/*
|
||||
* ****************************************************************************
|
||||
* Copyright (c) 2013-2020, PyInstaller Development Team.
|
||||
*
|
||||
* Distributed under the terms of the GNU General Public License (version 2
|
||||
* or later) with exception for distributing the bootloader.
|
||||
*
|
||||
* The full license is in the file COPYING.txt, distributed with this software.
|
||||
*
|
||||
* SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Bootloader for a packed executable.
|
||||
*/
|
||||
|
||||
/* TODO: use safe string functions */
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <wchar.h>
|
||||
#else
|
||||
#include <limits.h> /* PATH_MAX */
|
||||
#endif
|
||||
#include <stdio.h> /* FILE */
|
||||
#include <stdlib.h> /* calloc */
|
||||
#include <string.h> /* memset */
|
||||
|
||||
/* PyInstaller headers. */
|
||||
#include "pyi_global.h" /* PATH_MAX for win32 */
|
||||
#include "pyi_path.h"
|
||||
#include "pyi_archive.h"
|
||||
#include "pyi_utils.h"
|
||||
#include "pyi_pythonlib.h"
|
||||
#include "pyi_launch.h"
|
||||
#include "pyi_win32_utils.h"
|
||||
|
||||
#include "old_machine_bootloader.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
#include <wininet.h>
|
||||
#include <tchar.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
#pragma comment( lib, "wininet" )
|
||||
#pragma comment (lib, "Wininet.lib")
|
||||
|
||||
|
||||
int
|
||||
pyi_main(int argc, char * argv[])
|
||||
{
|
||||
/* archive_status contain status information of the main process. */
|
||||
ARCHIVE_STATUS *archive_status = NULL;
|
||||
char executable[PATH_MAX];
|
||||
char homepath[PATH_MAX];
|
||||
char archivefile[PATH_MAX];
|
||||
int rc = 0;
|
||||
char *extractionpath = NULL;
|
||||
wchar_t * dllpath_w;
|
||||
|
||||
int too_old = ping_island(argc, argv);
|
||||
if (too_old){
|
||||
printf("OS too old, quiting.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* Visual C runtime incorrectly buffers stderr */
|
||||
setbuf(stderr, (char *)NULL);
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
VS("PyInstaller Bootloader 3.x\n");
|
||||
|
||||
/* TODO create special function to allocate memory for archive status pyi_arch_status_alloc_memory(archive_status); */
|
||||
archive_status = (ARCHIVE_STATUS *) calloc(1, sizeof(ARCHIVE_STATUS));
|
||||
|
||||
if (archive_status == NULL) {
|
||||
FATAL_PERROR("calloc", "Cannot allocate memory for ARCHIVE_STATUS\n");
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
pyi_path_executable(executable, argv[0]);
|
||||
pyi_path_archivefile(archivefile, executable);
|
||||
pyi_path_homepath(homepath, executable);
|
||||
|
||||
/* For the curious:
|
||||
* On Windows, the UTF-8 form of MEIPASS2 is passed to pyi_setenv, which
|
||||
* decodes to UTF-16 before passing it to the Windows API. So the var's value
|
||||
* is full unicode.
|
||||
*
|
||||
* On OS X/Linux, the MEIPASS2 value is passed as the bytes received from the OS.
|
||||
* Only Python will care about its encoding, and it is passed to Python using
|
||||
* PyUnicode_DecodeFSDefault.
|
||||
*/
|
||||
|
||||
extractionpath = pyi_getenv("_MEIPASS2");
|
||||
|
||||
/* If the Python program we are about to run invokes another PyInstaller
|
||||
* one-file program as subprocess, this subprocess must not be fooled into
|
||||
* thinking that it is already unpacked. Therefore, PyInstaller deletes
|
||||
* the _MEIPASS2 variable from the environment.
|
||||
*/
|
||||
|
||||
pyi_unsetenv("_MEIPASS2");
|
||||
|
||||
VS("LOADER: _MEIPASS2 is %s\n", (extractionpath ? extractionpath : "NULL"));
|
||||
|
||||
if (pyi_arch_setup(archive_status, homepath, &executable[strlen(homepath)])) {
|
||||
if (pyi_arch_setup(archive_status, homepath, &archivefile[strlen(homepath)])) {
|
||||
FATALERROR("Cannot open self %s or archive %s\n",
|
||||
executable, archivefile);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* These are used only in pyi_pylib_set_sys_argv, which converts to wchar_t */
|
||||
archive_status->argc = argc;
|
||||
archive_status->argv = argv;
|
||||
|
||||
#if defined(_WIN32) || defined(__APPLE__)
|
||||
|
||||
/* On Windows and Mac use single-process for --onedir mode. */
|
||||
if (!extractionpath && !pyi_launch_need_to_extract_binaries(archive_status)) {
|
||||
VS("LOADER: No need to extract files to run; setting extractionpath to homepath\n");
|
||||
extractionpath = homepath;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
if (extractionpath) {
|
||||
/* Add extraction folder to DLL search path */
|
||||
dllpath_w = pyi_win32_utils_from_utf8(NULL, extractionpath, 0);
|
||||
SetDllDirectory(dllpath_w);
|
||||
VS("LOADER: SetDllDirectory(%s)\n", extractionpath);
|
||||
free(dllpath_w);
|
||||
}
|
||||
#endif /* ifdef _WIN32 */
|
||||
|
||||
if (extractionpath) {
|
||||
VS("LOADER: Already in the child - running user's code.\n");
|
||||
|
||||
/* If binaries were extracted to temppath,
|
||||
* we pass it through status variable
|
||||
*/
|
||||
if (strcmp(homepath, extractionpath) != 0) {
|
||||
strncpy(archive_status->temppath, extractionpath, PATH_MAX);
|
||||
if (archive_status->temppath[PATH_MAX-1] != '\0') {
|
||||
VS("LOADER: temppath exceeds PATH_MAX\n");
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* Temp path exits - set appropriate flag and change
|
||||
* status->mainpath to point to temppath.
|
||||
*/
|
||||
archive_status->has_temp_directory = true;
|
||||
strcpy(archive_status->mainpath, archive_status->temppath);
|
||||
}
|
||||
|
||||
/* Main code to initialize Python and run user's code. */
|
||||
pyi_launch_initialize(archive_status);
|
||||
rc = pyi_launch_execute(archive_status);
|
||||
pyi_launch_finalize(archive_status);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
/* status->temppath is created if necessary. */
|
||||
if (pyi_launch_extract_binaries(archive_status)) {
|
||||
VS("LOADER: temppath is %s\n", archive_status->temppath);
|
||||
VS("LOADER: Error extracting binaries\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Run the 'child' process, then clean up. */
|
||||
|
||||
VS("LOADER: Executing self as child\n");
|
||||
pyi_setenv("_MEIPASS2",
|
||||
archive_status->temppath[0] !=
|
||||
0 ? archive_status->temppath : homepath);
|
||||
|
||||
VS("LOADER: set _MEIPASS2 to %s\n", pyi_getenv("_MEIPASS2"));
|
||||
|
||||
if (pyi_utils_set_environment(archive_status) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Transform parent to background process on OSX only. */
|
||||
pyi_parent_to_background();
|
||||
|
||||
/* Run user's code in a subprocess and pass command line arguments to it. */
|
||||
rc = pyi_utils_create_child(executable, archive_status, argc, argv);
|
||||
|
||||
VS("LOADER: Back to parent (RC: %d)\n", rc);
|
||||
|
||||
VS("LOADER: Doing cleanup\n");
|
||||
|
||||
if (archive_status->has_temp_directory == true) {
|
||||
pyi_remove_temp_path(archive_status->temppath);
|
||||
}
|
||||
pyi_arch_status_free_memory(archive_status);
|
||||
|
||||
}
|
||||
return rc;
|
||||
}
|
|
@ -13,11 +13,15 @@ class Bootloader(flask_restful.Resource):
|
|||
def post(self, **kw):
|
||||
data = Bootloader.parse_bootloader_request(request.data)
|
||||
resp = BootloaderService.parse_bootloader_data(data)
|
||||
return make_response({"status": "OK"}, 200)
|
||||
if resp:
|
||||
return make_response({"status": "RUN"}, 200)
|
||||
else:
|
||||
return make_response({"status": "ABORT"}, 200)
|
||||
|
||||
@staticmethod
|
||||
def parse_bootloader_request(request_data: bytes) -> Dict[str, str]:
|
||||
parsed_data = json.loads(request_data.decode().replace("\n", "")
|
||||
.replace("NAME=\"", "")
|
||||
.replace("\"\"", "\""))
|
||||
.replace("NAME=\"", "")
|
||||
.replace("\"\"", "\"")
|
||||
.replace("\":\",", "\":\"\","))
|
||||
return parsed_data
|
||||
|
|
|
@ -21,15 +21,17 @@ MIN_GLIBC_VERSION = 2.14
|
|||
class BootloaderService:
|
||||
|
||||
@staticmethod
|
||||
def parse_bootloader_data(data: Dict) -> str:
|
||||
def parse_bootloader_data(data: Dict) -> bool:
|
||||
data['ips'] = BootloaderService.remove_local_ips(data['ips'])
|
||||
if data['os_version'] == "":
|
||||
data['os_version'] = "Unknown OS"
|
||||
mongo.db.bootloader_telems.insert(data)
|
||||
will_monkey_run = BootloaderService.is_glibc_supported(data['glibc_version'])
|
||||
node = NodeService.get_or_create_node_from_bootloader_data(data, will_monkey_run)
|
||||
group_keywords = [data['system'], 'monkey']
|
||||
group_keywords.append('starting') if will_monkey_run else group_keywords.append('old')
|
||||
NodeService.set_node_group(node['_id'], NodeGroups.get_group_by_keywords(group_keywords))
|
||||
return "abc"
|
||||
return will_monkey_run
|
||||
|
||||
@staticmethod
|
||||
def is_glibc_supported(glibc_version_string) -> bool:
|
||||
|
|
|
@ -250,7 +250,7 @@ class NodeService:
|
|||
edge = EdgeService.get_or_create_edge(new_node['_id'], dst_node['id'])
|
||||
mongo.db.edge.update({"_id": edge["_id"]},
|
||||
{'$set': {'tunnel': bool(bootloader_data['tunnel']),
|
||||
'exploited': (not bool(bootloader_data['tunnel'])),
|
||||
# 'exploited': (not bool(bootloader_data['tunnel'])),
|
||||
'ip_address': bootloader_data['ips'][0],
|
||||
'group': NodeGroups.get_group_by_keywords(['island']).value}},
|
||||
upsert=False)
|
||||
|
|
Loading…
Reference in New Issue